summaryrefslogtreecommitdiffhomepage
path: root/src/app
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-10-24 18:48:54 +0900
committerAdam Malczewski <[email protected]>2026-10-24 18:48:54 +0900
commit34526ff48985643bed532b102e8943fa69e77a79 (patch)
tree4208ec0f5f1ef2cf1a9cd9710a442ce10a5f0c61 /src/app
parentdaefad66bdf8dee132d701a3b43ce0d227dde241 (diff)
parentb666d77df8cf4da6ae40fb5637268926f02cc44d (diff)
downloaddispatch-web-34526ff48985643bed532b102e8943fa69e77a79.tar.gz
dispatch-web-34526ff48985643bed532b102e8943fa69e77a79.zip
Merge branch 'feature/text-file-embeds' into dev
Diffstat (limited to 'src/app')
-rw-r--r--src/app/conversation-settings.svelte.ts16
-rw-r--r--src/app/store-types.ts4
-rw-r--r--src/app/store.svelte.ts7
-rw-r--r--src/app/views/ChatPane.svelte11
4 files changed, 36 insertions, 2 deletions
diff --git a/src/app/conversation-settings.svelte.ts b/src/app/conversation-settings.svelte.ts
index df259af..b853a8f 100644
--- a/src/app/conversation-settings.svelte.ts
+++ b/src/app/conversation-settings.svelte.ts
@@ -43,9 +43,11 @@ export function createConversationSettings(deps: {
// The active conversation's persisted working directory (per-tab). Seeded from
// the backend on focus change; null for a draft / when unset.
let cwd = $state<string | null>(null);
+ let textFileContextRevision = $state(0);
/** Refetch the workspace conversation's cwd into reactive state (works for a draft too). */
async function refreshCwd(): Promise<void> {
+ textFileContextRevision++;
const id = deps.workspaceConversationId();
try {
const res = await fetchImpl(`${httpBase}/conversations/${encodeURIComponent(id)}/cwd`);
@@ -68,6 +70,7 @@ export function createConversationSettings(deps: {
* so it is a silent no-op (mirrors `refreshCwd` for a draft).
*/
async function refreshComputer(): Promise<void> {
+ textFileContextRevision++;
const id = deps.workspaceConversationId();
// Clear immediately so a switch never shows the PREVIOUS conversation's
// computer while the fetch is in flight (null renders as "Local").
@@ -177,6 +180,9 @@ export function createConversationSettings(deps: {
refreshThinking,
refreshCompactPercent,
refreshVisionSettings,
+ get textFileContextRevision() {
+ return textFileContextRevision;
+ },
get cwd() {
return cwd;
},
@@ -213,7 +219,10 @@ export function createConversationSettings(deps: {
}
const data = (await res.json()) as CwdResponse;
const next = data.cwd ?? null;
- if (deps.workspaceConversationId() === id) cwd = next;
+ if (deps.workspaceConversationId() === id) {
+ cwd = next;
+ textFileContextRevision++;
+ }
return { ok: true, cwd: next };
} catch (err) {
return { ok: false, error: err instanceof Error ? err.message : "Set cwd request failed" };
@@ -241,7 +250,10 @@ export function createConversationSettings(deps: {
}
const data = (await res.json()) as ConversationComputerResponse;
const next = data.computerId ?? null;
- if (deps.workspaceConversationId() === id) computerId = next;
+ if (deps.workspaceConversationId() === id) {
+ computerId = next;
+ textFileContextRevision++;
+ }
return { ok: true, computerId: next };
} catch (err) {
return {
diff --git a/src/app/store-types.ts b/src/app/store-types.ts
index 774d041..6835166 100644
--- a/src/app/store-types.ts
+++ b/src/app/store-types.ts
@@ -35,6 +35,7 @@ import type {
HeartbeatStopResult,
} from "../features/heartbeat";
import type { LayoutStore } from "../features/layout";
+import type { TextFileClient } from "../features/markdown";
import type {
NamedAgent,
NamedAgentDeleteResult,
@@ -215,6 +216,9 @@ export interface AppStore {
warmNow(): Promise<WarmResult | null>;
/** The workspace conversation's persisted working directory, or null when unset. */
readonly cwd: string | null;
+ /** Invalidates live-file routing after known settings changes. */
+ readonly textFileContextRevision: number;
+ createTextFileClient(conversationId: string): TextFileClient;
/** The conversation workspace settings target: the active tab, or the pending draft's id. */
readonly currentConversationId: string;
/**
diff --git a/src/app/store.svelte.ts b/src/app/store.svelte.ts
index fa12036..8fcc4cc 100644
--- a/src/app/store.svelte.ts
+++ b/src/app/store.svelte.ts
@@ -21,6 +21,7 @@ import {
createLayoutStore,
listPanelViews,
} from "../features/layout";
+import { createTextFileClient } from "../features/markdown";
import type { NamedAgent, NamedAgentSelectionSnapshot } from "../features/named-agents";
import type { PluginsStore } from "../features/plugins";
import { createPluginsHttp, createPluginsStore } from "../features/plugins";
@@ -472,6 +473,12 @@ export function createAppStore(opts?: CreateAppStoreOptions): AppStore {
get storage() {
return localStorageOpt;
},
+ get textFileContextRevision(): number {
+ return settings.textFileContextRevision;
+ },
+ createTextFileClient(conversationId) {
+ return createTextFileClient(httpBase, conversationId, fetchImpl);
+ },
get cwd(): string | null {
return settings.cwd;
},
diff --git a/src/app/views/ChatPane.svelte b/src/app/views/ChatPane.svelte
index d132fad..b5e05bb 100644
--- a/src/app/views/ChatPane.svelte
+++ b/src/app/views/ChatPane.svelte
@@ -13,6 +13,16 @@
let { ports }: { ports: AppViewPorts } = $props();
const store = $derived(ports.store);
+ const textFiles = $derived.by(() => {
+ void store.activeWorkspaceId;
+ void store.textFileContextRevision;
+ const id = store.activeConversationId;
+ return id ? store.createTextFileClient(id) : undefined;
+ });
+ $effect(() => {
+ const client = textFiles;
+ return () => client?.dispose();
+ });
// Cache timer: Claude Code subscription models only (5-minute prompt-cache expiry).
const cacheTimer = $derived(
@@ -88,6 +98,7 @@
providerRetry={store.activeChat.providerRetry}
apiBaseUrl={store.httpBase}
cwd={store.cwd}
+ {textFiles}
{cacheTimer}
/>
{/key}