@norman-else/dsh-claude 0.1.45 → 0.1.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +55 -55
- package/LICENSE +21 -21
- package/README.md +200 -200
- package/cordis.patch.yml +12 -12
- package/legacy-preset/agent.cordis.yml +11 -11
- package/legacy-preset/preset.yml +4 -4
- package/lib/bin.mjs +0 -0
- package/lib/bin.mjs.map +1 -1
- package/lib/client.d.ts +3 -1
- package/lib/client.js +599 -241
- package/lib/client.js.map +1 -1
- package/lib/events-oovRTmX7.mjs.map +1 -1
- package/lib/index.mjs +123 -16
- package/lib/index.mjs.map +1 -1
- package/lib/presenters-BVWj7u0a.mjs.map +1 -1
- package/lib/preset-installer-CuosP3sA.mjs.map +1 -1
- package/lib/preset-route.mjs.map +1 -1
- package/package.json +197 -197
- package/preset/claude/agent.cordis.yml +11 -11
- package/preset/claude/preset.yml +4 -4
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["record","string","record","string","latest","claudeQuery","query","record","claudeQuery","query","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","collect","run","claudeQuery","MAX_TEXT_CHARS","MAX_PATH_CHARS","claudeQuery","safeMessage","MAX_SESSION_ID_CHARS","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","GH_TIMEOUT_MS","collect","record","MAX_REPLY_CHARS","claudeQuery","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","MAX_PATH_CHARS","collect","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","collect","MAX_BODY_BYTES","record","readJson","string","optionalString","ndjson","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","readJson","sessionId","string","MAX_OUTPUT_BYTES","MAX_SESSION_ID_CHARS","MAX_REQUEST_BYTES","MAX_REPLY_CHARS","record","MAX_SESSION_ID_CHARS","MAX_BODY_BYTES","record","readJson","MAX_PATH_CHARS","record","MAX_BODY_BYTES","record","readJson","record","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","readJson","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","readJson","safeMessage"],"sources":["../src/rewind.ts","../src/sidecar.ts","../src/async-queue.ts","../src/plan-feedback.ts","../src/permission.ts","../src/user-question.ts","../src/sdk-messages.ts","../src/model-catalog.ts","../src/plan-usage.ts","../src/spawn.ts","../src/worktree-snapshot.ts","../src/supervisor.ts","../src/review-comments.ts","../src/session-title.ts","../src/adapter.ts","../src/plugin-budget.ts","../src/http.ts","../src/doctor-routes.ts","../src/projection-routes.ts","../src/diff-funcname.ts","../src/repository-status.ts","../src/branch-name.ts","../src/repository-setup.ts","../src/repository-actions.ts","../src/repository-setup-routes.ts","../src/repository-action-routes.ts","../src/editor-open.ts","../src/editor-open-routes.ts","../src/prompts.ts","../src/github-url.ts","../src/pr-feedback.ts","../src/pr-feedback-routes.ts","../src/repository-status-routes.ts","../src/repository-file-routes.ts","../src/jira.ts","../src/jira-routes.ts","../src/ask.ts","../src/ask-routes.ts","../src/review-comment-routes.ts","../src/plan-feedback-routes.ts","../src/client-diagnostics-routes.ts","../src/rewind-routes.ts","../src/update-routes.ts","../src/plan-usage-routes.ts","../src/global-settings.ts","../src/index.ts"],"sourcesContent":["/** Rewind: drop one user message and everything after it.\r\n *\r\n * Two halves, because the two sides of a Claude session are owned by\r\n * different processes:\r\n *\r\n * - Claude's own transcript is rewound for real. Every completed DSH turn\r\n * records the last chain-entry uuid Claude emitted for it, so the next\r\n * spawn resumes at the kept turn's anchor (`resumeSessionAt`) and the model\r\n * genuinely forgets the discarded turns.\r\n * - The DSH session log is append-only and the Host renders every event it\r\n * holds — even compaction keeps the shadowed conversation on screen — so the\r\n * discarded rows are recorded here as hidden seq ranges and suppressed by\r\n * the browser instead of deleted.\r\n *\r\n * The files are a third half, and an optional one: every turn is admitted\r\n * against a captured working tree, so a rewind can put the checkout back to\r\n * where the discarded turns found it rather than leaving Claude to resume\r\n * against edits it no longer remembers making.\r\n */\r\nimport type { SessionEvent } from '@deepseek-ai/dsh-session'\r\n\r\n/** One inclusive span of hidden surface seqs. */\r\nexport interface ClaudeRewindRange {\r\n readonly start: number\r\n readonly end: number\r\n}\r\n\r\n/** The last Claude chain entry of one completed DSH turn. */\r\nexport interface ClaudeRewindAnchor {\r\n readonly turn: number\r\n readonly uuid: string\r\n}\r\n\r\n/** The git tree one DSH turn was admitted against. */\r\nexport interface ClaudeRewindSnapshot {\r\n readonly turn: number\r\n readonly tree: string\r\n}\r\n\r\n/** Fork target for the next Claude spawn; `fresh` starts an empty session. */\r\nexport type ClaudeRewindResume = { readonly resumeAt: string } | { readonly fresh: true }\r\n\r\nexport interface ClaudeRewindState {\r\n /** Hidden seq ranges, ascending and non-overlapping. */\r\n readonly ranges: readonly ClaudeRewindRange[]\r\n /** Chain anchors of the turns Claude still holds, ascending by turn. */\r\n readonly anchors: readonly ClaudeRewindAnchor[]\r\n /** Working trees the surviving turns started from, ascending by turn. */\r\n readonly snapshots: readonly ClaudeRewindSnapshot[]\r\n /** Armed once by a rewind, consumed by the next Claude spawn. */\r\n readonly pending?: ClaudeRewindResume\r\n}\r\n\r\nexport const EMPTY_REWIND_STATE: ClaudeRewindState = { ranges: [], anchors: [], snapshots: [] }\r\n\r\n/** Sessions outlive their rewinds; every list stays bounded. */\r\nexport const MAX_REWIND_RANGES = 200\r\nexport const MAX_REWIND_ANCHORS = 2_000\r\n/** Shorter than the anchors: each entry pins a whole tree in the object\r\n * database, and a rewind reaches back turns rather than hundreds of them. */\r\nexport const MAX_REWIND_SNAPSHOTS = 100\r\n\r\n/** Absorb one span into an ascending, non-overlapping range list. Adjacent\r\n * spans merge so a rewind of a rewind reads as one hidden block. */\r\nexport function mergeRewindRanges(\r\n ranges: readonly ClaudeRewindRange[],\r\n addition: ClaudeRewindRange,\r\n): ClaudeRewindRange[] {\r\n const merged: ClaudeRewindRange[] = []\r\n let { start, end } = addition\r\n for (const range of [...ranges].sort((left, right) => left.start - right.start)) {\r\n if (range.end + 1 < start) merged.push(range)\r\n else if (range.start > end + 1) {\r\n merged.push({ start, end })\r\n start = range.start\r\n end = range.end\r\n } else {\r\n start = Math.min(start, range.start)\r\n end = Math.max(end, range.end)\r\n }\r\n }\r\n merged.push({ start, end })\r\n return merged.slice(-MAX_REWIND_RANGES)\r\n}\r\n\r\nexport function isRewound(ranges: readonly ClaudeRewindRange[], seq: number): boolean {\r\n return ranges.some(range => seq >= range.start && seq <= range.end)\r\n}\r\n\r\n/** Record one completed turn's last chain entry, replacing a re-run turn. */\r\nexport function recordRewindAnchor(\r\n state: ClaudeRewindState,\r\n anchor: ClaudeRewindAnchor,\r\n): ClaudeRewindState {\r\n const anchors = [...state.anchors.filter(item => item.turn !== anchor.turn), anchor]\r\n .sort((left, right) => left.turn - right.turn)\r\n .slice(-MAX_REWIND_ANCHORS)\r\n return { ...state, anchors }\r\n}\r\n\r\n/** Record the working tree one turn was admitted against, replacing a re-run\r\n * turn's. */\r\nexport function recordRewindSnapshot(\r\n state: ClaudeRewindState,\r\n snapshot: ClaudeRewindSnapshot,\r\n): ClaudeRewindState {\r\n const snapshots = [...state.snapshots.filter(item => item.turn !== snapshot.turn), snapshot]\r\n .sort((left, right) => left.turn - right.turn)\r\n .slice(-MAX_REWIND_SNAPSHOTS)\r\n return { ...state, snapshots }\r\n}\r\n\r\n/** The turn a surface seq belongs to: the first turn opened at or after it.\r\n * A message accepted but never run belongs to no logged turn, so nothing\r\n * Claude holds is discarded and every anchor stays valid. */\r\nexport function turnAtOrAfter(events: readonly SessionEvent[], seq: number): number | undefined {\r\n for (const event of events) {\r\n if (event.seq >= seq && event.type === 'turn/start') return event.data.turn\r\n }\r\n return undefined\r\n}\r\n\r\n/** The working tree a rewind at `seq` restores: the snapshot of the first turn\r\n * it discards. Undefined when nothing is discarded, or when that turn ran\r\n * before this session captured trees. */\r\nexport function rewindRestoreTree(\r\n state: ClaudeRewindState,\r\n events: readonly SessionEvent[],\r\n seq: number,\r\n): string | undefined {\r\n const turn = turnAtOrAfter(events, seq)\r\n return turn === undefined ? undefined : state.snapshots.find(item => item.turn === turn)?.tree\r\n}\r\n\r\n/** Plan one rewind at `seq`, or undefined when the seq is not in the log.\r\n * Anchors and snapshots of the discarded turns go with them: after this\r\n * rewind Claude no longer holds those entries, so a later rewind must never\r\n * fork at one — nor restore a tree for a turn that no longer exists. */\r\nexport function planRewind(\r\n state: ClaudeRewindState,\r\n events: readonly SessionEvent[],\r\n seq: number,\r\n): ClaudeRewindState | undefined {\r\n const last = events.at(-1)?.seq\r\n if (last === undefined || seq > last) return undefined\r\n const turn = turnAtOrAfter(events, seq) ?? Number.MAX_SAFE_INTEGER\r\n const anchors = state.anchors.filter(anchor => anchor.turn < turn)\r\n const kept = anchors.at(-1)\r\n return {\r\n ranges: mergeRewindRanges(state.ranges, { start: seq, end: last }),\r\n anchors,\r\n snapshots: state.snapshots.filter(item => item.turn < turn),\r\n pending: kept === undefined ? { fresh: true } : { resumeAt: kept.uuid },\r\n }\r\n}\r\n","import { randomUUID } from 'node:crypto'\r\nimport { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\r\nimport { join } from 'node:path'\r\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\r\nimport type { SessionEvent } from '@deepseek-ai/dsh-session'\r\nimport {\r\n latestClaudeContextUsage,\r\n latestClaudeSessionBinding,\r\n latestClaudeTasks,\r\n normalizeActivity,\r\n normalizeContextUsage,\r\n normalizeTasksEvent,\r\n redactText,\r\n type ClaudeActivityEvent,\r\n type ClaudeActivityInput,\r\n type ClaudeContextUsageEvent,\r\n type ClaudeContextUsageInput,\r\n type ClaudeSessionBoundEvent,\r\n type ClaudeTaskInfo,\r\n type ClaudeTasksEvent,\r\n} from './events.ts'\r\nimport { CLAUDE_ACTIVITY_EVENT, SDK_VERSION, type ClaudeRenderMode } from './constants.ts'\r\nimport {\r\n EMPTY_REWIND_STATE,\r\n MAX_REWIND_ANCHORS,\r\n MAX_REWIND_RANGES,\r\n MAX_REWIND_SNAPSHOTS,\r\n recordRewindAnchor,\r\n recordRewindSnapshot,\r\n type ClaudeRewindAnchor,\r\n type ClaudeRewindRange,\r\n type ClaudeRewindSnapshot,\r\n type ClaudeRewindState,\r\n} from './rewind.ts'\r\n\r\nconst SIDECAR_SCHEMA_VERSION = 1\r\nconst MAX_ACTIVITIES = 10_000\r\n/** Trailing window that coalesces per-token transcript persistence into one\r\n * atomic disk write; live subscribers are notified synchronously regardless. */\r\nconst TEXT_FLUSH_MS = 150\r\n\r\nexport interface ClaudeSidecarProjection {\r\n readonly schemaVersion: typeof SIDECAR_SCHEMA_VERSION\r\n readonly revision: number\r\n readonly binding?: ClaudeSessionBoundEvent\r\n readonly activities: readonly ClaudeActivityEvent[]\r\n readonly contextUsage?: ClaudeContextUsageEvent\r\n readonly tasks?: ClaudeTasksEvent\r\n readonly rewind?: ClaudeRewindState\r\n}\r\n\r\n/** Change notification published to live subscribers after each accepted write.\r\n *\r\n * `checkpoint` is the one kind that carries no change: it restates where the\r\n * stream stands so a reader can notice it is behind. See {@link ClaudeSidecarRepository.checkpoint}. */\r\nexport type ClaudeSidecarDelta =\r\n | { kind: 'text'; turn: number; step: number; ordinal: number; append?: string; text?: string; renderer?: ClaudeRenderMode }\r\n | { kind: 'activity'; activity: ClaudeActivityEvent }\r\n | { kind: 'contextUsage'; value: ClaudeContextUsageEvent }\r\n | { kind: 'tasks'; value: ClaudeTasksEvent }\r\n | { kind: 'sync' }\r\n | { kind: 'checkpoint' }\r\n\r\n/** One delta as subscribers see it: numbered, so a reader that applies them in\r\n * order can tell a missing one from a slow one.\r\n *\r\n * The projection's own `revision` cannot do this job. Streaming prose notifies\r\n * subscribers without touching disk (see {@link ClaudeSidecarRepository.appendTranscriptText}),\r\n * so revisions and notifications advance on different clocks; this counter\r\n * advances once per notification and nothing else reads it. */\r\nexport type ClaudeSidecarNotification = ClaudeSidecarDelta & { readonly seq: number }\r\n\r\nexport interface ClaudeSidecarRepositoryOptions {\r\n readonly root?: string\r\n readonly legacyRoot?: string\r\n}\r\n\r\nfunction emptyProjection(): ClaudeSidecarProjection {\r\n return { schemaVersion: SIDECAR_SCHEMA_VERSION, revision: 0, activities: [] }\r\n}\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n ? value as Record<string, unknown>\r\n : undefined\r\n}\r\n\r\nfunction finiteInteger(value: unknown): value is number {\r\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0\r\n}\r\n\r\nfunction string(value: unknown, max: number): value is string {\r\n return typeof value === 'string' && value.length > 0 && value.length <= max\r\n}\r\n\r\nfunction binding(value: unknown): ClaudeSessionBoundEvent | undefined {\r\n const input = record(value)\r\n if (input === undefined\r\n || !string(input.claudeSessionId, 512)\r\n || !string(input.sdkVersion, 128)\r\n || !string(input.cwd, 4_096)\r\n || (input.cliVersion !== undefined && !string(input.cliVersion, 128))) return undefined\r\n return {\r\n claudeSessionId: input.claudeSessionId,\r\n sdkVersion: input.sdkVersion,\r\n cwd: input.cwd,\r\n ...(input.cliVersion === undefined ? {} : { cliVersion: input.cliVersion }),\r\n }\r\n}\r\n\r\nconst ACTIVITY_KINDS = new Set(['text', 'status', 'compaction', 'thinking', 'tool-call', 'tool-result', 'permission', 'question', 'subagent', 'usage', 'warning', 'error'])\r\nconst ACTIVITY_PHASES = new Set(['started', 'updated', 'completed', 'denied', 'failed'])\r\n\r\nfunction activity(value: unknown): ClaudeActivityEvent | undefined {\r\n const input = record(value)\r\n if (input === undefined\r\n || !finiteInteger(input.turn)\r\n || !finiteInteger(input.step)\r\n || !finiteInteger(input.ordinal)\r\n || typeof input.kind !== 'string'\r\n || !ACTIVITY_KINDS.has(input.kind)\r\n || (input.phase !== undefined && (typeof input.phase !== 'string' || !ACTIVITY_PHASES.has(input.phase)))) return undefined\r\n return normalizeActivity(input as unknown as ClaudeActivityEvent)\r\n}\r\n\r\nfunction contextUsage(value: unknown): ClaudeContextUsageEvent | undefined {\r\n const input = record(value)\r\n if (input === undefined || !Array.isArray(input.categories)) return undefined\r\n return normalizeContextUsage(input as unknown as ClaudeContextUsageInput)\r\n}\r\n\r\nfunction rewind(value: unknown): ClaudeRewindState | undefined {\r\n const input = record(value)\r\n if (input === undefined\r\n || !Array.isArray(input.ranges) || input.ranges.length > MAX_REWIND_RANGES\r\n || !Array.isArray(input.anchors) || input.anchors.length > MAX_REWIND_ANCHORS) return undefined\r\n const ranges: ClaudeRewindRange[] = []\r\n for (const item of input.ranges) {\r\n const range = record(item)\r\n if (range === undefined || !finiteInteger(range.start) || !finiteInteger(range.end) || range.end < range.start) return undefined\r\n ranges.push({ start: range.start, end: range.end })\r\n }\r\n const anchors: ClaudeRewindAnchor[] = []\r\n for (const item of input.anchors) {\r\n const anchor = record(item)\r\n if (anchor === undefined || !finiteInteger(anchor.turn) || !string(anchor.uuid, 128)) return undefined\r\n anchors.push({ turn: anchor.turn, uuid: anchor.uuid })\r\n }\r\n // Documents written before working-tree snapshots existed carry no list;\r\n // they read as a session that simply has no tree to restore.\r\n const snapshots: ClaudeRewindSnapshot[] = []\r\n if (input.snapshots !== undefined) {\r\n if (!Array.isArray(input.snapshots) || input.snapshots.length > MAX_REWIND_SNAPSHOTS) return undefined\r\n for (const item of input.snapshots) {\r\n const snapshot = record(item)\r\n if (snapshot === undefined || !finiteInteger(snapshot.turn) || !string(snapshot.tree, 64)) return undefined\r\n snapshots.push({ turn: snapshot.turn, tree: snapshot.tree })\r\n }\r\n }\r\n const pending = record(input.pending)\r\n if (input.pending !== undefined && pending === undefined) return undefined\r\n if (pending === undefined) return { ranges, anchors, snapshots }\r\n if (pending.fresh === true) return { ranges, anchors, snapshots, pending: { fresh: true } }\r\n if (!string(pending.resumeAt, 128)) return undefined\r\n return { ranges, anchors, snapshots, pending: { resumeAt: pending.resumeAt } }\r\n}\r\n\r\nfunction tasks(value: unknown): ClaudeTasksEvent | undefined {\r\n const input = record(value)\r\n if (input === undefined || !Array.isArray(input.tasks)) return undefined\r\n return normalizeTasksEvent(input.tasks as ClaudeTaskInfo[])\r\n}\r\n\r\nexport function parseClaudeSidecar(value: unknown): ClaudeSidecarProjection {\r\n const input = record(value)\r\n if (input === undefined\r\n || input.schemaVersion !== SIDECAR_SCHEMA_VERSION\r\n || !finiteInteger(input.revision)\r\n || !Array.isArray(input.activities)\r\n || input.activities.length > MAX_ACTIVITIES) {\r\n throw new Error('dsh-claude: invalid sidecar document')\r\n }\r\n const activities = input.activities.map(activity)\r\n if (activities.some(item => item === undefined)) throw new Error('dsh-claude: invalid sidecar activity')\r\n const parsedBinding = input.binding === undefined ? undefined : binding(input.binding)\r\n const parsedUsage = input.contextUsage === undefined ? undefined : contextUsage(input.contextUsage)\r\n const parsedTasks = input.tasks === undefined ? undefined : tasks(input.tasks)\r\n const parsedRewind = input.rewind === undefined ? undefined : rewind(input.rewind)\r\n if ((input.binding !== undefined && parsedBinding === undefined)\r\n || (input.contextUsage !== undefined && parsedUsage === undefined)\r\n || (input.tasks !== undefined && parsedTasks === undefined)\r\n || (input.rewind !== undefined && parsedRewind === undefined)) {\r\n throw new Error('dsh-claude: invalid sidecar projection')\r\n }\r\n return {\r\n schemaVersion: SIDECAR_SCHEMA_VERSION,\r\n revision: input.revision,\r\n activities: activities as ClaudeActivityEvent[],\r\n ...(parsedBinding === undefined ? {} : { binding: parsedBinding }),\r\n ...(parsedUsage === undefined ? {} : { contextUsage: parsedUsage }),\r\n ...(parsedTasks === undefined ? {} : { tasks: parsedTasks }),\r\n ...(parsedRewind === undefined ? {} : { rewind: parsedRewind }),\r\n }\r\n}\r\n\r\nfunction compareActivity(left: ClaudeActivityEvent, right: ClaudeActivityEvent): number {\r\n return left.turn - right.turn || left.step - right.step || left.ordinal - right.ordinal\r\n}\r\n\r\nfunction activityKey(value: ClaudeActivityEvent): string {\r\n return `${value.turn}:${value.step}:${value.ordinal}`\r\n}\r\n\r\nfunction mergeActivities(\r\n existing: readonly ClaudeActivityEvent[],\r\n additions: readonly ClaudeActivityEvent[],\r\n): ClaudeActivityEvent[] {\r\n const merged = new Map(existing.map(item => [activityKey(item), item]))\r\n for (const item of additions) merged.set(activityKey(item), item)\r\n return [...merged.values()].sort(compareActivity).slice(-MAX_ACTIVITIES)\r\n}\r\n\r\nfunction normalizeBinding(\r\n input: Omit<ClaudeSessionBoundEvent, 'sdkVersion'> & { sdkVersion?: string },\r\n): ClaudeSessionBoundEvent {\r\n return {\r\n claudeSessionId: redactText(input.claudeSessionId, 512),\r\n sdkVersion: redactText(input.sdkVersion ?? SDK_VERSION, 128),\r\n cwd: redactText(input.cwd, 4_096),\r\n ...(input.cliVersion === undefined ? {} : { cliVersion: redactText(input.cliVersion, 128) }),\r\n }\r\n}\r\n\r\nexport class ClaudeSidecarRepository {\r\n readonly root: string\r\n readonly legacyRoot: string | undefined\r\n readonly #pending = new Map<string, Promise<unknown>>()\r\n /** Latest durable projection per session; disk is read once and written through. */\r\n readonly #latest = new Map<string, ClaudeSidecarProjection>()\r\n readonly #listeners = new Map<string, Set<(delta: ClaudeSidecarNotification) => void>>()\r\n /** Notifications published per session, so a reader can spot a hole. */\r\n readonly #seq = new Map<string, number>()\r\n /** Streaming transcript segments not yet persisted, keyed by activity key. */\r\n readonly #live = new Map<string, Map<string, ClaudeActivityEvent>>()\r\n /** Monotonic revision boost so merged reads advance while text stays in memory. */\r\n readonly #boost = new Map<string, number>()\r\n readonly #flushTimers = new Map<string, ReturnType<typeof setTimeout>>()\r\n\r\n constructor(options: ClaudeSidecarRepositoryOptions = {}) {\r\n this.root = options.root ?? dshHomePath('plugins', 'dsh-claude', 'sessions')\r\n this.legacyRoot = options.legacyRoot\r\n ?? (options.root === undefined ? dshHomePath('plugins', 'dsh-claude-code', 'sessions') : undefined)\r\n }\r\n\r\n async read(sessionId: string): Promise<ClaudeSidecarProjection> {\r\n await this.#pending.get(sessionId)?.catch(() => undefined)\r\n return this.#merged(sessionId, await this.#base(sessionId))\r\n }\r\n\r\n /** Observe accepted changes for one session; returns the unsubscriber. */\r\n subscribe(sessionId: string, listener: (delta: ClaudeSidecarNotification) => void): () => void {\r\n let set = this.#listeners.get(sessionId)\r\n if (set === undefined) {\r\n set = new Set()\r\n this.#listeners.set(sessionId, set)\r\n }\r\n set.add(listener)\r\n return () => {\r\n set.delete(listener)\r\n if (set.size === 0) this.#listeners.delete(sessionId)\r\n }\r\n }\r\n\r\n /** Record streaming assistant prose without touching the disk on the hot\r\n * path: subscribers are notified synchronously (as an append when the\r\n * redacted text grows in place) and persistence is coalesced. */\r\n appendTranscriptText(\r\n sessionId: string,\r\n value: { turn: number; step: number; ordinal: number; text: string; renderer?: ClaudeRenderMode },\r\n ): void {\r\n const normalized = normalizeActivity({ kind: 'text', phase: 'updated', ...value })\r\n const key = activityKey(normalized)\r\n let overlay = this.#live.get(sessionId)\r\n if (overlay === undefined) {\r\n overlay = new Map()\r\n this.#live.set(sessionId, overlay)\r\n }\r\n const previous = overlay.get(key)\r\n overlay.set(key, normalized)\r\n this.#boost.set(sessionId, (this.#boost.get(sessionId) ?? 0) + 1)\r\n const text = normalized.text ?? ''\r\n const base = {\r\n turn: normalized.turn,\r\n step: normalized.step,\r\n ordinal: normalized.ordinal,\r\n ...(normalized.renderer === undefined ? {} : { renderer: normalized.renderer }),\r\n }\r\n // Redaction may rewrite earlier characters once a secret completes, so a\r\n // non-prefix update falls back to a full-text replacement.\r\n this.#notify(sessionId, previous?.text !== undefined && text.startsWith(previous.text)\r\n ? { kind: 'text', ...base, append: text.slice(previous.text.length) }\r\n : { kind: 'text', ...base, text })\r\n this.#scheduleTextFlush(sessionId)\r\n }\r\n\r\n /** Persist any pending streaming transcript now (segment close, turn end). */\r\n flushTranscriptText(sessionId: string): Promise<void> {\r\n const timer = this.#flushTimers.get(sessionId)\r\n if (timer !== undefined) {\r\n clearTimeout(timer)\r\n this.#flushTimers.delete(sessionId)\r\n }\r\n return this.#flushLive(sessionId)\r\n }\r\n\r\n /** How many notifications this session has published. */\r\n sequence(sessionId: string): number {\r\n return this.#seq.get(sessionId) ?? 0\r\n }\r\n\r\n /** Restate where the stream stands without changing anything.\r\n *\r\n * A reader detects a lost delta from the hole the NEXT one leaves, which\r\n * never comes when the lost delta was the last of a turn -- exactly the\r\n * case that leaves a finished tool group pulsing forever. Called at turn\r\n * settlement, this gives that reader the one line it needs to disagree. */\r\n checkpoint(sessionId: string): void {\r\n this.#deliver(sessionId, { kind: 'checkpoint', seq: this.sequence(sessionId) })\r\n }\r\n\r\n #notify(sessionId: string, delta: ClaudeSidecarDelta): void {\r\n const seq = this.sequence(sessionId) + 1\r\n this.#seq.set(sessionId, seq)\r\n this.#deliver(sessionId, { ...delta, seq } as ClaudeSidecarNotification)\r\n }\r\n\r\n #deliver(sessionId: string, notification: ClaudeSidecarNotification): void {\r\n const set = this.#listeners.get(sessionId)\r\n if (set === undefined) return\r\n for (const listener of [...set]) {\r\n try {\r\n listener(notification)\r\n } catch {\r\n // A subscriber failure must never affect durable state.\r\n }\r\n }\r\n }\r\n\r\n #merged(sessionId: string, base: ClaudeSidecarProjection): ClaudeSidecarProjection {\r\n const overlay = this.#live.get(sessionId)\r\n const boost = this.#boost.get(sessionId) ?? 0\r\n if ((overlay === undefined || overlay.size === 0) && boost === 0) return base\r\n return {\r\n ...base,\r\n revision: base.revision + boost,\r\n ...(overlay === undefined || overlay.size === 0\r\n ? {}\r\n : { activities: mergeActivities(base.activities, [...overlay.values()]) }),\r\n }\r\n }\r\n\r\n async #base(sessionId: string): Promise<ClaudeSidecarProjection> {\r\n const cached = this.#latest.get(sessionId)\r\n if (cached !== undefined) return cached\r\n const loaded = await this.#readNow(sessionId)\r\n this.#latest.set(sessionId, loaded)\r\n return loaded\r\n }\r\n\r\n #scheduleTextFlush(sessionId: string): void {\r\n if (this.#flushTimers.has(sessionId)) return\r\n const timer = setTimeout(() => {\r\n this.#flushTimers.delete(sessionId)\r\n void this.#flushLive(sessionId)\r\n }, TEXT_FLUSH_MS)\r\n timer.unref?.()\r\n this.#flushTimers.set(sessionId, timer)\r\n }\r\n\r\n async #flushLive(sessionId: string): Promise<void> {\r\n const overlay = this.#live.get(sessionId)\r\n if (overlay === undefined || overlay.size === 0) return\r\n const entries = [...overlay.entries()]\r\n try {\r\n await this.#update(sessionId, current => ({\r\n ...current,\r\n activities: mergeActivities(current.activities, entries.map(([, value]) => value)),\r\n }))\r\n } catch {\r\n // Keep the overlay; the next append or flush retries persistence.\r\n return\r\n }\r\n for (const [key, value] of entries) {\r\n if (overlay.get(key) === value) overlay.delete(key)\r\n }\r\n if (overlay.size === 0) this.#live.delete(sessionId)\r\n }\r\n\r\n writeBinding(\r\n sessionId: string,\r\n value: Omit<ClaudeSessionBoundEvent, 'sdkVersion'> & { sdkVersion?: string },\r\n ): Promise<ClaudeSidecarProjection> {\r\n const normalized = normalizeBinding(value)\r\n return this.#update(sessionId, current => ({ ...current, binding: normalized }))\r\n }\r\n\r\n appendActivity(\r\n sessionId: string,\r\n value: ClaudeActivityInput & { turn: number; step: number; ordinal: number },\r\n ): Promise<ClaudeSidecarProjection> {\r\n const normalized = normalizeActivity(value)\r\n return this.#update(sessionId, current => ({\r\n ...current,\r\n activities: mergeActivities(current.activities, [normalized]),\r\n }), false, { kind: 'activity', activity: normalized })\r\n }\r\n\r\n writeContextUsage(sessionId: string, value: ClaudeContextUsageInput): Promise<ClaudeSidecarProjection> {\r\n const normalized = normalizeContextUsage(value)\r\n return this.#update(sessionId, current => ({ ...current, contextUsage: normalized }), false, { kind: 'contextUsage', value: normalized })\r\n }\r\n\r\n writeTasks(sessionId: string, value: readonly ClaudeTaskInfo[]): Promise<ClaudeSidecarProjection> {\r\n const normalized = normalizeTasksEvent(value)\r\n return this.#update(sessionId, current => ({ ...current, tasks: normalized }), false, { kind: 'tasks', value: normalized })\r\n }\r\n\r\n /** Land one planned rewind: hidden ranges, surviving anchors, and the fork\r\n * target the next Claude spawn consumes.\r\n *\r\n * `droppedFromTurn` also drops the discarded turns' activity. The hidden\r\n * ranges are surface seqs and activity records carry none, so a reader that\r\n * works in turns — the plan panel, the task board — has nothing to filter\r\n * on and would go on showing a plan the session no longer contains. This\r\n * projection is rebuildable from the session log, so trimming it is not\r\n * losing anything the log still holds. */\r\n writeRewind(sessionId: string, value: ClaudeRewindState, droppedFromTurn?: number): Promise<ClaudeSidecarProjection> {\r\n return this.#update(sessionId, current => ({\r\n ...current,\r\n rewind: value,\r\n ...(droppedFromTurn === undefined ? {} : {\r\n activities: current.activities.filter(activity => activity.turn < droppedFromTurn),\r\n }),\r\n }), false, { kind: 'sync' })\r\n }\r\n\r\n /** Remember where Claude's chain ended for one completed DSH turn. */\r\n recordRewindAnchor(sessionId: string, turn: number, uuid: string): Promise<ClaudeSidecarProjection> {\r\n return this.#update(sessionId, current => ({\r\n ...current,\r\n rewind: recordRewindAnchor(current.rewind ?? EMPTY_REWIND_STATE, { turn, uuid }),\r\n }))\r\n }\r\n\r\n /** Remember the working tree one DSH turn was admitted against. */\r\n recordRewindSnapshot(sessionId: string, turn: number, tree: string): Promise<ClaudeSidecarProjection> {\r\n return this.#update(sessionId, current => ({\r\n ...current,\r\n rewind: recordRewindSnapshot(current.rewind ?? EMPTY_REWIND_STATE, { turn, tree }),\r\n }))\r\n }\r\n\r\n /** Disarm the fork target once a Claude process has resumed at it, so a\r\n * later respawn continues the rewound session instead of re-truncating it. */\r\n clearRewindPending(sessionId: string): Promise<ClaudeSidecarProjection> {\r\n return this.#update(sessionId, current => (current.rewind?.pending === undefined ? current : {\r\n ...current,\r\n rewind: { ranges: current.rewind.ranges, anchors: current.rewind.anchors, snapshots: current.rewind.snapshots },\r\n }))\r\n }\r\n\r\n importLegacy(sessionId: string, events: readonly SessionEvent[]): Promise<ClaudeSidecarProjection> {\r\n const importedActivities = events\r\n .filter(event => event.type === CLAUDE_ACTIVITY_EVENT)\r\n .map(event => activity(event.data))\r\n .filter((item): item is ClaudeActivityEvent => item !== undefined)\r\n const importedBinding = latestClaudeSessionBinding(events)\r\n const importedUsage = latestClaudeContextUsage(events)\r\n const importedTasks = latestClaudeTasks(events)\r\n return this.#update(sessionId, current => ({\r\n ...current,\r\n activities: mergeActivities(importedActivities, current.activities),\r\n ...(current.binding !== undefined || importedBinding === undefined ? {} : { binding: normalizeBinding(importedBinding) }),\r\n ...(current.contextUsage !== undefined || importedUsage === undefined ? {} : { contextUsage: normalizeContextUsage(importedUsage) }),\r\n ...(current.tasks !== undefined || importedTasks === undefined ? {} : { tasks: normalizeTasksEvent(importedTasks.tasks) }),\r\n }), true, { kind: 'sync' })\r\n }\r\n\r\n #path(sessionId: string, root = this.root): string {\r\n if (sessionId.length === 0 || sessionId.length > 1_024) throw new Error('dsh-claude: invalid session id')\r\n return join(root, `${Buffer.from(sessionId).toString('base64url')}.json`)\r\n }\r\n\r\n #update(\r\n sessionId: string,\r\n change: (current: ClaudeSidecarProjection) => Omit<ClaudeSidecarProjection, 'revision' | 'schemaVersion'> & Partial<Pick<ClaudeSidecarProjection, 'revision' | 'schemaVersion'>>,\r\n skipUnchanged = false,\r\n delta?: ClaudeSidecarDelta,\r\n ): Promise<ClaudeSidecarProjection> {\r\n const previous = this.#pending.get(sessionId) ?? Promise.resolve()\r\n const operation = previous.catch(() => undefined).then(async () => {\r\n const current = await this.#base(sessionId)\r\n const changed = parseClaudeSidecar({\r\n ...change(current),\r\n schemaVersion: SIDECAR_SCHEMA_VERSION,\r\n revision: current.revision,\r\n })\r\n if (skipUnchanged && JSON.stringify(changed) === JSON.stringify(current)) return current\r\n const next = { ...changed, revision: current.revision + 1 }\r\n await this.#writeNow(sessionId, next)\r\n this.#latest.set(sessionId, next)\r\n if (delta !== undefined) this.#notify(sessionId, delta)\r\n return next\r\n })\r\n this.#pending.set(sessionId, operation)\r\n void operation.finally(() => {\r\n if (this.#pending.get(sessionId) === operation) this.#pending.delete(sessionId)\r\n }).catch(() => undefined)\r\n return operation\r\n }\r\n\r\n async #readNow(sessionId: string): Promise<ClaudeSidecarProjection> {\r\n try {\r\n return parseClaudeSidecar(JSON.parse(await readFile(this.#path(sessionId), 'utf8')))\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\r\n }\r\n if (this.legacyRoot === undefined) return emptyProjection()\r\n try {\r\n return parseClaudeSidecar(JSON.parse(await readFile(this.#path(sessionId, this.legacyRoot), 'utf8')))\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return emptyProjection()\r\n throw error\r\n }\r\n }\r\n\r\n async #writeNow(sessionId: string, projection: ClaudeSidecarProjection): Promise<void> {\r\n await mkdir(this.root, { recursive: true, mode: 0o700 })\r\n await chmod(this.root, 0o700)\r\n const target = this.#path(sessionId)\r\n const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`\r\n try {\r\n await writeFile(temporary, `${JSON.stringify(projection)}\\n`, { mode: 0o600, flag: 'wx' })\r\n await chmod(temporary, 0o600)\r\n await rename(temporary, target)\r\n await chmod(target, 0o600)\r\n } finally {\r\n await rm(temporary, { force: true }).catch(() => undefined)\r\n }\r\n }\r\n}\r\n","export class AsyncQueueClosedError extends Error {\r\n constructor() {\r\n super('Async queue is closed')\r\n this.name = 'AsyncQueueClosedError'\r\n }\r\n}\r\n\r\ninterface Pending<T> {\r\n resolve: (result: IteratorResult<T>) => void\r\n reject: (error: unknown) => void\r\n}\r\n\r\nexport class AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\r\n readonly #values: T[] = []\r\n readonly #pending: Pending<T>[] = []\r\n #closed = false\r\n #failure: unknown\r\n\r\n get closed(): boolean {\r\n return this.#closed\r\n }\r\n\r\n push(value: T): void {\r\n if (this.#closed) throw new AsyncQueueClosedError()\r\n const waiter = this.#pending.shift()\r\n if (waiter !== undefined) waiter.resolve({ value, done: false })\r\n else this.#values.push(value)\r\n }\r\n\r\n close(): void {\r\n if (this.#closed) return\r\n this.#closed = true\r\n for (const waiter of this.#pending.splice(0)) waiter.resolve({ value: undefined, done: true })\r\n }\r\n\r\n fail(error: unknown): void {\r\n if (this.#closed) return\r\n this.#closed = true\r\n this.#failure = error\r\n for (const waiter of this.#pending.splice(0)) waiter.reject(error)\r\n }\r\n\r\n discard(error?: unknown): void {\r\n this.#values.splice(0)\r\n if (this.#closed) return\r\n this.#closed = true\r\n if (error === undefined) {\r\n for (const waiter of this.#pending.splice(0)) waiter.resolve({ value: undefined, done: true })\r\n return\r\n }\r\n this.#failure = error\r\n for (const waiter of this.#pending.splice(0)) waiter.resolve({ value: undefined, done: true })\r\n }\r\n\r\n next(): Promise<IteratorResult<T>> {\r\n const value = this.#values.shift()\r\n if (value !== undefined) return Promise.resolve({ value, done: false })\r\n if (this.#closed) {\r\n return this.#failure === undefined\r\n ? Promise.resolve({ value: undefined, done: true })\r\n : Promise.reject(this.#failure)\r\n }\r\n return new Promise<IteratorResult<T>>((resolve, reject) => {\r\n this.#pending.push({ resolve, reject })\r\n })\r\n }\r\n\r\n return(): Promise<IteratorResult<T>> {\r\n this.close()\r\n return Promise.resolve({ value: undefined, done: true })\r\n }\r\n\r\n [Symbol.asyncIterator](): AsyncIterator<T> {\r\n return this\r\n }\r\n}\r\n","/** One note the reviewer left on a plan: what they said, and the passage they\r\n * said it about. */\r\nexport interface PlanNote {\r\n /** The exact passage the note is anchored to, absent for a whole-plan note. */\r\n readonly quote?: string\r\n readonly text: string\r\n}\r\n\r\nconst MAX_NOTES = 30\r\nconst MAX_NOTE_CHARS = 2_000\r\nconst MAX_QUOTE_CHARS = 1_000\r\n\r\nexport class PlanFeedbackError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'PlanFeedbackError'\r\n this.code = code\r\n }\r\n}\r\n\r\n/** Validate and bound one submission's notes. */\r\nexport function planNotesOf(value: unknown): readonly PlanNote[] {\r\n if (!Array.isArray(value) || value.length === 0 || value.length > MAX_NOTES) {\r\n throw new PlanFeedbackError('invalid-request', 'The review notes are invalid.')\r\n }\r\n return value.map(item => {\r\n const note = item !== null && typeof item === 'object' ? item as Record<string, unknown> : undefined\r\n const text = typeof note?.text === 'string' ? note.text.trim() : ''\r\n if (text.length === 0 || text.length > MAX_NOTE_CHARS) {\r\n throw new PlanFeedbackError('invalid-request', 'A review note is empty or too long.')\r\n }\r\n const quote = typeof note?.quote === 'string' ? note.quote.trim().slice(0, MAX_QUOTE_CHARS) : ''\r\n return quote.length === 0 ? { text } : { quote, text }\r\n })\r\n}\r\n\r\n/** What Claude is told when the reviewer asks for changes.\r\n *\r\n * Addressed to Claude rather than logged at it: a rejection it cannot act on\r\n * is the thing this whole path exists to replace. The quotes are fenced as\r\n * block quotes so a passage containing its own Markdown cannot be mistaken\r\n * for the reviewer's instruction. */\r\nexport function planFeedbackMessage(notes: readonly PlanNote[]): string {\r\n const body = notes.map(note => note.quote === undefined\r\n ? note.text\r\n : `On this part of the plan:\\n${note.quote.split('\\n').map(line => `> ${line}`).join('\\n')}\\n\\n${note.text}`)\r\n return [\r\n 'The user reviewed the plan in DeepSeek Harness and asked for changes rather than approving or rejecting it.',\r\n '',\r\n body.join('\\n\\n---\\n\\n'),\r\n '',\r\n 'Revise the plan accordingly and propose it again.',\r\n ].join('\\n')\r\n}\r\n\r\n/** The seam between the panel's \"send for changes\" and the permission bridge\r\n * waiting on that plan's approval.\r\n *\r\n * The approval promise lives inside the bridge and cannot be resolved from\r\n * outside, so the bridge races it against this gate instead: whichever\r\n * answers first decides, and the loser is aborted. One waiter per tool use —\r\n * a plan is approved once. */\r\nexport class PlanFeedbackGate {\r\n readonly #waiting = new Map<string, (notes: readonly PlanNote[]) => void>()\r\n\r\n /** Notes for the plan under `toolUseId`, or undefined when the wait is\r\n * abandoned because the approval surface answered first. */\r\n wait(toolUseId: string, signal: AbortSignal): Promise<readonly PlanNote[] | undefined> {\r\n return new Promise(resolve => {\r\n const settle = (notes: readonly PlanNote[] | undefined): void => {\r\n if (this.#waiting.get(toolUseId) === deliver) this.#waiting.delete(toolUseId)\r\n signal.removeEventListener('abort', onAbort)\r\n resolve(notes)\r\n }\r\n const deliver = (notes: readonly PlanNote[]): void => { settle(notes) }\r\n const onAbort = (): void => { settle(undefined) }\r\n if (signal.aborted) {\r\n resolve(undefined)\r\n return\r\n }\r\n signal.addEventListener('abort', onAbort, { once: true })\r\n this.#waiting.set(toolUseId, deliver)\r\n })\r\n }\r\n\r\n /** Hand notes to a waiting plan approval. False when nothing is waiting —\r\n * the plan was already decided, or never existed. */\r\n submit(toolUseId: string, notes: readonly PlanNote[]): boolean {\r\n const deliver = this.#waiting.get(toolUseId)\r\n if (deliver === undefined) return false\r\n deliver(notes)\r\n return true\r\n }\r\n\r\n /** Whether a plan is currently open for review. */\r\n pending(toolUseId: string): boolean {\r\n return this.#waiting.has(toolUseId)\r\n }\r\n}\r\n","import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk'\r\nimport type { Agent } from '@deepseek-ai/dsh-agent'\r\nimport type { ApprovalOutcome, ApprovalService } from '@deepseek-ai/dsh-user-approval'\r\nimport {\r\n boundText,\r\n safeDetail,\r\n type ClaudeActivityInput,\r\n type ClaudeActivityCursor,\r\n} from './events.ts'\r\nimport type { UserQuestionBridge } from './user-question.ts'\r\nimport { planFeedbackMessage, type PlanFeedbackGate } from './plan-feedback.ts'\r\n\r\nexport type ApprovalRequester = Pick<ApprovalService, 'request'>\r\n\r\nexport interface ActivePermissionContext {\r\n agent: Agent\r\n cursor: ClaudeActivityCursor\r\n markActivity?: () => void\r\n recordDenial?: (toolUseId: string) => void\r\n hasFullAccess?: () => Promise<boolean>\r\n appendActivity: (activity: ClaudeActivityInput) => Promise<void>\r\n}\r\n\r\nexport type ActivePermissionContextProvider = () => ActivePermissionContext | undefined\r\n\r\nfunction denialMessage(outcome: ApprovalOutcome): string {\r\n switch (outcome) {\r\n case 'rejected': return 'The user rejected this action in DeepSeek Harness.'\r\n case 'cancelled': return 'The permission request was cancelled in DeepSeek Harness.'\r\n case 'unavailable': return 'No DeepSeek Harness approval surface was available; the action was denied.'\r\n case 'allowed-once': return ''\r\n }\r\n}\r\n\r\n/** Claude leaving plan mode is not an ordinary tool call: its argument is the\r\n * plan, written for the user, and the approval that follows is the user\r\n * agreeing to it. Everything else reads better as a prompt plus its input. */\r\nconst PLAN_TOOL = 'ExitPlanMode'\r\nconst MAX_REASON_CHARS = 1_200\r\n\r\n/** What the approval dialog says instead of the plan.\r\n *\r\n * A plan is written to be read at length, and the approval dialog is a\r\n * cramped modal that renders its reason as plain text: pasting the plan there\r\n * turned a document into an unreadable wall. The decision stays with the Host\r\n * — this is still an ordinary tool approval — and the plan itself is drawn by\r\n * the plugin's own panel, where Markdown and the reader's chosen prose\r\n * palette both apply. The dialog only has to say what is being decided and\r\n * where to read it. */\r\nconst PLAN_APPROVAL_PROMPT = 'Claude proposed a plan. Read it in the Plan panel, then approve or reject here.'\r\n\r\n/** The plan an `ExitPlanMode` call carries, if it carries one.\r\n *\r\n * Travels to the client on the permission activity's `text` field: `summary`\r\n * is capped at 1k and `detail` at 4k, both of which truncate a real plan,\r\n * while `text` holds 64k. Only `kind: 'text'` activities are drawn as prose\r\n * by the transcript, so a plan riding a `kind: 'permission'` record reaches\r\n * the panel without being painted twice. */\r\nexport function planText(toolName: string, input: Readonly<Record<string, unknown>>): string | undefined {\r\n if (toolName !== PLAN_TOOL) return undefined\r\n return typeof input.plan === 'string' && input.plan.length > 0 ? input.plan : undefined\r\n}\r\n\r\n/** The session's approval-policy override, or undefined when it never switched.\r\n *\r\n * The same fold the approval service does — the last `approval/policy` event\r\n * wins, because replaying the log IS the state. Read here rather than\r\n * imported so this package keeps its runtime surface to the Host services it\r\n * is actually handed. */\r\nexport function approvalPolicyOf(events: readonly { type: string; data: unknown }[]): string | undefined {\r\n for (let index = events.length - 1; index >= 0; index -= 1) {\r\n const event = events[index]\r\n if (event?.type !== 'approval/policy') continue\r\n const policy = (event.data as { policy?: unknown }).policy\r\n return typeof policy === 'string' ? policy : undefined\r\n }\r\n return undefined\r\n}\r\n\r\n/** The policy that answers every request with `rejected` before reaching an\r\n * answerer, so no approval surface is ever shown. DSH writes it alongside\r\n * `sandbox/mode: danger-full-access` — Full access means \"stop asking\". */\r\nconst SILENT_POLICY = 'never'\r\nconst ASKING_POLICY = 'ask'\r\n\r\nexport function permissionReason(\r\n toolName: string,\r\n input: Readonly<Record<string, unknown>>,\r\n options: Parameters<CanUseTool>[2],\r\n): string {\r\n if (planText(toolName, input) !== undefined) return PLAN_APPROVAL_PROMPT\r\n const prompt = options.title ?? options.description ?? options.decisionReason ?? `Claude Code wants to use ${toolName}.`\r\n const detail = safeDetail(input)\r\n return boundText(detail === undefined ? prompt : `${prompt}\\nInput: ${detail}`, MAX_REASON_CHARS)\r\n}\r\n\r\nexport function mapApprovalOutcome(\r\n outcome: ApprovalOutcome,\r\n input: Record<string, unknown>,\r\n toolUseID: string,\r\n): PermissionResult {\r\n if (outcome === 'allowed-once') {\r\n return {\r\n behavior: 'allow',\r\n updatedInput: input,\r\n toolUseID,\r\n decisionClassification: 'user_temporary',\r\n }\r\n }\r\n return {\r\n behavior: 'deny',\r\n message: denialMessage(outcome),\r\n toolUseID,\r\n decisionClassification: 'user_reject',\r\n }\r\n}\r\n\r\nexport function createPermissionBridge(\r\n approval: ApprovalRequester,\r\n activeContext: ActivePermissionContextProvider,\r\n userQuestion?: UserQuestionBridge,\r\n planFeedback?: PlanFeedbackGate,\r\n): CanUseTool {\r\n return async (toolName, input, options) => {\r\n if (toolName === 'AskUserQuestion') {\r\n return userQuestion === undefined\r\n ? {\r\n behavior: 'deny',\r\n message: 'DeepSeek Harness user questions are unavailable; the question was cancelled.',\r\n toolUseID: options.toolUseID,\r\n decisionClassification: 'user_reject',\r\n }\r\n : userQuestion(input, options)\r\n }\r\n const active = activeContext()\r\n if (active === undefined) {\r\n return {\r\n behavior: 'deny',\r\n message: 'No active DeepSeek Harness turn owns this Claude Code action.',\r\n toolUseID: options.toolUseID,\r\n decisionClassification: 'user_reject',\r\n }\r\n }\r\n\r\n active.markActivity?.()\r\n const reason = permissionReason(toolName, input, options)\r\n const plan = planText(toolName, input)\r\n const session = active.agent.session\r\n // Tracked outside the try so a throw anywhere below still puts the\r\n // session's own policy back; a failed ask must not leave Full access\r\n // asking about everything else.\r\n let silenced = false\r\n try {\r\n await active.appendActivity({\r\n kind: 'permission',\r\n phase: 'started',\r\n toolUseId: options.toolUseID,\r\n toolName,\r\n title: options.displayName ?? toolName,\r\n summary: options.title ?? options.description ?? reason,\r\n detail: input,\r\n // The plan panel reads this; see planText.\r\n ...(plan === undefined ? {} : { text: plan }),\r\n })\r\n // Full access says \"stop asking me before you act\". A plan is not an\r\n // action: it is the decision the user asked Claude to bring back, and\r\n // answering it on their behalf hands the plan straight back to Claude\r\n // before anyone has read it. So it is the one approval Full access does\r\n // not stand in for — a user who wanted the plan waived would not have\r\n // asked for a plan.\r\n //\r\n // Full access does not merely pre-answer the request, it silences it:\r\n // DSH writes `approval/policy: never` next to the access mode, and the\r\n // approval service returns `rejected` from that policy alone, before any\r\n // answerer runs, so no surface is ever shown. Waiving the short-circuit\r\n // below is therefore not enough — the ask has to be un-silenced for as\r\n // long as it is open, and put back exactly as it was afterwards.\r\n const userDecides = plan !== undefined\r\n silenced = userDecides && approvalPolicyOf(session.snapshotEvents()) === SILENT_POLICY\r\n if (silenced) session.append('approval/policy', { policy: ASKING_POLICY })\r\n const alreadyFullAccess = !userDecides && await active.hasFullAccess?.() === true\r\n // Approving and rejecting are the only answers the approval dialog has,\r\n // and neither is \"change this\". A reviewer who wants an edit can only\r\n // reject, which reaches Claude as a bare refusal it cannot act on. So a\r\n // plan's approval is raced against the panel: the dialog and the panel's\r\n // notes are two answers to the same question, and whichever arrives\r\n // first ends it. The loser is aborted rather than left hanging, so a\r\n // dialog nobody answered does not outlive the plan it was asking about.\r\n const revision = new AbortController()\r\n const notes = plan === undefined || planFeedback === undefined\r\n ? undefined\r\n : planFeedback.wait(options.toolUseID, AbortSignal.any([options.signal, revision.signal]))\r\n const decided = new AbortController()\r\n const asked = alreadyFullAccess\r\n ? Promise.resolve<ApprovalOutcome>('allowed-once')\r\n : approval.request({\r\n agent: active.agent,\r\n toolName,\r\n reason,\r\n signal: notes === undefined ? options.signal : AbortSignal.any([options.signal, decided.signal]),\r\n })\r\n const answer = notes === undefined\r\n ? { outcome: await asked }\r\n : await Promise.race([\r\n asked.then(outcome => { revision.abort(); return { outcome } }),\r\n notes.then(value => value === undefined ? undefined : { revisions: value }),\r\n ]).then(async first => {\r\n if (first !== undefined && 'revisions' in first) decided.abort()\r\n // `notes` resolving undefined means the wait was abandoned, which\r\n // only happens once the dialog has answered.\r\n return first ?? { outcome: await asked }\r\n })\r\n if ('revisions' in answer) {\r\n const message = planFeedbackMessage(answer.revisions)\r\n active.recordDenial?.(options.toolUseID)\r\n await active.appendActivity({\r\n kind: 'permission',\r\n phase: 'denied',\r\n toolUseId: options.toolUseID,\r\n toolName,\r\n title: options.displayName ?? toolName,\r\n summary: 'Sent back for changes in DeepSeek Harness',\r\n text: message,\r\n })\r\n return {\r\n behavior: 'deny',\r\n message,\r\n toolUseID: options.toolUseID,\r\n decisionClassification: 'user_reject',\r\n }\r\n }\r\n const outcome = answer.outcome\r\n // The access selector can change while the approval UI is open. Re-read\r\n // its durable state so an explicit Full access choice wins over the stale\r\n // request being closed as rejected/cancelled by that mode transition.\r\n // Not for a plan: there the user's answer IS the decision, and a Full\r\n // access switch mid-read must not overturn a rejection they just made.\r\n const fullAccess = alreadyFullAccess || (!userDecides && await active.hasFullAccess?.() === true)\r\n const effectiveOutcome = fullAccess ? 'allowed-once' : outcome\r\n const result = mapApprovalOutcome(effectiveOutcome, input, options.toolUseID)\r\n if (result.behavior === 'deny') active.recordDenial?.(options.toolUseID)\r\n await active.appendActivity({\r\n kind: 'permission',\r\n phase: effectiveOutcome === 'allowed-once' ? 'completed' : 'denied',\r\n toolUseId: options.toolUseID,\r\n toolName,\r\n title: options.displayName ?? toolName,\r\n summary: fullAccess\r\n ? 'Allowed by Full access in DeepSeek Harness'\r\n : effectiveOutcome === 'allowed-once'\r\n ? 'Allowed once in DeepSeek Harness'\r\n : denialMessage(effectiveOutcome),\r\n })\r\n return result\r\n } catch (error) {\r\n const message = options.signal.aborted\r\n ? 'The permission request was cancelled in DeepSeek Harness.'\r\n : 'DeepSeek Harness could not record or answer the permission request; the action was denied.'\r\n try {\r\n await active.appendActivity({\r\n kind: 'permission',\r\n phase: 'failed',\r\n toolUseId: options.toolUseID,\r\n toolName,\r\n title: options.displayName ?? toolName,\r\n summary: message,\r\n isError: true,\r\n detail: error,\r\n })\r\n } catch {\r\n // The permission path is already fail-closed; a second audit failure cannot widen it.\r\n }\r\n return {\r\n behavior: 'deny',\r\n message,\r\n toolUseID: options.toolUseID,\r\n decisionClassification: 'user_reject',\r\n }\r\n } finally {\r\n // Best effort: an append that fails here cannot be reported without\r\n // overwriting the decision this call already reached.\r\n try {\r\n if (silenced) session.append('approval/policy', { policy: SILENT_POLICY })\r\n } catch {\r\n // The session log is the only place this could be recorded, and it is\r\n // the thing that just failed.\r\n }\r\n }\r\n }\r\n}\r\n","import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk'\r\nimport type { Agent } from '@deepseek-ai/dsh-agent'\r\nimport type {\r\n AskUserQuestionAnswerItem,\r\n AskUserQuestionItem,\r\n UserQuestionService,\r\n} from '@deepseek-ai/dsh-user-questions'\r\nimport type { ClaudeActivityInput, ClaudeActivityCursor } from './events.ts'\r\n\r\nexport type UserQuestionRequester = Pick<UserQuestionService, 'ask'>\r\n\r\nexport interface ActiveUserQuestionContext {\r\n agent: Agent\r\n cursor: ClaudeActivityCursor\r\n markActivity?: () => void\r\n appendActivity: (activity: ClaudeActivityInput) => Promise<void>\r\n}\r\n\r\nexport type ActiveUserQuestionContextProvider = () => ActiveUserQuestionContext | undefined\r\nexport type UserQuestionBridge = (\r\n input: Record<string, unknown>,\r\n options: Parameters<CanUseTool>[2],\r\n) => Promise<PermissionResult>\r\n\r\nconst FAILURE_MESSAGE = 'DeepSeek Harness could not collect an answer; the question was cancelled.'\r\nconst INVALID_MESSAGE = 'Claude Code sent an invalid user-question request; the question was cancelled.'\r\n\r\nfunction failureMessage(error: unknown): string {\r\n const code = error !== null && typeof error === 'object' && 'code' in error\r\n ? (error as { code?: unknown }).code\r\n : undefined\r\n return typeof code === 'string' && /^[A-Z][A-Z0-9_]*$/.test(code)\r\n ? `${FAILURE_MESSAGE} (${code})`\r\n : FAILURE_MESSAGE\r\n}\r\n\r\nfunction deny(message: string, toolUseID: string): PermissionResult {\r\n return {\r\n behavior: 'deny',\r\n message,\r\n toolUseID,\r\n decisionClassification: 'user_reject',\r\n }\r\n}\r\n\r\nfunction optionalText(value: unknown): string | undefined {\r\n return typeof value === 'string' && value.length > 0 ? value : undefined\r\n}\r\n\r\nfunction parseQuestions(input: Record<string, unknown>, toolUseID: string): AskUserQuestionItem[] | undefined {\r\n if (!Array.isArray(input.questions) || input.questions.length === 0 || input.questions.length > 20) return undefined\r\n const seen = new Set<string>()\r\n const questions: AskUserQuestionItem[] = []\r\n for (const [index, value] of input.questions.entries()) {\r\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\r\n const item = value as Record<string, unknown>\r\n if (typeof item.question !== 'string' || item.question.length === 0 || seen.has(item.question)) return undefined\r\n seen.add(item.question)\r\n if (item.options !== undefined && !Array.isArray(item.options)) return undefined\r\n const options = (item.options ?? []).map(option => {\r\n if (option === null || typeof option !== 'object' || Array.isArray(option)) return undefined\r\n const record = option as Record<string, unknown>\r\n if (typeof record.label !== 'string' || record.label.length === 0) return undefined\r\n const description = optionalText(record.description)\r\n return { label: record.label, ...(description === undefined ? {} : { description }) }\r\n })\r\n if (options.some(option => option === undefined)) return undefined\r\n const header = optionalText(item.header)\r\n questions.push({\r\n id: `${toolUseID}:${index}`,\r\n question: item.question,\r\n ...(header === undefined ? {} : { header }),\r\n options: options as NonNullable<AskUserQuestionItem['options']>,\r\n multiSelect: item.multiSelect === true,\r\n })\r\n }\r\n return questions\r\n}\r\n\r\nfunction answerText(answer: AskUserQuestionAnswerItem | undefined, multiSelect: boolean): string {\r\n if (answer === undefined) return ''\r\n const custom = optionalText(answer.custom)\r\n if (!multiSelect && custom !== undefined) return custom\r\n return [...answer.selected, ...(custom === undefined ? [] : [custom])].join(', ')\r\n}\r\n\r\nexport function createUserQuestionBridge(\r\n userQuestions: UserQuestionRequester,\r\n activeContext: ActiveUserQuestionContextProvider,\r\n): UserQuestionBridge {\r\n return async (input, options) => {\r\n const active = activeContext()\r\n if (active === undefined) return deny('No active DeepSeek Harness turn owns this Claude Code question.', options.toolUseID)\r\n\r\n const questions = parseQuestions(input, options.toolUseID)\r\n if (questions === undefined) return deny(INVALID_MESSAGE, options.toolUseID)\r\n\r\n active.markActivity?.()\r\n try {\r\n await active.appendActivity({\r\n kind: 'question',\r\n phase: 'started',\r\n toolUseId: options.toolUseID,\r\n toolName: 'AskUserQuestion',\r\n title: 'Claude asked a question',\r\n summary: questions.length === 1 ? questions[0]!.question : `Claude asked ${questions.length} questions`,\r\n })\r\n const response = await userQuestions.ask({\r\n questions,\r\n agent: active.agent,\r\n signal: options.signal,\r\n })\r\n const answersById = new Map(response.answers.map(answer => [answer.id, answer]))\r\n const answers = Object.fromEntries(questions.map(question => [\r\n question.question,\r\n answerText(answersById.get(question.id), question.multiSelect === true),\r\n ]))\r\n await active.appendActivity({\r\n kind: 'question',\r\n phase: 'completed',\r\n toolUseId: options.toolUseID,\r\n toolName: 'AskUserQuestion',\r\n title: 'Claude asked a question',\r\n summary: 'Answered in DeepSeek Harness',\r\n })\r\n return {\r\n behavior: 'allow',\r\n updatedInput: { ...input, answers },\r\n toolUseID: options.toolUseID,\r\n decisionClassification: 'user_temporary',\r\n }\r\n } catch (error) {\r\n const message = failureMessage(error)\r\n try {\r\n await active.appendActivity({\r\n kind: 'question',\r\n phase: 'failed',\r\n toolUseId: options.toolUseID,\r\n toolName: 'AskUserQuestion',\r\n title: 'Claude asked a question',\r\n summary: message,\r\n isError: true,\r\n })\r\n } catch {\r\n // The question path is fail-closed; a second audit failure cannot widen it.\r\n }\r\n return deny(message, options.toolUseID)\r\n }\r\n }\r\n}\r\n","import type { SDKMessage } from '@anthropic-ai/claude-agent-sdk'\r\nimport type { ClaudeUsage } from './events.ts'\r\n\r\nexport type NormalizedSdkMessage =\r\n | { kind: 'init'; sessionId: string; cliVersion: string; cwd: string }\r\n | { kind: 'text-delta'; text: string; parentToolUseId?: string }\r\n | { kind: 'assistant-text'; text: string; parentToolUseId?: string }\r\n | { kind: 'thinking'; text: string; phase: 'updated' | 'completed'; parentToolUseId?: string }\r\n | { kind: 'tool-call'; toolUseId: string; toolName: string; input: unknown; parentToolUseId?: string }\r\n | { kind: 'tool-result'; toolUseId: string; output: unknown; isError: boolean; parentToolUseId?: string }\r\n | {\r\n kind: 'subagent'\r\n title: string\r\n summary?: string\r\n detail?: unknown\r\n phase: 'started' | 'updated' | 'completed' | 'failed'\r\n /** Structured task-board fields for task_started/progress/updated/notification. */\r\n taskId?: string\r\n taskStatus?: 'running' | 'completed' | 'failed' | 'stopped' | 'killed'\r\n description?: string\r\n subagentType?: string\r\n taskType?: string\r\n lastToolName?: string\r\n usage?: { totalTokens?: number; toolUses?: number; durationMs?: number }\r\n /** Ambient/housekeeping task: hide from chat rows, keep on the task board. */\r\n skipTranscript?: boolean\r\n }\r\n | {\r\n /** Level signal: full live background-task set (REPLACE semantics). */\r\n kind: 'background-tasks'\r\n tasks: readonly { taskId: string; taskType?: string; description: string }[]\r\n }\r\n | {\r\n /** Context compaction boundary. The CLI compacts locally without running a\r\n * model turn, so this is the only evidence the conversation was rewritten;\r\n * `trigger` stays absent when the CLI does not name one. */\r\n kind: 'compaction'\r\n trigger?: 'manual' | 'auto'\r\n preTokens?: number\r\n postTokens?: number\r\n durationMs?: number\r\n }\r\n | {\r\n /** Prompt-side accounting for ONE provider call, read off an assistant\r\n * message. Distinct from the `result` usage, which sums every call the\r\n * turn made — see `ClaudeSupervisor#reportedUsage`. */\r\n kind: 'request-usage'\r\n usage: ClaudeUsage\r\n parentToolUseId?: string\r\n }\r\n | { kind: 'status'; title: string; summary?: string; detail?: unknown }\r\n | { kind: 'warning'; title: string; summary?: string; detail?: unknown }\r\n | { kind: 'permission-denied'; toolUseId: string; toolName: string; summary: string }\r\n | { kind: 'result'; success: boolean; text?: string; errors?: readonly string[]; usage: ClaudeUsage; sessionId: string; userMessageUuid?: string; terminalReason?: string; permissionDenials?: readonly { toolName: string; toolUseId: string }[] }\r\n | { kind: 'protocol-error'; title: string; detail: unknown }\r\n | { kind: 'unknown'; title: string; detail: unknown }\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' ? value as Record<string, unknown> : undefined\r\n}\r\n\r\nfunction string(value: unknown): string | undefined {\r\n return typeof value === 'string' ? value : undefined\r\n}\r\n\r\nfunction finiteNumber(value: unknown): number | undefined {\r\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\r\n}\r\n\r\nfunction contentText(content: unknown): string {\r\n if (typeof content === 'string') return content\r\n if (!Array.isArray(content)) return ''\r\n return content.map(item => {\r\n const block = record(item)\r\n if (block?.type === 'text') return string(block.text) ?? ''\r\n return ''\r\n }).join('')\r\n}\r\n\r\nfunction taskUsageOf(usage: Record<string, unknown> | undefined): { totalTokens?: number; toolUses?: number; durationMs?: number } | undefined {\r\n if (usage === undefined) return undefined\r\n const normalized: { totalTokens?: number; toolUses?: number; durationMs?: number } = {}\r\n if (typeof usage.total_tokens === 'number') normalized.totalTokens = usage.total_tokens\r\n if (typeof usage.tool_uses === 'number') normalized.toolUses = usage.tool_uses\r\n if (typeof usage.duration_ms === 'number') normalized.durationMs = usage.duration_ms\r\n return Object.keys(normalized).length === 0 ? undefined : normalized\r\n}\r\n\r\n/** Read one Anthropic `usage` envelope. Shared by the per-call sample on an\r\n * assistant message and the turn total on a result message. */\r\nfunction usageOf(usage: Record<string, unknown> | undefined): ClaudeUsage {\r\n const normalized: ClaudeUsage = {}\r\n if (usage === undefined) return normalized\r\n if (typeof usage.input_tokens === 'number') normalized.inputTokens = usage.input_tokens\r\n if (typeof usage.output_tokens === 'number') normalized.outputTokens = usage.output_tokens\r\n if (typeof usage.cache_read_input_tokens === 'number') normalized.cacheReadTokens = usage.cache_read_input_tokens\r\n if (typeof usage.cache_creation_input_tokens === 'number') normalized.cacheCreationTokens = usage.cache_creation_input_tokens\r\n return normalized\r\n}\r\n\r\nfunction hasUsageCounts(usage: ClaudeUsage): boolean {\r\n return usage.inputTokens !== undefined\r\n || usage.outputTokens !== undefined\r\n || usage.cacheReadTokens !== undefined\r\n || usage.cacheCreationTokens !== undefined\r\n}\r\n\r\nfunction resultUsage(message: Record<string, unknown>): ClaudeUsage {\r\n const normalized = usageOf(record(message.usage))\r\n if (typeof message.total_cost_usd === 'number') normalized.cumulativeCostUsd = message.total_cost_usd\r\n return normalized\r\n}\r\n\r\nfunction normalizeAssistant(message: Record<string, unknown>): NormalizedSdkMessage[] {\r\n const envelope = record(message.message)\r\n const content = envelope?.content\r\n if (!Array.isArray(content)) return [{ kind: 'protocol-error', title: 'Malformed Claude assistant message', detail: message }]\r\n const parentToolUseId = string(message.parent_tool_use_id)\r\n const normalized: NormalizedSdkMessage[] = []\r\n for (const item of content) {\r\n const block = record(item)\r\n if (block === undefined) continue\r\n if (block.type === 'text') {\r\n const text = string(block.text)\r\n if (text !== undefined && text.length > 0) normalized.push({ kind: 'assistant-text', text, ...(parentToolUseId === undefined ? {} : { parentToolUseId }) })\r\n } else if (block.type === 'thinking') {\r\n const text = string(block.thinking)\r\n if (text !== undefined && text.length > 0) normalized.push({ kind: 'thinking', text, phase: 'completed', ...(parentToolUseId === undefined ? {} : { parentToolUseId }) })\r\n } else if (block.type === 'tool_use') {\r\n const toolUseId = string(block.id)\r\n const toolName = string(block.name)\r\n if (toolUseId !== undefined && toolName !== undefined) {\r\n normalized.push({\r\n kind: 'tool-call',\r\n toolUseId,\r\n toolName,\r\n input: block.input,\r\n ...(parentToolUseId === undefined ? {} : { parentToolUseId }),\r\n })\r\n }\r\n }\r\n }\r\n const usage = usageOf(record(envelope?.usage))\r\n if (hasUsageCounts(usage)) {\r\n normalized.push({ kind: 'request-usage', usage, ...(parentToolUseId === undefined ? {} : { parentToolUseId }) })\r\n }\r\n return normalized\r\n}\r\n\r\nfunction normalizeUser(message: Record<string, unknown>): NormalizedSdkMessage[] {\r\n // CLI ≥ 2.1.238 replays prior user messages (including local-command output\r\n // echoes with plain string content) when resuming a session. Replays and\r\n // block-less string echoes carry no tool results; they are not protocol\r\n // failures and must never kill the session.\r\n if (message.isReplay === true) return []\r\n const envelope = record(message.message)\r\n const content = envelope?.content\r\n if (typeof content === 'string') return []\r\n if (!Array.isArray(content)) return [{ kind: 'protocol-error', title: 'Malformed Claude user message', detail: message }]\r\n const parentToolUseId = string(message.parent_tool_use_id)\r\n const normalized: NormalizedSdkMessage[] = []\r\n for (const item of content) {\r\n const block = record(item)\r\n if (block?.type !== 'tool_result') continue\r\n const toolUseId = string(block.tool_use_id)\r\n if (toolUseId === undefined) continue\r\n normalized.push({\r\n kind: 'tool-result',\r\n toolUseId,\r\n output: message.tool_use_result ?? block.content,\r\n isError: block.is_error === true,\r\n ...(parentToolUseId === undefined ? {} : { parentToolUseId }),\r\n })\r\n }\r\n return normalized\r\n}\r\n\r\nfunction normalizeSystem(message: Record<string, unknown>): NormalizedSdkMessage[] {\r\n const subtype = string(message.subtype)\r\n if (subtype === 'init') {\r\n const sessionId = string(message.session_id)\r\n const cliVersion = string(message.claude_code_version)\r\n const cwd = string(message.cwd)\r\n return sessionId !== undefined && cliVersion !== undefined && cwd !== undefined\r\n ? [{ kind: 'init', sessionId, cliVersion, cwd }]\r\n : [{ kind: 'protocol-error', title: 'Malformed Claude initialization message', detail: message }]\r\n }\r\n if (subtype === 'status') {\r\n const status = message.status\r\n if (status === null) return [{ kind: 'status', title: 'Claude Code is ready' }]\r\n return [{ kind: 'status', title: `Claude Code ${String(status)}`, detail: message }]\r\n }\r\n if (subtype === 'session_state_changed') {\r\n return [{ kind: 'status', title: `Claude session ${String(message.state)}` }]\r\n }\r\n if (subtype === 'permission_denied') {\r\n const toolUseId = string(message.tool_use_id)\r\n const toolName = string(message.tool_name)\r\n if (toolUseId !== undefined && toolName !== undefined) {\r\n return [{\r\n kind: 'permission-denied',\r\n toolUseId,\r\n toolName,\r\n summary: string(message.message) ?? 'Claude Code denied the action',\r\n }]\r\n }\r\n }\r\n if (subtype === 'task_started') {\r\n const taskId = string(message.task_id)\r\n const description = string(message.description)\r\n const subagentType = string(message.subagent_type)\r\n const taskType = string(message.task_type)\r\n return [{\r\n kind: 'subagent',\r\n title: description ?? taskId ?? 'Claude subagent started',\r\n phase: 'started',\r\n detail: message,\r\n ...(taskId === undefined ? {} : { taskId }),\r\n taskStatus: 'running' as const,\r\n ...(description === undefined ? {} : { description }),\r\n ...(subagentType === undefined ? {} : { subagentType }),\r\n ...(taskType === undefined ? {} : { taskType }),\r\n ...(message.skip_transcript === true ? { skipTranscript: true } : {}),\r\n }]\r\n }\r\n if (subtype === 'task_progress') {\r\n const taskId = string(message.task_id)\r\n const description = string(message.description)\r\n const summary = string(message.summary)\r\n const subagentType = string(message.subagent_type)\r\n const lastToolName = string(message.last_tool_name)\r\n const usage = taskUsageOf(record(message.usage))\r\n return [{\r\n kind: 'subagent',\r\n title: summary ?? description ?? 'Claude subagent update',\r\n phase: 'updated',\r\n detail: message,\r\n ...(taskId === undefined ? {} : { taskId }),\r\n taskStatus: 'running' as const,\r\n ...(description === undefined ? {} : { description }),\r\n ...(subagentType === undefined ? {} : { subagentType }),\r\n ...(lastToolName === undefined ? {} : { lastToolName }),\r\n ...(summary === undefined ? {} : { summary }),\r\n ...(usage === undefined ? {} : { usage }),\r\n }]\r\n }\r\n if (subtype === 'task_updated') {\r\n const patch = record(message.patch)\r\n const status = string(patch?.status)\r\n const taskId = string(message.task_id)\r\n const description = string(patch?.description)\r\n const error = string(patch?.error)\r\n const taskStatus = status === undefined\r\n ? undefined\r\n : status === 'killed'\r\n ? 'killed' as const\r\n : status === 'completed'\r\n ? 'completed' as const\r\n : status === 'failed'\r\n ? 'failed' as const\r\n : 'running' as const\r\n return [{\r\n kind: 'subagent',\r\n title: description ?? 'Claude subagent update',\r\n phase: status === 'failed' || status === 'killed' ? 'failed' : status === 'completed' ? 'completed' : 'updated',\r\n detail: message,\r\n ...(taskId === undefined ? {} : { taskId }),\r\n ...(taskStatus === undefined ? {} : { taskStatus }),\r\n ...(description === undefined ? {} : { description }),\r\n ...(error === undefined ? {} : { summary: error }),\r\n }]\r\n }\r\n if (subtype === 'task_notification') {\r\n const failed = message.status === 'failed'\r\n const stopped = message.status === 'stopped' || message.status === 'cancelled'\r\n const taskId = string(message.task_id)\r\n const summary = string(message.summary)\r\n const taskStatus = failed ? 'failed' as const : stopped ? 'stopped' as const : 'completed' as const\r\n const usage = taskUsageOf(record(message.usage))\r\n return [{\r\n kind: 'subagent',\r\n title: summary ?? taskId ?? 'Claude subagent finished',\r\n phase: failed || stopped ? 'failed' : 'completed',\r\n detail: message,\r\n ...(taskId === undefined ? {} : { taskId }),\r\n taskStatus,\r\n ...(summary === undefined ? {} : { summary }),\r\n ...(usage === undefined ? {} : { usage }),\r\n }]\r\n }\r\n if (subtype === 'background_tasks_changed') {\r\n const tasks = Array.isArray(message.tasks) ? message.tasks : []\r\n return [{\r\n kind: 'background-tasks',\r\n tasks: tasks.flatMap(item => {\r\n const entry = record(item)\r\n const taskId = string(entry?.task_id)\r\n const description = string(entry?.description)\r\n const taskType = string(entry?.task_type)\r\n if (taskId === undefined || description === undefined) return []\r\n return [{\r\n taskId,\r\n description,\r\n ...(taskType === undefined ? {} : { taskType }),\r\n }]\r\n }),\r\n }]\r\n }\r\n if (subtype === 'api_retry') {\r\n return [{ kind: 'warning', title: 'Claude API retry', detail: message }]\r\n }\r\n if (subtype === 'compact_boundary') {\r\n // `/compact` runs entirely inside the CLI: no assistant turn, and the\r\n // `Compacted` echo arrives as a block-less user message that\r\n // `normalizeUser` drops. Without this branch the boundary fell through to\r\n // the generic fallback below and became audit-only 'status', so a\r\n // compacted conversation showed nothing at all.\r\n const metadata = record(message.compact_metadata)\r\n const trigger = metadata?.trigger === 'auto' || metadata?.trigger === 'manual' ? metadata.trigger : undefined\r\n const preTokens = finiteNumber(metadata?.pre_tokens)\r\n const postTokens = finiteNumber(metadata?.post_tokens)\r\n const durationMs = finiteNumber(metadata?.duration_ms)\r\n return [{\r\n kind: 'compaction',\r\n ...(trigger === undefined ? {} : { trigger }),\r\n ...(preTokens === undefined ? {} : { preTokens }),\r\n ...(postTokens === undefined ? {} : { postTokens }),\r\n ...(durationMs === undefined ? {} : { durationMs }),\r\n }]\r\n }\r\n if (subtype === 'informational' || subtype === 'notification' || subtype === 'local_command_output') {\r\n return [{\r\n kind: message.level === 'warning' ? 'warning' : 'status',\r\n title: string(message.content) ?? string(message.text) ?? 'Claude Code notice',\r\n detail: message,\r\n }]\r\n }\r\n if (subtype?.startsWith('hook_') === true || subtype === 'plugin_install') {\r\n return [{ kind: 'status', title: `Claude Code ${subtype.replaceAll('_', ' ')}`, detail: message }]\r\n }\r\n if (subtype !== undefined) {\r\n // Preserve unknown system lifecycle evidence (background tasks, resets,\r\n // worker/mirror lifecycle) as a bounded activity instead of silently\r\n // dropping it; the activity layer redacts and bounds the detail.\r\n return [{ kind: 'status', title: `Claude Code ${subtype.replaceAll('_', ' ')}`, detail: message }]\r\n }\r\n return []\r\n}\r\n\r\nconst RESULT_ERROR_SUBTYPES = new Set([\r\n 'error_during_execution',\r\n 'error_max_turns',\r\n 'error_max_budget_usd',\r\n 'error_max_structured_output_retries',\r\n])\r\n\r\nexport function normalizeSdkMessage(message: SDKMessage): NormalizedSdkMessage[] {\r\n const value = message as unknown as Record<string, unknown>\r\n if (value.type === 'stream_event') {\r\n const event = record(value.event)\r\n const parentToolUseId = string(value.parent_tool_use_id)\r\n if (event?.type === 'content_block_delta') {\r\n const delta = record(event.delta)\r\n if (delta?.type === 'text_delta') {\r\n const text = string(delta.text)\r\n return text === undefined ? [] : [{ kind: 'text-delta', text, ...(parentToolUseId === undefined ? {} : { parentToolUseId }) }]\r\n }\r\n if (delta?.type === 'thinking_delta') {\r\n const text = string(delta.thinking)\r\n return text === undefined ? [] : [{ kind: 'thinking', text, phase: 'updated', ...(parentToolUseId === undefined ? {} : { parentToolUseId }) }]\r\n }\r\n }\r\n return []\r\n }\r\n if (value.type === 'assistant') return normalizeAssistant(value)\r\n if (value.type === 'user') return normalizeUser(value)\r\n if (value.type === 'system') return normalizeSystem(value)\r\n if (value.type === 'result') {\r\n const sessionId = string(value.session_id)\r\n if (sessionId === undefined || (value.subtype !== 'success' && !RESULT_ERROR_SUBTYPES.has(String(value.subtype)))) {\r\n return [{ kind: 'protocol-error', title: 'Malformed Claude result message', detail: value }]\r\n }\r\n // A result is a success only when it is not flagged as an error. Local\r\n // 2.1.233 emits subtype:\"success\" with is_error:true for API/auth failures\r\n // (e.g. terminal_reason:\"api_error\"), so subtype alone is not authoritative.\r\n const success = value.subtype === 'success' && value.is_error !== true\r\n const errors = Array.isArray(value.errors)\r\n ? value.errors.filter((item): item is string => typeof item === 'string')\r\n : undefined\r\n const terminalReason = string(value.terminal_reason)\r\n const userMessageUuid = string(value.user_message_uuid)\r\n const permissionDenials = Array.isArray(value.permission_denials)\r\n ? value.permission_denials\r\n .map(item => record(item))\r\n .filter((item): item is Record<string, unknown> => item !== undefined)\r\n .map(item => {\r\n const toolName = string(item.tool_name)\r\n const toolUseId = string(item.tool_use_id)\r\n return toolName === undefined || toolUseId === undefined ? undefined : { toolName, toolUseId }\r\n })\r\n .filter((item): item is { toolName: string; toolUseId: string } => item !== undefined)\r\n .slice(0, 40)\r\n : undefined\r\n return [{\r\n kind: 'result',\r\n success,\r\n ...(success && typeof value.result === 'string' ? { text: value.result } : {}),\r\n ...(errors === undefined ? {} : { errors }),\r\n ...(terminalReason === undefined ? {} : { terminalReason }),\r\n ...(permissionDenials === undefined || permissionDenials.length === 0 ? {} : { permissionDenials }),\r\n usage: resultUsage(value),\r\n sessionId,\r\n ...(userMessageUuid === undefined ? {} : { userMessageUuid }),\r\n }]\r\n }\r\n if (value.type === 'auth_status') {\r\n return [{\r\n kind: value.error === undefined ? 'status' : 'warning',\r\n title: value.error === undefined ? 'Claude authentication status changed' : 'Claude authentication failed',\r\n detail: value.error ?? value.output,\r\n }]\r\n }\r\n if (value.type === 'rate_limit_event') {\r\n // The CLI pushes subscription-quota status after API activity. Every\r\n // update stays audit-only ('status' never enters the conversation flow);\r\n // a blocking state surfaces through the repository status bar badge that\r\n // reads these titles from the projection instead.\r\n const info = record(value.rate_limit_info)\r\n const status = string(info?.status)\r\n const blocking = status !== undefined && status !== 'allowed'\r\n return [{\r\n kind: 'status',\r\n title: blocking ? 'Claude rate limit is blocking requests' : 'Claude rate limit status changed',\r\n detail: value.rate_limit_info,\r\n }]\r\n }\r\n return [{ kind: 'unknown', title: `Unknown Claude SDK message: ${String(value.type)}`, detail: value }]\r\n}\r\n\r\nexport function extractSdkContentText(content: unknown): string {\r\n return contentText(content)\r\n}\r\n","/** The Claude Code model lineup, read from the running CLI instead of pinned\r\n * here.\r\n *\r\n * Anthropic ships models between releases of this plugin -- Fable arrived in a\r\n * CLI update, not in one of ours -- so a table maintained here is stale the day\r\n * it is written, and a model the user can already pick in `/model` is missing\r\n * from the DSH selector until someone edits an array. The CLI answers the same\r\n * question itself: every session's initialize response carries the lineup it\r\n * would show in `/model`, already narrowed to the logged-in account's plan and\r\n * to any `availableModels` restriction the settings cascade imposes.\r\n *\r\n * What DSH persists on a session, though, must NOT be a CLI model id. DSH\r\n * stores the selector row's id verbatim and matches it back by string\r\n * equality, so a concrete id (`claude-fable-5-1[1m]`) turns into a dangling\r\n * reference the moment Anthropic bumps the version -- the session keeps\r\n * pointing at a row nothing advertises any more, and the composer falls back\r\n * to printing the raw id. The selector therefore advertises an alias this\r\n * plugin owns (`fable[1m]`), derived from the row rather than tabulated, and\r\n * the CLI id it stands for is kept beside it and used only at dispatch.\r\n */\r\nimport {\r\n query as claudeQuery,\r\n type ModelInfo,\r\n type Options as ClaudeOptions,\r\n type Query,\r\n type SDKUserMessage,\r\n} from '@anthropic-ai/claude-agent-sdk'\r\n\r\n/** One selectable model, in the shape the adapter advertises to DSH. */\r\nexport interface ClaudeModelRow {\r\n /** Stable selector id, persisted by DSH on the session. An alias this plugin\r\n * owns -- never a CLI model id, which changes under it. */\r\n readonly id: string\r\n /** The spelling the CLI is actually given for this row. */\r\n readonly value: string\r\n readonly name: string\r\n readonly description: string\r\n readonly contextWindow?: number\r\n}\r\n\r\n/** A 1M-context route spells it in the id (`opus[1m]`, `claude-fable-5-1[1m]`). */\r\nconst WIDE_ROUTE = /\\[1m\\]$/u\r\n\r\n/** What the selector shows before the lineup is known -- the probe below failed\r\n * or has not answered yet. `default` is the only id that is valid on every\r\n * release and plan; the rest are the stable `/model` spellings Claude Code has\r\n * kept across releases, and every one of them is a spelling the CLI accepts,\r\n * so a session that persists one still dispatches. */\r\nconst SEED: readonly ClaudeModelRow[] = [\r\n { id: 'default', value: 'default', name: 'Default (recommended)', description: '' },\r\n { id: 'opus[1m]', value: 'opus[1m]', name: 'Opus (1M context)', description: '', contextWindow: 1_000_000 },\r\n { id: 'fable', value: 'fable', name: 'Fable', description: '' },\r\n { id: 'sonnet', value: 'sonnet', name: 'Sonnet', description: '' },\r\n { id: 'haiku', value: 'haiku', name: 'Haiku', description: '' },\r\n]\r\n\r\n/** A 1M-context route spells it in the id, so this needs no capacity table\r\n * either. It is only a floor: the supervisor overrides it with the window the\r\n * CLI reports once a turn has run. */\r\nfunction declaredContextWindow(row: ModelInfo): number | undefined {\r\n return WIDE_ROUTE.test(row.resolvedModel ?? row.value) ? 1_000_000 : undefined\r\n}\r\n\r\n/**\r\n * The selector id for one CLI row: the model's family, plus the `[1m]` marker\r\n * when the route carries one.\r\n *\r\n * Derived, never tabulated -- a family this plugin has never heard of gets its\r\n * id the same way, so a model Anthropic ships tomorrow lands in the selector\r\n * without an edit here, and a version bump (`claude-fable-5-1` ->\r\n * `claude-fable-5-2`) leaves an already-persisted selection pointing at the\r\n * same row. The family is the first non-numeric segment, which covers both\r\n * spellings Anthropic has used (`claude-fable-5-1`, `claude-3-5-sonnet-…`).\r\n *\r\n * Read off `value` alone, never the id it resolves to: `default` names a route\r\n * whose resolution moves with the account and the release, so folding the\r\n * resolved `[1m]` in would flip an already-persisted `default` to `default[1m]`\r\n * the day Anthropic repoints it.\r\n * @param value - the CLI's own id for the row.\r\n * @returns the alias to advertise.\r\n */\r\nexport function claudeModelAlias(value: string): string {\r\n const wide = WIDE_ROUTE.test(value)\r\n const bare = value.replace(WIDE_ROUTE, '').replace(/^claude-/u, '')\r\n const family = bare.split('-').find(segment => !/^\\d+$/u.test(segment)) ?? bare\r\n return wide ? `${family}[1m]` : family\r\n}\r\n\r\nfunction projectModel(row: ModelInfo, id: string): ClaudeModelRow {\r\n const contextWindow = declaredContextWindow(row)\r\n return {\r\n id,\r\n value: row.value,\r\n name: row.displayName,\r\n description: row.description,\r\n ...(contextWindow === undefined ? {} : { contextWindow }),\r\n }\r\n}\r\n\r\n// ponytail: a module-level latest-value cache, mirroring plan usage. The plugin\r\n// runs one supervisor per Host process and the lineup is account-wide, so\r\n// per-session state would buy nothing.\r\nlet latest: readonly ClaudeModelRow[] | undefined\r\nlet inflight: Promise<readonly ClaudeModelRow[]> | undefined\r\n\r\n/**\r\n * Learn the lineup from one session's initialize response.\r\n * @param models - the CLI's own `/model` rows; an empty list is ignored so a\r\n * CLI that answers without a catalog cannot blank the selector.\r\n */\r\nexport function recordClaudeModels(models: readonly ModelInfo[]): void {\r\n if (models.length === 0) return\r\n const taken = new Set<string>()\r\n latest = models.map(row => {\r\n const alias = claudeModelAlias(row.value)\r\n // Two rows of one family in the same lineup (a previous generation kept\r\n // alongside the current one) cannot share an id; the later row keeps the\r\n // CLI's own spelling rather than silently shadowing the first.\r\n const id = taken.has(alias) ? row.value : alias\r\n taken.add(id)\r\n return projectModel(row, id)\r\n })\r\n}\r\n\r\n/** The lineup to advertise: whatever the CLI last reported, else the seed. */\r\nexport function latestClaudeModels(): readonly ClaudeModelRow[] {\r\n return latest ?? SEED\r\n}\r\n\r\n/** A throwaway probe should not outlive a wedged CLI. */\r\nexport const CLAUDE_MODEL_PROBE_TIMEOUT_MS = 20_000\r\n\r\n/**\r\n * Read the lineup from a throwaway CLI process.\r\n *\r\n * Waiting for a session to start is too late: DSH loads the model catalog once\r\n * per Host generation, at connect, and does not reload it when this plugin\r\n * later learns the real lineup. A selector left on the seed until then hands\r\n * out seed ids, which is exactly how a session ends up persisting an id the\r\n * next launch cannot resolve. This query carries no tools, no permission\r\n * bridge and no session binding: it starts, reports what `/model` would show,\r\n * and is killed -- no prompt is ever sent, so it costs no tokens.\r\n * @param executablePath - the resolved CLI, or '' to let the SDK find it.\r\n * @param factory - test seam for the SDK query.\r\n * @returns the CLI's own `/model` rows.\r\n */\r\nexport async function probeClaudeModels(\r\n executablePath: string,\r\n factory: (params: { prompt: AsyncIterable<SDKUserMessage>; options: ClaudeOptions }) => Query = claudeQuery,\r\n): Promise<readonly ModelInfo[]> {\r\n const lifetime = new AbortController()\r\n const timer = setTimeout(() => lifetime.abort(), CLAUDE_MODEL_PROBE_TIMEOUT_MS)\r\n timer.unref?.()\r\n // The SDK ends a query as soon as its prompt stream closes, so hold the\r\n // stream open and let the abort below tear the process down instead.\r\n const prompt = (async function* (): AsyncGenerator<SDKUserMessage> {\r\n await new Promise<never>(() => {})\r\n })()\r\n const query = factory({\r\n prompt,\r\n options: {\r\n cwd: process.cwd(),\r\n abortController: lifetime,\r\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\r\n },\r\n })\r\n try {\r\n void (async () => { for await (const _ of query) { /* drain */ } })().catch(() => undefined)\r\n // Aborting tears the probe process down, but the SDK's pending\r\n // initialization is not documented to settle with it, and an unsettled one\r\n // would hang the catalog load (and the browser connection serving it) for\r\n // the life of the Host. The deadline is therefore enforced here too.\r\n const initialization = await Promise.race([\r\n query.initializationResult(),\r\n new Promise<never>((_resolve, reject) => {\r\n const deadline = setTimeout(\r\n () => reject(new Error('dsh-claude: the model lineup probe did not answer in time')),\r\n CLAUDE_MODEL_PROBE_TIMEOUT_MS,\r\n )\r\n deadline.unref?.()\r\n }),\r\n ])\r\n return initialization.models\r\n } finally {\r\n clearTimeout(timer)\r\n lifetime.abort()\r\n }\r\n}\r\n\r\n/**\r\n * The lineup, learning it from the CLI the first time DSH asks for the catalog.\r\n * @param probe - reads the CLI's rows; a failure leaves the seed in place and\r\n * is retried on the next catalog load.\r\n * @returns the rows to advertise, never rejecting.\r\n */\r\nexport function ensureClaudeModels(probe: () => Promise<readonly ModelInfo[]>): Promise<readonly ClaudeModelRow[]> {\r\n if (latest !== undefined) return Promise.resolve(latest)\r\n inflight ??= probe()\r\n .then(models => { recordClaudeModels(models) })\r\n .catch(() => undefined)\r\n .then(() => {\r\n inflight = undefined\r\n return latestClaudeModels()\r\n })\r\n return inflight\r\n}\r\n\r\n/**\r\n * Look one id up in the current lineup.\r\n * @param id - the id DSH persisted on the session, which may be an alias, a\r\n * concrete CLI id persisted before this plugin aliased anything, or a row the\r\n * running CLI no longer lists.\r\n * @returns the row, or undefined when the lineup does not cover the id.\r\n */\r\nexport function claudeModelRow(id: string): ClaudeModelRow | undefined {\r\n const rows = latestClaudeModels()\r\n return rows.find(row => row.id === id)\r\n ?? rows.find(row => row.value === id)\r\n ?? rows.find(row => row.id === claudeModelAlias(id))\r\n}\r\n\r\n/**\r\n * The spelling to hand the CLI for one selector id.\r\n * @param id - the id DSH persisted on the session.\r\n * @returns the CLI's own id, or the selector id itself when the lineup does not\r\n * cover it -- the seed vocabulary is made of spellings the CLI accepts, and a\r\n * session persisted before this plugin aliased anything already holds one.\r\n */\r\nexport function claudeModelValue(id: string): string {\r\n return claudeModelRow(id)?.value ?? id\r\n}\r\n\r\n/** Test seam: drop the learned lineup. */\r\nexport function resetClaudeModels(): void {\r\n latest = undefined\r\n inflight = undefined\r\n}\r\n","/** Claude.ai plan rate-limit windows behind the CLI's `/usage` panel.\r\n *\r\n * The Agent SDK exposes them through an experimental query method whose name\r\n * advertises its own instability, so every read is guarded: a missing method,\r\n * a shape change, or an API-key session all degrade to `available: false`\r\n * instead of breaking the settings page. */\r\nimport { query as claudeQuery, type Options as ClaudeOptions, type Query, type SDKUserMessage } from '@anthropic-ai/claude-agent-sdk'\r\n\r\n/** The SDK's own name for the unstable `/usage` control request; it is\r\n * documented to change when the API stabilizes, so it lives in one place. */\r\nexport const PLAN_USAGE_METHOD = 'usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET'\r\n\r\n/** A throwaway probe should not outlive a wedged control request. */\r\nexport const PLAN_USAGE_TIMEOUT_MS = 20_000\r\n\r\n/** Invoke the experimental usage control request, or say why we cannot. */\r\nexport function readPlanUsageFrom(query: Query): Promise<unknown> {\r\n const read = (query as Partial<Record<typeof PLAN_USAGE_METHOD, () => Promise<unknown>>>)[PLAN_USAGE_METHOD]\r\n if (typeof read !== 'function') throw new Error('dsh-claude: this Claude Agent SDK build exposes no plan usage API')\r\n return read.call(query)\r\n}\r\n\r\n/** One utilization window. `label` is only set for server-named model buckets\r\n * (e.g. 'Fable'); the fixed windows are translated client-side from `id`. */\r\nexport interface PlanUsageWindow {\r\n readonly id: string\r\n readonly label?: string\r\n readonly utilization?: number\r\n readonly resetsAt?: string\r\n}\r\n\r\nexport interface PlanUsageReport {\r\n readonly available: boolean\r\n readonly subscription?: string\r\n readonly windows: readonly PlanUsageWindow[]\r\n readonly fetchedAt: number\r\n readonly message?: string\r\n}\r\n\r\n/** Fixed windows in display order; the SDK omits the ones a plan does not have. */\r\nconst FIXED_WINDOWS = ['five_hour', 'seven_day', 'seven_day_opus', 'seven_day_sonnet'] as const\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return typeof value === 'object' && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\n/** Utilization is documented as 0-100; clamp so a server glitch cannot render\r\n * a bar wider than its track or a negative width. */\r\nfunction utilization(value: unknown): number | undefined {\r\n return typeof value === 'number' && Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : undefined\r\n}\r\n\r\nfunction resetsAt(value: unknown): string | undefined {\r\n return typeof value === 'string' && value.length > 0 ? value : undefined\r\n}\r\n\r\nfunction window(id: string, source: unknown, label?: string): PlanUsageWindow | undefined {\r\n const entry = record(source)\r\n if (entry === undefined) return undefined\r\n const used = utilization(entry.utilization)\r\n const reset = resetsAt(entry.resets_at)\r\n if (used === undefined && reset === undefined) return undefined\r\n return {\r\n id,\r\n ...(label === undefined ? {} : { label }),\r\n ...(used === undefined ? {} : { utilization: used }),\r\n ...(reset === undefined ? {} : { resetsAt: reset }),\r\n }\r\n}\r\n\r\n/** Project the SDK's `/usage` response onto the windows the settings card shows. */\r\nexport function normalizePlanUsage(value: unknown, fetchedAt: number): PlanUsageReport {\r\n const response = record(value)\r\n const subscription = typeof response?.subscription_type === 'string' ? response.subscription_type : undefined\r\n const limits = record(response?.rate_limits)\r\n if (response?.rate_limits_available !== true || limits === undefined) {\r\n return {\r\n available: false,\r\n ...(subscription === undefined ? {} : { subscription }),\r\n windows: [],\r\n fetchedAt,\r\n }\r\n }\r\n const windows = [\r\n ...FIXED_WINDOWS.map(id => window(id, limits[id])),\r\n ...(Array.isArray(limits.model_scoped) ? limits.model_scoped : []).map((entry: unknown, index: number) => {\r\n const name = record(entry)?.display_name\r\n return window(`model:${typeof name === 'string' ? name : index}`, entry, typeof name === 'string' ? name : undefined)\r\n }),\r\n ].filter((entry): entry is PlanUsageWindow => entry !== undefined)\r\n return {\r\n available: windows.length > 0,\r\n ...(subscription === undefined ? {} : { subscription }),\r\n windows,\r\n fetchedAt,\r\n }\r\n}\r\n\r\n/** Read plan limits from a throwaway Claude process.\r\n *\r\n * Deliberately NOT routed through the supervisor. Borrowing a session's\r\n * process fails outright while that session is mid-turn, and for a session\r\n * with no process yet it would resume the whole conversation — and possibly\r\n * evict another idle session to make room — just to read three numbers. This\r\n * query carries no tools, no permission bridge, and no session binding: it\r\n * starts, answers one control request, and is killed. */\r\nexport async function probePlanUsage(\r\n executablePath: string,\r\n fetchedAt: number,\r\n factory: (params: { prompt: AsyncIterable<SDKUserMessage>; options: ClaudeOptions }) => Query = claudeQuery,\r\n): Promise<PlanUsageReport> {\r\n const lifetime = new AbortController()\r\n const timer = setTimeout(() => lifetime.abort(), PLAN_USAGE_TIMEOUT_MS)\r\n timer.unref?.()\r\n // The SDK ends a query as soon as its prompt stream closes, so hold the\r\n // stream open and let the abort below tear the process down instead.\r\n const prompt = (async function* (): AsyncGenerator<SDKUserMessage> {\r\n await new Promise<never>(() => {})\r\n })()\r\n const query = factory({\r\n prompt,\r\n options: {\r\n cwd: process.cwd(),\r\n abortController: lifetime,\r\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\r\n },\r\n })\r\n try {\r\n // Control responses only arrive while the message stream is pumped.\r\n void (async () => { for await (const _ of query) { /* drain */ } })().catch(() => undefined)\r\n // Aborting tears the probe process down, but the SDK's pending control\r\n // request is not documented to settle with it — and an unsettled one hangs\r\n // the route (and the browser connection serving it) for the life of the\r\n // Host. The deadline is therefore enforced here too, not only on the\r\n // process.\r\n const read = await Promise.race([\r\n readPlanUsageFrom(query),\r\n new Promise<never>((_resolve, reject) => {\r\n const deadline = setTimeout(() => reject(new Error('dsh-claude: the plan usage request did not answer in time')), PLAN_USAGE_TIMEOUT_MS)\r\n deadline.unref?.()\r\n }),\r\n ])\r\n return normalizePlanUsage(read, fetchedAt)\r\n } finally {\r\n clearTimeout(timer)\r\n lifetime.abort()\r\n }\r\n}\r\n\r\n// ponytail: a module-level latest-value cache, not a store class. The plugin\r\n// runs one supervisor per Host process and the report is global to the Claude\r\n// account, so per-session state would buy nothing. Promote to a keyed store\r\n// only if the plugin ever serves more than one Claude account at a time.\r\nlet latest: PlanUsageReport | undefined\r\n\r\nexport function recordPlanUsage(report: PlanUsageReport): void {\r\n latest = report\r\n}\r\n\r\nexport function latestPlanUsage(): PlanUsageReport | undefined {\r\n return latest\r\n}\r\n\r\n/** Test seam: drop the cached report. */\r\nexport function resetPlanUsage(): void {\r\n latest = undefined\r\n}\r\n","import { EventEmitter } from 'node:events'\r\nimport type { Readable, Writable } from 'node:stream'\r\nimport type { SpawnOptions, SpawnedProcess } from '@anthropic-ai/claude-agent-sdk'\r\nimport {\r\n DSH_ENV_PREFIX,\r\n SENSITIVE_ENV_PATTERN,\r\n type SubprocessHandle,\r\n type SubprocessRuntime,\r\n} from '@deepseek-ai/dsh-subprocess'\r\n\r\nexport const CLAUDE_PROCESS_GRACE_MS = 2_000\r\nexport const CLAUDE_STDERR_TAIL_BYTES = 32 * 1024\r\n\r\nconst ADDITIONAL_SENSITIVE_ENV_PATTERN = /(?:authorization|cookie|credential|database[_-]?url|private[_-]?key|netrc)/iu\r\n\r\nexport function scrubClaudeSpawnEnv(env: Readonly<Record<string, string | undefined>>): NodeJS.ProcessEnv {\r\n const safe: NodeJS.ProcessEnv = {}\r\n for (const [key, value] of Object.entries(env)) {\r\n if (value === undefined) continue\r\n if (key.toUpperCase().startsWith(DSH_ENV_PREFIX)) continue\r\n if (SENSITIVE_ENV_PATTERN.test(key)) continue\r\n if (ADDITIONAL_SENSITIVE_ENV_PATTERN.test(key)) continue\r\n safe[key] = value\r\n }\r\n return safe\r\n}\r\n\r\nexport class ManagedClaudeProcess extends EventEmitter implements SpawnedProcess {\r\n readonly stdin: Writable\r\n readonly stdout: Readable\r\n readonly handle: SubprocessHandle\r\n #killed = false\r\n #exitCode: number | null = null\r\n #signalCode: NodeJS.Signals | null = null\r\n\r\n constructor(handle: SubprocessHandle) {\r\n super()\r\n if (handle.stdin === undefined || handle.stdout === undefined) {\r\n throw new Error('dsh-claude: managed Claude process requires piped stdin/stdout')\r\n }\r\n this.handle = handle\r\n this.stdin = handle.stdin\r\n this.stdout = handle.stdout\r\n void handle.done.then(\r\n outcome => {\r\n this.#exitCode = outcome.exitCode\r\n this.#signalCode = outcome.signal\r\n this.emit('exit', outcome.exitCode, outcome.signal)\r\n },\r\n error => {\r\n this.emit('error', error instanceof Error ? error : new Error(String(error)))\r\n },\r\n )\r\n }\r\n\r\n get killed(): boolean {\r\n return this.#killed\r\n }\r\n\r\n get exitCode(): number | null {\r\n return this.#exitCode\r\n }\r\n\r\n get signalCode(): NodeJS.Signals | null {\r\n return this.#signalCode\r\n }\r\n\r\n kill(signal: NodeJS.Signals): boolean {\r\n if (this.#exitCode !== null || this.#signalCode !== null) return false\r\n this.#killed = true\r\n this.handle.terminate()\r\n return true\r\n }\r\n\r\n stderrTail(): string {\r\n return this.handle.collected.stderr?.readFrom(0).text ?? ''\r\n }\r\n}\r\n\r\nexport type SpawnObserver = (process: ManagedClaudeProcess, options: SpawnOptions) => void\r\n\r\nexport function createManagedClaudeSpawner(\r\n runtime: Pick<SubprocessRuntime, 'spawn'>,\r\n executablePath: string,\r\n observe?: SpawnObserver,\r\n): (options: SpawnOptions) => SpawnedProcess {\r\n return options => {\r\n if (options.command !== executablePath) {\r\n throw new Error(`dsh-claude: SDK requested unexpected executable ${JSON.stringify(options.command)}`)\r\n }\r\n const handle = runtime.spawn({\r\n argv: [executablePath, ...options.args],\r\n cwd: options.cwd ?? process.cwd(),\r\n stdio: {\r\n stdin: 'pipe',\r\n stdout: 'pipe',\r\n stderr: { maxBytes: CLAUDE_STDERR_TAIL_BYTES },\r\n },\r\n graceMs: CLAUDE_PROCESS_GRACE_MS,\r\n signal: options.signal,\r\n env: scrubClaudeSpawnEnv(options.env),\r\n })\r\n const managed = new ManagedClaudeProcess(handle)\r\n observe?.(managed, options)\r\n return managed\r\n }\r\n}\r\n","/** Working-tree snapshots taken and restored with git's own plumbing.\n *\n * A rewind that only truncates Claude's transcript leaves the files Claude\n * wrote on disk, so the next turn resumes against a checkout the model no\n * longer remembers writing. Git already stores trees: a throwaway index turns\n * the working tree into one tree object without touching HEAD, the real\n * index, or the checkout, and a restore reads that tree back.\n *\n * Ignored files stay outside the snapshot in both directions. `git add -A`\n * honours `.gitignore`, so build output and `node_modules` are neither\n * captured nor removed.\n */\nimport { randomUUID } from 'node:crypto'\nimport { rm } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\n\nconst MAX_OUTPUT_BYTES = 64 * 1024\n/** `add -A` walks the whole checkout; a large repository needs more than the\n * status probes' five seconds, and this sits in front of every turn. */\nconst GIT_TIMEOUT_MS = 30_000\nconst OBJECT_NAME = /^[0-9a-f]{40}$|^[0-9a-f]{64}$/u\n/** A snapshot holds the bytes on disk, not git's line-ending translation of\n * them. Under `core.autocrlf=true` a plain `add` would store LF and the\n * restore would write CRLF, so a rewind on Windows would flip every LF file. */\nconst GIT_OPTIONS = ['-c', 'core.autocrlf=false'] as const\n\ntype SnapshotRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n\ninterface CommandResult {\n readonly exitCode: number | null\n readonly stdout: string\n}\n\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\n const outcome = await handle.done\n return { exitCode: outcome.exitCode, stdout: handle.collected.stdout?.readFrom(0).text ?? '' }\n}\n\nasync function run(\n runtime: SnapshotRuntime,\n git: string,\n args: readonly string[],\n cwd: string,\n env: Record<string, string> = {},\n): Promise<CommandResult> {\n return collect(runtime.spawn({\n argv: [git, ...GIT_OPTIONS, ...args],\n cwd,\n stdio: {\n stdin: 'ignore',\n stdout: { maxBytes: MAX_OUTPUT_BYTES },\n stderr: { maxBytes: MAX_OUTPUT_BYTES },\n },\n graceMs: 1_000,\n signal: AbortSignal.timeout(GIT_TIMEOUT_MS),\n env,\n }))\n}\n\n/** Capture the working tree as a git tree object.\n *\n * Undefined whenever git cannot answer -- no git, not a repository, a locked\n * or broken checkout. Snapshots are advisory: a turn without one simply\n * cannot offer a file rewind, and must never fail for it.\n *\n * ponytail: the tree is unreachable from any ref, so `git gc --prune` will\n * eventually collect it. Two weeks is git's default grace period and a rewind\n * happens minutes after the turn it undoes; anchor it to a real ref only if\n * snapshots ever need to outlive a gc.\n */\nexport async function captureWorktreeTree(runtime: SnapshotRuntime, cwd: string): Promise<string | undefined> {\n let git: string\n try {\n git = await runtime.resolveExecutable('git')\n } catch {\n return undefined\n }\n const indexFile = join(tmpdir(), `dsh-claude-index-${process.pid}-${randomUUID()}`)\n const env = { GIT_INDEX_FILE: indexFile }\n try {\n // Seeding from HEAD leaves `add -A` only the differences to record. An\n // unborn branch has no HEAD, and starting from the empty index is right.\n await run(runtime, git, ['read-tree', 'HEAD'], cwd, env)\n const staged = await run(runtime, git, ['add', '-A'], cwd, env)\n if (staged.exitCode !== 0) return undefined\n const written = await run(runtime, git, ['write-tree'], cwd, env)\n const tree = written.stdout.trim()\n return written.exitCode === 0 && OBJECT_NAME.test(tree) ? tree : undefined\n } catch {\n return undefined\n } finally {\n await rm(indexFile, { force: true }).catch(() => undefined)\n }\n}\n\n/** Put a captured tree back over the working tree, reporting whether it landed.\n *\n * Files the tree holds are rewritten, and files created after the snapshot are\n * removed. Nothing outside the snapshot's own scope is touched: ignored files\n * survive, because `clean` runs without `-x`.\n */\nexport async function restoreWorktreeTree(runtime: SnapshotRuntime, cwd: string, tree: string): Promise<boolean> {\n if (!OBJECT_NAME.test(tree)) return false\n let git: string\n try {\n git = await runtime.resolveExecutable('git')\n } catch {\n return false\n }\n try {\n // A tree a gc has already collected must fail here rather than halfway\n // through, with the checkout reset to nothing.\n const kind = await run(runtime, git, ['cat-file', '-t', tree], cwd)\n if (kind.exitCode !== 0 || kind.stdout.trim() !== 'tree') return false\n const read = await run(runtime, git, ['read-tree', '--reset', '-u', tree], cwd)\n if (read.exitCode !== 0) return false\n // Everything the snapshot held now sits in the index, so this removes\n // exactly what was created after it -- no more.\n await run(runtime, git, ['clean', '-fd'], cwd)\n // The snapshot flattened staged, unstaged, and untracked work into one\n // tree. Putting the index back on HEAD makes the restored files read as\n // the ordinary unstaged edits they were, at the cost of forgetting which\n // of them had been staged. An unborn branch has no HEAD and keeps the\n // flattened index; there is nothing else to reset to.\n await run(runtime, git, ['reset', '--mixed', 'HEAD'], cwd)\n return true\n } catch {\n return false\n }\n}\n","import { randomUUID } from 'node:crypto'\r\nimport {\r\n query as claudeQuery,\r\n type EffortLevel,\r\n type Options as ClaudeOptions,\r\n type PermissionMode,\r\n type Query,\r\n type SDKControlGetContextUsageResponse,\r\n type SDKMessage,\r\n type SDKUserMessage,\r\n type Settings as ClaudeSettings,\r\n type SlashCommand,\r\n} from '@anthropic-ai/claude-agent-sdk'\r\nimport type { Agent } from '@deepseek-ai/dsh-agent'\r\nimport { ToolCallId, createToolResultMessage } from '@deepseek-ai/dsh-llm'\r\nimport type { ApprovalService } from '@deepseek-ai/dsh-user-approval'\r\nimport type { UserQuestionService } from '@deepseek-ai/dsh-user-questions'\r\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\nimport { AsyncQueue } from './async-queue.ts'\r\nimport { DEFAULT_CLAUDE_RENDER_MODE, TASK_TOOL_NAMES, type ClaudeRenderMode } from './constants.ts'\r\nimport {\r\n currentClaudeActivityCursor,\r\n redactText,\r\n safeDetail,\r\n type ClaudeActivityCursor,\r\n type ClaudeActivityInput,\r\n type ClaudeTaskInfo,\r\n type ClaudeUsage,\r\n} from './events.ts'\r\nimport { createPermissionBridge } from './permission.ts'\r\nimport { PlanFeedbackGate } from './plan-feedback.ts'\r\nimport { createUserQuestionBridge } from './user-question.ts'\r\nimport { ClaudeSidecarRepository } from './sidecar.ts'\r\nimport { CLAUDE_PRESENTER_NAMES, dynamicPresenterDefinition } from './presenters.ts'\r\nimport { normalizeSdkMessage, type NormalizedSdkMessage } from './sdk-messages.ts'\r\nimport { claudeModelValue, recordClaudeModels } from './model-catalog.ts'\r\nimport { readPlanUsageFrom } from './plan-usage.ts'\r\nimport { createManagedClaudeSpawner, type ManagedClaudeProcess } from './spawn.ts'\r\nimport { captureWorktreeTree } from './worktree-snapshot.ts'\r\n\r\nexport const CLAUDE_INITIALIZATION_TIMEOUT_MS = 30_000\r\nexport const CLAUDE_INTERRUPT_TIMEOUT_MS = 5_000\r\n/** Control requests must settle; a wedged one must not clog the metadata chain. */\r\nexport const CLAUDE_METADATA_TIMEOUT_MS = 15_000\r\n\r\nexport type ClaudeSupervisorState =\r\n | 'starting'\r\n | 'idle'\r\n | 'running'\r\n | 'interrupting'\r\n | 'disconnected'\r\n | 'outcome-unknown'\r\n | 'disposed'\r\n\r\nexport interface ClaudeSupervisorConfig {\r\n executablePath: string\r\n idleTimeoutMs: number\r\n maxProcesses: number\r\n defaultModel: string\r\n /** Which renderer the visible turn is produced for; read per message so a\r\n * Settings change lands on the next turn without a Host restart. */\r\n renderMode?: ClaudeRenderMode\r\n}\r\n\r\nexport type ClaudeTurnStreamEvent =\r\n | { type: 'text-delta'; text: string }\r\n /** One settled Claude thinking block, forwarded only for the native\r\n * renderer, which draws it as a DSH reasoning block. */\r\n | { type: 'thinking'; text: string }\r\n | { type: 'usage'; usage: ClaudeUsage }\r\n | { type: 'segment-complete'; text: string }\r\n | { type: 'complete'; text: string }\r\n\r\nexport type ClaudeThinkingMode = 'off' | 'ultracode' | EffortLevel\r\n\r\nexport type DshSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'\r\n\r\nconst CLAUDE_MODE_BY_SANDBOX: Readonly<Record<DshSandboxMode, PermissionMode>> = {\r\n 'read-only': 'plan',\r\n 'workspace-write': 'acceptEdits',\r\n 'danger-full-access': 'bypassPermissions',\r\n}\r\n\r\n/** Fold DSH's native access selector into Claude Code's closest permission mode. */\r\nexport function claudePermissionMode(events: readonly { type: string; data: unknown }[]): PermissionMode {\r\n for (let index = events.length - 1; index >= 0; index -= 1) {\r\n const event = events[index]\r\n if (event?.type !== 'sandbox/mode') continue\r\n const mode = (event.data as { mode?: unknown }).mode\r\n return typeof mode === 'string' && mode in CLAUDE_MODE_BY_SANDBOX\r\n ? CLAUDE_MODE_BY_SANDBOX[mode as DshSandboxMode]\r\n : 'plan'\r\n }\r\n return 'plan'\r\n}\r\n\r\nexport interface ClaudeTurnRequest {\r\n agent: Agent\r\n prompt: SDKUserMessage['message']['content']\r\n model?: string\r\n thinkingMode?: ClaudeThinkingMode\r\n /** The renderer this turn is produced for, frozen by the caller before the\r\n * turn starts. The setting is live, so reading it per record would let a\r\n * mid-turn switch stamp one step's records with both renderers -- which the\r\n * Client reads as \"natively drawn\" for the whole step, while the adapter,\r\n * which froze its own answer at turn start, streamed nothing natively.\r\n * Omitted falls back to the shared config. */\r\n renderMode?: ClaudeRenderMode\r\n signal?: AbortSignal\r\n}\r\n\r\nexport interface ClaudeSupervisorSnapshot {\r\n sessionId: string\r\n claudeSessionId?: string\r\n state: ClaudeSupervisorState\r\n cwd: string\r\n model: string\r\n thinkingMode?: ClaudeThinkingMode\r\n lastUsedAt: number\r\n pid?: number\r\n}\r\n\r\nexport class ClaudeTurnBusyError extends Error {\r\n constructor(sessionId: string) {\r\n super(`Claude Code session ${sessionId} already has an active or interrupting turn`)\r\n this.name = 'ClaudeTurnBusyError'\r\n }\r\n}\r\n\r\nexport class ClaudeOutcomeUnknownError extends Error {\r\n constructor(message = 'Claude Code exited after activity; side-effect outcome is unknown and the prompt was not replayed') {\r\n super(message)\r\n this.name = 'ClaudeOutcomeUnknownError'\r\n }\r\n}\r\n\r\nexport class ClaudeProtocolError extends Error {\r\n constructor(message: string) {\r\n super(message)\r\n this.name = 'ClaudeProtocolError'\r\n }\r\n}\r\n\r\nexport class ClaudeProcessLimitError extends Error {\r\n constructor(maxProcesses: number) {\r\n super(`Claude Code process limit reached (${maxProcesses}) and no idle session can be evicted`)\r\n this.name = 'ClaudeProcessLimitError'\r\n }\r\n}\r\n\r\nexport type ClaudeQueryFactory = (params: {\r\n prompt: AsyncIterable<SDKUserMessage>\r\n options: ClaudeOptions\r\n}) => Query\r\n\r\ninterface ActiveTurn {\r\n agent: Agent\r\n cursor: ClaudeActivityCursor\r\n /** Whether this turn is produced for DSH's own renderer. Frozen at admission\r\n * so every record of the turn carries one answer. */\r\n native: boolean\r\n output: AsyncQueue<ClaudeTurnStreamEvent>\r\n promptUuid: ReturnType<typeof randomUUID>\r\n phase: 'primary' | 'waiting-tasks' | 'follow-up'\r\n sawActivity: boolean\r\n sawTextDelta: boolean\r\n text: string\r\n /** Visible prose for the current top-level assistant segment. */\r\n transcriptText: string\r\n /** Stable sidecar ordinal reused while the current assistant segment grows. */\r\n transcriptTextOrdinal: number | undefined\r\n thinking: string\r\n /** Newest single-call prompt accounting; what DSH's context meter divides. */\r\n requestUsage: ClaudeUsage | undefined\r\n /** When this turn was admitted, and when it first put a token on screen.\r\n * The transcript has no other clock: activities carry no timestamps. */\r\n startedAt: number\r\n firstOutputAt: number | undefined\r\n aborted: boolean\r\n deniedToolUseIds: Set<string>\r\n /** Root tool calls still waiting for their result, by toolUseId, with the\r\n * tool name a result carries none of. Emptied as results arrive, so what\r\n * remains when a turn ends is exactly what never got an answer. */\r\n openCalls: Map<string, string>\r\n signal?: AbortSignal\r\n abortListener?: () => void\r\n}\r\n\r\ninterface SupervisorEntry {\r\n sessionId: string\r\n ownerAgent: Agent\r\n cwd: string\r\n model: string\r\n thinkingMode: ClaudeThinkingMode | undefined\r\n permissionMode: PermissionMode\r\n state: ClaudeSupervisorState\r\n lastUsedAt: number\r\n input: AsyncQueue<SDKUserMessage>\r\n query: Query\r\n /** Official SDK initialization control request; no stdin nudge is required. */\r\n sdkInitialization: Promise<void>\r\n lifetime: AbortController\r\n process: ManagedClaudeProcess | undefined\r\n claudeSessionId: string | undefined\r\n active: ActiveTurn | undefined\r\n idleTimer: ReturnType<typeof setTimeout> | undefined\r\n /** Whether the message stream has emitted system/init for session binding. */\r\n initialized: boolean\r\n expectedResume: string | undefined\r\n /** Newest main-chain entry uuid Claude emitted; the anchor a rewind of the\r\n * next turn forks at. Sidechain (subagent) entries are not chain entries. */\r\n lastChainUuid: string | undefined\r\n /** Whether this process consumed an armed rewind fork target at spawn. */\r\n consumedRewind: boolean\r\n /** Live Claude task board (subagents and background tasks), keyed by task id. */\r\n tasks: Map<string, ClaudeTaskInfo>\r\n /** Last time a task snapshot was persisted (progress throttling). */\r\n taskSnapshotAt: number\r\n /** Pending throttled snapshot flush timer. */\r\n taskSnapshotTimer: ReturnType<typeof setTimeout> | undefined\r\n pump: Promise<void>\r\n}\r\n\r\nfunction abortFailure(): Error {\r\n const error = new Error('Claude Code turn aborted')\r\n error.name = 'AbortError'\r\n return error\r\n}\r\n\r\nfunction signalAborted(signal: AbortSignal | undefined): boolean {\r\n return signal?.aborted === true\r\n}\r\n\r\ninterface TurnAdmission {\r\n request: ClaudeTurnRequest\r\n resolve: (output: AsyncIterable<ClaudeTurnStreamEvent>) => void\r\n reject: (error: unknown) => void\r\n delivered: boolean\r\n admitting: boolean\r\n waitedForCapacity: boolean\r\n cancellation: AbortController\r\n completion: Promise<void>\r\n complete: () => void\r\n abortListener?: () => void\r\n}\r\n\r\ninterface MetadataAdmission {\r\n sessionId: string\r\n cancellation: AbortController\r\n started: boolean\r\n completion: Promise<void>\r\n complete: () => void\r\n}\r\n\r\nasync function withTimeout<T>(operation: Promise<T>, timeoutMs: number, label: string): Promise<T> {\r\n let timer: ReturnType<typeof setTimeout> | undefined\r\n try {\r\n return await Promise.race([\r\n operation,\r\n new Promise<never>((_resolve, reject) => {\r\n timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs)\r\n timer.unref?.()\r\n }),\r\n ])\r\n } finally {\r\n if (timer !== undefined) clearTimeout(timer)\r\n }\r\n}\r\n\r\nasync function withAbort<T>(operation: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\r\n if (signal === undefined) return operation\r\n if (signal.aborted) throw abortFailure()\r\n let abortListener: (() => void) | undefined\r\n try {\r\n return await Promise.race([\r\n operation,\r\n new Promise<never>((_resolve, reject) => {\r\n abortListener = () => { reject(abortFailure()) }\r\n signal.addEventListener('abort', abortListener, { once: true })\r\n }),\r\n ])\r\n } finally {\r\n if (abortListener !== undefined) signal.removeEventListener('abort', abortListener)\r\n }\r\n}\r\n\r\n/** The uuid of one main-chain transcript entry, or undefined for anything a\r\n * rewind must not fork at: stream partials, results, and sidechain traffic. */\r\nfunction chainEntryUuid(message: SDKMessage): string | undefined {\r\n if (message.type !== 'assistant' && message.type !== 'user') return undefined\r\n const envelope = message as { uuid?: unknown; parent_tool_use_id?: unknown }\r\n if (typeof envelope.parent_tool_use_id === 'string') return undefined\r\n return typeof envelope.uuid === 'string' && envelope.uuid.length > 0 ? envelope.uuid : undefined\r\n}\r\n\r\nfunction sdkUserMessage(prompt: SDKUserMessage['message']['content'], uuid: ReturnType<typeof randomUUID>): SDKUserMessage {\r\n return {\r\n type: 'user',\r\n message: { role: 'user', content: prompt },\r\n parent_tool_use_id: null,\r\n uuid,\r\n }\r\n}\r\n\r\nconst BACKGROUND_TASK_REPORT_PROMPT = [\r\n 'The background tasks launched by your preceding response have now all settled.',\r\n 'Report their final completed or failed outcomes concisely to the user.',\r\n 'Do not start new tools or tasks, and do not repeat the earlier progress update.',\r\n].join(' ')\r\n\r\nfunction usageSummary(usage: ClaudeUsage): string {\r\n const input = usage.inputTokens ?? 0\r\n const output = usage.outputTokens ?? 0\r\n const cost = usage.cumulativeCostUsd === undefined\r\n ? ''\r\n : ` · $${usage.cumulativeCostUsd.toFixed(4)} cumulative`\r\n return `${input} input / ${output} output tokens${cost}`\r\n}\r\n\r\nfunction errorSummary(error: unknown): string {\r\n return error instanceof Error ? error.message : String(error)\r\n}\r\n\r\n/** Root-call activity summary; subagent dispatches lead with Claude's own task description. */\r\nfunction rootCallSummary(toolName: string, input: unknown): string {\r\n if (TASK_TOOL_NAMES.has(toolName)) {\r\n const description = input !== null && typeof input === 'object'\r\n ? (input as Record<string, unknown>).description\r\n : undefined\r\n if (typeof description === 'string' && description.length > 0) return description\r\n return 'Claude dispatched a subagent'\r\n }\r\n return `Claude called ${toolName}`\r\n}\r\n\r\nexport class ClaudeSupervisor {\r\n readonly #entries = new Map<string, SupervisorEntry>()\r\n readonly #interruptions = new Map<string, Promise<void>>()\r\n readonly #runtime: Pick<SubprocessRuntime, 'spawn' | 'resolveExecutable'>\r\n readonly #approval: Pick<ApprovalService, 'request'>\r\n readonly #userQuestions: Pick<UserQuestionService, 'ask'>\r\n /** Lets the plan panel answer a plan's approval with revisions. */\r\n readonly planFeedback = new PlanFeedbackGate()\r\n readonly #config: ClaudeSupervisorConfig\r\n readonly #queryFactory: ClaudeQueryFactory\r\n readonly #runDetached: <T>(operation: () => T) => T\r\n readonly #sidecar: ClaudeSidecarRepository\r\n readonly #dynamicPresenterNames = new WeakMap<Agent, Set<string>>()\r\n readonly #contextWindows = new Map<string, number>()\r\n #disposed = false\r\n #admissionGate: Promise<void> = Promise.resolve()\r\n /** FIFO user turns live outside the gate while capacity-blocked, so\r\n * best-effort metadata can still enter the serialized path and fail. */\r\n readonly #turnAdmissions: TurnAdmission[] = []\r\n readonly #metadataAdmissions = new Set<MetadataAdmission>()\r\n #admissionDrainScheduled = false\r\n /** Prevent a capacity change between a failed attempt and parking the head\r\n * from becoming a lost wake-up. */\r\n #admissionRevision = 0\r\n #blockedAdmissionRevision: number | undefined\r\n\r\n constructor(dependencies: {\r\n runtime: Pick<SubprocessRuntime, 'spawn' | 'resolveExecutable'>\r\n approval: Pick<ApprovalService, 'request'>\r\n userQuestions: Pick<UserQuestionService, 'ask'>\r\n config: ClaudeSupervisorConfig\r\n queryFactory?: ClaudeQueryFactory\r\n runDetached?: <T>(operation: () => T) => T\r\n sidecar?: ClaudeSidecarRepository\r\n }) {\r\n this.#runtime = dependencies.runtime\r\n this.#approval = dependencies.approval\r\n this.#userQuestions = dependencies.userQuestions\r\n this.#config = dependencies.config\r\n this.#queryFactory = dependencies.queryFactory ?? (params => claudeQuery(params))\r\n this.#runDetached = dependencies.runDetached ?? (operation => operation())\r\n this.#sidecar = dependencies.sidecar ?? new ClaudeSidecarRepository()\r\n }\r\n\r\n snapshots(): ClaudeSupervisorSnapshot[] {\r\n return [...this.#entries.values()].map(entry => ({\r\n sessionId: entry.sessionId,\r\n ...(entry.claudeSessionId === undefined ? {} : { claudeSessionId: entry.claudeSessionId }),\r\n state: entry.state,\r\n cwd: entry.cwd,\r\n model: entry.model,\r\n ...(entry.thinkingMode === undefined ? {} : { thinkingMode: entry.thinkingMode }),\r\n lastUsedAt: entry.lastUsedAt,\r\n ...(entry.process === undefined ? {} : { pid: entry.process.handle.pid }),\r\n }))\r\n }\r\n\r\n supportedCommands(agent: Agent, model = this.#config.defaultModel): Promise<readonly SlashCommand[]> {\r\n return this.#runMetadata(agent, model, query => query.supportedCommands())\r\n }\r\n\r\n async contextUsage(agent: Agent, model = this.#config.defaultModel): Promise<SDKControlGetContextUsageResponse> {\r\n return this.#runMetadata(agent, model, async (query, entry) => {\r\n const usage = await query.getContextUsage()\r\n this.#recordContextWindow(entry.model, usage)\r\n return usage\r\n })\r\n }\r\n\r\n /** Cache a window under both the selector id the caller asked for and the\r\n * concrete model the CLI reports, so either name resolves it later. */\r\n #recordContextWindow(model: string, usage: SDKControlGetContextUsageResponse): void {\r\n const contextWindow = usage.rawMaxTokens > 0 ? usage.rawMaxTokens : usage.maxTokens\r\n if (contextWindow <= 0) return\r\n this.#contextWindows.set(model, contextWindow)\r\n this.#contextWindows.set(usage.model, contextWindow)\r\n }\r\n\r\n /** Learn a model's context window the first time a turn finishes on it.\r\n *\r\n * DSH hides its context meter entirely unless the route publishes a\r\n * capacity, and these numbers move with Claude releases — so none are\r\n * hardcoded; the CLI is asked over the session's own live process.\r\n *\r\n * Turn completion is the earliest honest moment to ask. `entry.model` is\r\n * already the model that just ran, so no model switch is provoked — which\r\n * rules out asking from `resolveModel`, since DSH resolves every model in\r\n * the catalog to build its picker and `#metadataEntry` would switch the live\r\n * session once per entry. And nothing is lost by waiting: the meter needs a\r\n * usage sample too, and no turn has reported one before the first turn ends.\r\n *\r\n * Best-effort — a failure leaves the window unknown (the meter stays hidden,\r\n * exactly as before) and the next completed turn tries again. */\r\n async #learnContextWindow(entry: SupervisorEntry): Promise<void> {\r\n if (this.#contextWindows.has(entry.model)) return\r\n try {\r\n const usage = await withTimeout(\r\n entry.query.getContextUsage(),\r\n CLAUDE_METADATA_TIMEOUT_MS,\r\n 'Claude context window probe',\r\n )\r\n this.#recordContextWindow(entry.model, usage)\r\n } catch {\r\n // Intentionally silent: this is opportunistic chrome, never turn-critical.\r\n }\r\n }\r\n\r\n contextWindow(model: string): number | undefined {\r\n return this.#contextWindows.get(model)\r\n }\r\n\r\n /** Raw `/usage` payload, read over a session's existing process. Only the\r\n * idle-time metadata bridge uses this; a user-triggered refresh runs\r\n * probePlanUsage instead so it never waits on, or perturbs, a session. */\r\n planUsage(agent: Agent, model = this.#config.defaultModel): Promise<unknown> {\r\n return this.#runMetadata(agent, model, query => readPlanUsageFrom(query))\r\n }\r\n\r\n runTurn(request: ClaudeTurnRequest): Promise<AsyncIterable<ClaudeTurnStreamEvent>> {\r\n const interruption = this.#interruptions.get(request.agent.id as string)\r\n if (interruption !== undefined) return interruption.then(() => this.runTurn(request))\r\n return new Promise((resolve, reject) => {\r\n let complete: (() => void) | undefined\r\n const completion = new Promise<void>(done => { complete = done })\r\n const admission: TurnAdmission = {\r\n request,\r\n resolve,\r\n reject,\r\n delivered: false,\r\n admitting: false,\r\n waitedForCapacity: false,\r\n cancellation: new AbortController(),\r\n completion,\r\n complete: () => { complete?.() },\r\n }\r\n if (request.signal !== undefined) {\r\n const abortListener = () => {\r\n if (!admission.admitting) {\r\n this.#finishTurnAdmission(admission, { error: abortFailure() })\r\n } else if (admission.waitedForCapacity && !admission.delivered) {\r\n admission.delivered = true\r\n admission.reject(abortFailure())\r\n }\r\n this.#admissionRevision += 1\r\n this.#blockedAdmissionRevision = undefined\r\n this.#scheduleTurnAdmissions()\r\n }\r\n admission.abortListener = abortListener\r\n request.signal.addEventListener('abort', abortListener, { once: true })\r\n }\r\n this.#turnAdmissions.push(admission)\r\n this.#scheduleTurnAdmissions()\r\n })\r\n }\r\n\r\n async #drainTurnAdmissions(): Promise<void> {\r\n while (this.#turnAdmissions.length > 0) {\r\n const admission = this.#turnAdmissions[0]!\r\n if (signalAborted(admission.request.signal)) {\r\n this.#finishTurnAdmission(admission, { error: abortFailure() })\r\n continue\r\n }\r\n const attemptedRevision = this.#admissionRevision\r\n admission.admitting = true\r\n try {\r\n const output = await this.#runTurnAdmitted(\r\n admission.request,\r\n admission.waitedForCapacity,\r\n admission.cancellation.signal,\r\n )\r\n this.#finishTurnAdmission(admission, { output })\r\n } catch (error) {\r\n if (\r\n error instanceof ClaudeProcessLimitError\r\n && !signalAborted(admission.request.signal)\r\n && !admission.cancellation.signal.aborted\r\n && !this.#disposed\r\n ) {\r\n admission.admitting = false\r\n admission.waitedForCapacity = true\r\n if (attemptedRevision === this.#admissionRevision) {\r\n this.#blockedAdmissionRevision = attemptedRevision\r\n return\r\n }\r\n continue\r\n }\r\n this.#finishTurnAdmission(admission, { error })\r\n }\r\n }\r\n }\r\n\r\n #finishTurnAdmission(\r\n admission: TurnAdmission,\r\n outcome: { output: AsyncIterable<ClaudeTurnStreamEvent> } | { error: unknown },\r\n ): void {\r\n if (this.#turnAdmissions[0] === admission) this.#turnAdmissions.shift()\r\n else {\r\n const index = this.#turnAdmissions.indexOf(admission)\r\n if (index >= 0) this.#turnAdmissions.splice(index, 1)\r\n }\r\n admission.admitting = false\r\n if (admission.request.signal !== undefined && admission.abortListener !== undefined) {\r\n admission.request.signal.removeEventListener('abort', admission.abortListener)\r\n }\r\n if (!admission.delivered) {\r\n admission.delivered = true\r\n if ('error' in outcome) admission.reject(outcome.error)\r\n else admission.resolve(outcome.output)\r\n }\r\n admission.complete()\r\n }\r\n\r\n #scheduleTurnAdmissions(): void {\r\n if (\r\n this.#admissionDrainScheduled\r\n || this.#turnAdmissions.length === 0\r\n || this.#blockedAdmissionRevision === this.#admissionRevision\r\n ) return\r\n this.#admissionDrainScheduled = true\r\n const operation = this.#admissionGate.then(() => this.#drainTurnAdmissions())\r\n this.#admissionGate = operation.then(() => undefined, () => undefined)\r\n const finished = () => {\r\n this.#admissionDrainScheduled = false\r\n this.#scheduleTurnAdmissions()\r\n }\r\n void operation.then(finished, finished)\r\n }\r\n\r\n async #runTurnAdmitted(\r\n request: ClaudeTurnRequest,\r\n abortDuringAdmission: boolean,\r\n cancellationSignal: AbortSignal,\r\n ): Promise<AsyncIterable<ClaudeTurnStreamEvent>> {\r\n if (this.#disposed) throw new Error('dsh-claude: supervisor is disposed')\r\n if (cancellationSignal.aborted) throw abortFailure()\r\n if (signalAborted(request.signal)) throw abortFailure()\r\n const sessionId = request.agent.id as string\r\n let entry = this.#entries.get(sessionId)\r\n let createdForRequest: SupervisorEntry | undefined\r\n const throwIfUnavailable = async (): Promise<void> => {\r\n const failure = this.#disposed\r\n ? new Error('dsh-claude: supervisor is disposed')\r\n : cancellationSignal.aborted || (abortDuringAdmission && signalAborted(request.signal))\r\n ? abortFailure()\r\n : undefined\r\n if (failure === undefined) return\r\n if (createdForRequest !== undefined) {\r\n if (this.#entries.get(sessionId) === createdForRequest) this.#entries.delete(sessionId)\r\n await this.#disposeEntry(createdForRequest)\r\n createdForRequest = undefined\r\n }\r\n throw failure\r\n }\r\n if (entry?.state === 'disposed' || entry?.state === 'disconnected' || entry?.state === 'outcome-unknown') {\r\n this.#entries.delete(sessionId)\r\n await this.#disposeEntry(entry)\r\n await throwIfUnavailable()\r\n entry = undefined\r\n }\r\n if (entry === undefined) {\r\n await this.#makeRoom()\r\n await throwIfUnavailable()\r\n try {\r\n entry = await this.#createEntry(\r\n request.agent,\r\n request.model ?? this.#config.defaultModel,\r\n request.thinkingMode,\r\n abortDuringAdmission ? request.signal : undefined,\r\n cancellationSignal,\r\n )\r\n } catch (error) {\r\n await throwIfUnavailable()\r\n throw error\r\n }\r\n createdForRequest = entry\r\n await throwIfUnavailable()\r\n this.#entries.set(sessionId, entry)\r\n }\r\n if (entry.ownerAgent !== request.agent) {\r\n throw new Error(`dsh-claude: live agent identity changed for session ${sessionId}`)\r\n }\r\n if (entry.active !== undefined || entry.state === 'interrupting') throw new ClaudeTurnBusyError(sessionId)\r\n try {\r\n const initialization = withAbort(entry.sdkInitialization, cancellationSignal)\r\n await (abortDuringAdmission ? withAbort(initialization, request.signal) : initialization)\r\n } catch (error) {\r\n await throwIfUnavailable()\r\n throw error\r\n }\r\n await throwIfUnavailable()\r\n\r\n if (entry.idleTimer !== undefined) {\r\n clearTimeout(entry.idleTimer)\r\n entry.idleTimer = undefined\r\n }\r\n const model = request.model ?? this.#config.defaultModel\r\n if (request.thinkingMode !== entry.thinkingMode || model !== entry.model) {\r\n // The SDK only accepts effort/thinking at query start, and a live\r\n // setModel is not enough for the model either: the CLI freezes its\r\n // system prompt (including the \"you are powered by\" line) at the first\r\n // context-usage request, which the metadata refresh issues on every new\r\n // process, so a switched session answers as the old model. Rebuild the\r\n // query; the persisted Claude session binding keeps the context.\r\n this.#entries.delete(sessionId)\r\n await this.#disposeEntry(entry)\r\n if (createdForRequest === entry) createdForRequest = undefined\r\n await throwIfUnavailable()\r\n try {\r\n entry = await this.#createEntry(\r\n request.agent,\r\n model,\r\n request.thinkingMode,\r\n abortDuringAdmission ? request.signal : undefined,\r\n cancellationSignal,\r\n )\r\n } catch (error) {\r\n await throwIfUnavailable()\r\n throw error\r\n }\r\n createdForRequest = entry\r\n await throwIfUnavailable()\r\n this.#entries.set(sessionId, entry)\r\n try {\r\n const initialization = withAbort(entry.sdkInitialization, cancellationSignal)\r\n await (abortDuringAdmission ? withAbort(initialization, request.signal) : initialization)\r\n } catch (error) {\r\n await throwIfUnavailable()\r\n throw error\r\n }\r\n } else {\r\n await this.#syncPermissionMode(entry)\r\n }\r\n await throwIfUnavailable()\r\n\r\n const promptUuid = randomUUID()\r\n const cursor = currentClaudeActivityCursor(request.agent.session.snapshotEvents())\r\n const projection = await this.#sidecar.read(sessionId)\r\n await throwIfUnavailable()\r\n cursor.nextOrdinal = projection.activities.reduce((next, activity) => (\r\n activity.turn === cursor.turn && activity.step === cursor.step\r\n ? Math.max(next, activity.ordinal + 1)\r\n : next\r\n ), 0)\r\n const active: ActiveTurn = {\r\n agent: request.agent,\r\n cursor,\r\n native: (request.renderMode ?? this.#config.renderMode ?? DEFAULT_CLAUDE_RENDER_MODE) === 'native',\r\n output: new AsyncQueue<ClaudeTurnStreamEvent>(),\r\n promptUuid,\r\n phase: 'primary',\r\n sawActivity: false,\r\n sawTextDelta: false,\r\n text: '',\r\n transcriptText: '',\r\n transcriptTextOrdinal: undefined,\r\n thinking: '',\r\n requestUsage: undefined,\r\n startedAt: Date.now(),\r\n firstOutputAt: undefined,\r\n aborted: false,\r\n deniedToolUseIds: new Set(),\r\n openCalls: new Map(),\r\n ...(request.signal === undefined ? {} : { signal: request.signal }),\r\n }\r\n entry.active = active\r\n entry.state = 'running'\r\n entry.lastUsedAt = Date.now()\r\n await this.#captureWorktree(entry, cursor.turn)\r\n try {\r\n await this.#appendActivity(active, {\r\n kind: 'status',\r\n phase: 'started',\r\n title: 'Claude Code turn started',\r\n })\r\n } catch (error) {\r\n active.output.fail(error)\r\n entry.active = undefined\r\n if (this.#entries.get(sessionId) === entry) this.#entries.delete(sessionId)\r\n await this.#disposeEntry(entry)\r\n throw error\r\n }\r\n if (signalAborted(request.signal)) {\r\n active.aborted = true\r\n active.output.fail(abortFailure())\r\n await this.#appendActivity(active, {\r\n kind: 'status',\r\n phase: 'failed',\r\n title: 'Claude Code turn cancelled before submission',\r\n })\r\n entry.active = undefined\r\n if (!abortDuringAdmission || createdForRequest === undefined) {\r\n entry.state = 'idle'\r\n entry.lastUsedAt = Date.now()\r\n this.#armIdleTimer(entry)\r\n }\r\n await throwIfUnavailable()\r\n return active.output\r\n }\r\n if (request.signal !== undefined) {\r\n const abortListener = () => { void this.#startInterrupt(entry as SupervisorEntry) }\r\n active.abortListener = abortListener\r\n request.signal.addEventListener('abort', abortListener, { once: true })\r\n }\r\n entry.input.push(sdkUserMessage(request.prompt, promptUuid))\r\n return active.output\r\n }\r\n\r\n #runMetadata<T>(\r\n agent: Agent,\r\n model: string,\r\n operation: (query: Query, entry: SupervisorEntry) => Promise<T>,\r\n ): Promise<T> {\r\n if (this.#turnAdmissions.some(admission => admission.waitedForCapacity)) {\r\n return Promise.reject(new ClaudeProcessLimitError(this.#config.maxProcesses))\r\n }\r\n let complete: (() => void) | undefined\r\n const admission: MetadataAdmission = {\r\n sessionId: agent.id as string,\r\n cancellation: new AbortController(),\r\n started: false,\r\n completion: new Promise<void>(done => { complete = done }),\r\n complete: () => { complete?.() },\r\n }\r\n this.#metadataAdmissions.add(admission)\r\n const admitted = this.#admissionGate.then(async () => {\r\n admission.started = true\r\n if (this.#disposed) throw new Error('dsh-claude: supervisor is disposed')\r\n if (admission.cancellation.signal.aborted) throw abortFailure()\r\n if (this.#turnAdmissions.some(admission => admission.waitedForCapacity)) {\r\n throw new ClaudeProcessLimitError(this.#config.maxProcesses)\r\n }\r\n const entry = await this.#metadataEntry(agent, model, admission.cancellation.signal)\r\n try {\r\n // Use the SDK's initialize control request. system/init is emitted only\r\n // after the first real stdin message and is reserved for session binding.\r\n await withAbort(entry.sdkInitialization, admission.cancellation.signal)\r\n return await withAbort(\r\n this.#control(entry, operation(entry.query, entry), 'Claude metadata request'),\r\n admission.cancellation.signal,\r\n )\r\n } finally {\r\n entry.lastUsedAt = Date.now()\r\n if (entry.active === undefined && entry.state === 'idle') this.#armIdleTimer(entry)\r\n }\r\n }).finally(() => { this.#finishMetadataAdmission(admission) })\r\n this.#admissionGate = admitted.then(() => undefined, () => undefined)\r\n return withAbort(admitted, admission.cancellation.signal)\r\n }\r\n\r\n async #metadataEntry(\r\n agent: Agent,\r\n model: string,\r\n cancellationSignal: AbortSignal,\r\n ): Promise<SupervisorEntry> {\r\n if (cancellationSignal.aborted) throw abortFailure()\r\n const sessionId = agent.id as string\r\n let entry = this.#entries.get(sessionId)\r\n if (entry?.state === 'disposed' || entry?.state === 'disconnected' || entry?.state === 'outcome-unknown') {\r\n this.#entries.delete(sessionId)\r\n await this.#disposeEntry(entry)\r\n if (cancellationSignal.aborted) throw abortFailure()\r\n entry = undefined\r\n }\r\n if (entry === undefined) {\r\n await this.#makeRoom()\r\n if (cancellationSignal.aborted) throw abortFailure()\r\n entry = await this.#createEntry(agent, model, undefined, undefined, cancellationSignal)\r\n if (cancellationSignal.aborted) {\r\n await this.#disposeEntry(entry)\r\n throw abortFailure()\r\n }\r\n this.#entries.set(sessionId, entry)\r\n }\r\n if (entry.ownerAgent !== agent) {\r\n throw new Error(`dsh-claude: live agent identity changed for session ${sessionId}`)\r\n }\r\n if (entry.active !== undefined || entry.state === 'interrupting') throw new ClaudeTurnBusyError(sessionId)\r\n if (entry.idleTimer !== undefined) {\r\n clearTimeout(entry.idleTimer)\r\n entry.idleTimer = undefined\r\n }\r\n await withAbort(this.#syncPermissionMode(entry), cancellationSignal)\r\n if (cancellationSignal.aborted) throw abortFailure()\r\n // Never switch a live entry here: `model` is only the seed for a fresh\r\n // process. The idle metadata refresh runs with the plugin default, and\r\n // letting it call setModel raced runTurn's own switch -- a session the user\r\n // set to Fable answered on Opus whenever the refresh landed last.\r\n return entry\r\n }\r\n\r\n /** Run one SDK control request against a live entry, and discard the entry if\r\n * it does not answer.\r\n *\r\n * Turn admission attempts and metadata reads share one process-wide gate,\r\n * so an unbounded control request stalls every session until the Host restarts.\r\n * Bounding it is only half the cure: a timeout also proves this query has\r\n * stopped answering, and keeping the entry means the next caller reuses the\r\n * same dead process — timing out again, forever. Discarding it lets the next\r\n * attempt spawn a fresh one. Every control request goes through here so a\r\n * new call site cannot quietly reintroduce either half. */\r\n async #control<T>(\r\n entry: SupervisorEntry,\r\n operation: Promise<T>,\r\n label: string,\r\n timeoutMs = CLAUDE_METADATA_TIMEOUT_MS,\r\n ): Promise<T> {\r\n try {\r\n return await withTimeout(operation, timeoutMs, label)\r\n } catch (error) {\r\n if (this.#entries.get(entry.sessionId) === entry) this.#entries.delete(entry.sessionId)\r\n await this.#disposeEntry(entry)\r\n throw error\r\n }\r\n }\r\n\r\n async #syncPermissionMode(entry: SupervisorEntry): Promise<void> {\r\n const mode = claudePermissionMode(entry.ownerAgent.session.snapshotEvents())\r\n if (mode === entry.permissionMode) return\r\n await this.#control(entry, entry.query.setPermissionMode(mode), 'Claude Code permission mode switch')\r\n entry.permissionMode = mode\r\n }\r\n\r\n #finishMetadataAdmission(admission: MetadataAdmission): void {\r\n this.#metadataAdmissions.delete(admission)\r\n admission.complete()\r\n }\r\n\r\n #cancelMetadataAdmissions(\r\n predicate: (admission: MetadataAdmission) => boolean,\r\n ): Promise<void>[] {\r\n const cancelled = [...this.#metadataAdmissions].filter(predicate)\r\n for (const admission of cancelled) {\r\n admission.cancellation.abort()\r\n if (!admission.started) this.#finishMetadataAdmission(admission)\r\n }\r\n return cancelled.map(admission => admission.completion)\r\n }\r\n\r\n #cancelTurnAdmissions(\r\n predicate: (admission: TurnAdmission) => boolean,\r\n error: Error,\r\n ): Promise<void>[] {\r\n const cancelled = this.#turnAdmissions.filter(predicate)\r\n for (const admission of cancelled) {\r\n admission.cancellation.abort()\r\n if (!admission.delivered) {\r\n admission.delivered = true\r\n admission.reject(error)\r\n }\r\n if (!admission.admitting) this.#finishTurnAdmission(admission, { error })\r\n }\r\n if (cancelled.length > 0) {\r\n this.#admissionRevision += 1\r\n this.#blockedAdmissionRevision = undefined\r\n this.#scheduleTurnAdmissions()\r\n }\r\n return cancelled.map(admission => admission.completion)\r\n }\r\n\r\n limitsChanged(): void {\r\n if (this.#disposed) return\r\n this.#notifyCapacityChange()\r\n this.#scheduleLimitReconciliation()\r\n }\r\n\r\n async disposeSession(sessionId: string): Promise<void> {\r\n const pendingAdmissions = this.#cancelTurnAdmissions(\r\n admission => (admission.request.agent.id as string) === sessionId,\r\n abortFailure(),\r\n )\r\n const pendingMetadata = this.#cancelMetadataAdmissions(\r\n admission => admission.sessionId === sessionId,\r\n )\r\n const entry = this.#entries.get(sessionId)\r\n if (entry !== undefined) this.#entries.delete(sessionId)\r\n await Promise.allSettled([\r\n ...pendingAdmissions,\r\n ...pendingMetadata,\r\n ...(entry === undefined ? [] : [this.#disposeEntry(entry)]),\r\n ])\r\n }\r\n\r\n async dispose(): Promise<void> {\r\n if (this.#disposed) return\r\n this.#disposed = true\r\n const pendingAdmissions = this.#cancelTurnAdmissions(\r\n () => true,\r\n new Error('dsh-claude: supervisor is disposed'),\r\n )\r\n const pendingMetadata = this.#cancelMetadataAdmissions(() => true)\r\n const entries = [...this.#entries.values()]\r\n this.#entries.clear()\r\n this.#notifyCapacityChange()\r\n await Promise.allSettled([\r\n ...pendingAdmissions,\r\n ...pendingMetadata,\r\n ...entries.map(entry => this.#disposeEntry(entry)),\r\n ])\r\n }\r\n\r\n async #makeRoom(): Promise<void> {\r\n while (this.#entries.size >= this.#config.maxProcesses) {\r\n const idle = [...this.#entries.values()]\r\n .filter(entry => entry.active === undefined && entry.state === 'idle')\r\n .sort((left, right) => left.lastUsedAt - right.lastUsedAt)[0]\r\n if (idle === undefined) throw new ClaudeProcessLimitError(this.#config.maxProcesses)\r\n this.#entries.delete(idle.sessionId)\r\n await this.#disposeEntry(idle)\r\n }\r\n }\r\n\r\n async #trimExcessIdle(): Promise<void> {\r\n while (this.#entries.size > this.#config.maxProcesses) {\r\n const idle = [...this.#entries.values()]\r\n .filter(entry => entry.active === undefined && entry.state === 'idle')\r\n .sort((left, right) => left.lastUsedAt - right.lastUsedAt)[0]\r\n if (idle === undefined) return\r\n this.#entries.delete(idle.sessionId)\r\n await this.#disposeEntry(idle)\r\n }\r\n }\r\n\r\n #notifyCapacityChange(): void {\r\n this.#admissionRevision += 1\r\n this.#blockedAdmissionRevision = undefined\r\n this.#scheduleTurnAdmissions()\r\n }\r\n\r\n #scheduleLimitReconciliation(): void {\r\n const operation = this.#admissionGate.then(() => this.#trimExcessIdle())\r\n this.#admissionGate = operation.then(() => undefined, () => undefined)\r\n }\r\n\r\n async #createEntry(\r\n agent: Agent,\r\n model: string,\r\n thinkingMode?: ClaudeThinkingMode,\r\n signal?: AbortSignal,\r\n cancellationSignal?: AbortSignal,\r\n ): Promise<SupervisorEntry> {\r\n const sessionId = agent.id as string\r\n const cwd = agent.session.header.cwd ?? process.cwd()\r\n const input = new AsyncQueue<SDKUserMessage>()\r\n const lifetime = new AbortController()\r\n const projection = await this.#sidecar.importLegacy(sessionId, agent.session.snapshotEvents())\r\n if (signalAborted(signal) || signalAborted(cancellationSignal)) throw abortFailure()\r\n const binding = projection.binding\r\n // A rewound session resumes at the kept turn's chain anchor, or drops its\r\n // binding entirely when the rewind discarded every turn. The truncating\r\n // resume may land in a different Claude session id, so the identity guard\r\n // stands down for exactly this spawn and re-binds from system/init.\r\n const pendingRewind = projection.rewind?.pending\r\n const forkAt = pendingRewind !== undefined && 'resumeAt' in pendingRewind ? pendingRewind.resumeAt : undefined\r\n const startFresh = pendingRewind !== undefined && 'fresh' in pendingRewind\r\n const permissionMode = claudePermissionMode(agent.session.snapshotEvents())\r\n const entry = {\r\n sessionId,\r\n ownerAgent: agent,\r\n cwd,\r\n model,\r\n thinkingMode,\r\n permissionMode,\r\n state: 'starting' as ClaudeSupervisorState,\r\n lastUsedAt: Date.now(),\r\n input,\r\n lifetime,\r\n claudeSessionId: startFresh ? undefined : binding?.claudeSessionId,\r\n expectedResume: startFresh || forkAt !== undefined ? undefined : binding?.claudeSessionId,\r\n lastChainUuid: undefined,\r\n consumedRewind: pendingRewind !== undefined,\r\n initialized: false,\r\n idleTimer: undefined,\r\n tasks: new Map<string, ClaudeTaskInfo>(),\r\n taskSnapshotAt: 0,\r\n taskSnapshotTimer: undefined,\r\n } as SupervisorEntry\r\n\r\n const activeInteraction = () => {\r\n const active = entry.active\r\n return active === undefined ? undefined : {\r\n agent: active.agent,\r\n cursor: active.cursor,\r\n markActivity: () => { active.sawActivity = true },\r\n recordDenial: (toolUseId: string) => { active.deniedToolUseIds.add(toolUseId) },\r\n hasFullAccess: async () => {\r\n await this.#syncPermissionMode(entry)\r\n return entry.permissionMode === 'bypassPermissions'\r\n },\r\n appendActivity: (activity: ClaudeActivityInput) => this.#appendActivity(active, activity),\r\n }\r\n }\r\n const userQuestion = createUserQuestionBridge(this.#userQuestions, activeInteraction)\r\n const canUseTool = createPermissionBridge(this.#approval, activeInteraction, userQuestion, this.planFeedback)\r\n const options: ClaudeOptions = {\r\n pathToClaudeCodeExecutable: this.#config.executablePath,\r\n cwd,\r\n settingSources: ['user', 'project', 'local'],\r\n systemPrompt: { type: 'preset', preset: 'claude_code' },\r\n tools: { type: 'preset', preset: 'claude_code' },\r\n includePartialMessages: true,\r\n permissionMode,\r\n allowDangerouslySkipPermissions: true,\r\n canUseTool,\r\n abortController: lifetime,\r\n spawnClaudeCodeProcess: createManagedClaudeSpawner(this.#runtime, this.#config.executablePath, process => {\r\n entry.process = process\r\n }),\r\n ...(binding === undefined || startFresh ? {} : {\r\n resume: binding.claudeSessionId,\r\n ...(forkAt === undefined ? {} : { resumeSessionAt: forkAt }),\r\n }),\r\n // `model` is the selector alias DSH persists; the CLI is given the id\r\n // that alias currently stands for.\r\n model: claudeModelValue(model),\r\n ...(thinkingMode === undefined\r\n ? {}\r\n : thinkingMode === 'off'\r\n ? { thinking: { type: 'disabled' } as const }\r\n : thinkingMode === 'ultracode'\r\n ? { settings: { ultracode: true } satisfies ClaudeSettings }\r\n : { effort: thinkingMode }),\r\n }\r\n entry.query = this.#queryFactory({ prompt: input, options })\r\n entry.pump = this.#runDetached(() => this.#pump(entry))\r\n entry.sdkInitialization = withTimeout(\r\n entry.query.initializationResult(),\r\n CLAUDE_INITIALIZATION_TIMEOUT_MS,\r\n 'Claude SDK initialization',\r\n ).then((initialization) => {\r\n // The CLI's own /model lineup rides along on initialize, so the selector\r\n // tracks whatever Claude Code ships without a table in this plugin and\r\n // without a control request of its own.\r\n recordClaudeModels(initialization.models)\r\n if (entry.state === 'starting') entry.state = 'idle'\r\n })\r\n void entry.sdkInitialization.catch(error => this.#handleDisconnect(entry, error))\r\n return entry\r\n }\r\n\r\n async #pump(entry: SupervisorEntry): Promise<void> {\r\n try {\r\n for await (const sdkMessage of entry.query) {\r\n const chainUuid = chainEntryUuid(sdkMessage as SDKMessage)\r\n if (chainUuid !== undefined) entry.lastChainUuid = chainUuid\r\n for (const message of normalizeSdkMessage(sdkMessage as SDKMessage)) {\r\n await this.#handleMessage(entry, message)\r\n }\r\n }\r\n if (entry.state !== 'disposed') await this.#handleDisconnect(entry, new Error('Claude Code stream ended'))\r\n } catch (error) {\r\n if (entry.state !== 'disposed') await this.#handleDisconnect(entry, error)\r\n }\r\n }\r\n\r\n async #handleMessage(entry: SupervisorEntry, message: NormalizedSdkMessage): Promise<void> {\r\n if (message.kind === 'init') {\r\n // Claude Code can re-emit system/init across turns in long-lived\r\n // streaming-input mode (e.g. the auth-error path). Treat it idempotently:\r\n // refresh the session id/version and negotiated state, and only reject a\r\n // genuine identity/cwd mismatch.\r\n const firstInitialization = !entry.initialized\r\n if (entry.expectedResume !== undefined && message.sessionId !== entry.expectedResume) {\r\n throw new ClaudeProtocolError(`Claude Code resumed unexpected session ${message.sessionId}; expected ${entry.expectedResume}`)\r\n }\r\n if (message.cwd !== entry.cwd) {\r\n throw new ClaudeProtocolError(`Claude Code initialized in unexpected cwd ${message.cwd}; expected ${entry.cwd}`)\r\n }\r\n entry.initialized = true\r\n entry.claudeSessionId = message.sessionId\r\n entry.state = entry.active === undefined ? 'idle' : 'running'\r\n // A newly created Query cannot retain tasks from the previous process,\r\n // but repeated init messages from this same long-lived Query are only\r\n // protocol refreshes and must not erase background work still running.\r\n if (firstInitialization && entry.tasks.size > 0) {\r\n entry.tasks.clear()\r\n await this.#flushTasksSnapshot(entry)\r\n }\r\n await this.#sidecar.writeBinding(entry.sessionId, {\r\n claudeSessionId: message.sessionId,\r\n cliVersion: message.cliVersion,\r\n cwd: message.cwd,\r\n })\r\n // The fork target is spent the moment Claude resumes at it; leaving it\r\n // armed would re-truncate the session on the next respawn.\r\n if (entry.consumedRewind) {\r\n entry.consumedRewind = false\r\n await this.#sidecar.clearRewindPending(entry.sessionId)\r\n }\r\n return\r\n }\r\n\r\n // Task lifecycle is session-scoped, not turn-scoped: background tasks and\r\n // subagents settle while no DSH turn is active, and their notifications\r\n // must still reach the task board instead of being dropped with turn-less\r\n // messages below.\r\n const taskId = message.kind === 'subagent' ? message.taskId : undefined\r\n if (message.kind === 'subagent' && taskId !== undefined) {\r\n await this.#trackTask(entry, message, taskId, entry.active?.cursor.turn)\r\n } else if (message.kind === 'background-tasks') {\r\n await this.#trackBackgroundLevel(entry, message.tasks, entry.active?.cursor.turn)\r\n }\r\n\r\n const active = entry.active\r\n if (active === undefined) return\r\n if (message.kind === 'result') {\r\n if (entry.claudeSessionId === undefined) {\r\n throw new ClaudeProtocolError('Claude Code sent a result before initialization')\r\n }\r\n if (message.sessionId !== entry.claudeSessionId) {\r\n throw new ClaudeProtocolError(`Claude Code result session ${message.sessionId} does not match ${entry.claudeSessionId}`)\r\n }\r\n if (active.phase === 'waiting-tasks') {\r\n // The CLI may automatically react to each completed background task and\r\n // emit a top-level result, correlated or not. Publish that prose as a\r\n // completed progress block, but keep the original DSH turn open until\r\n // every owned task settles and the explicit final report returns.\r\n await this.#completeProgressSegment(active, message)\r\n return\r\n }\r\n if (message.userMessageUuid !== undefined && message.userMessageUuid !== active.promptUuid) {\r\n // A stale internal continuation must not settle the explicit final\r\n // report request. Primary-turn mismatches remain protocol failures.\r\n if (active.phase === 'follow-up') return\r\n throw new ClaudeProtocolError(`Claude Code result for user message ${message.userMessageUuid} does not match active request ${active.promptUuid}`)\r\n }\r\n await this.#completeTurn(entry, active, message)\r\n return\r\n }\r\n if (message.kind === 'protocol-error') {\r\n throw new ClaudeProtocolError(`${message.title}: ${JSON.stringify(message.detail).slice(0, 1_000)}`)\r\n }\r\n active.sawActivity = true\r\n\r\n switch (message.kind) {\r\n case 'text-delta':\r\n if (message.parentToolUseId !== undefined) return\r\n active.sawTextDelta = true\r\n active.text += message.text\r\n active.transcriptText += message.text\r\n await this.#upsertTranscriptText(active)\r\n active.firstOutputAt ??= Date.now()\r\n active.output.push({ type: 'text-delta', text: message.text })\r\n return\r\n case 'assistant-text':\r\n if (message.parentToolUseId !== undefined) return\r\n if (!active.sawTextDelta) {\r\n // Complete assistant text is the fallback when no partial text delta\r\n // streamed. Mark text-delta seen so that additional complete\r\n // assistant records sharing the same message.id (one per completed\r\n // content block) do not duplicate the text.\r\n active.sawTextDelta = true\r\n active.text += message.text\r\n active.transcriptText += message.text\r\n await this.#upsertTranscriptText(active)\r\n active.firstOutputAt ??= Date.now()\r\n active.output.push({ type: 'text-delta', text: message.text })\r\n }\r\n return\r\n case 'thinking':\r\n if (message.parentToolUseId !== undefined) return\r\n if (message.phase === 'updated') {\r\n active.thinking += message.text\r\n return\r\n }\r\n active.thinking = message.text\r\n await this.#appendActivity(active, {\r\n kind: 'thinking',\r\n phase: 'completed',\r\n title: 'Claude thinking',\r\n summary: message.text,\r\n })\r\n // The plugin transcript reads thinking off the sidecar; the native\r\n // renderer needs it on the stream to build a reasoning block.\r\n if (active.native) active.output.push({ type: 'thinking', text: message.text })\r\n return\r\n case 'tool-call':\r\n if (message.parentToolUseId === undefined) this.#closeTranscriptTextSegment(active)\r\n await this.#appendActivity(active, {\r\n kind: message.parentToolUseId === undefined ? 'tool-call' : 'subagent',\r\n phase: 'started',\r\n toolUseId: message.toolUseId,\r\n ...(message.parentToolUseId === undefined ? {} : { parentToolUseId: message.parentToolUseId }),\r\n toolName: message.toolName,\r\n title: message.toolName,\r\n summary: message.parentToolUseId === undefined ? rootCallSummary(message.toolName, message.input) : `Subagent called ${message.toolName}`,\r\n detail: message.input,\r\n })\r\n if (message.parentToolUseId === undefined) {\r\n active.openCalls.set(message.toolUseId, message.toolName)\r\n // Only root calls are mirrored: a subagent's nested tools belong to\r\n // the Task card that dispatched them, and the native channel has no\r\n // nesting to hang them under.\r\n if (active.native) {\r\n this.#ensureDynamicPresenter(active.agent, message.toolName)\r\n await this.#appendNativeToolCall(active, message)\r\n }\r\n }\r\n return\r\n case 'tool-result':\r\n active.openCalls.delete(message.toolUseId)\r\n await this.#appendActivity(active, {\r\n kind: message.parentToolUseId === undefined ? 'tool-result' : 'subagent',\r\n phase: message.isError ? 'failed' : 'completed',\r\n toolUseId: message.toolUseId,\r\n ...(message.parentToolUseId === undefined ? {} : { parentToolUseId: message.parentToolUseId }),\r\n title: message.isError ? 'Tool failed' : 'Tool completed',\r\n detail: message.output,\r\n isError: message.isError,\r\n })\r\n if (message.parentToolUseId === undefined && active.native) {\r\n await this.#appendNativeToolResult(active, message)\r\n }\r\n return\r\n case 'subagent':\r\n await this.#appendActivity(active, {\r\n kind: 'subagent',\r\n phase: message.phase,\r\n ...(message.taskId === undefined ? {} : { taskId: message.taskId }),\r\n title: message.title,\r\n summary: message.summary,\r\n detail: message.detail,\r\n isError: message.phase === 'failed',\r\n })\r\n return\r\n case 'request-usage':\r\n // A subagent call bills against its own context, so it never stands in\r\n // for the main conversation's size.\r\n if (message.parentToolUseId === undefined) active.requestUsage = message.usage\r\n return\r\n case 'compaction':\r\n // Close the open prose span first: compaction sits *between* what was\r\n // said before and after it, never inside one text segment.\r\n this.#closeTranscriptTextSegment(active)\r\n await this.#appendActivity(active, {\r\n kind: 'compaction',\r\n phase: 'completed',\r\n title: 'Claude compacted the conversation',\r\n detail: {\r\n ...(message.trigger === undefined ? {} : { trigger: message.trigger }),\r\n ...(message.preTokens === undefined ? {} : { preTokens: message.preTokens }),\r\n ...(message.postTokens === undefined ? {} : { postTokens: message.postTokens }),\r\n ...(message.durationMs === undefined ? {} : { durationMs: message.durationMs }),\r\n },\r\n })\r\n return\r\n case 'status':\r\n case 'warning':\r\n case 'unknown':\r\n await this.#appendActivity(active, {\r\n kind: message.kind === 'status' ? 'status' : 'warning',\r\n phase: 'updated',\r\n title: message.title,\r\n ...('summary' in message ? { summary: message.summary } : {}),\r\n ...('detail' in message ? { detail: message.detail } : {}),\r\n })\r\n return\r\n case 'permission-denied':\r\n await this.#appendActivity(active, {\r\n kind: 'permission',\r\n phase: 'denied',\r\n toolUseId: message.toolUseId,\r\n toolName: message.toolName,\r\n title: message.toolName,\r\n summary: message.summary,\r\n })\r\n // A denied call never produces a tool result, so the native card would\r\n // stay pending forever. Settle it as the failure it is.\r\n if (active.native) {\r\n await this.#appendNativeToolResult(active, {\r\n kind: 'tool-result',\r\n toolUseId: message.toolUseId,\r\n output: message.summary,\r\n isError: true,\r\n })\r\n }\r\n return\r\n }\r\n }\r\n\r\n /** The turn's accounting with its wall clock attached. The transcript draws\r\n * this line itself under the plugin renderer: activities carry no\r\n * timestamps, so a duration it did not measure is a duration nobody has. */\r\n #timedUsage(active: ActiveTurn, usage: ClaudeUsage): ClaudeUsage {\r\n const now = Date.now()\r\n return {\r\n ...usage,\r\n durationMs: Math.max(0, now - active.startedAt),\r\n ...(active.firstOutputAt === undefined ? {} : { ttftMs: Math.max(0, active.firstOutputAt - active.startedAt) }),\r\n }\r\n }\r\n\r\n /** Register one presenter-only mirror for a tool name the static preset\r\n * registry does not cover (MCP tools, newly added built-ins). Runs in the\r\n * agent scope so the mirror is visible only to this preset's sessions and\r\n * unwinds with the agent; failure keeps the generic card, never the turn. */\r\n #ensureDynamicPresenter(agent: Agent, name: string): void {\r\n if (CLAUDE_PRESENTER_NAMES.has(name)) return\r\n let known = this.#dynamicPresenterNames.get(agent)\r\n if (known === undefined) {\r\n known = new Set<string>()\r\n this.#dynamicPresenterNames.set(agent, known)\r\n }\r\n if (known.has(name)) return\r\n try {\r\n agent.ctx.tools.register(dynamicPresenterDefinition(name))\r\n known.add(name)\r\n } catch {\r\n // A late or disposed agent keeps the generic card; presentation must\r\n // never unsettle the Claude turn.\r\n }\r\n }\r\n\r\n /** Mirror one root Claude tool call into the durable native tool channel so\r\n * the host's tool presentation renders it exactly like a DSH-executed call.\r\n * Presentation duplication is best-effort and never unsettles the turn. */\r\n async #appendNativeToolCall(\r\n active: ActiveTurn,\r\n message: Extract<NormalizedSdkMessage, { kind: 'tool-call' }>,\r\n ): Promise<void> {\r\n try {\r\n await active.agent.session.append('tool/call', {\r\n turn: active.cursor.turn,\r\n step: active.cursor.step,\r\n callId: ToolCallId(message.toolUseId),\r\n name: message.toolName,\r\n arguments: safeDetail(message.input) ?? '{}',\r\n })\r\n } catch {\r\n // Presentation duplication must never unsettle the Claude turn.\r\n }\r\n }\r\n\r\n async #appendNativeToolResult(\r\n active: ActiveTurn,\r\n message: Pick<Extract<NormalizedSdkMessage, { kind: 'tool-result' }>, 'kind' | 'toolUseId' | 'output' | 'isError'>,\r\n ): Promise<void> {\r\n const text = typeof message.output === 'string' ? redactText(message.output) : safeDetail(message.output) ?? ''\r\n try {\r\n await active.agent.session.append('tool/result', {\r\n turn: active.cursor.turn,\r\n step: active.cursor.step,\r\n message: createToolResultMessage({\r\n callId: ToolCallId(message.toolUseId),\r\n content: [{ type: 'text', text }],\r\n isError: message.isError,\r\n }),\r\n }, { surfaceOp: 'append' })\r\n } catch {\r\n // Presentation duplication must never unsettle the Claude turn.\r\n }\r\n }\r\n\r\n /** Merge one task lifecycle message into the session's task board. */\r\n async #trackTask(\r\n entry: SupervisorEntry,\r\n message: Extract<NormalizedSdkMessage, { kind: 'subagent' }>,\r\n taskId: string,\r\n originTurn: number | undefined,\r\n ): Promise<void> {\r\n const previous = entry.tasks.get(taskId)\r\n const next: ClaudeTaskInfo = {\r\n taskId,\r\n description: message.description ?? previous?.description ?? message.title,\r\n status: message.taskStatus ?? previous?.status ?? 'running',\r\n }\r\n const resolvedOriginTurn = previous?.originTurn ?? originTurn\r\n if (resolvedOriginTurn !== undefined) next.originTurn = resolvedOriginTurn\r\n const subagentType = message.subagentType ?? previous?.subagentType\r\n if (subagentType !== undefined) next.subagentType = subagentType\r\n const taskType = message.taskType ?? previous?.taskType\r\n if (taskType !== undefined) next.taskType = taskType\r\n const lastToolName = message.lastToolName ?? previous?.lastToolName\r\n if (lastToolName !== undefined) next.lastToolName = lastToolName\r\n const summary = message.summary ?? previous?.summary\r\n if (summary !== undefined) next.summary = summary\r\n const usage = message.usage ?? previous?.usage\r\n if (usage !== undefined) next.usage = usage\r\n if (previous?.backgrounded === true) next.backgrounded = true\r\n entry.tasks.set(taskId, next)\r\n const settled = next.status !== 'running'\r\n await this.#scheduleTasksSnapshot(entry, settled)\r\n if (settled) await this.#continueAfterTasks(entry)\r\n }\r\n\r\n /** Fold the background-task level signal into the board (REPLACE semantics\r\n * for the backgrounded flag: only the listed tasks are detached). */\r\n async #trackBackgroundLevel(\r\n entry: SupervisorEntry,\r\n tasks: readonly { taskId: string; taskType?: string; description: string }[],\r\n originTurn: number | undefined,\r\n ): Promise<void> {\r\n const live = new Set(tasks.map(task => task.taskId))\r\n let changed = false\r\n for (const task of tasks) {\r\n const existing = entry.tasks.get(task.taskId)\r\n if (existing === undefined) {\r\n entry.tasks.set(task.taskId, {\r\n taskId: task.taskId,\r\n description: task.description,\r\n status: 'running',\r\n ...(originTurn === undefined ? {} : { originTurn }),\r\n ...(task.taskType === undefined ? {} : { taskType: task.taskType }),\r\n backgrounded: true,\r\n })\r\n changed = true\r\n } else if (existing.backgrounded !== true || existing.status !== 'running') {\r\n entry.tasks.set(task.taskId, { ...existing, status: 'running', backgrounded: true })\r\n changed = true\r\n }\r\n }\r\n for (const task of entry.tasks.values()) {\r\n if (task.backgrounded === true && task.status === 'running' && !live.has(task.taskId)) {\r\n entry.tasks.set(task.taskId, { ...task, status: 'completed' })\r\n changed = true\r\n }\r\n }\r\n if (changed) {\r\n await this.#scheduleTasksSnapshot(entry, true)\r\n await this.#continueAfterTasks(entry)\r\n }\r\n }\r\n\r\n #hasRunningTasks(entry: SupervisorEntry, active: ActiveTurn): boolean {\r\n return [...entry.tasks.values()].some(task => (\r\n task.originTurn === active.cursor.turn && task.backgrounded === true && task.status === 'running'\r\n ))\r\n }\r\n\r\n async #continueAfterTasks(entry: SupervisorEntry): Promise<void> {\r\n const active = entry.active\r\n if (active === undefined || active.phase !== 'waiting-tasks' || this.#hasRunningTasks(entry, active)) return\r\n active.phase = 'follow-up'\r\n active.promptUuid = randomUUID()\r\n active.sawTextDelta = false\r\n active.text = ''\r\n this.#closeTranscriptTextSegment(active)\r\n active.thinking = ''\r\n await this.#appendSafely(active, {\r\n kind: 'status',\r\n phase: 'updated',\r\n title: 'Claude Code is reporting background task results',\r\n })\r\n entry.input.push(sdkUserMessage(BACKGROUND_TASK_REPORT_PROMPT, active.promptUuid))\r\n }\r\n\r\n /** Persist the task board. Settled transitions flush immediately; progress\r\n * ticks throttle to one snapshot per second to bound log volume. */\r\n async #scheduleTasksSnapshot(entry: SupervisorEntry, immediate: boolean): Promise<void> {\r\n const THROTTLE_MS = 1_000\r\n const elapsed = Date.now() - entry.taskSnapshotAt\r\n if (!immediate && elapsed < THROTTLE_MS) {\r\n if (entry.taskSnapshotTimer === undefined) {\r\n entry.taskSnapshotTimer = setTimeout(() => {\r\n entry.taskSnapshotTimer = undefined\r\n void this.#flushTasksSnapshot(entry)\r\n }, THROTTLE_MS - elapsed)\r\n entry.taskSnapshotTimer.unref?.()\r\n }\r\n return\r\n }\r\n await this.#flushTasksSnapshot(entry)\r\n }\r\n\r\n async #flushTasksSnapshot(entry: SupervisorEntry): Promise<void> {\r\n if (entry.taskSnapshotTimer !== undefined) {\r\n clearTimeout(entry.taskSnapshotTimer)\r\n entry.taskSnapshotTimer = undefined\r\n }\r\n entry.taskSnapshotAt = Date.now()\r\n // Snapshot persistence is best-effort: the in-memory board stays\r\n // authoritative and the next change re-flushes.\r\n await this.#sidecar.writeTasks(entry.sessionId, [...entry.tasks.values()]).catch(() => undefined)\r\n }\r\n\r\n /** What DSH is told about token usage: newest call's prompt, whole turn's output.\r\n *\r\n * `TokenUsage` is documented as \"token accounting for ONE model call\", and\r\n * DSH's token meter divides `uncachedInput + cacheRead + cacheWrite` by the\r\n * context window to draw context pressure. One Claude turn makes many calls\r\n * and the CLI's result usage sums all of them, so reporting that sum pinned\r\n * the meter at 100%: a 35-call turn reads the same prompt from cache 35\r\n * times, which sums past the window without the conversation ever growing.\r\n * The newest single call answers \"how big is this conversation now\".\r\n *\r\n * Output is deliberately excluded from that pressure sum, so the same\r\n * argument never applied to it — and taking it from the newest call reported\r\n * whatever the wrap-up message happened to cost, which is a couple of tokens\r\n * after a turn that wrote thousands. The turn total is the honest figure.\r\n *\r\n * The sidecar activity keeps the whole turn total for both — that is the\r\n * audit and cost record, and nothing divides it by a window. */\r\n #reportedUsage(\r\n active: ActiveTurn,\r\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\r\n ): ClaudeUsage {\r\n const prompt = active.requestUsage\r\n if (prompt === undefined) return result.usage\r\n return {\r\n ...prompt,\r\n ...(result.usage.outputTokens === undefined ? {} : { outputTokens: result.usage.outputTokens }),\r\n }\r\n }\r\n\r\n async #completeProgressSegment(\r\n active: ActiveTurn,\r\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\r\n ): Promise<void> {\r\n if (!active.sawTextDelta && active.text.length === 0 && result.text !== undefined) {\r\n active.text = result.text\r\n active.transcriptText = result.text\r\n await this.#upsertTranscriptText(active)\r\n active.output.push({ type: 'text-delta', text: result.text })\r\n }\r\n await this.#upsertTranscriptText(active)\r\n active.output.push({ type: 'segment-complete', text: active.text })\r\n active.sawTextDelta = false\r\n active.text = ''\r\n this.#closeTranscriptTextSegment(active)\r\n active.thinking = ''\r\n }\r\n\r\n /** The turn's accounting, recorded once the turn is actually over.\r\n *\r\n * A turn that hands off to background tasks passes through the same result\r\n * handling on its way to `waiting-tasks`, and recording there drew a closing\r\n * total under a turn that was still running. */\r\n async #recordTurnUsage(\r\n active: ActiveTurn,\r\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\r\n ): Promise<void> {\r\n if (result.usage.inputTokens === undefined && result.usage.outputTokens === undefined && result.usage.cumulativeCostUsd === undefined) return\r\n await this.#appendSafely(active, {\r\n kind: 'usage',\r\n phase: 'completed',\r\n title: 'Claude usage',\r\n summary: usageSummary(result.usage),\r\n usage: this.#timedUsage(active, result.usage),\r\n })\r\n active.output.push({ type: 'usage', usage: this.#reportedUsage(active, result) })\r\n }\r\n\r\n async #completeTurn(\r\n entry: SupervisorEntry,\r\n active: ActiveTurn,\r\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\r\n ): Promise<void> {\r\n if (entry.active !== active) return\r\n if (active.aborted) {\r\n await this.#upsertTranscriptText(active)\r\n await this.#flushTranscript(active)\r\n await this.#settleOpenCalls(active, 'Cancelled with the turn')\r\n await this.#appendSafely(active, {\r\n kind: 'status',\r\n phase: 'failed',\r\n title: 'Claude Code turn cancelled',\r\n })\r\n entry.active = undefined\r\n entry.state = 'idle'\r\n entry.lastUsedAt = Date.now()\r\n await this.#recordChainAnchor(entry, active)\r\n this.#checkpointProjection(entry)\r\n this.#armIdleTimer(entry)\r\n this.#notifyCapacityChange()\r\n this.#scheduleLimitReconciliation()\r\n return\r\n }\r\n const unmatchedDenials = (result.permissionDenials ?? [])\r\n .filter(denial => !active.deniedToolUseIds.has(denial.toolUseId))\r\n if (unmatchedDenials.length > 0) {\r\n await this.#appendSafely(active, {\r\n kind: 'permission',\r\n phase: 'denied',\r\n title: 'Claude Code auto-denied tool calls',\r\n summary: unmatchedDenials.map(denial => denial.toolName).join(', '),\r\n })\r\n }\r\n if (!result.success) {\r\n await this.#recordTurnUsage(active, result)\r\n if (!active.sawTextDelta && active.text.length === 0 && result.text !== undefined) {\r\n active.text = result.text\r\n active.transcriptText = result.text\r\n await this.#upsertTranscriptText(active)\r\n active.output.push({ type: 'text-delta', text: result.text })\r\n }\r\n await this.#upsertTranscriptText(active)\r\n await this.#flushTranscript(active)\r\n const message = result.errors?.join('\\n')\r\n ?? (result.terminalReason !== undefined ? `Claude Code failed the turn (${result.terminalReason})` : 'Claude Code failed the turn')\r\n await this.#appendSafely(active, {\r\n kind: 'error',\r\n phase: 'failed',\r\n title: 'Claude Code turn failed',\r\n summary: message,\r\n isError: true,\r\n })\r\n active.output.fail(new Error(message))\r\n } else {\r\n if (!active.sawTextDelta && active.text.length === 0 && result.text !== undefined) {\r\n active.text = result.text\r\n active.transcriptText = result.text\r\n await this.#upsertTranscriptText(active)\r\n active.output.push({ type: 'text-delta', text: result.text })\r\n }\r\n await this.#upsertTranscriptText(active)\r\n if (active.phase === 'primary' && this.#hasRunningTasks(entry, active)) {\r\n active.phase = 'waiting-tasks'\r\n await this.#appendSafely(active, {\r\n kind: 'status',\r\n phase: 'updated',\r\n title: 'Claude Code is waiting for background tasks',\r\n })\r\n await this.#completeProgressSegment(active, result)\r\n return\r\n }\r\n await this.#recordTurnUsage(active, result)\r\n await this.#appendSafely(active, {\r\n kind: 'status',\r\n phase: 'completed',\r\n title: 'Claude Code turn completed',\r\n })\r\n await this.#flushTranscript(active)\r\n active.output.push({ type: 'complete', text: active.text })\r\n active.output.close()\r\n }\r\n if (active.signal !== undefined && active.abortListener !== undefined) {\r\n active.signal.removeEventListener('abort', active.abortListener)\r\n }\r\n entry.active = undefined\r\n entry.state = 'idle'\r\n entry.lastUsedAt = Date.now()\r\n await this.#recordChainAnchor(entry, active)\r\n this.#checkpointProjection(entry)\r\n this.#armIdleTimer(entry)\r\n this.#notifyCapacityChange()\r\n this.#scheduleLimitReconciliation()\r\n await this.#learnContextWindow(entry)\r\n }\r\n\r\n /** Tell every reader where this session's delta stream ended.\r\n *\r\n * A reader that lost the turn's last delta has nothing later to reveal the\r\n * hole, and a settled turn produces nothing further -- so a finished tool\r\n * group would keep pulsing until the session was reopened by hand. Last\r\n * line of the turn, best effort: presentation must never unsettle it. */\r\n #checkpointProjection(entry: SupervisorEntry): void {\r\n try {\r\n this.#sidecar.checkpoint(entry.sessionId)\r\n } catch {\r\n // A reader that misses the checkpoint is no worse off than before it.\r\n }\r\n }\r\n\r\n /** Pin the working tree this turn is about to change, so a rewind of it can\r\n * put the checkout back where the turn found it.\r\n *\r\n * Awaited, and deliberately: a snapshot taken after Claude's first edit\r\n * would restore to a state that never existed. It costs one `git add -A`\r\n * against a throwaway index per turn, and best effort throughout -- a\r\n * session with no repository simply never offers a file rewind. */\r\n async #captureWorktree(entry: SupervisorEntry, turn: number): Promise<void> {\r\n try {\r\n const tree = await captureWorktreeTree(this.#runtime, entry.cwd)\r\n if (tree === undefined) return\r\n await this.#sidecar.recordRewindSnapshot(entry.sessionId, turn, tree)\r\n } catch {\r\n // The snapshot is advisory; a failed capture never fails the turn.\r\n }\r\n }\r\n\r\n /** Pin where Claude's chain ended for the DSH turn that just settled, so a\r\n * later rewind of the following turn can fork exactly here. Best effort:\r\n * a missing anchor only makes a rewind fall back to an earlier turn. */\r\n async #recordChainAnchor(entry: SupervisorEntry, active: ActiveTurn): Promise<void> {\r\n const uuid = entry.lastChainUuid\r\n if (uuid === undefined) return\r\n try {\r\n await this.#sidecar.recordRewindAnchor(entry.sessionId, active.cursor.turn, uuid)\r\n } catch {\r\n // The sidecar is advisory; a failed anchor never fails the turn.\r\n }\r\n }\r\n\r\n async #upsertTranscriptText(active: ActiveTurn): Promise<void> {\r\n if (active.transcriptText.length === 0) return\r\n const ordinal = active.transcriptTextOrdinal ?? active.cursor.nextOrdinal++\r\n active.transcriptTextOrdinal = ordinal\r\n try {\r\n // Hot path: notify live subscribers synchronously; disk persistence is\r\n // coalesced inside the repository and flushed at segment/turn edges.\r\n this.#sidecar.appendTranscriptText(active.agent.id as string, {\r\n text: active.transcriptText,\r\n ...(active.native ? { renderer: 'native' as const } : {}),\r\n turn: active.cursor.turn,\r\n step: active.cursor.step,\r\n ordinal,\r\n })\r\n } catch {\r\n // Transcript persistence is presentational and must not change a Claude outcome.\r\n }\r\n }\r\n\r\n async #flushTranscript(active: ActiveTurn): Promise<void> {\r\n await this.#sidecar.flushTranscriptText(active.agent.id as string).catch(() => undefined)\r\n }\r\n\r\n #closeTranscriptTextSegment(active: ActiveTurn): void {\r\n void this.#flushTranscript(active)\r\n active.transcriptText = ''\r\n active.transcriptTextOrdinal = undefined\r\n }\r\n\r\n async #appendActivity(active: ActiveTurn, activity: ClaudeActivityInput): Promise<void> {\r\n const ordinal = active.cursor.nextOrdinal++\r\n await this.#sidecar.appendActivity(active.agent.id as string, {\r\n ...activity,\r\n // Stamp the renderer this record was produced for. The Client reads it\r\n // back per step, so a step drawn natively is never also drawn by the\r\n // plugin transcript -- and history keeps whichever renderer produced it.\r\n ...(active.native ? { renderer: 'native' as const } : {}),\r\n turn: active.cursor.turn,\r\n step: active.cursor.step,\r\n ordinal,\r\n })\r\n }\r\n\r\n /** Persist durable activity without letting a storage failure unsettle the\r\n * in-memory turn or leak process ownership. Audit failure is best-effort. */\r\n async #appendSafely(active: ActiveTurn, activity: ClaudeActivityInput): Promise<void> {\r\n await this.#appendActivity(active, activity).catch(() => undefined)\r\n }\r\n\r\n #startInterrupt(entry: SupervisorEntry): Promise<void> {\r\n const existing = this.#interruptions.get(entry.sessionId)\r\n if (existing !== undefined) return existing\r\n const interruption = this.#interrupt(entry).finally(() => {\r\n this.#interruptions.delete(entry.sessionId)\r\n })\r\n this.#interruptions.set(entry.sessionId, interruption)\r\n return interruption\r\n }\r\n\r\n /** Close out the root tool calls a turn is ending without answers for.\r\n *\r\n * A tool result is the only thing that ever settles a call, and a turn that\r\n * is cancelled or disconnected produces none: the transcript would keep\r\n * drawing those calls as running for as long as the session lives, and no\r\n * later event would ever correct it. Written as the failures they are. */\r\n async #settleOpenCalls(active: ActiveTurn, summary: string): Promise<void> {\r\n const open = [...active.openCalls]\r\n active.openCalls.clear()\r\n for (const [toolUseId, toolName] of open) {\r\n await this.#appendSafely(active, {\r\n kind: 'tool-result',\r\n phase: 'failed',\r\n toolUseId,\r\n toolName,\r\n title: 'Tool cancelled',\r\n summary,\r\n isError: true,\r\n })\r\n // The native card has the same hole, and the same fix as a denied call.\r\n if (active.native) {\r\n await this.#appendNativeToolResult(active, {\r\n kind: 'tool-result',\r\n toolUseId,\r\n output: summary,\r\n isError: true,\r\n })\r\n }\r\n }\r\n }\r\n\r\n async #interrupt(entry: SupervisorEntry): Promise<void> {\r\n const active = entry.active\r\n if (active === undefined || entry.state === 'interrupting') return\r\n entry.state = 'interrupting'\r\n active.aborted = true\r\n active.output.fail(abortFailure())\r\n await this.#upsertTranscriptText(active)\r\n let interruptError: unknown\r\n try {\r\n const receipt = await withTimeout(entry.query.interrupt(), CLAUDE_INTERRUPT_TIMEOUT_MS, 'Claude Code interrupt')\r\n const queued = receipt?.still_queued ?? []\r\n if (queued.includes(active.promptUuid)) {\r\n throw new Error(`Claude Code interrupt left submitted prompt ${active.promptUuid} queued`)\r\n }\r\n } catch (error) {\r\n interruptError = error\r\n }\r\n await this.#settleOpenCalls(active, 'Cancelled with the turn').catch(() => undefined)\r\n try {\r\n await this.#appendActivity(active, {\r\n kind: 'status',\r\n phase: 'failed',\r\n title: interruptError === undefined ? 'Claude Code turn cancelled' : 'Claude Code cancelled; process entry reset',\r\n ...(interruptError === undefined ? {} : { summary: errorSummary(interruptError) }),\r\n })\r\n } catch {\r\n // The active output is already aborted; process cleanup cannot wait for audit availability.\r\n }\r\n if (this.#entries.get(entry.sessionId) === entry) this.#entries.delete(entry.sessionId)\r\n await this.#disposeEntry(entry)\r\n }\r\n\r\n async #handleDisconnect(entry: SupervisorEntry, error: unknown): Promise<void> {\r\n const active = entry.active\r\n const stderr = entry.process?.stderrTail()\r\n if (active !== undefined) {\r\n await this.#upsertTranscriptText(active)\r\n await this.#flushTranscript(active)\r\n if (active.signal !== undefined && active.abortListener !== undefined) {\r\n active.signal.removeEventListener('abort', active.abortListener)\r\n }\r\n const unknown = active.sawActivity\r\n entry.state = unknown ? 'outcome-unknown' : 'disconnected'\r\n const failure = unknown\r\n ? new ClaudeOutcomeUnknownError(stderr === undefined || stderr.length === 0 ? undefined : `Claude Code exited after activity; outcome unknown. ${stderr}`)\r\n : new Error(stderr === undefined || stderr.length === 0 ? errorSummary(error) : stderr)\r\n await this.#settleOpenCalls(active, 'Claude Code stopped before the tool answered').catch(() => undefined)\r\n await this.#appendSafely(active, {\r\n kind: 'error',\r\n phase: 'failed',\r\n title: unknown ? 'Claude Code outcome unknown' : 'Claude Code disconnected',\r\n summary: failure.message,\r\n isError: true,\r\n detail: error,\r\n })\r\n active.output.fail(failure)\r\n entry.active = undefined\r\n } else {\r\n entry.state = 'disconnected'\r\n }\r\n this.#entries.delete(entry.sessionId)\r\n await this.#disposeEntry(entry)\r\n }\r\n\r\n #armIdleTimer(entry: SupervisorEntry): void {\r\n if (this.#config.idleTimeoutMs <= 0) return\r\n const timer = setTimeout(() => {\r\n if (entry.active !== undefined || entry.state !== 'idle') return\r\n this.#entries.delete(entry.sessionId)\r\n void this.#disposeEntry(entry)\r\n }, this.#config.idleTimeoutMs)\r\n timer.unref?.()\r\n entry.idleTimer = timer\r\n }\r\n\r\n async #disposeEntry(entry: SupervisorEntry): Promise<void> {\r\n if (entry.state === 'disposed') return\r\n if (entry.idleTimer !== undefined) clearTimeout(entry.idleTimer)\r\n entry.state = 'disposed'\r\n entry.input.discard(abortFailure())\r\n entry.query.close()\r\n entry.lifetime.abort()\r\n if (entry.active !== undefined) entry.active.output.fail(abortFailure())\r\n entry.process?.kill('SIGTERM')\r\n if (entry.process !== undefined) {\r\n try {\r\n await entry.process.handle.waitForExit(AbortSignal.timeout(5_000))\r\n } catch {\r\n // The DSH subprocess owner still holds the tree and will finish escalation.\r\n }\r\n }\r\n this.#notifyCapacityChange()\r\n }\r\n}\r\n","import { randomUUID } from 'node:crypto'\r\n\r\nconst MAX_COMMENTS_PER_SESSION = 50\r\nconst MAX_TEXT_CHARS = 2_000\r\nconst MAX_PATH_CHARS = 1_024\r\nconst MAX_LINE = 10_000_000\r\n\r\nexport type ReviewCommentSide = 'old' | 'new'\r\n\r\nexport interface ReviewComment {\r\n readonly id: string\r\n readonly path: string\r\n /** Last (anchor) line of the comment. */\r\n readonly line: number\r\n /** First line when the comment spans a range; absent for single-line comments. */\r\n readonly startLine?: number\r\n readonly side: ReviewCommentSide\r\n readonly text: string\r\n}\r\n\r\nexport class ReviewCommentError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'ReviewCommentError'\r\n this.code = code\r\n }\r\n}\r\n\r\nfunction validSide(value: unknown): value is ReviewCommentSide {\r\n return value === 'old' || value === 'new'\r\n}\r\n\r\n/** Pending line comments queued per session until the next user turn drains them. */\r\nexport class ReviewCommentStore {\r\n readonly #comments = new Map<string, ReviewComment[]>()\r\n\r\n add(sessionId: string, input: { path: unknown; line: unknown; startLine?: unknown; side: unknown; text: unknown }): ReviewComment {\r\n const path = typeof input.path === 'string' ? input.path.trim() : ''\r\n const text = typeof input.text === 'string' ? input.text.trim() : ''\r\n if (path.length === 0 || path.length > MAX_PATH_CHARS || /[\\0\\r\\n]/u.test(path)) {\r\n throw new ReviewCommentError('invalid-request', 'The comment path is invalid.')\r\n }\r\n if (text.length === 0 || text.length > MAX_TEXT_CHARS || text.includes('\\0')) {\r\n throw new ReviewCommentError('invalid-request', 'The comment text is invalid.')\r\n }\r\n if (typeof input.line !== 'number' || !Number.isSafeInteger(input.line) || input.line < 1 || input.line > MAX_LINE) {\r\n throw new ReviewCommentError('invalid-request', 'The comment line is invalid.')\r\n }\r\n if (!validSide(input.side)) throw new ReviewCommentError('invalid-request', 'The comment side is invalid.')\r\n const startLine = input.startLine === undefined || input.startLine === null ? undefined : input.startLine\r\n if (startLine !== undefined && (typeof startLine !== 'number' || !Number.isSafeInteger(startLine) || startLine < 1 || startLine > input.line)) {\r\n throw new ReviewCommentError('invalid-request', 'The comment start line is invalid.')\r\n }\r\n const existing = this.#comments.get(sessionId) ?? []\r\n if (existing.length >= MAX_COMMENTS_PER_SESSION) {\r\n throw new ReviewCommentError('too-many-comments', 'Too many pending review comments. Remove one before adding another.')\r\n }\r\n const comment: ReviewComment = { id: randomUUID(), path, line: input.line, ...(startLine === undefined || startLine === input.line ? {} : { startLine }), side: input.side, text }\r\n this.#comments.set(sessionId, [...existing, comment])\r\n return comment\r\n }\r\n\r\n remove(sessionId: string, id: string): boolean {\r\n const existing = this.#comments.get(sessionId)\r\n if (existing === undefined) return false\r\n const next = existing.filter(comment => comment.id !== id)\r\n if (next.length === existing.length) return false\r\n if (next.length === 0) this.#comments.delete(sessionId)\r\n else this.#comments.set(sessionId, next)\r\n return true\r\n }\r\n\r\n list(sessionId: string): readonly ReviewComment[] {\r\n return this.#comments.get(sessionId) ?? []\r\n }\r\n\r\n /** Remove and return every pending comment; called when a user turn consumes them. */\r\n drain(sessionId: string): readonly ReviewComment[] {\r\n const existing = this.#comments.get(sessionId) ?? []\r\n this.#comments.delete(sessionId)\r\n return existing\r\n }\r\n\r\n disposeSession(sessionId: string): void {\r\n this.#comments.delete(sessionId)\r\n }\r\n\r\n dispose(): void {\r\n this.#comments.clear()\r\n }\r\n}\r\n\r\n/** Render drained comments as the prompt block preceding the user's message text. */\r\nexport function formatReviewComments(comments: readonly ReviewComment[]): string {\r\n const lines = comments.map((comment, index) => (\r\n `${index + 1}. ${comment.path}:${comment.startLine === undefined ? comment.line : `${comment.startLine}-${comment.line}`}${comment.side === 'old' ? ' (old side)' : ''} — ${comment.text}`\r\n ))\r\n return [\r\n '<user-review-comments>',\r\n 'The user attached these code review comments to this message. Each references a file and line (or line range) from the current working tree diff:',\r\n ...lines,\r\n '</user-review-comments>',\r\n ].join('\\n')\r\n}\r\n","/** Answer DSH's auxiliary session-title request with a throwaway Haiku turn.\r\n *\r\n * DSH titles a session by asking the model behind the session's own route for\r\n * a summary of the first human message. That route is this plugin, and the\r\n * session's Claude process must not answer it: the title call carries a\r\n * plugin-authored system prompt and would land in the user's transcript. A\r\n * separate one-shot turn keeps it out, for the same reasons as the branch-name\r\n * summary and the plan-usage probe. Deployments that never installed a second\r\n * model provider still get a readable title, since the only model this plugin\r\n * needs is the one it already runs. */\r\nimport { query as claudeQuery, type Options as ClaudeOptions, type Query } from '@anthropic-ai/claude-agent-sdk'\r\n\r\n/** Cheapest model that can summarize a sentence in the language it was written in. */\r\nexport const SESSION_TITLE_MODEL = 'haiku'\r\n\r\n/** Backstop only. The title service wraps its own deadline (60s by default)\r\n * around the call and passes it as `signal`, so a shorter budget here just\r\n * kills a turn the caller was still happy to wait for — a cold CLI start plus\r\n * one Haiku reply routinely passes ten seconds. */\r\nexport const SESSION_TITLE_TIMEOUT_MS = 60_000\r\n\r\n/** DSH frames the messages as JSON under its own byte cap; this only bounds a\r\n * caller that does not. */\r\nconst MAX_INPUT_CHARS = 8_000\r\n/** Longer than any title DSH accepts (80 bytes), short enough to bound prose. */\r\nconst MAX_TITLE_CHARS = 200\r\n\r\nexport interface SessionTitleRequest {\r\n /** DSH's own title instruction, including its target length and language rule. */\r\n readonly system?: string\r\n /** The framed human messages to title. */\r\n readonly input: string\r\n /** Cancellation from the title service when a newer revision supersedes this one. */\r\n readonly signal?: AbortSignal\r\n}\r\n\r\n/** Carry DSH's instruction as the prompt's own preamble: a Claude Code turn has\r\n * no separate system slot this plugin can borrow without replacing the CLI's. */\r\nexport function sessionTitlePrompt(request: SessionTitleRequest): string {\r\n const input = request.input.trim().slice(0, MAX_INPUT_CHARS)\r\n return request.system === undefined || request.system.length === 0\r\n ? input\r\n : `${request.system}\\n\\n${input}`\r\n}\r\n\r\n/** The one line of the reply that is the title. DSH strips control characters\r\n * and truncates to its own byte cap, so nothing else is cleaned here. */\r\nexport function sessionTitleLine(reply: string): string {\r\n const line = reply.split('\\n').map(candidate => candidate.trim()).find(candidate => candidate.length > 0)\r\n return line === undefined ? '' : line.slice(0, MAX_TITLE_CHARS)\r\n}\r\n\r\n/**\r\n * Summarize the framed messages into one title line.\r\n *\r\n * Rejects rather than returning a placeholder: the title service logs the\r\n * failure and keeps the deterministic first-words fallback, which is a better\r\n * label than anything this function could invent.\r\n */\r\nexport async function summarizeSessionTitle(\r\n executablePath: string,\r\n request: SessionTitleRequest,\r\n factory: (params: { prompt: string; options: ClaudeOptions }) => Query = claudeQuery,\r\n): Promise<string> {\r\n const prompt = sessionTitlePrompt(request)\r\n if (prompt.length === 0) throw new Error('dsh-claude: the session-title request carried no text')\r\n const lifetime = new AbortController()\r\n const abort = (): void => { lifetime.abort() }\r\n request.signal?.addEventListener('abort', abort, { once: true })\r\n const timer = setTimeout(abort, SESSION_TITLE_TIMEOUT_MS)\r\n timer.unref?.()\r\n try {\r\n const query = factory({\r\n prompt,\r\n options: {\r\n cwd: process.cwd(),\r\n abortController: lifetime,\r\n model: SESSION_TITLE_MODEL,\r\n allowedTools: [],\r\n // Isolated from filesystem settings on purpose: a CLAUDE.md instruction\r\n // aimed at the coding session (\"always answer in English\", \"start every\r\n // reply with a checklist\") would be answering the wrong question here.\r\n settingSources: [],\r\n maxTurns: 1,\r\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\r\n },\r\n })\r\n for await (const message of query) {\r\n if (message.type !== 'result' || message.subtype !== 'success') continue\r\n const title = sessionTitleLine(message.result)\r\n if (title.length > 0) return title\r\n break\r\n }\r\n throw new Error('dsh-claude: the session-title turn produced no title')\r\n } finally {\r\n clearTimeout(timer)\r\n request.signal?.removeEventListener('abort', abort)\r\n lifetime.abort()\r\n }\r\n}\r\n","import {\r\n LlmAdapter,\r\n ReasoningEffortId,\r\n type GenerateOptions,\r\n type LlmModelInfo,\r\n type LlmProviderInfo,\r\n type LlmResolvedModelInfo,\r\n type PreparedAdapterCall,\r\n type ResolvedRetryPolicy,\r\n type StreamChunk,\r\n type TokenUsage,\r\n} from '@deepseek-ai/dsh-llm'\r\nimport type { Agent, AgentRegistry } from '@deepseek-ai/dsh-agent'\r\nimport type { AttachmentStore, ImageAttachmentRef, ImageMediaType } from '@deepseek-ai/dsh-attachment'\r\nimport type { ModelInfo, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk'\r\nimport { CLAUDE_CODE_PRESET_ID, CLAUDE_CODE_PROVIDER, DEFAULT_CLAUDE_RENDER_MODE, type ClaudeRenderMode } from './constants.ts'\r\nimport type { ClaudeSupervisor, ClaudeThinkingMode } from './supervisor.ts'\r\nimport type { ClaudeUsage } from './events.ts'\r\nimport { claudeModelRow, ensureClaudeModels } from './model-catalog.ts'\r\nimport { formatReviewComments, type ReviewComment } from './review-comments.ts'\r\nimport { summarizeSessionTitle, type SessionTitleRequest } from './session-title.ts'\r\n\r\nconst THINKING_MODES = [\r\n { id: 'off', name: 'Off', description: 'No extended thinking.' },\r\n { id: 'low', name: 'Low', description: 'Minimal thinking, fastest responses.' },\r\n { id: 'medium', name: 'Medium', description: 'Moderate thinking.' },\r\n { id: 'high', name: 'High', description: 'Deep reasoning (Claude Code default).' },\r\n { id: 'xhigh', name: 'Extra High', description: 'Deeper than high; unsupported models silently downgrade to high.' },\r\n { id: 'max', name: 'Max', description: 'Maximum effort; unsupported models silently downgrade.' },\r\n { id: 'ultracode', name: 'Ultracode', description: 'Extra-high effort plus standing dynamic-workflow orchestration; requires an xhigh-capable model.' },\r\n] as const\r\n\r\nexport function thinkingModeFor(effort: ReasoningEffortId | undefined): ClaudeThinkingMode | undefined {\r\n if (effort === undefined) return undefined\r\n if (THINKING_MODES.some(mode => mode.id === (effort as string))) return effort as unknown as ClaudeThinkingMode\r\n throw new Error(`dsh-claude: unsupported reasoning effort ${JSON.stringify(effort)}`)\r\n}\r\n\r\nconst NO_RETRY_POLICY: ResolvedRetryPolicy = Object.freeze({\r\n mode: 'normal',\r\n maxRetries: 0,\r\n retryableCodes: Object.freeze([]),\r\n initialDelayMs: 500,\r\n maxDelayMs: 10_000,\r\n jitterRatio: 0.1,\r\n})\r\n\r\ntype ClaudePrompt = SDKUserMessage['message']['content']\r\ntype ClaudePromptBlock = Exclude<ClaudePrompt, string>[number]\r\ntype AttachmentReader = Pick<AttachmentStore, 'imageLimits' | 'readImage'>\r\n\r\nfunction abortIfRequested(signal: AbortSignal | undefined): void {\r\n if (signal?.aborted !== true) return\r\n if (signal.reason instanceof Error) throw signal.reason\r\n const error = new Error('Claude Code input resolution aborted')\r\n error.name = 'AbortError'\r\n throw error\r\n}\r\n\r\nfunction finiteNonNegative(value: unknown): value is number {\r\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\r\n}\r\n\r\nfunction validateImageRef(ref: ImageAttachmentRef, attachments: AttachmentReader, imageIndex: number): void {\r\n const limits = attachments.imageLimits\r\n if (!limits.mediaTypes.includes(ref.mediaType)) {\r\n throw new Error(`dsh-claude: image ${imageIndex} has an unsupported media type`)\r\n }\r\n if (!finiteNonNegative(ref.bytes) || ref.bytes > limits.maxImageBytes) {\r\n throw new Error(`dsh-claude: image ${imageIndex} exceeds the configured byte limit`)\r\n }\r\n const maxDimension = 'maxImageDimension' in limits && finiteNonNegative(limits.maxImageDimension)\r\n ? limits.maxImageDimension\r\n : undefined\r\n if (!finiteNonNegative(ref.width) || !finiteNonNegative(ref.height)\r\n || ref.width * ref.height > limits.maxImagePixels\r\n || (maxDimension !== undefined && (ref.width > maxDimension || ref.height > maxDimension))) {\r\n throw new Error(`dsh-claude: image ${imageIndex} exceeds the configured dimension limit`)\r\n }\r\n}\r\n\r\n/**\r\n * Prepend the session's pending diff-review comments to the outgoing user\r\n * prompt. The comments are drained once per turn: they are formatted into one\r\n * `<user-review-comments>` block placed ahead of the user's own text (or as a\r\n * leading text block for multi-part prompts) so Claude reads them in the same\r\n * turn that consumed them.\r\n */\r\nexport function injectReviewComments(prompt: ClaudePrompt, comments: readonly ReviewComment[]): ClaudePrompt {\r\n if (comments.length === 0) return prompt\r\n const block = formatReviewComments(comments)\r\n if (typeof prompt === 'string') return `${block}\\n\\n${prompt}`\r\n return [{ type: 'text', text: block }, ...prompt]\r\n}\r\n\r\nfunction imageBlock(data: Uint8Array, mediaType: ImageMediaType): ClaudePromptBlock {\r\n return {\r\n type: 'image',\r\n source: {\r\n type: 'base64',\r\n media_type: mediaType,\r\n data: Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('base64'),\r\n },\r\n }\r\n}\r\n\r\n/** Resolve only the newest direct human message; Claude's session owns history. */\r\nexport async function resolveDirectUserPrompt(\r\n messages: GenerateOptions['messages'],\r\n attachments: AttachmentReader,\r\n signal?: AbortSignal,\r\n): Promise<ClaudePrompt> {\r\n const message = [...messages].reverse().find(candidate => (\r\n candidate.role === 'user' && candidate.source.kind === 'user'\r\n ))\r\n if (message === undefined) {\r\n throw new Error('dsh-claude: no direct human input was present in this model step')\r\n }\r\n\r\n const imageRefs = message.content\r\n .filter((block): block is Extract<typeof block, { type: 'image' }> => block.type === 'image')\r\n .map(block => block.attachment)\r\n const limits = attachments.imageLimits\r\n if (imageRefs.length > limits.maxImagesPerMessage) {\r\n throw new Error('dsh-claude: prompt exceeds the configured image-count limit')\r\n }\r\n let declaredBytes = 0\r\n imageRefs.forEach((ref, index) => {\r\n validateImageRef(ref, attachments, index + 1)\r\n declaredBytes += ref.bytes\r\n if (!Number.isSafeInteger(declaredBytes) || declaredBytes > limits.maxMessageImageBytes) {\r\n throw new Error('dsh-claude: prompt exceeds the configured aggregate image-byte limit')\r\n }\r\n })\r\n\r\n if (imageRefs.length === 0) {\r\n const text = message.content\r\n .filter((block): block is Extract<typeof block, { type: 'text' }> => block.type === 'text')\r\n .map(block => block.text)\r\n .join('\\n')\r\n .trim()\r\n if (text.length > 0) return text\r\n throw new Error('dsh-claude: the newest direct human message has no supported content')\r\n }\r\n\r\n const content: ClaudePromptBlock[] = []\r\n let imageIndex = 0\r\n let verifiedBytes = 0\r\n for (const block of message.content) {\r\n abortIfRequested(signal)\r\n if (block.type === 'text') {\r\n content.push({ type: 'text', text: block.text })\r\n continue\r\n }\r\n if (block.type !== 'image') continue\r\n imageIndex += 1\r\n let stored: Awaited<ReturnType<AttachmentStore['readImage']>>\r\n try {\r\n stored = await attachments.readImage(block.attachment, signal)\r\n } catch {\r\n abortIfRequested(signal)\r\n throw new Error(`dsh-claude: image ${imageIndex} could not be read or verified`)\r\n }\r\n abortIfRequested(signal)\r\n validateImageRef(stored.ref, attachments, imageIndex)\r\n if (stored.data.byteLength !== stored.ref.bytes || stored.ref.mediaType !== block.attachment.mediaType) {\r\n throw new Error(`dsh-claude: image ${imageIndex} failed attachment verification`)\r\n }\r\n verifiedBytes += stored.data.byteLength\r\n if (!Number.isSafeInteger(verifiedBytes) || verifiedBytes > limits.maxMessageImageBytes) {\r\n throw new Error('dsh-claude: prompt exceeds the configured aggregate image-byte limit')\r\n }\r\n content.push(imageBlock(stored.data, stored.ref.mediaType))\r\n }\r\n if (content.length === 0) {\r\n throw new Error('dsh-claude: the newest direct human message has no supported content')\r\n }\r\n return content\r\n}\r\n\r\nfunction tokenUsage(usage: ClaudeUsage): TokenUsage {\r\n const normalized: TokenUsage = {\r\n inputTokens: usage.inputTokens ?? 0,\r\n outputTokens: usage.outputTokens ?? 0,\r\n }\r\n if (usage.cacheReadTokens !== undefined) normalized.cacheReadTokens = usage.cacheReadTokens\r\n if (usage.cacheCreationTokens !== undefined) normalized.cacheWriteTokens = usage.cacheCreationTokens\r\n return normalized\r\n}\r\n\r\n/** Flatten a hand-built auxiliary request to text. Unlike a conversation turn\r\n * it has no images and no human-sourced message to single out: every message\r\n * in it was assembled by the plugin that asked the question. */\r\nfunction auxiliaryText(messages: GenerateOptions['messages']): string {\r\n return messages\r\n .flatMap(message => message.content\r\n .filter((block): block is Extract<typeof block, { type: 'text' }> => block.type === 'text')\r\n .map(block => block.text))\r\n .join('\\n')\r\n}\r\n\r\nfunction resolveAgent(agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>, options: GenerateOptions): Agent {\r\n const initiator = agents.currentInitiator()\r\n if (initiator !== undefined) return initiator\r\n if (options.sessionId !== undefined) {\r\n const agent = agents.get(options.sessionId)\r\n if (agent !== undefined) return agent\r\n }\r\n throw new Error('dsh-claude: the model request has no live owning DSH agent')\r\n}\r\n\r\nexport class ClaudeCodeAdapter extends LlmAdapter {\r\n readonly #supervisor: ClaudeSupervisor\r\n readonly #agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>\r\n readonly #attachments: AttachmentReader\r\n readonly #presetIdFor: (agent: Agent) => string | undefined\r\n readonly #drainReviewComments: (sessionId: string) => readonly ReviewComment[]\r\n /** The renderer setting, read from its file at the start of each turn. A\r\n * cached copy would go stale whenever the file is edited outside the\r\n * Settings dialog, and the read is dwarfed by the process the turn spawns. */\r\n readonly #renderMode: () => Promise<ClaudeRenderMode>\r\n readonly #summarizeTitle: (request: SessionTitleRequest) => Promise<string>\r\n /** Reads the CLI's own `/model` rows, so the selector never has to advertise\r\n * the seed vocabulary once the CLI can answer for itself. */\r\n readonly #probeModels: () => Promise<readonly ModelInfo[]>\r\n\r\n constructor(\r\n supervisor: ClaudeSupervisor,\r\n agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>,\r\n attachments: AttachmentReader,\r\n presetIdFor: (agent: Agent) => string | undefined,\r\n drainReviewComments: (sessionId: string) => readonly ReviewComment[] = () => [],\r\n renderMode: () => Promise<ClaudeRenderMode> = async () => DEFAULT_CLAUDE_RENDER_MODE,\r\n summarizeTitle: (request: SessionTitleRequest) => Promise<string> = request => summarizeSessionTitle('', request),\r\n probeModels: () => Promise<readonly ModelInfo[]> = async () => [],\r\n ) {\r\n super()\r\n this.#supervisor = supervisor\r\n this.#agents = agents\r\n this.#attachments = attachments\r\n this.#presetIdFor = presetIdFor\r\n this.#drainReviewComments = drainReviewComments\r\n this.#renderMode = renderMode\r\n this.#summarizeTitle = summarizeTitle\r\n this.#probeModels = probeModels\r\n }\r\n\r\n override providerInfo(provider: string): LlmProviderInfo {\r\n return { id: provider, name: 'Claude Code' }\r\n }\r\n\r\n override providerRetryPolicy(): ResolvedRetryPolicy {\r\n return NO_RETRY_POLICY\r\n }\r\n\r\n override async listModels(provider: string): Promise<readonly LlmModelInfo[]> {\r\n const models = await ensureClaudeModels(this.#probeModels)\r\n return models.map(model => ({\r\n provider,\r\n id: model.id,\r\n name: model.name,\r\n description: model.description,\r\n inputModalities: ['text', 'image'],\r\n }))\r\n }\r\n\r\n override async resolveModel(provider: string, model: string, _signal?: AbortSignal): Promise<LlmResolvedModelInfo> {\r\n const known = claudeModelRow(model)\r\n const contextWindow = this.#supervisor.contextWindow(model) ?? known?.contextWindow\r\n return {\r\n provider,\r\n id: model,\r\n name: known?.name ?? `Claude Code ${model}`,\r\n ...(known === undefined ? {} : { description: known.description }),\r\n ...(contextWindow === undefined ? {} : { context: { contextWindow } }),\r\n inputModalities: ['text', 'image'],\r\n reasoning: {\r\n efforts: THINKING_MODES.map(mode => ({\r\n id: ReasoningEffortId(mode.id),\r\n name: mode.name,\r\n description: mode.description,\r\n })),\r\n },\r\n }\r\n }\r\n\r\n override async prepareCall(\r\n provider: string,\r\n model: string,\r\n signal?: AbortSignal,\r\n ): Promise<PreparedAdapterCall> {\r\n return {\r\n model: await this.resolveModel(provider, model, signal),\r\n stream: options => this.stream(options),\r\n }\r\n }\r\n\r\n /** Title the session from its own provider without touching its process.\r\n *\r\n * DSH routes the title request at the session's model, which is this\r\n * adapter; a deployment with no second provider configured would otherwise\r\n * never get a title at all and keep the first five words of the first\r\n * message. A throwaway Haiku turn answers it, so the session's transcript,\r\n * context, and permission bridge stay out of it. */\r\n async *#titleStream(options: GenerateOptions): AsyncIterable<StreamChunk> {\r\n const title = await this.#summarizeTitle({\r\n ...(options.system === undefined ? {} : { system: options.system }),\r\n input: auxiliaryText(options.messages),\r\n ...(options.signal === undefined ? {} : { signal: options.signal }),\r\n })\r\n yield { type: 'block-start', index: 0, blockType: 'text' }\r\n yield { type: 'text-delta', index: 0, text: title }\r\n yield { type: 'block-end', index: 0, block: { type: 'text', text: title } }\r\n yield { type: 'finish', reason: { kind: 'stop' } }\r\n }\r\n\r\n override async *stream(options: GenerateOptions): AsyncIterable<StreamChunk> {\r\n if (options.purpose === 'session-title') {\r\n yield* this.#titleStream(options)\r\n return\r\n }\r\n if (options.purpose !== undefined) {\r\n // Compaction stays out: Claude Code compacts its own context, and a DSH\r\n // summary of a transcript it does not own would be replayed at nobody.\r\n throw new Error(`dsh-claude: auxiliary ${options.purpose} calls are not routed into the Claude session`)\r\n }\r\n const agent = resolveAgent(this.#agents, options)\r\n if (this.#presetIdFor(agent) !== CLAUDE_CODE_PRESET_ID) {\r\n throw new Error(`dsh-claude: provider ${CLAUDE_CODE_PROVIDER} is available only to the ${CLAUDE_CODE_PRESET_ID} preset`)\r\n }\r\n const thinkingMode = thinkingModeFor(options.reasoningEffort)\r\n let prompt: ClaudePrompt\r\n try {\r\n prompt = await resolveDirectUserPrompt(options.messages, this.#attachments, options.signal)\r\n } catch (error) {\r\n if ((error as Error).name !== 'AbortError') throw error\r\n yield {\r\n type: 'finish',\r\n reason: {\r\n kind: 'aborted',\r\n failure: { code: 'aborted', message: error instanceof Error ? error.message : 'Claude Code input resolution aborted' },\r\n },\r\n }\r\n return\r\n }\r\n // The plugin renderer draws the visible transcript from the sidecar, so\r\n // prose and Claude tool groups share one exact ordinal stream and DSH\r\n // receives only an empty assistant completion anchor plus usage/lifecycle\r\n // metadata. The native renderer needs the opposite: every visible span\r\n // arrives as ordinary DSH content blocks.\r\n //\r\n // Read once, here, and handed to the supervisor: the setting is live, and\r\n // the two halves of a turn must agree. Deciding separately let a switch\r\n // mid-turn leave the prose buffered for a renderer that was no longer\r\n // drawing it, so the turn finished with nothing on screen.\r\n const renderMode = await this.#renderMode()\r\n const native = renderMode === 'native'\r\n const events = await this.#supervisor.runTurn({\r\n agent,\r\n prompt: injectReviewComments(prompt, this.#drainReviewComments(agent.id as string)),\r\n model: options.model,\r\n renderMode,\r\n ...(thinkingMode === undefined ? {} : { thinkingMode }),\r\n ...(options.signal === undefined ? {} : { signal: options.signal }),\r\n })\r\n let pendingUsage: TokenUsage | undefined\r\n let completed = false\r\n let blockIndex = 0\r\n let text = ''\r\n /** Settle the buffered prose as one text block. Each Claude result is one\r\n * block so tool activity stays ahead of the prose it explains and a\r\n * background-task report can follow in a block of its own. */\r\n function* flushText(): Generator<StreamChunk> {\r\n if (text.length === 0) return\r\n const settled = text\r\n text = ''\r\n yield { type: 'block-start', index: blockIndex, blockType: 'text' }\r\n yield { type: 'text-delta', index: blockIndex, text: settled }\r\n yield { type: 'block-end', index: blockIndex, block: { type: 'text', text: settled } }\r\n blockIndex += 1\r\n }\r\n try {\r\n for await (const event of events) {\r\n if (event.type === 'usage') {\r\n pendingUsage = tokenUsage(event.usage)\r\n continue\r\n }\r\n if (event.type === 'text-delta') {\r\n if (native) text += event.text\r\n continue\r\n }\r\n if (event.type === 'thinking') {\r\n if (!native) continue\r\n // Thinking settles before the prose it precedes, so nothing is\r\n // buffered yet; flush anyway to keep block order faithful when a\r\n // model interleaves the two.\r\n yield* flushText()\r\n yield { type: 'block-start', index: blockIndex, blockType: 'reasoning' }\r\n yield { type: 'reasoning-delta', index: blockIndex, text: event.text }\r\n yield { type: 'block-end', index: blockIndex, block: { type: 'reasoning', text: event.text } }\r\n blockIndex += 1\r\n continue\r\n }\r\n yield* flushText()\r\n if (event.type === 'segment-complete') continue\r\n completed = true\r\n if (pendingUsage !== undefined) yield { type: 'usage', usage: pendingUsage }\r\n yield { type: 'finish', reason: { kind: 'stop' } }\r\n }\r\n } catch (error) {\r\n if ((error as Error).name === 'AbortError') {\r\n completed = true\r\n yield* flushText()\r\n yield {\r\n type: 'finish',\r\n reason: {\r\n kind: 'aborted',\r\n failure: { code: 'aborted', message: error instanceof Error ? error.message : 'Claude Code turn aborted' },\r\n },\r\n }\r\n return\r\n }\r\n throw error\r\n }\r\n if (!completed) throw new Error('dsh-claude: Claude turn stream ended without a result')\r\n }\r\n}\r\n\r\nexport function createClaudeCodeAdapter(\r\n supervisor: ClaudeSupervisor,\r\n agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>,\r\n attachments: AttachmentReader,\r\n presetIdFor: (agent: Agent) => string | undefined,\r\n drainReviewComments: (sessionId: string) => readonly ReviewComment[] = () => [],\r\n renderMode: () => Promise<ClaudeRenderMode> = async () => DEFAULT_CLAUDE_RENDER_MODE,\r\n summarizeTitle: (request: SessionTitleRequest) => Promise<string> = request => summarizeSessionTitle('', request),\r\n probeModels: () => Promise<readonly ModelInfo[]> = async () => [],\r\n): ClaudeCodeAdapter {\r\n return new ClaudeCodeAdapter(supervisor, agents, attachments, presetIdFor, drainReviewComments, renderMode, summarizeTitle, probeModels)\r\n}\r\n","/**\r\n * The plugin's connection budget, in one table.\r\n *\r\n * A browser opens a small fixed number of connections to one origin — six for\r\n * HTTP/1.1 in Chromium — and shares them with the Host's own traffic. Every\r\n * response this plugin holds open costs one of them for its lifetime, and a\r\n * request that cannot get one waits in the browser's queue where no server-side\r\n * deadline can reach it. When the pool is exhausted the panels that would\r\n * *diagnose* the problem are the first thing to stop answering, which is how\r\n * this failure has always presented: four settings cards timing out at once\r\n * against a Host that is demonstrably healthy.\r\n *\r\n * So the budget is a fixed constant rather than a function of how much work is\r\n * in flight. Steady state is one connection (the multiplexed projection\r\n * carrier); the peak is `PLUGIN_GLOBAL_PERMITS`, whatever the session count.\r\n *\r\n * Both halves read this file, which is the point: a route declares a budget\r\n * class and the client derives its wait from the same entry, so a server\r\n * deadline can never be quietly longer than the client's patience.\r\n */\r\n\r\n/** Server-side budget classes. A route declares a class, never a number. */\r\nexport const ROUTE_BUDGET_MS = {\r\n /** Answers from memory or a single bounded probe. */\r\n fast: 5_000,\r\n /** Chains local Git work. */\r\n git: 45_000,\r\n /** Reaches the network: remote Git, `gh`, the npm registry. */\r\n remote: 150_000,\r\n} as const\r\n\r\nexport type RouteBudget = keyof typeof ROUTE_BUDGET_MS\r\n\r\n/** The client waits one round trip longer, so the route's own 504 wins the\r\n * race and the caller learns which budget elapsed instead of guessing. */\r\nexport const CLIENT_GRACE_MS = 3_000\r\n\r\nexport function clientBudgetMs(budget: RouteBudget): number {\r\n return ROUTE_BUDGET_MS[budget] + CLIENT_GRACE_MS\r\n}\r\n\r\n/** A request that never got a permit fails fast and says so, rather than\r\n * spending its whole budget queued behind work it cannot see. */\r\nexport const QUEUE_WAIT_BUDGET_MS = 4_000\r\n\r\n/** Connections this plugin may hold at once, across every lane. */\r\nexport const PLUGIN_GLOBAL_PERMITS = 4\r\n\r\n/** Per-lane ceilings inside the global budget.\r\n *\r\n * The projection carrier holds a permanently reserved permit outside these,\r\n * so three remain. `write + stream <= 2` leaves one permit that only a read\r\n * can take: a diagnostic read always has somewhere to go, however many slow\r\n * actions are in flight. That invariant is what stops a 150s repository\r\n * action from reproducing the original symptom through a new mechanism. */\r\nexport const PLUGIN_LANE_CAPS = { read: 2, write: 1, stream: 1 } as const\r\n\r\nexport type PluginLane = keyof typeof PLUGIN_LANE_CAPS\r\n\r\n/** Both halves cap the multiplex at the same number. */\r\nexport const MAX_MULTIPLEX_SESSIONS = 16\r\n","import type { IncomingMessage, ServerResponse } from 'node:http'\r\nimport type { Context } from '@deepseek-ai/cordis'\r\nimport type { WebRouteKind } from '@deepseek-ai/dsh-host-webserver'\r\nimport { deadline } from '@deepseek-ai/dsh-timeout'\r\nimport { ROUTE_BUDGET_MS, type RouteBudget } from './plugin-budget.ts'\r\n\r\n/** Accept only loopback, same-origin browser requests to plugin-private routes. */\r\nexport function trustedRequest(req: IncomingMessage): boolean {\r\n const remote = req.socket.remoteAddress\r\n if (remote !== '127.0.0.1' && remote !== '::1' && remote !== '::ffff:127.0.0.1') return false\r\n const site = req.headers['sec-fetch-site']\r\n if (site === 'cross-site') return false\r\n const host = req.headers.host\r\n if (host === undefined) return false\r\n const authority = /^(?:127\\.0\\.0\\.1|\\[?::1\\]?|localhost)(?::\\d+)?$/i\r\n if (!authority.test(host)) return false\r\n const origin = req.headers.origin\r\n if (origin === undefined) return true\r\n try {\r\n const originUrl = new URL(origin)\r\n return originUrl.host === host && authority.test(originUrl.host)\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\n/** Send a non-cacheable JSON response with MIME sniffing disabled. */\r\nexport function json(res: ServerResponse, status: number, value: unknown): void {\r\n res.writeHead(status, {\r\n 'content-type': 'application/json; charset=utf-8',\r\n 'cache-control': 'no-store',\r\n 'x-content-type-options': 'nosniff',\r\n })\r\n res.end(JSON.stringify(value))\r\n}\r\n\r\nconst ROUTE_TIMEOUT_CODE = 'DSH_CLAUDE_ROUTE'\r\nconst DEFAULT_BODY_BYTES = 1024 * 1024\r\n\r\nexport type PluginMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\r\n\r\n/** What a route handler is given. Deliberately not the `ServerResponse`: a\r\n * unary handler that cannot reach the socket cannot hold it open. */\r\nexport interface PluginRouteIo {\r\n /** Aborts on client disconnect OR when the route's budget elapses. */\r\n readonly signal: AbortSignal\r\n readonly method: PluginMethod\r\n readonly url: URL\r\n /** Read the request body once, byte-capped, as JSON. */\r\n body<T = Record<string, unknown>>(maxBytes?: number): Promise<T>\r\n}\r\n\r\nexport interface PluginUnaryRoute {\r\n mode: 'unary'\r\n kind: WebRouteKind\r\n path: string\r\n methods: readonly PluginMethod[]\r\n budget: RouteBudget\r\n /** No `ServerResponse` in scope, by construction. */\r\n handler: (io: PluginRouteIo) => Promise<{ status: number; value: unknown }>\r\n}\r\n\r\nexport interface PluginStreamRoute {\r\n mode: 'stream'\r\n kind: WebRouteKind\r\n path: string\r\n methods: readonly PluginMethod[]\r\n /** Hard ceiling on live responses for this path; the oldest is evicted. */\r\n maxConcurrent: number\r\n /** Dedupe identity; a second open with the same key supersedes the first. */\r\n streamKey: (url: URL) => string\r\n handler: (res: ServerResponse, io: PluginRouteIo) => Promise<void>\r\n}\r\n\r\nexport type PluginRoute = PluginUnaryRoute | PluginStreamRoute\r\n\r\n/** Bounds live streaming responses per path, so a teardown bug cannot become a\r\n * permanent connection leak. Registration is per path, not global, because a\r\n * wedged projection stream must not evict an in-flight repository setup. */\r\nclass StreamRegistry {\r\n readonly #open = new Map<string, Map<string, () => void>>()\r\n\r\n admit(path: string, key: string, max: number, close: () => void): () => void {\r\n let live = this.#open.get(path)\r\n if (live === undefined) {\r\n live = new Map()\r\n this.#open.set(path, live)\r\n }\r\n // A reopen under the same identity is the client reconnecting; the older\r\n // response is the stale one, so it goes rather than the new arrival.\r\n live.get(key)?.()\r\n live.set(key, close)\r\n while (live.size > max) {\r\n const oldest = live.keys().next()\r\n if (oldest.done === true) break\r\n const evict = live.get(oldest.value)\r\n live.delete(oldest.value)\r\n evict?.()\r\n }\r\n return () => {\r\n const current = this.#open.get(path)\r\n if (current?.get(key) === close) current.delete(key)\r\n }\r\n }\r\n}\r\n\r\nconst streams = new StreamRegistry()\r\n\r\nfunction isPluginMethod(value: string | undefined): value is PluginMethod {\r\n return value === 'GET' || value === 'POST' || value === 'PATCH' || value === 'DELETE'\r\n}\r\n\r\n/** Distinguishable so the wrapper can answer 413 rather than folding an\r\n * oversized body into whatever generic failure the handler reports. */\r\nexport class PluginBodyTooLargeError extends Error {\r\n constructor() {\r\n super('Request body is too large')\r\n this.name = 'PluginBodyTooLargeError'\r\n }\r\n}\r\n\r\nasync function readBody(req: IncomingMessage, maxBytes: number): Promise<unknown> {\r\n const declared = Number(req.headers['content-length'] ?? 0)\r\n if (!Number.isFinite(declared) || declared < 0 || declared > maxBytes) throw new PluginBodyTooLargeError()\r\n const chunks: Buffer[] = []\r\n let bytes = 0\r\n for await (const chunk of req) {\r\n const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as Uint8Array)\r\n bytes += data.byteLength\r\n if (bytes > maxBytes) throw new PluginBodyTooLargeError()\r\n chunks.push(data)\r\n }\r\n if (bytes === 0) return {}\r\n return JSON.parse(Buffer.concat(chunks).toString('utf8')) as unknown\r\n}\r\n\r\nfunction rejectOn(signal: AbortSignal): Promise<never> {\r\n return new Promise((_resolve, reject) => {\r\n if (signal.aborted) {\r\n reject(signal.reason as Error)\r\n return\r\n }\r\n signal.addEventListener('abort', () => reject(signal.reason as Error), { once: true })\r\n })\r\n}\r\n\r\n/**\r\n * Register one plugin route.\r\n *\r\n * This is the only place in the package that calls `ctx.webServer.register`,\r\n * and the ordering inside it is the fix rather than an implementation detail:\r\n * the disconnect listeners are attached before the first `await`, so a client\r\n * that goes away while the handler is still assembling its first response\r\n * still tears the route's work down. The previous per-route code attached\r\n * `res.on('close')` after awaiting an unbounded repository probe, which is how\r\n * the projection stream reached 53 opens against 33 closes.\r\n */\r\nexport function registerPluginRoute(ctx: Context, route: PluginRoute): void {\r\n const label = `dsh-claude: ${route.path}`\r\n ctx.effect(() => ctx.webServer.register({\r\n kind: route.kind,\r\n path: route.path,\r\n handler: async (req, res) => {\r\n const method = req.method\r\n if (!isPluginMethod(method) || !route.methods.includes(method)) {\r\n return json(res, 405, { error: 'method not allowed' })\r\n }\r\n if (!trustedRequest(req)) return json(res, 403, { error: 'forbidden' })\r\n // Before any await: a disconnect during setup must still cancel.\r\n const aborted = new AbortController()\r\n const abort = (): void => { aborted.abort() }\r\n // `req` emits 'close' when the request is COMPLETE, not only when the\r\n // client vanishes — so reading a body fires it, and an unguarded abort\r\n // here cancels every POST route the instant it parses its own input.\r\n // `complete` is what tells the two apart.\r\n req.on('close', () => { if (!req.complete) abort() })\r\n res.on('close', abort)\r\n const url = new URL(req.url ?? '/', 'http://localhost')\r\n if (route.mode === 'stream') {\r\n const release = streams.admit(route.path, route.streamKey(url), route.maxConcurrent, abort)\r\n const io: PluginRouteIo = {\r\n signal: aborted.signal,\r\n method,\r\n url,\r\n body: async <T,>(maxBytes = DEFAULT_BODY_BYTES) => await readBody(req, maxBytes) as T,\r\n }\r\n try {\r\n await route.handler(res, io)\r\n } catch (error) {\r\n if (!res.headersSent) json(res, 500, { error: 'stream-failed' })\r\n ctx.logger.warn(`dsh-claude: ${route.path} stream failed: ${error instanceof Error ? error.message : String(error)}`)\r\n } finally {\r\n release()\r\n res.end()\r\n }\r\n return\r\n }\r\n const budgetMs = ROUTE_BUDGET_MS[route.budget]\r\n const bounded = deadline(aborted.signal, budgetMs, ROUTE_TIMEOUT_CODE)\r\n const io: PluginRouteIo = {\r\n signal: bounded.signal,\r\n method,\r\n url,\r\n body: async <T,>(maxBytes = DEFAULT_BODY_BYTES) => await readBody(req, maxBytes) as T,\r\n }\r\n try {\r\n const result = await Promise.race([route.handler(io), rejectOn(bounded.signal)])\r\n if (!res.writableEnded) json(res, result.status, result.value)\r\n } catch (error) {\r\n if (res.writableEnded || res.headersSent) return\r\n if (bounded.signal.aborted && !aborted.signal.aborted) {\r\n return json(res, 504, { error: 'deadline', budget: route.budget, ms: budgetMs })\r\n }\r\n if (aborted.signal.aborted) return\r\n if (error instanceof PluginBodyTooLargeError) {\r\n return json(res, 413, { error: 'body-too-large', message: 'The request body is too large.' })\r\n }\r\n json(res, 400, { error: error instanceof Error ? error.message : 'request failed' })\r\n } finally {\r\n bounded[Symbol.dispose]()\r\n }\r\n },\r\n }), label)\r\n}\r\n\r\n/**\r\n * Memoise an executable lookup with a deadline, dropping the cache when it\r\n * fails.\r\n *\r\n * A route budget frees the socket but does nothing about a cached promise that\r\n * never settles: one hung PATH probe otherwise poisons every later request for\r\n * the life of the process, and the route deadline just turns that into a\r\n * steady stream of 504s. Caching only the resolved value keeps the retry.\r\n */\r\nexport function memoizeExecutable(\r\n resolve: (signal: AbortSignal) => Promise<string>,\r\n timeoutMs: number,\r\n): () => Promise<string> {\r\n let pending: Promise<string> | undefined\r\n return () => {\r\n if (pending !== undefined) return pending\r\n const bounded = deadline(undefined, timeoutMs, ROUTE_TIMEOUT_CODE)\r\n const attempt = resolve(bounded.signal)\r\n .finally(() => { bounded[Symbol.dispose]() })\r\n .catch((error: unknown) => {\r\n pending = undefined\r\n throw error\r\n })\r\n pending = attempt\r\n return attempt\r\n }\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type { Agent } from '@deepseek-ai/dsh-agent'\r\nimport type {} from '@deepseek-ai/dsh-agent-presets'\r\nimport type {} from '@deepseek-ai/dsh-commands'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_DOCTOR_PATH } from './constants.ts'\r\nimport { runClaudeDoctor, type ExecutableRuntime } from './executable.ts'\r\nimport type { ClaudeSupervisor, ClaudeSupervisorConfig } from './supervisor.ts'\r\nimport { redactText } from './events.ts'\r\nimport { registerPluginRoute } from './http.ts'\r\n\r\nexport const CLAUDE_DOCTOR_PROBE_TIMEOUT_MS = 15_000\r\n\r\n/** Live metadata-bridge state per agent, maintained by the host plugin. */\r\nexport interface ClaudeBridgeDiagnostic {\r\n attempts: number\r\n lastError?: string\r\n lastCatalog?: number\r\n registered?: string[]\r\n}\r\n\r\nexport const claudeBridgeDiagnostics = new WeakMap<Agent, ClaudeBridgeDiagnostic>()\r\n\r\nfunction safeMessage(error: unknown): string {\r\n return redactText(error instanceof Error ? error.message : String(error), 1_000)\r\n}\r\n\r\n/** Live command-bridge diagnostics: which agents exist, their presets, and how\r\n * many slash commands each agent's registry layer resolves. */\r\nfunction commandDiagnostics(ctx: Context): unknown {\r\n try {\r\n const agents = ctx.agents.list()\r\n return {\r\n total: agents.length,\r\n agents: agents.map(agent => {\r\n const info: { id: string; preset?: string; commandCount?: number; sample?: string[]; error?: string; bridge?: ClaudeBridgeDiagnostic } = { id: String(agent.id) }\r\n try {\r\n const preset = ctx.agentPresets.composedPreset(agent.ctx)\r\n if (preset !== undefined) info.preset = preset\r\n } catch (error) {\r\n info.error = safeMessage(error)\r\n }\r\n try {\r\n const list = ctx.commands.list(agent)\r\n info.commandCount = list.length\r\n info.sample = list.slice(0, 10).map(command => command.name)\r\n } catch (error) {\r\n info.error = info.error === undefined ? safeMessage(error) : `${info.error}; ${safeMessage(error)}`\r\n }\r\n const bridge = claudeBridgeDiagnostics.get(agent)\r\n if (bridge !== undefined) info.bridge = bridge\r\n return info\r\n }),\r\n }\r\n } catch (error) {\r\n return { error: safeMessage(error) }\r\n }\r\n}\r\n\r\nexport function registerClaudeDoctorRoutes(\r\n ctx: Context,\r\n runtime: ExecutableRuntime,\r\n supervisor: ClaudeSupervisor,\r\n config: ClaudeSupervisorConfig,\r\n resolutionError?: unknown,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_DOCTOR_PATH,\r\n methods: ['GET'],\r\n budget: 'git',\r\n handler: async io => {\r\n try {\r\n if (resolutionError !== undefined) {\r\n return { status: 200, value: {\r\n executable: {\r\n status: 'missing',\r\n searched: config.executablePath.length > 0 ? [config.executablePath] : ['claude', '~/.local/bin/claude', '/opt/homebrew/bin/claude', '/usr/local/bin/claude'],\r\n },\r\n version: { status: 'not-run' },\r\n authentication: { status: 'not-run' },\r\n handshake: 'not-run',\r\n message: safeMessage(resolutionError),\r\n limits: {\r\n idleTimeoutMs: config.idleTimeoutMs,\r\n maxProcesses: config.maxProcesses,\r\n },\r\n processes: { count: 0, active: 0 },\r\n } }\r\n }\r\n const report = await runClaudeDoctor(runtime, {\r\n configuredPath: config.executablePath,\r\n cwd: process.cwd(),\r\n // Threaded so freeing the socket also stops the probe, rather than\r\n // leaving a spawn nobody is waiting for; the ceiling stays its own.\r\n signal: AbortSignal.any([io.signal, AbortSignal.timeout(CLAUDE_DOCTOR_PROBE_TIMEOUT_MS)]),\r\n })\r\n const processes = supervisor.snapshots()\r\n if (processes.some(process => process.claudeSessionId !== undefined)) report.handshake = 'ok'\r\n return { status: 200, value: {\r\n ...report,\r\n limits: {\r\n idleTimeoutMs: config.idleTimeoutMs,\r\n maxProcesses: config.maxProcesses,\r\n },\r\n processes: {\r\n count: processes.length,\r\n active: processes.filter(process => process.state === 'running' || process.state === 'starting').length,\r\n },\r\n commandBridge: commandDiagnostics(ctx),\r\n } }\r\n } catch (error) {\r\n return { status: 500, value: { error: safeMessage(error) } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport type { ServerResponse } from 'node:http'\r\nimport { CLAUDE_PROJECTION_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport { MAX_MULTIPLEX_SESSIONS } from './plugin-budget.ts'\r\nimport type { ClaudeSidecarProjection, ClaudeSidecarRepository } from './sidecar.ts'\r\nimport type { ClaudeCommandView } from './command-bridge.ts'\r\nimport type { RepositoryStatus } from './repository-status.ts'\r\nimport type { ReviewComment } from './review-comments.ts'\r\n\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\n/** Slow-moving metadata refresh and stream heartbeat cadence; deliberately off\r\n * the transcript hot path so git/gh latency never delays visible text. */\r\nconst META_REFRESH_MS = 5_000\r\n/** The multiplexed carrier's path segment. Session ids are `session-<uuid>`,\r\n * so this cannot collide with one. */\r\nconst MULTI_SEGMENT = 'multi'\r\n\r\ntype ProjectionTarget =\r\n | { readonly kind: 'snapshot'; readonly sessionId: string }\r\n | { readonly kind: 'multi'; readonly sessionIds: readonly string[] }\r\n\r\nfunction validSessionId(value: string): boolean {\r\n return value.length > 0 && value.length <= MAX_SESSION_ID_CHARS\r\n}\r\n\r\nfunction targetFromUrl(url: URL): ProjectionTarget | undefined {\r\n const prefix = `${CLAUDE_PROJECTION_PATH}/`\r\n if (!url.pathname.startsWith(prefix)) return undefined\r\n const encoded = url.pathname.slice(prefix.length)\r\n if (encoded.length === 0 || encoded.includes('/')) return undefined\r\n if (encoded === MULTI_SEGMENT) {\r\n const raw = url.searchParams.get('sessions')\r\n if (raw === null) return undefined\r\n const sessionIds = [...new Set(raw.split(',').filter(id => id.length > 0))]\r\n if (sessionIds.length === 0 || sessionIds.length > MAX_MULTIPLEX_SESSIONS) return undefined\r\n if (!sessionIds.every(validSessionId)) return undefined\r\n return { kind: 'multi', sessionIds }\r\n }\r\n try {\r\n const sessionId = decodeURIComponent(encoded)\r\n return validSessionId(sessionId) ? { kind: 'snapshot', sessionId } : undefined\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\ninterface ProjectionMeta {\r\n readonly owned: boolean\r\n readonly commands: readonly ClaudeCommandView[]\r\n readonly repository?: RepositoryStatus\r\n readonly reviewComments: readonly ReviewComment[]\r\n}\r\n\r\nfunction envelope(projection: ClaudeSidecarProjection, meta: ProjectionMeta): Record<string, unknown> {\r\n return {\r\n schemaVersion: projection.schemaVersion,\r\n revision: projection.revision,\r\n owned: meta.owned,\r\n commands: meta.commands,\r\n activities: projection.activities,\r\n ...(projection.contextUsage === undefined ? {} : { contextUsage: projection.contextUsage }),\r\n ...(projection.tasks === undefined ? {} : { tasks: projection.tasks }),\r\n ...(meta.repository === undefined ? {} : { repository: meta.repository }),\r\n reviewComments: meta.reviewComments,\r\n // Ranges only: the chain anchors behind a rewind are Claude transcript\r\n // identities and stay on this side of the boundary.\r\n ...(projection.rewind === undefined ? {} : { rewind: { ranges: projection.rewind.ranges } }),\r\n }\r\n}\r\n\r\n/** Register the browser-readable, credential-free sidecar projection endpoint.\r\n *\r\n * `GET <path>/:sessionId` returns one snapshot. `GET <path>/multi?sessions=a,b`\r\n * returns ONE NDJSON stream carrying every listed session, each line stamped\r\n * with its `session`.\r\n *\r\n * There is deliberately no per-session stream URL. The browser shares a small\r\n * fixed connection budget between this plugin and the Host, and a stream per\r\n * session spent it in proportion to how many Claude sessions existed — which\r\n * is what left the settings panel unable to get a connection at all. One\r\n * carrier is one connection, whatever the session count. */\r\nexport function registerClaudeProjectionRoute(\r\n ctx: Context,\r\n sidecar: ClaudeSidecarRepository,\r\n ownsSession: (sessionId: string) => boolean,\r\n commandsForSession: (sessionId: string) => readonly ClaudeCommandView[] = () => [],\r\n repositoryForSession: (sessionId: string) => Promise<RepositoryStatus | undefined> = async () => undefined,\r\n reviewCommentsForSession: (sessionId: string) => readonly ReviewComment[] = () => [],\r\n): void {\r\n const info = (message: string): void => {\r\n ctx.logger?.info?.(message)\r\n }\r\n\r\n /** Everything the host already knows, without touching the repository. */\r\n const localMeta = (sessionId: string): ProjectionMeta => {\r\n const owned = ownsSession(sessionId)\r\n return {\r\n owned,\r\n commands: commandsForSession(sessionId),\r\n reviewComments: owned ? reviewCommentsForSession(sessionId) : [],\r\n }\r\n }\r\n\r\n const assembleMeta = async (sessionId: string): Promise<ProjectionMeta> => {\r\n const meta = localMeta(sessionId)\r\n const repository = meta.owned ? await repositoryForSession(sessionId) : undefined\r\n return { ...meta, ...(repository === undefined ? {} : { repository }) }\r\n }\r\n\r\n const streamMulti = async (res: ServerResponse, io: PluginRouteIo, sessionIds: readonly string[]): Promise<void> => {\r\n info(`dsh-claude: projection stream opened for ${sessionIds.length} session(s)`)\r\n let textDeltas = 0\r\n let textBytes = 0\r\n let textSince = Date.now()\r\n // Headers first, before any await. One session whose repository probe is\r\n // slow must not delay every other session's first paint — and until the\r\n // headers are out the client cannot even tell the carrier is alive.\r\n // `no-transform` keeps a compressing proxy from buffering the sole carrier.\r\n res.writeHead(200, {\r\n 'content-type': 'application/x-ndjson; charset=utf-8',\r\n 'cache-control': 'no-store, no-transform',\r\n 'x-content-type-options': 'nosniff',\r\n })\r\n res.flushHeaders?.()\r\n let closed = false\r\n const writeLine = (value: unknown): void => {\r\n if (closed) return\r\n try {\r\n res.write(`${JSON.stringify(value)}\\n`)\r\n } catch {\r\n closed = true\r\n }\r\n }\r\n const metas = new Map<string, ProjectionMeta>()\r\n const writeMeta = (sessionId: string, meta: ProjectionMeta): void => {\r\n metas.set(sessionId, meta)\r\n writeLine({\r\n type: 'meta',\r\n session: sessionId,\r\n owned: meta.owned,\r\n commands: meta.commands,\r\n ...(meta.repository === undefined ? {} : { repository: meta.repository }),\r\n reviewComments: meta.reviewComments,\r\n })\r\n }\r\n const writeSnapshot = async (sessionId: string): Promise<void> => {\r\n const projection = await sidecar.read(sessionId)\r\n // The repository probe runs a chain of git commands and a `gh pr view`\r\n // over the network -- seconds, where the transcript is already in\r\n // memory. It rides a later meta line so the prose paints first.\r\n const meta = metas.get(sessionId) ?? localMeta(sessionId)\r\n metas.set(sessionId, meta)\r\n // Where the notification stream stands as of this read, so the first\r\n // delta after this line has a number to be contiguous with.\r\n writeLine({ type: 'snapshot', session: sessionId, seq: sidecar.sequence(sessionId), ...envelope(projection, meta) })\r\n const probed = await assembleMeta(sessionId)\r\n if (closed || JSON.stringify(probed) === JSON.stringify(metas.get(sessionId))) return\r\n writeMeta(sessionId, probed)\r\n }\r\n // Subscribe every lane synchronously, before the first await: a delta that\r\n // lands while the snapshots are still assembling belongs to this carrier.\r\n const unsubscribes = sessionIds.map(sessionId => sidecar.subscribe(sessionId, delta => {\r\n switch (delta.kind) {\r\n case 'text':\r\n textDeltas += 1\r\n textBytes += (delta.append ?? delta.text ?? '').length\r\n if (textDeltas % 25 === 0) {\r\n const elapsed = Date.now() - textSince\r\n info(`dsh-claude: stream 25 text deltas ${textBytes}B in ${elapsed}ms`)\r\n textBytes = 0\r\n textSince = Date.now()\r\n }\r\n writeLine({\r\n type: 'text',\r\n session: sessionId,\r\n turn: delta.turn,\r\n step: delta.step,\r\n ordinal: delta.ordinal,\r\n ...(delta.append === undefined ? {} : { append: delta.append }),\r\n ...(delta.text === undefined ? {} : { text: delta.text }),\r\n ...(delta.renderer === undefined ? {} : { renderer: delta.renderer }),\r\n seq: delta.seq,\r\n })\r\n return\r\n case 'activity':\r\n writeLine({ type: 'activity', session: sessionId, activity: delta.activity, seq: delta.seq })\r\n return\r\n case 'contextUsage':\r\n writeLine({ type: 'contextUsage', session: sessionId, value: delta.value, seq: delta.seq })\r\n return\r\n case 'tasks':\r\n writeLine({ type: 'tasks', session: sessionId, value: delta.value, seq: delta.seq })\r\n return\r\n case 'checkpoint':\r\n writeLine({ type: 'checkpoint', session: sessionId, seq: delta.seq })\r\n return\r\n case 'sync':\r\n void writeSnapshot(sessionId).catch(() => undefined)\r\n }\r\n }))\r\n // Per-session, in parallel: a wedged repository probe costs its own lane\r\n // its first paint, not everyone else's.\r\n for (const sessionId of sessionIds) {\r\n void writeSnapshot(sessionId).catch(() => undefined)\r\n }\r\n // One sweep at a time. Each lane's probe chains git commands and a network\r\n // `gh pr view`, and the interval has no idea how long the last one took --\r\n // so a tick that lands on a sweep still in flight starts a second set of\r\n // the same probes rather than waiting. At a lane or two that never showed;\r\n // at a full carrier it is sixteen serial probes per tick, arriving faster\r\n // than they drain. Skipping a tick costs at most one refresh of metadata\r\n // that is deliberately off the transcript's hot path.\r\n let sweeping = false\r\n const timer = setInterval(() => {\r\n // The heartbeat leads, and does not ride the sweep. It is the only thing\r\n // keeping bytes on a carrier between turns, and an idle connection the\r\n // far end reaps is the ending that costs the Client its transcript.\r\n writeLine({ type: 'ping' })\r\n if (sweeping) return\r\n sweeping = true\r\n void (async () => {\r\n for (const sessionId of sessionIds) {\r\n if (closed) return\r\n const next = await assembleMeta(sessionId)\r\n if (closed) return\r\n if (JSON.stringify(next) === JSON.stringify(metas.get(sessionId))) continue\r\n writeMeta(sessionId, next)\r\n }\r\n })().catch(() => undefined).finally(() => { sweeping = false })\r\n }, META_REFRESH_MS)\r\n timer.unref?.()\r\n // Teardown rides the wrapper's signal, which is armed before any await —\r\n // the previous hand-written `res.on('close')` was attached only after the\r\n // first metadata probe resolved, so a client that gave up during that\r\n // window left the interval and every subscription running for good.\r\n await new Promise<void>(resolve => {\r\n const finish = (): void => {\r\n if (closed) return\r\n closed = true\r\n clearInterval(timer)\r\n for (const unsubscribe of unsubscribes) unsubscribe()\r\n info(`dsh-claude: projection stream closed after ${textDeltas} text deltas`)\r\n resolve()\r\n }\r\n if (io.signal.aborted) finish()\r\n else io.signal.addEventListener('abort', finish, { once: true })\r\n })\r\n }\r\n\r\n registerPluginRoute(ctx, {\r\n mode: 'stream',\r\n kind: 'prefix',\r\n path: CLAUDE_PROJECTION_PATH,\r\n methods: ['GET'],\r\n // One carrier. A reconnect supersedes the old one rather than stacking.\r\n maxConcurrent: 1,\r\n streamKey: () => MULTI_SEGMENT,\r\n handler: async (res, io) => {\r\n const target = targetFromUrl(io.url)\r\n if (target === undefined) {\r\n res.writeHead(400, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' })\r\n res.write(JSON.stringify({ error: 'invalid session id' }))\r\n return\r\n }\r\n if (target.kind === 'multi') return await streamMulti(res, io, target.sessionIds)\r\n // A steady 2s cadence here means a stale (pre-streaming) client bundle.\r\n info(`dsh-claude: projection poll for ${target.sessionId.slice(0, 64)}`)\r\n try {\r\n const projection = await sidecar.read(target.sessionId)\r\n const body = envelope(projection, await assembleMeta(target.sessionId))\r\n res.writeHead(200, {\r\n 'content-type': 'application/json; charset=utf-8',\r\n 'cache-control': 'no-store',\r\n 'x-content-type-options': 'nosniff',\r\n })\r\n res.write(JSON.stringify(body))\r\n } catch {\r\n if (res.headersSent) return\r\n res.writeHead(500, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' })\r\n res.write(JSON.stringify({ error: 'projection unavailable' }))\r\n }\r\n },\r\n })\r\n}\r\n","import { mkdir, writeFile } from 'node:fs/promises'\r\nimport { dirname } from 'node:path'\r\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\r\n\r\n/** Extensions mapped onto a funcname driver, so `@@` hunk headers name the\r\n * method a change sits in. Without one git falls back to \"the last line that\r\n * starts in column 0\", which in Java or Kotlin is always the class. */\r\nexport const DIFF_ATTRIBUTES = [\r\n '*.java diff=java',\r\n '*.kt diff=kotlin',\r\n '*.kts diff=kotlin',\r\n '*.py diff=python',\r\n '*.pyi diff=python',\r\n '*.js diff=dshweb',\r\n '*.jsx diff=dshweb',\r\n '*.mjs diff=dshweb',\r\n '*.cjs diff=dshweb',\r\n '*.ts diff=dshweb',\r\n '*.tsx diff=dshweb',\r\n '*.mts diff=dshweb',\r\n '*.cts diff=dshweb',\r\n '*.vue diff=dshweb',\r\n '*.svelte diff=dshweb',\r\n '*.css diff=css',\r\n '*.scss diff=css',\r\n '*.less diff=css',\r\n '',\r\n].join('\\n')\r\n\r\n/** git ships no JavaScript driver, so this is the one pattern we write ourselves.\r\n *\r\n * POSIX extended regexes, one per line, matched top-down: a leading `!` marks a\r\n * line that can never be a header, and the reported text is capture group 1 --\r\n * hence the outer parentheses around everything worth showing.\r\n *\r\n * Line 2 keeps git's own fallback (anything unindented), because a driver\r\n * replaces that fallback rather than extending it, and most of a frontend file's\r\n * declarations already live in column 0. Lines 3 and 4 add what the fallback\r\n * cannot see: nested declarations, and indented class or object methods.\r\n *\r\n * ponytail: a method line must end in `{`. Allowing `)` too would pick up every\r\n * bare `foo(bar)` statement, which reads as a header and hides the real one.\r\n */\r\nexport const DSHWEB_FUNCNAME = [\r\n '!^[ \\t]*(if|else|for|while|do|switch|case|catch|try|finally|return|await|new|throw|typeof)[^A-Za-z0-9_$]',\r\n '^([A-Za-z_$].*)$',\r\n '^[ \\t]*((export[ \\t]+)?(default[ \\t]+)?(declare[ \\t]+)?(abstract[ \\t]+)?(async[ \\t]+)?(function|class|interface|enum|namespace|module)[ \\t].*)$',\r\n '^[ \\t]*(((public|private|protected|static|readonly|abstract|async|get|set)[ \\t]+)*[A-Za-z_$#][A-Za-z0-9_$]*[ \\t]*[:=]?[ \\t]*(async[ \\t]+)?[(<][^;]*\\\\{)[ \\t]*$',\r\n].join('\\n')\r\n\r\nlet attributesFile: Promise<string | undefined> | undefined\r\n\r\nasync function writeAttributes(): Promise<string | undefined> {\r\n const path = dshHomePath('plugins', 'dsh-claude', 'diff-attributes')\r\n try {\r\n await mkdir(dirname(path), { recursive: true })\r\n await writeFile(path, DIFF_ATTRIBUTES, 'utf8')\r\n return path\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\n/** `-c` overrides to place in front of a `git diff`, teaching it which funcname\r\n * driver each extension uses.\r\n *\r\n * `core.attributesFile` is the lowest-precedence attribute source, so a\r\n * repository that already declares its own `.gitattributes` still wins. Better\r\n * hunk headers are cosmetic: a failed write drops the overrides and the diff\r\n * runs exactly as before.\r\n */\r\nexport async function diffFuncnameArgs(): Promise<readonly string[]> {\r\n attributesFile ??= writeAttributes()\r\n const path = await attributesFile\r\n if (path === undefined) return []\r\n return ['-c', `core.attributesFile=${path}`, '-c', `diff.dshweb.xfuncname=${DSHWEB_FUNCNAME}`]\r\n}\r\n","import { readFile, stat } from 'node:fs/promises'\r\nimport { isAbsolute, join, resolve, sep } from 'node:path'\r\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\nimport { diffFuncnameArgs } from './diff-funcname.ts'\r\n\r\nconst MAX_OUTPUT_BYTES = 64 * 1024\r\nconst MAX_DIFF_BYTES = 256 * 1024\r\nconst MAX_FILE_BYTES = 8 * 1024 * 1024\r\nexport const MAX_FILE_LINES_PER_REQUEST = 500\r\nconst MAX_UNTRACKED_DIFFS = 50\r\nconst GIT_TIMEOUT_MS = 5_000\r\nconst GH_TIMEOUT_MS = 8_000\r\nconst CACHE_TTL_MS = 5_000\r\nconst MAX_TEXT_CHARS = 1_024\r\nconst MAX_CONFLICT_PATHS = 100\r\n\r\n/** A git operation left half-finished in the working tree, waiting for the\r\n * user to resolve conflicts and continue -- or to abort. */\r\nexport type RepositoryOperation = 'rebase' | 'merge' | 'cherry-pick' | 'revert'\r\nexport type RepositoryCheckState = 'passing' | 'pending' | 'failing' | 'none'\r\nexport type RepositoryReviewState = 'approved' | 'changes-requested' | 'review-required' | 'none'\r\n\r\nexport interface RepositoryPullRequestStatus {\r\n readonly number: number\r\n readonly title: string\r\n readonly url: string\r\n readonly state: 'open' | 'closed' | 'merged'\r\n readonly draft: boolean\r\n readonly review: RepositoryReviewState\r\n readonly checks: RepositoryCheckState\r\n readonly mergeState?: string\r\n readonly author?: string\r\n readonly createdAt?: string\r\n readonly mergedAt?: string\r\n readonly baseBranch?: string\r\n}\r\n\r\nexport interface RepositoryDiffStatus {\r\n readonly additions: number\r\n readonly deletions: number\r\n readonly files: number\r\n readonly patch?: string\r\n readonly truncated: boolean\r\n}\r\n\r\nexport interface RepositoryStatus {\r\n readonly status: 'ready' | 'not-repository' | 'unavailable'\r\n readonly cwd: string\r\n readonly root?: string\r\n readonly branch?: string\r\n readonly detached?: boolean\r\n readonly worktree?: boolean\r\n readonly dirty?: boolean\r\n readonly upstream?: boolean\r\n readonly ahead?: number\r\n readonly behind?: number\r\n readonly remote?: string\r\n readonly pullRequest?: RepositoryPullRequestStatus\r\n readonly diff?: RepositoryDiffStatus\r\n /** Commits on origin/<base> that are not on HEAD, for open pull requests. */\r\n readonly baseBehind?: number\r\n /** Unmerged paths: the files a stopped merge or rebase is waiting on. */\r\n readonly conflicts?: readonly string[]\r\n /** The stopped operation itself, present even once every conflict is staged. */\r\n readonly operation?: RepositoryOperation\r\n}\r\n\r\ntype RepositoryRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\r\n\r\ninterface CommandResult {\r\n readonly exitCode: number | null\r\n readonly stdout: string\r\n readonly lossy: boolean\r\n}\r\n\r\nfunction bounded(value: string): string {\r\n return value.trim().slice(0, MAX_TEXT_CHARS)\r\n}\r\n\r\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\r\n const outcome = await handle.done\r\n const stdout = handle.collected.stdout?.readFrom(0)\r\n return {\r\n exitCode: outcome.exitCode,\r\n stdout: stdout?.text ?? '',\r\n lossy: stdout?.lossy === true,\r\n }\r\n}\r\n\r\nasync function run(\r\n runtime: RepositoryRuntime,\r\n executable: string,\r\n args: readonly string[],\r\n cwd: string,\r\n timeoutMs: number,\r\n maxBytes = MAX_OUTPUT_BYTES,\r\n): Promise<CommandResult> {\r\n const signal = AbortSignal.timeout(timeoutMs)\r\n return collect(runtime.spawn({\r\n argv: [executable, ...args],\r\n cwd,\r\n stdio: {\r\n stdin: 'ignore',\r\n stdout: { maxBytes },\r\n stderr: { maxBytes: MAX_OUTPUT_BYTES },\r\n },\r\n graceMs: 1_000,\r\n signal,\r\n env: {},\r\n }))\r\n}\r\n\r\nfunction normalizedPath(value: string): string {\r\n return value.replaceAll('\\\\', '/').replace(/\\/+$/u, '').toLocaleLowerCase('en-US')\r\n}\r\n\r\nexport function parseGitStatus(output: string): {\r\n branch?: string\r\n detached: boolean\r\n dirty: boolean\r\n upstream: boolean\r\n ahead?: number\r\n behind?: number\r\n conflicts?: readonly string[]\r\n} {\r\n let branch: string | undefined\r\n let detached = false\r\n let dirty = false\r\n let upstream = false\r\n let ahead: number | undefined\r\n let behind: number | undefined\r\n const conflicts: string[] = []\r\n for (const line of output.split(/\\r?\\n/u)) {\r\n if (line.startsWith('# branch.head ')) {\r\n const head = bounded(line.slice('# branch.head '.length))\r\n if (head === '(detached)') detached = true\r\n else if (head.length > 0 && head !== '(unknown)') branch = head\r\n continue\r\n }\r\n if (line.startsWith('# branch.upstream ')) {\r\n upstream = true\r\n continue\r\n }\r\n if (line.startsWith('# branch.ab ')) {\r\n const counts = /^# branch\\.ab \\+(\\d+) -(\\d+)$/u.exec(line)\r\n if (counts !== null) {\r\n ahead = Number(counts[1])\r\n behind = Number(counts[2])\r\n }\r\n continue\r\n }\r\n // `u <XY> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>`: unmerged paths\r\n // are the only conflict signal the status carries, and they also read as\r\n // dirty below -- a stopped merge owns the tree until it is resolved.\r\n if (line.startsWith('u ')) {\r\n const path = line.split(' ').slice(10).join(' ')\r\n if (path.length > 0 && conflicts.length < MAX_CONFLICT_PATHS) conflicts.push(bounded(path))\r\n }\r\n if (line.length > 0 && !line.startsWith('# ')) dirty = true\r\n }\r\n return {\r\n ...(branch === undefined ? {} : { branch }),\r\n detached,\r\n dirty,\r\n upstream,\r\n ...(ahead === undefined ? {} : { ahead }),\r\n ...(behind === undefined ? {} : { behind }),\r\n ...(conflicts.length === 0 ? {} : { conflicts }),\r\n }\r\n}\r\n\r\n/** Ordered so the rebase directories win: a conflicted rebase also writes\r\n * MERGE_HEAD-like state, and the two are resumed by different commands. */\r\nconst OPERATION_MARKERS: readonly (readonly [string, RepositoryOperation])[] = [\r\n ['rebase-merge', 'rebase'],\r\n ['rebase-apply', 'rebase'],\r\n ['MERGE_HEAD', 'merge'],\r\n ['CHERRY_PICK_HEAD', 'cherry-pick'],\r\n ['REVERT_HEAD', 'revert'],\r\n]\r\n\r\nexport interface RepositoryOperationState {\r\n readonly operation: RepositoryOperation\r\n /** The branch the rebase parked. Git status only reports `(detached)` while\r\n * it replays, so `head-name` is the only place the real branch survives. */\r\n readonly branch?: string\r\n}\r\n\r\n/** Reads the in-progress operation out of the worktree's own git dir -- linked\r\n * worktrees keep their own, so this must not be handed the common dir. */\r\nexport async function detectRepositoryOperation(gitDir: string): Promise<RepositoryOperationState | undefined> {\r\n for (const [marker, operation] of OPERATION_MARKERS) {\r\n const path = join(gitDir, marker)\r\n try {\r\n await stat(path)\r\n } catch {\r\n continue\r\n }\r\n const headName = operation === 'rebase' ? await readFile(join(path, 'head-name'), 'utf8').catch(() => '') : ''\r\n const branch = bounded(headName).replace(/^refs\\/heads\\//u, '')\r\n // A rebase started from a detached HEAD writes exactly that as the name.\r\n return { operation, ...(branch.length === 0 || branch.includes(' ') ? {} : { branch }) }\r\n }\r\n return undefined\r\n}\r\n\r\nexport function parseDiffNumstat(value: string): Omit<RepositoryDiffStatus, 'patch' | 'truncated'> {\r\n let additions = 0\r\n let deletions = 0\r\n let files = 0\r\n for (const line of value.split(/\\r?\\n/u)) {\r\n if (line.length === 0) continue\r\n const [added, deleted] = line.split('\\t')\r\n files += 1\r\n if (added !== undefined && /^\\d+$/u.test(added)) additions += Number(added)\r\n if (deleted !== undefined && /^\\d+$/u.test(deleted)) deletions += Number(deleted)\r\n }\r\n return { additions, deletions, files }\r\n}\r\n\r\nexport function parseGitHubRemote(value: string): string | undefined {\r\n const remote = bounded(value)\r\n const match = /^(?:https:\\/\\/github\\.com\\/|git@github\\.com:|ssh:\\/\\/git@github\\.com\\/)([^/\\s]+)\\/([^/\\s]+?)(?:\\.git)?$/iu.exec(remote)\r\n if (match?.[1] === undefined || match[2] === undefined) return undefined\r\n return `${match[1]}/${match[2]}`\r\n}\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n ? value as Record<string, unknown>\r\n : undefined\r\n}\r\n\r\nexport function aggregateChecks(value: unknown): RepositoryCheckState {\r\n if (!Array.isArray(value) || value.length === 0) return 'none'\r\n let pending = false\r\n for (const item of value) {\r\n const check = record(item)\r\n if (check === undefined) continue\r\n const conclusion = typeof check.conclusion === 'string' ? check.conclusion.toUpperCase() : undefined\r\n const status = typeof check.status === 'string' ? check.status.toUpperCase() : undefined\r\n const state = typeof check.state === 'string' ? check.state.toUpperCase() : undefined\r\n if (['FAILURE', 'ERROR', 'CANCELLED', 'TIMED_OUT', 'ACTION_REQUIRED'].includes(conclusion ?? state ?? '')) return 'failing'\r\n if (status !== undefined && status !== 'COMPLETED') pending = true\r\n if (['PENDING', 'EXPECTED'].includes(state ?? '')) pending = true\r\n }\r\n return pending ? 'pending' : 'passing'\r\n}\r\n\r\nfunction reviewState(value: unknown): RepositoryReviewState {\r\n if (value === 'APPROVED') return 'approved'\r\n if (value === 'CHANGES_REQUESTED') return 'changes-requested'\r\n if (value === 'REVIEW_REQUIRED') return 'review-required'\r\n return 'none'\r\n}\r\n\r\nexport function parsePullRequest(value: unknown): RepositoryPullRequestStatus | undefined {\r\n const input = record(value)\r\n if (input === undefined\r\n || !Number.isSafeInteger(input.number)\r\n || Number(input.number) <= 0\r\n || typeof input.title !== 'string'\r\n || typeof input.url !== 'string') return undefined\r\n let url: URL\r\n try {\r\n url = new URL(input.url)\r\n } catch {\r\n return undefined\r\n }\r\n if (url.protocol !== 'https:' || url.hostname !== 'github.com') return undefined\r\n const rawState = typeof input.state === 'string' ? input.state.toUpperCase() : ''\r\n const state = input.mergedAt !== undefined && input.mergedAt !== null\r\n ? 'merged'\r\n : rawState === 'OPEN' ? 'open' : rawState === 'CLOSED' ? 'closed' : undefined\r\n if (state === undefined) return undefined\r\n return {\r\n number: Number(input.number),\r\n title: bounded(input.title),\r\n url: url.href,\r\n state,\r\n draft: input.isDraft === true,\r\n review: reviewState(input.reviewDecision),\r\n checks: aggregateChecks(input.statusCheckRollup),\r\n ...(typeof input.mergeStateStatus === 'string'\r\n ? { mergeState: bounded(input.mergeStateStatus) }\r\n : {}),\r\n ...(typeof record(input.author)?.login === 'string'\r\n ? { author: bounded(String(record(input.author)?.login)) }\r\n : {}),\r\n ...(typeof input.createdAt === 'string' && Number.isFinite(Date.parse(input.createdAt))\r\n ? { createdAt: new Date(input.createdAt).toISOString() }\r\n : {}),\r\n ...(typeof input.mergedAt === 'string' && Number.isFinite(Date.parse(input.mergedAt))\r\n ? { mergedAt: new Date(input.mergedAt).toISOString() }\r\n : {}),\r\n ...(typeof input.baseRefName === 'string' && bounded(input.baseRefName).length > 0\r\n ? { baseBranch: bounded(input.baseRefName) }\r\n : {}),\r\n }\r\n}\r\n\r\nexport interface RepositoryFileLines {\r\n /** Requested 1-based inclusive slice of the working-tree file, clipped to its end. */\r\n readonly lines: readonly string[]\r\n /** Total line count of the file. */\r\n readonly total: number\r\n}\r\n\r\nexport class RepositoryFileError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'RepositoryFileError'\r\n this.code = code\r\n }\r\n}\r\n\r\nexport class RepositoryStatusService {\r\n readonly #runtime: RepositoryRuntime\r\n readonly #cacheTtlMs: number\r\n readonly #cache = new Map<string, { expiresAt: number; value: Promise<RepositoryStatus> }>()\r\n readonly #lastReady = new Map<string, RepositoryStatus>()\r\n #gitExecutable?: Promise<string>\r\n #ghExecutable?: Promise<string | undefined>\r\n\r\n constructor(runtime: RepositoryRuntime, cacheTtlMs = CACHE_TTL_MS) {\r\n this.#runtime = runtime\r\n this.#cacheTtlMs = cacheTtlMs\r\n }\r\n\r\n /** `signal` bounds the scan itself, not just the caller's patience: the\r\n * untracked-file diff below is a serial spawn loop that can outlive any\r\n * route budget, and work nobody is waiting for still occupies the process. */\r\n inspect(cwd: string, signal?: AbortSignal): Promise<RepositoryStatus> {\r\n const current = this.#cache.get(cwd)\r\n if (current !== undefined && current.expiresAt > Date.now()) return current.value\r\n const value = this.#inspect(cwd, signal).then(next => this.#stabilize(cwd, next))\r\n this.#cache.set(cwd, { expiresAt: Date.now() + this.#cacheTtlMs, value })\r\n void value.catch(() => this.#cache.delete(cwd))\r\n return value\r\n }\r\n\r\n invalidate(cwd: string): void {\r\n this.#cache.delete(cwd)\r\n this.#lastReady.delete(cwd)\r\n }\r\n\r\n dispose(): void {\r\n this.#cache.clear()\r\n this.#lastReady.clear()\r\n }\r\n\r\n #stabilize(cwd: string, next: RepositoryStatus): RepositoryStatus {\r\n const previous = this.#lastReady.get(cwd)\r\n if (next.status !== 'ready') return previous ?? next\r\n const sameCheckout = previous?.status === 'ready'\r\n && previous.root === next.root\r\n && previous.branch === next.branch\r\n const stable = sameCheckout\r\n ? {\r\n ...next,\r\n ...(next.pullRequest === undefined && previous.pullRequest !== undefined ? { pullRequest: previous.pullRequest } : {}),\r\n ...(next.pullRequest === undefined && previous.pullRequest !== undefined && previous.diff !== undefined\r\n ? { diff: previous.diff }\r\n : next.diff === undefined && previous.diff !== undefined ? { diff: previous.diff } : {}),\r\n }\r\n : next\r\n this.#lastReady.set(cwd, stable)\r\n return stable\r\n }\r\n\r\n /** Lines [from, to] of a working-tree file, used to expand unmodified context around diff hunks. */\r\n async fileLines(cwd: string, relativePath: string, from: number, to: number): Promise<RepositoryFileLines> {\r\n if (relativePath.length === 0 || isAbsolute(relativePath) || relativePath.includes('\\0') || relativePath.split(/[\\\\/]/u).includes('..')) {\r\n throw new RepositoryFileError('invalid-request', 'The file path must be relative to the repository.')\r\n }\r\n if (!Number.isSafeInteger(from) || !Number.isSafeInteger(to) || from < 1 || to < from || to - from >= MAX_FILE_LINES_PER_REQUEST) {\r\n throw new RepositoryFileError('invalid-request', 'The requested line range is invalid.')\r\n }\r\n const git = await this.#git()\r\n const top = await run(this.#runtime, git, ['rev-parse', '--path-format=absolute', '--show-toplevel'], cwd, GIT_TIMEOUT_MS)\r\n if (top.exitCode !== 0) throw new RepositoryFileError('not-repository', 'The directory is not inside a git repository.')\r\n const root = resolve(top.stdout.trim())\r\n const target = resolve(root, relativePath)\r\n if (target !== root && !target.startsWith(root + sep)) throw new RepositoryFileError('invalid-request', 'The file path escapes the repository.')\r\n const content = await readFile(target, 'utf8')\r\n if (content.length > MAX_FILE_BYTES) throw new RepositoryFileError('too-large', 'The file is too large to expand.')\r\n const all = content.split(/\\r?\\n/u)\r\n if (all.at(-1) === '') all.pop()\r\n return { lines: all.slice(from - 1, to), total: all.length }\r\n }\r\n\r\n async #git(): Promise<string> {\r\n this.#gitExecutable ??= this.#runtime.resolveExecutable('git')\r\n return this.#gitExecutable\r\n }\r\n\r\n async #gh(): Promise<string | undefined> {\r\n this.#ghExecutable ??= this.#runtime.resolveExecutable('gh').catch(() => undefined)\r\n return this.#ghExecutable\r\n }\r\n\r\n async #inspect(cwd: string, signal?: AbortSignal): Promise<RepositoryStatus> {\r\n const safeCwd = bounded(cwd)\r\n let git: string\r\n try {\r\n git = await this.#git()\r\n } catch {\r\n return { status: 'unavailable', cwd: safeCwd }\r\n }\r\n try {\r\n const paths = await run(this.#runtime, git, [\r\n 'rev-parse', '--path-format=absolute', '--show-toplevel', '--absolute-git-dir', '--git-common-dir',\r\n ], cwd, GIT_TIMEOUT_MS)\r\n if (paths.exitCode !== 0) return { status: 'not-repository', cwd: safeCwd }\r\n const [rootValue, gitDirValue, commonDirValue] = paths.stdout.split(/\\r?\\n/u)\r\n const root = bounded(rootValue ?? '')\r\n const gitDir = bounded(gitDirValue ?? '')\r\n const commonDir = bounded(commonDirValue ?? '')\r\n if (root.length === 0 || gitDir.length === 0 || commonDir.length === 0) return { status: 'unavailable', cwd: safeCwd }\r\n const statusResult = await run(this.#runtime, git, ['status', '--porcelain=v2', '--branch', '--untracked-files=normal'], cwd, GIT_TIMEOUT_MS)\r\n if (statusResult.exitCode !== 0) return { status: 'unavailable', cwd: safeCwd }\r\n const status = parseGitStatus(statusResult.stdout)\r\n const operation = await detectRepositoryOperation(gitDir)\r\n // A stopped rebase detaches HEAD, which would otherwise drop the branch,\r\n // its pull request and every control keyed on them for as long as the\r\n // conflict lasts -- exactly when the user needs them most.\r\n const branch = operation?.branch ?? status.branch\r\n const remoteResult = await run(this.#runtime, git, ['remote', 'get-url', 'origin'], cwd, GIT_TIMEOUT_MS)\r\n const remote = remoteResult.exitCode === 0 ? parseGitHubRemote(remoteResult.stdout) : undefined\r\n const pullRequest = branch === undefined || remote === undefined\r\n ? undefined\r\n : await this.#pullRequest(cwd, remote, branch)\r\n const diffBase = pullRequest?.baseBranch === undefined\r\n ? 'HEAD'\r\n : await this.#mergeBase(cwd, git, pullRequest.baseBranch) ?? 'HEAD'\r\n const diff = status.dirty || diffBase !== 'HEAD'\r\n ? await this.#diff(cwd, git, diffBase, signal)\r\n : { additions: 0, deletions: 0, files: 0, truncated: false }\r\n const baseBehind = pullRequest?.state === 'open' && pullRequest.baseBranch !== undefined\r\n ? await this.#baseBehind(cwd, git, pullRequest.baseBranch)\r\n : undefined\r\n return {\r\n status: 'ready',\r\n cwd: safeCwd,\r\n root,\r\n ...status,\r\n ...(branch === undefined ? {} : { branch }),\r\n ...(operation === undefined ? {} : { operation: operation.operation }),\r\n worktree: normalizedPath(gitDir) !== normalizedPath(commonDir),\r\n ...(remote === undefined ? {} : { remote }),\r\n ...(pullRequest === undefined ? {} : { pullRequest }),\r\n ...(diff === undefined ? {} : { diff }),\r\n ...(baseBehind === undefined ? {} : { baseBehind }),\r\n }\r\n } catch {\r\n return { status: 'unavailable', cwd: safeCwd }\r\n }\r\n }\r\n\r\n async #baseBehind(cwd: string, git: string, baseBranch: string): Promise<number | undefined> {\r\n try {\r\n const result = await run(this.#runtime, git, ['rev-list', '--count', `HEAD..refs/remotes/origin/${baseBranch}`, '--'], cwd, GIT_TIMEOUT_MS)\r\n if (result.exitCode !== 0 || result.lossy) return undefined\r\n const count = Number(bounded(result.stdout))\r\n return Number.isSafeInteger(count) && count >= 0 ? count : undefined\r\n } catch {\r\n return undefined\r\n }\r\n }\r\n\r\n async #mergeBase(cwd: string, git: string, baseBranch: string): Promise<string | undefined> {\r\n try {\r\n const result = await run(this.#runtime, git, ['merge-base', 'HEAD', `refs/remotes/origin/${baseBranch}`], cwd, GIT_TIMEOUT_MS)\r\n if (result.exitCode !== 0 || result.lossy) return undefined\r\n const oid = bounded(result.stdout)\r\n return /^[0-9a-f]{40}$/iu.test(oid) ? oid : undefined\r\n } catch {\r\n return undefined\r\n }\r\n }\r\n\r\n async #diff(cwd: string, git: string, base: string, signal?: AbortSignal): Promise<RepositoryDiffStatus | undefined> {\r\n try {\r\n const numstat = await run(this.#runtime, git, ['diff', '--no-ext-diff', '--numstat', base, '--'], cwd, GIT_TIMEOUT_MS)\r\n if (numstat.exitCode !== 0 || numstat.lossy) return undefined\r\n const summary = parseDiffNumstat(numstat.stdout)\r\n const patch = await run(this.#runtime, git, [...await diffFuncnameArgs(), 'diff', '--no-ext-diff', '--no-color', '--unified=3', base, '--'], cwd, GIT_TIMEOUT_MS, MAX_DIFF_BYTES)\r\n if (patch.exitCode !== 0) return { ...summary, truncated: true }\r\n const untracked = await this.#untrackedDiff(cwd, git, signal)\r\n const combinedPatch = `${patch.stdout}${untracked.patch}`\r\n return {\r\n additions: summary.additions + untracked.additions,\r\n deletions: summary.deletions,\r\n files: summary.files + untracked.files,\r\n ...(patch.lossy ? {} : { patch: combinedPatch.slice(0, MAX_DIFF_BYTES) }),\r\n truncated: patch.lossy || untracked.truncated || combinedPatch.length > MAX_DIFF_BYTES,\r\n }\r\n } catch {\r\n return undefined\r\n }\r\n }\r\n\r\n async #untrackedDiff(cwd: string, git: string, signal?: AbortSignal): Promise<{ additions: number; files: number; patch: string; truncated: boolean }> {\r\n const listed = await run(this.#runtime, git, ['ls-files', '--others', '--exclude-standard', '-z'], cwd, GIT_TIMEOUT_MS)\r\n if (listed.exitCode !== 0 || listed.lossy) return { additions: 0, files: 0, patch: '', truncated: listed.lossy }\r\n const paths = listed.stdout.split('\\0').filter(path => path.length > 0)\r\n let additions = 0\r\n let patch = ''\r\n let truncated = paths.length > MAX_UNTRACKED_DIFFS\r\n for (const path of paths.slice(0, MAX_UNTRACKED_DIFFS)) {\r\n // The caller is gone or the route budget elapsed: stop spawning.\r\n if (signal?.aborted === true) return { additions, files: paths.length, patch, truncated: true }\r\n const result = await run(this.#runtime, git, [\r\n 'diff', '--no-ext-diff', '--no-color', '--unified=3', '--numstat', '--patch', '--no-index', '--', '/dev/null', path,\r\n ], cwd, GIT_TIMEOUT_MS, MAX_DIFF_BYTES)\r\n if (result.exitCode !== 0 && result.exitCode !== 1) {\r\n truncated = true\r\n continue\r\n }\r\n const start = result.stdout.indexOf('diff --git ')\r\n additions += parseDiffNumstat(start >= 0 ? result.stdout.slice(0, start) : result.stdout).additions\r\n if (result.lossy) truncated = true\r\n else if (start >= 0) patch += result.stdout.slice(start)\r\n }\r\n return { additions, files: paths.length, patch, truncated }\r\n }\r\n\r\n async #pullRequest(cwd: string, repository: string, branch: string): Promise<RepositoryPullRequestStatus | undefined> {\r\n const gh = await this.#gh()\r\n if (gh === undefined) return undefined\r\n try {\r\n const result = await run(this.#runtime, gh, [\r\n 'pr', 'view', branch,\r\n '--repo', repository,\r\n '--json', 'number,title,url,state,isDraft,reviewDecision,mergeStateStatus,mergedAt,statusCheckRollup,author,createdAt,baseRefName',\r\n ], cwd, GH_TIMEOUT_MS)\r\n if (result.exitCode !== 0) return undefined\r\n return parsePullRequest(JSON.parse(result.stdout))\r\n } catch {\r\n return undefined\r\n }\r\n }\r\n}\r\n","/** Name a generated worktree branch after what the user is about to ask for.\r\n *\r\n * The composer draft is the only description of the work that exists before\r\n * the session starts, and it is usually not English and never branch-safe, so\r\n * a throwaway Haiku turn compresses it into a slug. Naming is a nicety: every\r\n * failure here returns `undefined` and the caller keeps its timestamped name. */\r\nimport { query as claudeQuery, type Options as ClaudeOptions, type Query } from '@anthropic-ai/claude-agent-sdk'\r\n\r\n/** Cheapest model that can translate and compress a sentence. */\r\nexport const BRANCH_SUMMARY_MODEL = 'haiku'\r\n\r\n/** A branch name is not worth blocking worktree creation on for long. */\r\nexport const BRANCH_SUMMARY_TIMEOUT_MS = 15_000\r\n\r\nconst MAX_INTENT_CHARS = 2_000\r\n/** A compliant reply is one short fragment; anything longer is prose. */\r\nconst MAX_REPLY_CHARS = 80\r\n/** More words than this is a sentence, not the fragment we asked for. */\r\nconst MAX_SLUG_WORDS = 6\r\nconst MAX_SLUG_CHARS = 48\r\n\r\nexport function branchSummaryPrompt(intent: string): string {\r\n return [\r\n 'Summarize this software task as a Git branch name fragment.',\r\n 'Reply with 2-5 lowercase English words joined by hyphens and nothing else:',\r\n 'no quotes, no slashes, no prefix, no punctuation, no explanation.',\r\n 'Translate the task to English if it is written in another language.',\r\n '',\r\n 'Task:',\r\n `\"\"\"\\n${intent.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`,\r\n ].join('\\n')\r\n}\r\n\r\n/** Branch-safe slug for a model reply, or `undefined` when the reply is not\r\n * the fragment we asked for. Mangling a refusal or a paragraph into a slug\r\n * would produce a worse name than the timestamped fallback. */\r\nexport function branchSlug(reply: string): string | undefined {\r\n const line = reply.trim()\r\n if (line.length === 0 || line.length > MAX_REPLY_CHARS || /[\\r\\n]/u.test(line)) return undefined\r\n const words = line.toLocaleLowerCase('en-US')\r\n .replace(/[^a-z0-9]+/gu, '-')\r\n .split('-')\r\n .filter(word => word.length > 0)\r\n if (words.length === 0 || words.length > MAX_SLUG_WORDS) return undefined\r\n // ponytail: a long fragment is cut mid-word; six short words almost never\r\n // reach 48 characters, and a branch name is allowed to be blunt.\r\n const slug = words.join('-').slice(0, MAX_SLUG_CHARS).replace(/-+$/u, '')\r\n return slug.length === 0 ? undefined : slug\r\n}\r\n\r\n/** First free name in `<candidate>`, `<candidate>-2`, `<candidate>-3`, … */\r\nexport function uniqueBranchName(candidate: string, taken: readonly string[]): string {\r\n const existing = new Set(taken)\r\n if (!existing.has(candidate)) return candidate\r\n for (let index = 2; index < 100; index += 1) {\r\n const name = `${candidate}-${index}`\r\n if (!existing.has(name)) return name\r\n }\r\n return candidate\r\n}\r\n\r\n/** Compress a composer draft into a branch slug with a throwaway Claude turn.\r\n *\r\n * Deliberately NOT routed through the supervisor, for the same reasons as the\r\n * plan-usage probe: there is no session to borrow yet. The turn is isolated\r\n * from filesystem settings as well, because a CLAUDE.md instruction (\"always\r\n * reply in the user's language\") turns the answer into an unusable slug. */\r\nexport async function summarizeBranchSlug(\r\n executablePath: string,\r\n intent: string,\r\n factory: (params: { prompt: string; options: ClaudeOptions }) => Query = claudeQuery,\r\n): Promise<string | undefined> {\r\n const task = intent.trim().slice(0, MAX_INTENT_CHARS)\r\n if (task.length === 0) return undefined\r\n const lifetime = new AbortController()\r\n const timer = setTimeout(() => lifetime.abort(), BRANCH_SUMMARY_TIMEOUT_MS)\r\n timer.unref?.()\r\n try {\r\n const query = factory({\r\n prompt: branchSummaryPrompt(task),\r\n options: {\r\n cwd: process.cwd(),\r\n abortController: lifetime,\r\n model: BRANCH_SUMMARY_MODEL,\r\n allowedTools: [],\r\n settingSources: [],\r\n maxTurns: 1,\r\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\r\n },\r\n })\r\n for await (const message of query) {\r\n if (message.type === 'result' && message.subtype === 'success') return branchSlug(message.result)\r\n }\r\n return undefined\r\n } catch {\r\n return undefined\r\n } finally {\r\n clearTimeout(timer)\r\n lifetime.abort()\r\n }\r\n}\r\n","import { randomUUID } from 'node:crypto'\r\nimport { mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises'\r\nimport { basename, isAbsolute, join, resolve } from 'node:path'\r\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\r\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\nimport { uniqueBranchName } from './branch-name.ts'\r\n\r\nconst MAX_OUTPUT_BYTES = 128 * 1024\r\nconst GIT_TIMEOUT_MS = 10_000\r\nconst GIT_FETCH_TIMEOUT_MS = 60_000\r\nconst MAX_PATH_CHARS = 4_096\r\nconst MAX_BRANCH_CHARS = 512\r\nconst LEASE_SCHEMA_VERSION = 1\r\n// ponytail: grace only needs to outlive the worktree-create -> workspace-register\r\n// hop (seconds); two minutes keeps deletion feeling prompt while staying safe.\r\nconst CLEANUP_GRACE_MS = 2 * 60_000\r\n\r\ntype RepositorySetupRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\r\n\r\ninterface CommandResult {\r\n readonly exitCode: number | null\r\n readonly stdout: string\r\n readonly stderr: string\r\n readonly lossy: boolean\r\n}\r\n\r\nexport interface RepositoryBranchList {\r\n readonly root: string\r\n readonly current?: string\r\n readonly dirty: boolean\r\n readonly branches: readonly string[]\r\n readonly remoteBranches: readonly string[]\r\n}\r\n\r\nexport type RepositorySetupStage = 'inspecting' | 'fetching' | 'summarizing' | 'creating-worktree' | 'saving-worktree' | 'switching-branch'\r\nexport type RepositorySetupProgress = (stage: RepositorySetupStage) => void\r\n\r\nexport interface RepositorySetupResult {\r\n readonly mode: 'checkout' | 'worktree'\r\n readonly root: string\r\n readonly path: string\r\n readonly branch: string\r\n readonly leaseId?: string\r\n}\r\n\r\nexport interface RepositoryCleanupResult {\r\n readonly mode: 'checkout' | 'worktree'\r\n readonly root: string\r\n readonly branch: string\r\n}\r\n\r\ninterface WorktreeLease {\r\n readonly id: string\r\n readonly root: string\r\n readonly path: string\r\n readonly branch: string\r\n readonly createdAt: string\r\n readonly pluginGeneratedBranch: boolean\r\n readonly sessionId?: string\r\n}\r\n\r\ninterface LeaseDocument {\r\n readonly schemaVersion: typeof LEASE_SCHEMA_VERSION\r\n readonly leases: readonly WorktreeLease[]\r\n}\r\n\r\nexport interface RepositorySetupServiceOptions {\r\n readonly leasePath?: string\r\n readonly worktreeRoot?: string\r\n readonly branchPrefix?: () => Promise<string>\r\n readonly cleanupGraceMs?: number\r\n /** Compress the composer draft into a branch slug; `undefined` result (or an\r\n * omitted option) falls back to the timestamped name. */\r\n readonly summarizeBranch?: (intent: string) => Promise<string | undefined>\r\n}\r\n\r\nexport class RepositorySetupError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'RepositorySetupError'\r\n this.code = code\r\n }\r\n}\r\n\r\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\r\n const outcome = await handle.done\r\n const stdout = handle.collected.stdout?.readFrom(0)\r\n const stderr = handle.collected.stderr?.readFrom(0)\r\n return {\r\n exitCode: outcome.exitCode,\r\n stdout: stdout?.text ?? '',\r\n stderr: stderr?.text ?? '',\r\n lossy: stdout?.lossy === true || stderr?.lossy === true,\r\n }\r\n}\r\n\r\nfunction safePath(value: string): string {\r\n if (value.length === 0 || value.length > MAX_PATH_CHARS || !isAbsolute(value) || value.includes('\\0')) {\r\n throw new RepositorySetupError('invalid-path', 'The workspace path is invalid.')\r\n }\r\n return resolve(value)\r\n}\r\n\r\nfunction safeBranch(value: string): string {\r\n if (value.length === 0 || value.length > MAX_BRANCH_CHARS || value.trim() !== value || /[\\0\\r\\n]/u.test(value)) {\r\n throw new RepositorySetupError('invalid-branch', 'The branch name is invalid.')\r\n }\r\n return value\r\n}\r\n\r\nfunction parseCurrentBranch(value: string): string | undefined {\r\n const branch = value.trim()\r\n return branch.length === 0 || branch === 'HEAD' ? undefined : branch\r\n}\r\n\r\nexport function parseWorktreeBranches(value: string): ReadonlyMap<string, string> {\r\n const occupied = new Map<string, string>()\r\n let path: string | undefined\r\n for (const line of `${value}\\n`.split(/\\r?\\n/u)) {\r\n if (line.startsWith('worktree ')) path = line.slice('worktree '.length)\r\n else if (line.startsWith('branch refs/heads/') && path !== undefined) {\r\n occupied.set(line.slice('branch refs/heads/'.length), path)\r\n } else if (line.length === 0) path = undefined\r\n }\r\n return occupied\r\n}\r\n\r\nfunction slug(value: string, fallback: string): string {\r\n const normalized = value.toLocaleLowerCase('en-US').replace(/[^a-z0-9._-]+/gu, '-').replace(/^-+|-+$/gu, '')\r\n return normalized.slice(0, 48) || fallback\r\n}\r\n\r\n/** A branch name as one path segment: `/` and anything else unsafe folds to\r\n * `-`, case is kept so a ticket key stays scannable (`PSOS-5683`, not\r\n * `psos-5683`). Flattened rather than nested on purpose -- see\r\n * {@link worktreeDirectoryName}. */\r\nfunction branchSegment(branch: string): string {\r\n const flattened = branch.replace(/[^A-Za-z0-9._-]+/gu, '-').replace(/^[-.]+/u, '').replace(/-+$/u, '')\r\n return flattened.slice(0, 48).replace(/-+$/u, '') || 'branch'\r\n}\r\n\r\n/** Name a worktree directory after the repository and the branch it holds, so\r\n * the workspace list reads without opening a session.\r\n *\r\n * One flat segment, never a `feature/x` subdirectory: the orphan sweep lists\r\n * this root one level deep, and a prefix directory holds no lease of its own,\r\n * so it would be removed along with every live worktree inside it. */\r\nexport function worktreeDirectoryName(root: string, branch: string): string {\r\n return `${slug(basename(root), 'repository')}-${branchSegment(branch)}`\r\n}\r\n\r\n/** Comparable form for path identity: resolved, forward slashes, case-folded\r\n * so Windows drive-letter or case spelling differences cannot hide a match. */\r\nexport function comparablePath(value: string): string {\r\n return resolve(value).replaceAll('\\\\', '/').toLocaleLowerCase('en-US')\r\n}\r\n\r\nfunction pathExists(value: string): Promise<boolean> {\r\n return stat(value).then(() => true, () => false)\r\n}\r\n\r\nfunction lease(value: unknown): WorktreeLease | undefined {\r\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\r\n const input = value as Record<string, unknown>\r\n if (typeof input.id !== 'string' || typeof input.root !== 'string' || typeof input.path !== 'string'\r\n || typeof input.branch !== 'string' || typeof input.createdAt !== 'string'\r\n || (input.pluginGeneratedBranch !== undefined && typeof input.pluginGeneratedBranch !== 'boolean')\r\n || (input.sessionId !== undefined && typeof input.sessionId !== 'string')) return undefined\r\n return {\r\n id: input.id,\r\n root: input.root,\r\n path: input.path,\r\n branch: input.branch,\r\n createdAt: input.createdAt,\r\n pluginGeneratedBranch: input.pluginGeneratedBranch === true,\r\n ...(input.sessionId === undefined ? {} : { sessionId: input.sessionId }),\r\n }\r\n}\r\n\r\nexport class RepositorySetupService {\r\n readonly #runtime: RepositorySetupRuntime\r\n readonly #leasePath: string\r\n readonly #worktreeRoot: string\r\n readonly #branchPrefix: () => Promise<string>\r\n readonly #summarizeBranch: (intent: string) => Promise<string | undefined>\r\n readonly #cleanupGraceMs: number\r\n #gitPath: Promise<string> | undefined\r\n #pending: Promise<unknown> = Promise.resolve()\r\n\r\n constructor(runtime: RepositorySetupRuntime, options: RepositorySetupServiceOptions = {}) {\r\n this.#runtime = runtime\r\n this.#leasePath = options.leasePath ?? dshHomePath('plugins', 'dsh-claude', 'worktrees.json')\r\n this.#worktreeRoot = options.worktreeRoot ?? dshHomePath('plugins', 'dsh-claude', 'worktrees')\r\n this.#branchPrefix = options.branchPrefix ?? (async () => 'claude')\r\n this.#summarizeBranch = options.summarizeBranch ?? (async () => undefined)\r\n this.#cleanupGraceMs = options.cleanupGraceMs ?? CLEANUP_GRACE_MS\r\n }\r\n\r\n async listBranches(cwd: string): Promise<RepositoryBranchList> {\r\n const git = await this.#git()\r\n return this.#listBranches(git, await this.#repositoryRoot(git, safePath(cwd)))\r\n }\r\n\r\n /** Refresh remote-tracking refs before listing: a branch pushed after this\r\n * checkout last fetched has no local ref, so the picker cannot offer it. */\r\n async refreshBranches(cwd: string): Promise<RepositoryBranchList> {\r\n const git = await this.#git()\r\n const root = await this.#repositoryRoot(git, safePath(cwd))\r\n await this.#fetchRemotes(git, root)\r\n return this.#listBranches(git, root)\r\n }\r\n\r\n async #listBranches(git: string, root: string): Promise<RepositoryBranchList> {\r\n const [status, refs, remoteRefs] = await Promise.all([\r\n this.#run(git, ['status', '--porcelain=v2', '--branch', '--untracked-files=normal'], root),\r\n this.#run(git, ['for-each-ref', '--format=%(refname:short)', 'refs/heads'], root),\r\n this.#run(git, ['for-each-ref', '--format=%(refname:short) %(symref)', 'refs/remotes'], root),\r\n ])\r\n if (status.exitCode !== 0 || status.lossy || refs.exitCode !== 0 || refs.lossy\r\n || remoteRefs.exitCode !== 0 || remoteRefs.lossy) {\r\n throw new RepositorySetupError('repository-unavailable', 'The repository state is unavailable.')\r\n }\r\n const current = status.stdout.split(/\\r?\\n/u)\r\n .find(line => line.startsWith('# branch.head '))\r\n ?.slice('# branch.head '.length)\r\n const branches = refs.stdout.split(/\\r?\\n/u).filter(Boolean).sort((left, right) => left.localeCompare(right))\r\n const remoteBranches = remoteRefs.stdout.split(/\\r?\\n/u)\r\n .map(line => line.trim().split(/\\s+/u))\r\n .filter(parts => parts[0] !== undefined && parts[0].length > 0 && parts.length === 1)\r\n .map(parts => parts[0]!)\r\n .sort((left, right) => left.localeCompare(right))\r\n const currentBranch = current === undefined ? undefined : parseCurrentBranch(current)\r\n return {\r\n root,\r\n ...(currentBranch === undefined ? {} : { current: currentBranch }),\r\n dirty: status.stdout.split(/\\r?\\n/u).some(line => line.length > 0 && !line.startsWith('# ')),\r\n branches,\r\n remoteBranches,\r\n }\r\n }\r\n\r\n async setup(\r\n cwd: string,\r\n branchValue: string,\r\n useWorktree: boolean,\r\n explicitBranchName?: string,\r\n progress: RepositorySetupProgress = () => {},\r\n intent?: string,\r\n ): Promise<RepositorySetupResult> {\r\n progress('inspecting')\r\n const branch = safeBranch(branchValue)\r\n const info = await this.listBranches(cwd)\r\n const local = info.branches.includes(branch)\r\n const remote = info.remoteBranches.includes(branch)\r\n if (!local && !remote) {\r\n throw new RepositorySetupError('branch-not-found', 'The selected local or remote-tracking branch does not exist.')\r\n }\r\n const requestedBranch = explicitBranchName === undefined ? undefined : safeBranch(explicitBranchName)\r\n if (useWorktree) {\r\n return this.#createWorktree(\r\n info,\r\n branch,\r\n local ? `refs/heads/${branch}` : `refs/remotes/${branch}`,\r\n requestedBranch,\r\n requestedBranch !== undefined && info.branches.includes(requestedBranch),\r\n progress,\r\n intent,\r\n )\r\n }\r\n progress('switching-branch')\r\n return !local && remote ? this.#checkoutRemote(info, branch) : this.#checkout(info, branch)\r\n }\r\n\r\n /** Tear down a merged branch: remove a plugin worktree (and its lease and\r\n * branch), or switch a plain checkout back to the base branch and delete\r\n * the merged branch. Refuses dirty trees. */\r\n async cleanupMerged(pathValue: string, baseBranch: string): Promise<RepositoryCleanupResult> {\r\n const path = safePath(pathValue)\r\n const base = safeBranch(baseBranch)\r\n const git = await this.#git()\r\n const status = await this.#run(git, ['status', '--porcelain=v1', '--untracked-files=normal'], path)\r\n if (status.exitCode !== 0 || status.lossy) throw new RepositorySetupError('repository-unavailable', 'The repository state is unavailable.')\r\n if (status.stdout.trim().length > 0) throw new RepositorySetupError('dirty-workspace', 'Commit or stash workspace changes before cleaning up.')\r\n const lease = (await this.#readLeases()).find(item => comparablePath(item.path) === comparablePath(path))\r\n if (lease !== undefined) {\r\n return this.#serialize(async () => {\r\n const removed = await this.#run(git, ['worktree', 'remove', '--', lease.path], lease.root)\r\n if (removed.exitCode !== 0) throw new RepositorySetupError('worktree-remove-failed', 'Git could not remove the worktree.')\r\n await this.#run(git, ['branch', '-D', '--', lease.branch], lease.root).catch(() => undefined)\r\n const current = await this.#readLeases()\r\n await this.#writeLeases(current.filter(item => item.id !== lease.id))\r\n return { mode: 'worktree' as const, root: lease.root, branch: lease.branch }\r\n })\r\n }\r\n const root = await this.#repositoryRoot(git, path)\r\n const head = await this.#run(git, ['symbolic-ref', '--quiet', '--short', 'HEAD'], root)\r\n const branch = head.exitCode === 0 ? head.stdout.trim() : ''\r\n if (branch.length === 0 || branch === base) throw new RepositorySetupError('nothing-to-clean', 'The checkout is already on the base branch.')\r\n const switched = await this.#run(git, ['switch', '--', base], root)\r\n if (switched.exitCode !== 0) throw new RepositorySetupError('checkout-failed', 'Git could not switch to the base branch.')\r\n await this.#run(git, ['branch', '-D', '--', branch], root).catch(() => undefined)\r\n await this.#run(git, ['pull', '--ff-only'], root, GIT_FETCH_TIMEOUT_MS).catch(() => undefined)\r\n return { mode: 'checkout', root, branch }\r\n }\r\n\r\n bindLease(leaseId: string, sessionId: string): Promise<void> {\r\n if (leaseId.length === 0 || leaseId.length > 128 || sessionId.length === 0 || sessionId.length > 1_024) {\r\n return Promise.reject(new RepositorySetupError('invalid-lease', 'The worktree lease is invalid.'))\r\n }\r\n return this.#serialize(async () => {\r\n const leases = await this.#readLeases()\r\n const index = leases.findIndex(item => item.id === leaseId)\r\n if (index < 0) throw new RepositorySetupError('lease-not-found', 'The worktree lease no longer exists.')\r\n const existing = leases[index]\r\n if (existing === undefined) throw new RepositorySetupError('lease-not-found', 'The worktree lease no longer exists.')\r\n leases[index] = { ...existing, sessionId }\r\n await this.#writeLeases(leases)\r\n })\r\n }\r\n\r\n /** Reconcile leases against the set of directories still referenced by a\r\n * workspace. Deleting a workspace is the user saying they are done with it,\r\n * so an unreferenced worktree goes even with uncommitted changes; its\r\n * sessions are archived first, through `archiveSessions`, or the Host\r\n * rebuilds the deleted workspace from their headers on the next boot.\r\n * Fresh leases are retained for a grace period so a worktree created\r\n * moments ago cannot be swept before its workspace registration lands.\r\n *\r\n * Every command runs from the repository root, never from the worktree\r\n * being removed: spawning in a directory that is already gone throws\r\n * ENOENT, which used to strand the lease forever. */\r\n cleanupOrphans(\r\n activePaths: readonly string[],\r\n archiveSessions?: (worktreePath: string) => Promise<void>,\r\n ): Promise<void> {\r\n const active = new Set(activePaths.map(comparablePath))\r\n return this.#serialize(async () => {\r\n const leases = await this.#readLeases()\r\n const retained: WorktreeLease[] = []\r\n let changed = false\r\n const git = await this.#git()\r\n const now = Date.now()\r\n for (const item of leases) {\r\n const age = now - Date.parse(item.createdAt)\r\n if (active.has(comparablePath(item.path)) || !(age >= this.#cleanupGraceMs)) {\r\n retained.push(item)\r\n continue\r\n }\r\n try {\r\n // Best effort: a Host that cannot archive must not strand the lease,\r\n // and the worktree removal below is what the user asked for.\r\n await archiveSessions?.(item.path).catch(() => undefined)\r\n if (await pathExists(item.path)) {\r\n const removed = await this.#run(git, ['worktree', 'remove', '--force', '--', item.path], item.root)\r\n if (removed.exitCode !== 0) {\r\n retained.push(item)\r\n continue\r\n }\r\n } else {\r\n // The directory is already gone; let Git forget the stale\r\n // worktree registration before the lease follows it.\r\n await this.#run(git, ['worktree', 'prune'], item.root).catch(() => undefined)\r\n }\r\n if (item.pluginGeneratedBranch) {\r\n await this.#run(git, ['branch', '-D', '--', item.branch], item.root).catch(() => undefined)\r\n }\r\n changed = true\r\n } catch {\r\n if (await pathExists(item.root)) retained.push(item)\r\n else changed = true // the repository itself is gone; the lease is dead weight\r\n }\r\n }\r\n if (changed) await this.#writeLeases(retained)\r\n await this.#removeUnleasedDirectories(retained, active, now, archiveSessions)\r\n })\r\n }\r\n\r\n /** Remove directories under the plugin's own worktree root that no lease and\r\n * no workspace claims. A lease file lost to a crash, or a worktree whose\r\n * lease write failed, otherwise leaves a directory nothing will ever sweep.\r\n * The grace period covers the gap between `worktree add` and the lease\r\n * write, so a worktree being created right now is never taken. */\r\n async #removeUnleasedDirectories(\r\n retained: readonly WorktreeLease[],\r\n active: ReadonlySet<string>,\r\n now: number,\r\n archiveSessions?: (worktreePath: string) => Promise<void>,\r\n ): Promise<void> {\r\n const leased = new Set(retained.map(item => comparablePath(item.path)))\r\n let entries: string[]\r\n try {\r\n entries = await readdir(this.#worktreeRoot)\r\n } catch {\r\n return // no worktree root yet, or it is unreadable; nothing to sweep\r\n }\r\n for (const entry of entries) {\r\n const path = join(this.#worktreeRoot, entry)\r\n const key = comparablePath(path)\r\n if (leased.has(key) || active.has(key)) continue\r\n try {\r\n const info = await stat(path)\r\n if (!info.isDirectory()) continue\r\n const created = info.birthtimeMs > 0 ? info.birthtimeMs : info.mtimeMs\r\n // Date.now() truncates to whole milliseconds while birthtime carries a\r\n // fraction, so a directory created moments ago can read as newer than\r\n // the clock; clamp rather than let that skip a sweep.\r\n if (Math.max(0, now - created) < this.#cleanupGraceMs) continue\r\n // A lost lease is still the user's deleted workspace: its sessions\r\n // have to be archived here too, or the Host rebuilds the workspace\r\n // from their headers on the next boot.\r\n await archiveSessions?.(path).catch(() => undefined)\r\n await rm(path, { recursive: true, force: true })\r\n } catch {\r\n // A directory that vanished under us, or one we may not remove; the\r\n // next pass sees it again.\r\n }\r\n }\r\n }\r\n\r\n async #checkoutRemote(info: RepositoryBranchList, remoteBranch: string): Promise<RepositorySetupResult> {\r\n const separator = remoteBranch.indexOf('/')\r\n if (separator <= 0 || separator === remoteBranch.length - 1) {\r\n throw new RepositorySetupError('invalid-branch', 'The remote-tracking branch name is invalid.')\r\n }\r\n const localBranch = safeBranch(remoteBranch.slice(separator + 1))\r\n if (info.branches.includes(localBranch)) {\r\n const git = await this.#git()\r\n const upstream = await this.#run(git, ['for-each-ref', '--format=%(upstream:short)', `refs/heads/${localBranch}`], info.root)\r\n if (upstream.exitCode !== 0 || upstream.lossy) {\r\n throw new RepositorySetupError('repository-unavailable', 'The local branch tracking state is unavailable.')\r\n }\r\n if (upstream.stdout.trim() !== remoteBranch) {\r\n throw new RepositorySetupError('branch-tracking-conflict', `The local branch ${localBranch} does not track ${remoteBranch}.`)\r\n }\r\n return this.#checkout(info, localBranch)\r\n }\r\n if (info.dirty) throw new RepositorySetupError('dirty-workspace', 'Commit or stash workspace changes before switching branches.')\r\n const git = await this.#git()\r\n const switched = await this.#run(git, ['switch', '--track', '-c', localBranch, `refs/remotes/${remoteBranch}`], info.root)\r\n if (switched.exitCode !== 0) throw new RepositorySetupError('checkout-failed', 'Git could not create the local tracking branch.')\r\n return { mode: 'checkout', root: info.root, path: info.root, branch: localBranch }\r\n }\r\n\r\n async #fetchRemotes(git: string, root: string): Promise<void> {\r\n const fetched = await this.#run(\r\n git,\r\n ['-c', 'credential.interactive=never', 'fetch', '--all', '--prune'],\r\n root,\r\n GIT_FETCH_TIMEOUT_MS,\r\n )\r\n if (fetched.exitCode !== 0 || fetched.lossy) {\r\n throw new RepositorySetupError('fetch-failed', 'Git could not refresh remote references.')\r\n }\r\n }\r\n\r\n /** The remote-tracking ref a local base branch follows, when that ref still\r\n * exists. Falls back to the local branch for a branch with no upstream. */\r\n async #upstreamRef(git: string, info: RepositoryBranchList, branch: string): Promise<string | undefined> {\r\n const upstream = await this.#run(git, ['for-each-ref', '--format=%(upstream:short)', `refs/heads/${branch}`], info.root)\r\n if (upstream.exitCode !== 0 || upstream.lossy) return undefined\r\n const name = upstream.stdout.trim()\r\n return name.length > 0 && info.remoteBranches.includes(name) ? `refs/remotes/${name}` : undefined\r\n }\r\n\r\n async #checkout(info: RepositoryBranchList, branch: string): Promise<RepositorySetupResult> {\r\n if (info.current !== branch) {\r\n if (info.dirty) throw new RepositorySetupError('dirty-workspace', 'Commit or stash workspace changes before switching branches.')\r\n const git = await this.#git()\r\n const worktrees = await this.#run(git, ['worktree', 'list', '--porcelain'], info.root)\r\n if (worktrees.exitCode !== 0 || worktrees.lossy) throw new RepositorySetupError('repository-unavailable', 'Worktree state is unavailable.')\r\n const occupiedPath = parseWorktreeBranches(worktrees.stdout).get(branch)\r\n if (occupiedPath !== undefined && resolve(occupiedPath) !== info.root) {\r\n throw new RepositorySetupError('branch-occupied', 'The selected branch is already checked out in another worktree.')\r\n }\r\n const switched = await this.#run(git, ['switch', '--', branch], info.root)\r\n if (switched.exitCode !== 0) throw new RepositorySetupError('checkout-failed', 'Git could not switch to the selected branch.')\r\n }\r\n return { mode: 'checkout', root: info.root, path: info.root, branch }\r\n }\r\n\r\n async #createWorktree(\r\n info: RepositoryBranchList,\r\n baseBranch: string,\r\n baseRef: string,\r\n explicitBranchName: string | undefined,\r\n reuseExistingBranch: boolean,\r\n progress: RepositorySetupProgress,\r\n intent: string | undefined,\r\n ): Promise<RepositorySetupResult> {\r\n const { root } = info\r\n const git = await this.#git()\r\n progress('fetching')\r\n await this.#fetchRemotes(git, root)\r\n // A fresh worktree is meant to start from the remote tip the fetch just\r\n // refreshed, not from whatever the local base branch last pulled.\r\n const startRef = reuseExistingBranch ? baseRef : (await this.#upstreamRef(git, info, baseBranch)) ?? baseRef\r\n const suffix = randomUUID().slice(0, 8)\r\n const stamp = new Date().toISOString().replace(/[-:]/gu, '').replace(/\\.\\d{3}Z$/u, 'Z')\r\n const branch = explicitBranchName ?? await this.#generatedBranch(info, baseBranch, intent, stamp, suffix, progress)\r\n const path = join(this.#worktreeRoot, await this.#freeDirectoryName(root, branch))\r\n progress('creating-worktree')\r\n await mkdir(this.#worktreeRoot, { recursive: true })\r\n // A stale registration from a deleted worktree directory would keep the\r\n // existing branch \"checked out\" and block reusing it.\r\n if (reuseExistingBranch) await this.#run(git, ['worktree', 'prune'], root).catch(() => undefined)\r\n const created = await this.#run(\r\n git,\r\n reuseExistingBranch ? ['worktree', 'add', '--', path, branch] : ['worktree', 'add', '-b', branch, path, startRef],\r\n root,\r\n )\r\n if (created.exitCode !== 0) {\r\n const detail = created.stderr.split(/\\r?\\n/u).map(line => line.trim()).filter(line => line.length > 0).at(-1)\r\n throw new RepositorySetupError('worktree-failed', detail === undefined ? 'Git could not create the worktree.' : `Git could not create the worktree: ${detail}`)\r\n }\r\n const item: WorktreeLease = {\r\n id: randomUUID(),\r\n root,\r\n path,\r\n branch,\r\n createdAt: new Date().toISOString(),\r\n pluginGeneratedBranch: explicitBranchName === undefined,\r\n }\r\n progress('saving-worktree')\r\n try {\r\n await this.#serialize(async () => {\r\n const leases = await this.#readLeases()\r\n await this.#writeLeases([...leases, item])\r\n })\r\n } catch (error) {\r\n await this.#run(git, ['worktree', 'remove', '--force', '--', path], root).catch(() => undefined)\r\n if (!reuseExistingBranch) await this.#run(git, ['branch', '-D', '--', branch], root).catch(() => undefined)\r\n throw error\r\n }\r\n return { mode: 'worktree', root, path, branch, leaseId: item.id }\r\n }\r\n\r\n /** `<prefix>/<what the draft is about>`, falling back to\r\n * `<prefix>/<base branch>-<stamp>-<random>` whenever the summary is missing\r\n * or unusable. The prefix and the fallback shape are unchanged. */\r\n /** The branch-named directory, or the first `-2`, `-3`, ... spelling free of\r\n * anything already on disk. Names no longer carry a timestamp, so a stale\r\n * directory a crash left behind -- or two branches that fold to the same\r\n * segment -- would otherwise fail `worktree add` outright. Compared\r\n * case-folded, since a case-insensitive filesystem would collide anyway. */\r\n async #freeDirectoryName(root: string, branch: string): Promise<string> {\r\n const base = worktreeDirectoryName(root, branch)\r\n const taken = await readdir(this.#worktreeRoot).then(\r\n entries => new Set(entries.map(entry => entry.toLocaleLowerCase('en-US'))),\r\n () => new Set<string>(),\r\n )\r\n if (!taken.has(base.toLocaleLowerCase('en-US'))) return base\r\n for (let index = 2; index < 100; index += 1) {\r\n const candidate = `${base}-${index}`\r\n if (!taken.has(candidate.toLocaleLowerCase('en-US'))) return candidate\r\n }\r\n return base\r\n }\r\n\r\n async #generatedBranch(\r\n info: RepositoryBranchList,\r\n baseBranch: string,\r\n intent: string | undefined,\r\n stamp: string,\r\n suffix: string,\r\n progress: RepositorySetupProgress,\r\n ): Promise<string> {\r\n const prefix = safeBranch(await this.#branchPrefix())\r\n if (intent !== undefined && intent.trim().length > 0) {\r\n progress('summarizing')\r\n // The summary is a convenience, never a reason to fail the worktree.\r\n const summary = await this.#summarizeBranch(intent).catch(() => undefined)\r\n if (summary !== undefined) return uniqueBranchName(`${prefix}/${summary}`, info.branches)\r\n }\r\n return `${prefix}/${slug(baseBranch, 'branch')}-${stamp}-${suffix}`\r\n }\r\n\r\n async #repositoryRoot(git: string, cwd: string): Promise<string> {\r\n const result = await this.#run(git, ['rev-parse', '--path-format=absolute', '--show-toplevel'], cwd)\r\n const root = result.stdout.trim()\r\n if (result.exitCode !== 0 || result.lossy || root.length === 0 || !isAbsolute(root)) {\r\n throw new RepositorySetupError('not-repository', 'The workspace is not a Git repository.')\r\n }\r\n return resolve(root)\r\n }\r\n\r\n #git(): Promise<string> {\r\n // A cached pending or rejected lookup would wedge every later request, so\r\n // bound it and drop the cache on failure.\r\n this.#gitPath ??= this.#runtime.resolveExecutable('git', undefined, AbortSignal.timeout(GIT_TIMEOUT_MS))\r\n .catch((error: unknown) => {\r\n this.#gitPath = undefined\r\n throw error\r\n })\r\n return this.#gitPath\r\n }\r\n\r\n\r\n async #run(executable: string, args: readonly string[], cwd: string, timeoutMs = GIT_TIMEOUT_MS): Promise<CommandResult> {\r\n return collect(this.#runtime.spawn({\r\n argv: [executable, ...args],\r\n cwd,\r\n stdio: {\r\n stdin: 'ignore',\r\n stdout: { maxBytes: MAX_OUTPUT_BYTES },\r\n stderr: { maxBytes: MAX_OUTPUT_BYTES },\r\n },\r\n graceMs: 1_000,\r\n signal: AbortSignal.timeout(timeoutMs),\r\n env: {},\r\n }))\r\n }\r\n\r\n async #readLeases(): Promise<WorktreeLease[]> {\r\n try {\r\n const parsed = JSON.parse(await readFile(this.#leasePath, 'utf8')) as unknown\r\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return []\r\n const input = parsed as Record<string, unknown>\r\n if (input.schemaVersion !== LEASE_SCHEMA_VERSION || !Array.isArray(input.leases)) return []\r\n return input.leases.map(lease).filter((item): item is WorktreeLease => item !== undefined)\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return []\r\n throw error\r\n }\r\n }\r\n\r\n async #writeLeases(leases: readonly WorktreeLease[]): Promise<void> {\r\n await mkdir(resolve(this.#leasePath, '..'), { recursive: true })\r\n const temporary = `${this.#leasePath}.${process.pid}.${randomUUID()}.tmp`\r\n const document: LeaseDocument = { schemaVersion: LEASE_SCHEMA_VERSION, leases }\r\n try {\r\n await writeFile(temporary, `${JSON.stringify(document, null, 2)}\\n`, { mode: 0o600 })\r\n await rename(temporary, this.#leasePath)\r\n } finally {\r\n await rm(temporary, { force: true }).catch(() => undefined)\r\n }\r\n }\r\n\r\n #serialize<T>(operation: () => Promise<T>): Promise<T> {\r\n const result = this.#pending.then(operation, operation)\r\n this.#pending = result.then(() => undefined, () => undefined)\r\n return result\r\n }\r\n}\r\n","import { createHash } from 'node:crypto'\r\nimport { basename } from 'node:path'\r\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\nimport { diffFuncnameArgs } from './diff-funcname.ts'\r\nimport { detectRepositoryOperation } from './repository-status.ts'\r\n\r\nconst MAX_OUTPUT_BYTES = 256 * 1024\r\nconst MAX_PATCH_CHARS = 64 * 1024\r\nconst MAX_MESSAGE_CHARS = 512\r\nconst MAX_PR_TEXT_CHARS = 8 * 1024\r\nconst MAX_UNPUSHED_COMMITS = 20\r\nconst GIT_TIMEOUT_MS = 15_000\r\nconst REMOTE_TIMEOUT_MS = 60_000\r\nconst GENERATE_TIMEOUT_MS = 60_000\r\n/** One cold `claude -p` per generation, so everything the subject line cannot\r\n * use is cost: MCP servers (which `ask` already skips for the same reason,\r\n * and which stall for as long as an unreachable one takes to give up) and the\r\n * user's own hooks and settings. Project settings stay: a repository's commit\r\n * conventions belong in the message. `--tools ''` keeps `--output-format`\r\n * between it and the prompt -- both flags are variadic. */\r\nconst GENERATE_ARGUMENTS: readonly string[] = [\r\n '-p',\r\n '--strict-mcp-config', '--mcp-config', '{\"mcpServers\":{}}',\r\n '--setting-sources', 'project,local',\r\n '--tools', '', '--output-format', 'text',\r\n]\r\n\r\ntype RepositoryActionRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\r\nexport type RepositoryActionKind = 'commit' | 'commit-push' | 'push' | 'create-pr' | 'merge-pr' | 'update-branch' | 'resolve-continue' | 'resolve-abort'\r\nexport type RepositoryMergeMethod = 'merge' | 'squash' | 'rebase'\r\n\r\ninterface CommandResult {\r\n readonly exitCode: number | null\r\n readonly stdout: string\r\n readonly stderr: string\r\n readonly lossy: boolean\r\n}\r\n\r\nexport interface RepositoryActionFile {\r\n readonly path: string\r\n readonly staged: boolean\r\n readonly unstaged: boolean\r\n readonly untracked: boolean\r\n}\r\n\r\nexport interface RepositoryActionCommit {\r\n readonly hash: string\r\n readonly subject: string\r\n}\r\n\r\nexport interface RepositoryActionPreview {\r\n readonly root: string\r\n readonly branch: string\r\n readonly head: string\r\n readonly fingerprint: string\r\n readonly files: readonly RepositoryActionFile[]\r\n readonly patch: string\r\n readonly truncated: boolean\r\n readonly hasStaged: boolean\r\n readonly hasUnstaged: boolean\r\n readonly hasUntracked: boolean\r\n readonly upstream?: string\r\n readonly unpushedCommits: readonly RepositoryActionCommit[]\r\n readonly unpushedTruncated: boolean\r\n}\r\n\r\nexport interface RepositoryActionRequest {\r\n readonly action: RepositoryActionKind\r\n readonly fingerprint: string\r\n readonly message: string\r\n readonly includeUnstaged: boolean\r\n readonly prTitle?: string\r\n readonly prBody?: string\r\n readonly baseBranch?: string\r\n readonly draft?: boolean\r\n readonly mergeMethod?: RepositoryMergeMethod\r\n /** Push once `resolve-continue` finishes the operation it resumed. */\r\n readonly push?: boolean\r\n}\r\n\r\nexport interface RepositoryActionResult {\r\n readonly commit: string\r\n readonly pushed: boolean\r\n readonly pullRequestUrl?: string\r\n /** Conflicted paths left in the working tree by an update-branch merge or\r\n * rebase, or by the commit a resumed one stopped on next. */\r\n readonly conflicts?: readonly string[]\r\n}\r\n\r\nexport class RepositoryActionError extends Error {\r\n readonly code: string\r\n readonly commit?: string\r\n\r\n constructor(code: string, message: string, commit?: string) {\r\n super(message)\r\n this.name = 'RepositoryActionError'\r\n this.code = code\r\n if (commit !== undefined) this.commit = commit\r\n }\r\n}\r\n\r\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\r\n const outcome = await handle.done\r\n const stdout = handle.collected.stdout?.readFrom(0)\r\n const stderr = handle.collected.stderr?.readFrom(0)\r\n return {\r\n exitCode: outcome.exitCode,\r\n stdout: stdout?.text ?? '',\r\n stderr: stderr?.text ?? '',\r\n lossy: stdout?.lossy === true || stderr?.lossy === true,\r\n }\r\n}\r\n\r\nfunction safeText(value: string, maximum: number, label: string): string {\r\n const text = value.trim()\r\n if (text.length === 0 || text.length > maximum || /[\\0\\r]/u.test(text)) {\r\n throw new RepositoryActionError('invalid-request', `${label} is invalid.`)\r\n }\r\n return text\r\n}\r\n\r\nexport function isProtectedWarpPath(path: string): boolean {\r\n return basename(path.replaceAll('\\\\', '/')).toLocaleLowerCase('en-US') === 'warp.md'\r\n}\r\n\r\nexport function parseRepositoryActionStatus(output: string): readonly RepositoryActionFile[] {\r\n const files = new Map<string, RepositoryActionFile>()\r\n const records = output.includes('\\0') ? output.split('\\0') : output.split(/\\r?\\n/u)\r\n for (let position = 0; position < records.length; position += 1) {\r\n const line = records[position] ?? ''\r\n if (line.length < 4) continue\r\n const index = line[0] ?? ' '\r\n const worktree = line[1] ?? ' '\r\n let path = line.slice(3)\r\n const rename = path.lastIndexOf(' -> ')\r\n if (rename >= 0) path = path.slice(rename + 4)\r\n if (output.includes('\\0') && (index === 'R' || index === 'C' || worktree === 'R' || worktree === 'C')) position += 1\r\n if (path.length === 0 || path.includes('\\0') || isProtectedWarpPath(path)) continue\r\n files.set(path, {\r\n path,\r\n staged: index !== ' ' && index !== '?',\r\n unstaged: worktree !== ' ' && worktree !== '?',\r\n untracked: index === '?' && worktree === '?',\r\n })\r\n }\r\n return [...files.values()].sort((left, right) => left.path.localeCompare(right.path))\r\n}\r\n\r\nfunction conflictPaths(result: CommandResult): readonly string[] {\r\n if (result.exitCode !== 0 || result.lossy) return []\r\n return result.stdout.split(/\\r?\\n/u).filter(line => line.length > 0).slice(0, 100)\r\n}\r\n\r\nfunction fallbackCommitMessage(files: readonly RepositoryActionFile[]): string {\r\n if (files.length === 1) return `Update ${files[0]?.path ?? 'repository files'}`\r\n return `Update ${files.length} repository files`\r\n}\r\n\r\nfunction normalizedGeneratedMessage(value: string, fallback: string): string {\r\n const first = value.split(/\\r?\\n/u).map(line => line.trim()).find(Boolean)\r\n if (first === undefined) return fallback\r\n const message = first.replace(/^['\"`]+|['\"`]+$/gu, '').replace(/[\\0\\r\\n]/gu, ' ').trim()\r\n return message.length === 0 || message.length > 72 ? fallback : message\r\n}\r\n\r\nfunction validPrUrl(value: string): string | undefined {\r\n try {\r\n const url = new URL(value.trim())\r\n return url.protocol === 'https:' && url.hostname === 'github.com' ? url.href : undefined\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n\r\nexport function validPullRequestBody(value: string): boolean {\r\n const body = value.trim()\r\n const match = /^Summary:\\s+([^\\r\\n]+)\\r?\\n\\r?\\nChanges:\\s*\\r?\\n([\\s\\S]+)$/u.exec(body)\r\n const summary = match?.[1]?.trim()\r\n const changes = match?.[2]?.trim()\r\n if (summary === undefined || summary.length === 0 || changes === undefined || changes.length === 0) return false\r\n return !/^#{1,6}\\s|^[A-Za-z][A-Za-z ]+:\\s*$/mu.test(changes)\r\n}\r\n\r\nexport class RepositoryActionService {\r\n readonly #runtime: RepositoryActionRuntime\r\n readonly #claudeExecutable: string\r\n readonly #invalidate: (cwd: string) => void\r\n #gitExecutable?: Promise<string>\r\n #ghExecutable?: Promise<string>\r\n #pending: Promise<unknown> = Promise.resolve()\r\n\r\n constructor(runtime: RepositoryActionRuntime, claudeExecutable: string, invalidate: (cwd: string) => void = () => {}) {\r\n this.#runtime = runtime\r\n this.#claudeExecutable = claudeExecutable\r\n this.#invalidate = invalidate\r\n }\r\n\r\n preview(cwd: string): Promise<RepositoryActionPreview> {\r\n return this.#preview(cwd)\r\n }\r\n\r\n async generateMessage(cwd: string, fingerprint: string): Promise<string> {\r\n const preview = await this.#preview(cwd)\r\n if (preview.fingerprint !== fingerprint) throw new RepositoryActionError('repository-changed', 'Repository changes have changed. Refresh the commit panel.')\r\n const fallback = fallbackCommitMessage(preview.files)\r\n const prompt = [\r\n 'Write one concise English git commit subject (imperative mood, maximum 72 characters).',\r\n 'Return only the subject without quotes, markdown, body, or explanation.',\r\n `Files: ${preview.files.map(file => file.path).join(', ')}`,\r\n `Diff:\\n${preview.patch.slice(0, 24 * 1024)}`,\r\n ].join('\\n')\r\n try {\r\n const result = await this.#run(this.#claudeExecutable, GENERATE_ARGUMENTS.concat(prompt), preview.root, GENERATE_TIMEOUT_MS)\r\n return result.exitCode === 0 && !result.lossy ? normalizedGeneratedMessage(result.stdout, fallback) : fallback\r\n } catch {\r\n return fallback\r\n }\r\n }\r\n\r\n execute(cwd: string, request: RepositoryActionRequest): Promise<RepositoryActionResult> {\r\n const operation = this.#pending.then(() => this.#execute(cwd, request))\r\n this.#pending = operation.then(() => undefined, () => undefined)\r\n return operation\r\n }\r\n\r\n async #execute(cwd: string, request: RepositoryActionRequest): Promise<RepositoryActionResult> {\r\n // A stopped rebase leaves a detached HEAD and an unmerged tree, which the\r\n // preview refuses outright -- so resuming one has to run before it.\r\n if (request.action === 'resolve-continue' || request.action === 'resolve-abort') return this.#resolve(cwd, request.action, request.push === true)\r\n const before = await this.#preview(cwd)\r\n if (before.fingerprint !== request.fingerprint) throw new RepositoryActionError('repository-changed', 'Repository changes have changed. Refresh the commit panel.')\r\n if (request.action === 'push') {\r\n const git = await this.#git()\r\n try {\r\n await this.#push(git, before.root, before.branch)\r\n } catch (error) {\r\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.')\r\n }\r\n this.#invalidate(before.root)\r\n return { commit: before.head, pushed: true }\r\n }\r\n if (request.action === 'merge-pr') {\r\n const method = request.mergeMethod\r\n if (method !== 'merge' && method !== 'squash' && method !== 'rebase') {\r\n throw new RepositoryActionError('invalid-request', 'The merge method is invalid.')\r\n }\r\n let gh: string\r\n try {\r\n gh = await this.#gh()\r\n } catch (error) {\r\n throw new RepositoryActionError('gh-unavailable', error instanceof Error ? error.message : 'GitHub CLI is unavailable.')\r\n }\r\n const merged = await this.#run(gh, ['pr', 'merge', `--${method}`], before.root, REMOTE_TIMEOUT_MS)\r\n if (merged.exitCode !== 0 || merged.lossy) {\r\n const reason = merged.stderr.split(/\\r?\\n/u).map(line => line.trim()).filter(line => line.length > 0).at(-1)\r\n throw new RepositoryActionError('merge-failed', reason === undefined || reason.length === 0 ? 'The pull request could not be merged.' : reason)\r\n }\r\n this.#invalidate(before.root)\r\n return { commit: before.head, pushed: true }\r\n }\r\n if (request.action === 'update-branch') {\r\n const base = safeText(request.baseBranch ?? '', 512, 'Base branch')\r\n if (before.files.length > 0) {\r\n throw new RepositoryActionError('dirty-workspace', 'Commit or stash workspace changes before updating the branch.')\r\n }\r\n const method = request.mergeMethod ?? 'rebase'\r\n if (method !== 'merge' && method !== 'rebase') throw new RepositoryActionError('invalid-request', 'Update branch supports merge or rebase.')\r\n const git = await this.#git()\r\n await this.#mustRun(git, ['fetch', 'origin', '--', base], before.root, REMOTE_TIMEOUT_MS, 'fetch-failed', 'Git could not fetch the base branch.')\r\n const merged = await this.#run(git, method === 'rebase' ? ['rebase', '--', `origin/${base}`] : ['merge', '--no-edit', '--', `origin/${base}`], before.root, REMOTE_TIMEOUT_MS)\r\n if (merged.exitCode !== 0 || merged.lossy) {\r\n const conflicts = conflictPaths(await this.#run(git, ['diff', '--name-only', '--diff-filter=U', '--'], before.root, GIT_TIMEOUT_MS))\r\n if (conflicts.length === 0) {\r\n await this.#run(git, [method, '--abort'], before.root, GIT_TIMEOUT_MS).catch(() => undefined)\r\n throw new RepositoryActionError('merge-failed', `Git could not ${method} the base branch.`)\r\n }\r\n // Leave the conflicted tree in place: resolving it is the next step.\r\n this.#invalidate(before.root)\r\n return { commit: before.head, pushed: false, conflicts }\r\n }\r\n const mergedHead = (await this.#mustRun(git, ['rev-parse', 'HEAD'], before.root, GIT_TIMEOUT_MS, 'merge-failed', 'The updated commit could not be verified.')).stdout.trim()\r\n try {\r\n // A rebase rewrites the branch, so the push must replace the remote ref; --force-with-lease still refuses if someone else pushed.\r\n await this.#push(git, before.root, before.branch, method === 'rebase')\r\n } catch (error) {\r\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.', mergedHead)\r\n }\r\n this.#invalidate(before.root)\r\n return { commit: mergedHead, pushed: true }\r\n }\r\n const message = safeText(request.message, MAX_MESSAGE_CHARS, 'Commit message')\r\n if (before.files.length === 0 && request.action !== 'create-pr') {\r\n throw new RepositoryActionError('nothing-to-commit', 'There are no changes to commit.')\r\n }\r\n const git = await this.#git()\r\n let oid = before.head\r\n if (before.files.length > 0) {\r\n await this.#rejectStagedWarp(git, before.root)\r\n if (request.includeUnstaged) {\r\n const paths = before.files.filter(file => file.unstaged || file.untracked).map(file => file.path)\r\n if (paths.length > 0) await this.#mustRun(git, ['add', '--', ...paths], before.root, GIT_TIMEOUT_MS, 'stage-failed', 'Changes could not be staged.')\r\n }\r\n await this.#rejectStagedWarp(git, before.root)\r\n const staged = await this.#run(git, ['diff', '--cached', '--quiet', '--exit-code', '--'], before.root, GIT_TIMEOUT_MS)\r\n if (staged.exitCode === 0) throw new RepositoryActionError('nothing-to-commit', 'There are no staged changes to commit.')\r\n if (staged.exitCode !== 1) throw new RepositoryActionError('repository-unavailable', 'The staged changes could not be verified.')\r\n await this.#mustRun(git, ['commit', '-m', message, '--'], before.root, GIT_TIMEOUT_MS, 'commit-failed', 'Git commit failed.')\r\n oid = (await this.#mustRun(git, ['rev-parse', 'HEAD'], before.root, GIT_TIMEOUT_MS, 'commit-failed', 'The new commit could not be verified.')).stdout.trim()\r\n this.#invalidate(before.root)\r\n if (request.action === 'commit') return { commit: oid, pushed: false }\r\n }\r\n try {\r\n await this.#push(git, before.root, before.branch)\r\n } catch (error) {\r\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.', oid)\r\n }\r\n this.#invalidate(before.root)\r\n if (request.action === 'commit-push') return { commit: oid, pushed: true }\r\n const title = safeText(request.prTitle ?? message, 256, 'Pull request title')\r\n const body = safeText(request.prBody ?? '', MAX_PR_TEXT_CHARS, 'Pull request description')\r\n if (!validPullRequestBody(body)) {\r\n throw new RepositoryActionError('invalid-pr-description', 'Pull request description must contain only Summary and Changes sections.', oid)\r\n }\r\n let gh: string\r\n try {\r\n gh = await this.#gh()\r\n } catch (error) {\r\n throw new RepositoryActionError('gh-unavailable', error instanceof Error ? error.message : 'GitHub CLI is unavailable.', oid)\r\n }\r\n const args = ['pr', 'create', '--title', title, '--body', body]\r\n if (request.draft !== false) args.push('--draft')\r\n if (request.baseBranch !== undefined) args.push('--base', safeText(request.baseBranch, 512, 'Base branch'))\r\n const created = await this.#run(gh, args, before.root, REMOTE_TIMEOUT_MS)\r\n const url = created.exitCode === 0 && !created.lossy ? validPrUrl(created.stdout) : undefined\r\n if (url === undefined) throw new RepositoryActionError('pr-failed', 'The pull request could not be created.', oid)\r\n return { commit: oid, pushed: true, pullRequestUrl: url }\r\n }\r\n\r\n /** Finishes or discards the merge, rebase, cherry-pick or revert git is\r\n * waiting on. The operation is read from the git dir rather than taken from\r\n * the caller: `--continue` and `--abort` are only safe against the one that\r\n * is actually in progress. */\r\n async #resolve(cwd: string, action: 'resolve-continue' | 'resolve-abort', push: boolean): Promise<RepositoryActionResult> {\r\n const git = await this.#git()\r\n const paths = await this.#mustRun(git, ['rev-parse', '--path-format=absolute', '--show-toplevel', '--absolute-git-dir'], cwd, GIT_TIMEOUT_MS, 'not-repository', 'The session directory is not a Git repository.')\r\n const [rootValue, gitDirValue] = paths.stdout.split(/\\r?\\n/u)\r\n const root = (rootValue ?? '').trim()\r\n const gitDir = (gitDirValue ?? '').trim()\r\n if (root.length === 0 || gitDir.length === 0) throw new RepositoryActionError('repository-unavailable', 'Repository state is unavailable.')\r\n const state = await detectRepositoryOperation(gitDir)\r\n if (state === undefined) throw new RepositoryActionError('no-operation', 'No merge, rebase, cherry-pick or revert is in progress.')\r\n const operation = state.operation\r\n if (action === 'resolve-abort') {\r\n await this.#mustRun(git, [operation, '--abort'], root, GIT_TIMEOUT_MS, 'abort-failed', `Git could not abort the ${operation}.`)\r\n this.#invalidate(root)\r\n return { commit: await this.#head(git, root), pushed: false }\r\n }\r\n const unmerged = conflictPaths(await this.#run(git, ['diff', '--name-only', '--diff-filter=U', '--'], root, GIT_TIMEOUT_MS))\r\n if (unmerged.length > 0) throw new RepositoryActionError('unresolved-conflicts', 'Resolve and stage every conflicted file before continuing.')\r\n // `core.editor=true` accepts the prepared message: nothing here can host an\r\n // editor, and a rebase that opens one would hang until the timeout.\r\n const continued = await this.#run(git, ['-c', 'core.editor=true', operation, '--continue'], root, REMOTE_TIMEOUT_MS)\r\n this.#invalidate(root)\r\n if (continued.exitCode !== 0 || continued.lossy) {\r\n // A rebase replays commit by commit, so the next one can stop on its own\r\n // conflicts: that is progress, not a failure, and it keeps the panel open.\r\n const next = conflictPaths(await this.#run(git, ['diff', '--name-only', '--diff-filter=U', '--'], root, GIT_TIMEOUT_MS))\r\n if (next.length > 0) return { commit: await this.#head(git, root), pushed: false, conflicts: next }\r\n const reason = continued.stderr.split(/\\r?\\n/u).map(line => line.trim()).filter(line => line.length > 0).at(-1)\r\n throw new RepositoryActionError('continue-failed', reason === undefined || reason.length === 0 ? `Git could not continue the ${operation}.` : reason)\r\n }\r\n const head = await this.#head(git, root)\r\n if (!push) return { commit: head, pushed: false }\r\n const branch = await this.#run(git, ['symbolic-ref', '--quiet', '--short', 'HEAD'], root, GIT_TIMEOUT_MS)\r\n if (branch.exitCode !== 0 || branch.lossy) throw new RepositoryActionError('detached-head', 'The finished operation left a detached HEAD, so nothing was pushed.', head)\r\n try {\r\n // A rebase rewrote the branch, so its push has to replace the remote ref.\r\n await this.#push(git, root, branch.stdout.trim(), operation === 'rebase')\r\n } catch (error) {\r\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.', head)\r\n }\r\n this.#invalidate(root)\r\n return { commit: head, pushed: true }\r\n }\r\n\r\n async #head(git: string, root: string): Promise<string> {\r\n const head = await this.#run(git, ['rev-parse', 'HEAD'], root, GIT_TIMEOUT_MS)\r\n return head.exitCode === 0 && !head.lossy ? head.stdout.trim() : ''\r\n }\r\n\r\n async #preview(cwd: string): Promise<RepositoryActionPreview> {\r\n const git = await this.#git()\r\n const rootResult = await this.#mustRun(git, ['rev-parse', '--path-format=absolute', '--show-toplevel'], cwd, GIT_TIMEOUT_MS, 'not-repository', 'The session directory is not a Git repository.')\r\n const root = rootResult.stdout.trim()\r\n const funcname = await diffFuncnameArgs()\r\n const [branchResult, headResult, statusResult, stagedPatch, unstagedPatch] = await Promise.all([\r\n this.#run(git, ['symbolic-ref', '--quiet', '--short', 'HEAD'], root, GIT_TIMEOUT_MS),\r\n this.#run(git, ['rev-parse', 'HEAD'], root, GIT_TIMEOUT_MS),\r\n this.#run(git, ['status', '--porcelain=v1', '-z', '--untracked-files=all'], root, GIT_TIMEOUT_MS),\r\n this.#run(git, [...funcname, 'diff', '--cached', '--no-ext-diff', '--no-color', '--unified=3', '--', ':(exclude)WARP.md', ':(exclude)**/WARP.md'], root, GIT_TIMEOUT_MS, MAX_OUTPUT_BYTES),\r\n this.#run(git, [...funcname, 'diff', '--no-ext-diff', '--no-color', '--unified=3', '--', ':(exclude)WARP.md', ':(exclude)**/WARP.md'], root, GIT_TIMEOUT_MS, MAX_OUTPUT_BYTES),\r\n ])\r\n if (branchResult.exitCode !== 0) throw new RepositoryActionError('detached-head', 'A detached HEAD cannot be committed from this panel.')\r\n if (headResult.exitCode !== 0 || statusResult.exitCode !== 0 || statusResult.lossy) throw new RepositoryActionError('repository-unavailable', 'Repository state is unavailable.')\r\n const files = parseRepositoryActionStatus(statusResult.stdout)\r\n const patch = `${stagedPatch.stdout}${stagedPatch.stdout.length > 0 && unstagedPatch.stdout.length > 0 ? '\\n' : ''}${unstagedPatch.stdout}`.slice(0, MAX_PATCH_CHARS)\r\n const branch = branchResult.stdout.trim()\r\n const head = headResult.stdout.trim()\r\n const fingerprint = createHash('sha256').update([head, branch, statusResult.stdout, stagedPatch.stdout, unstagedPatch.stdout].join('\\0')).digest('hex')\r\n const upstreamResult = await this.#run(git, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'], root, GIT_TIMEOUT_MS)\r\n const upstream = upstreamResult.exitCode === 0 && !upstreamResult.lossy ? upstreamResult.stdout.trim() : undefined\r\n const logResult = await this.#run(git, [\r\n 'log', '--format=%H%x09%s', `-n`, String(MAX_UNPUSHED_COMMITS + 1), upstream === undefined ? 'HEAD' : '@{upstream}..HEAD', '--',\r\n ], root, GIT_TIMEOUT_MS)\r\n const commitLines = logResult.exitCode === 0 && !logResult.lossy\r\n ? logResult.stdout.split(/\\r?\\n/u).filter(line => line.includes('\\t'))\r\n : []\r\n const unpushedCommits = commitLines.slice(0, MAX_UNPUSHED_COMMITS).flatMap(line => {\r\n const tab = line.indexOf('\\t')\r\n const hash = line.slice(0, tab)\r\n return /^[0-9a-f]{40}$/iu.test(hash) ? [{ hash, subject: line.slice(tab + 1).slice(0, 140) }] : []\r\n })\r\n return {\r\n root,\r\n branch,\r\n head,\r\n fingerprint,\r\n files,\r\n patch,\r\n truncated: stagedPatch.lossy || unstagedPatch.lossy || stagedPatch.stdout.length + unstagedPatch.stdout.length > MAX_PATCH_CHARS,\r\n hasStaged: files.some(file => file.staged),\r\n hasUnstaged: files.some(file => file.unstaged),\r\n hasUntracked: files.some(file => file.untracked),\r\n ...(upstream === undefined ? {} : { upstream }),\r\n unpushedCommits,\r\n unpushedTruncated: commitLines.length > MAX_UNPUSHED_COMMITS,\r\n }\r\n }\r\n\r\n async #rejectStagedWarp(git: string, cwd: string): Promise<void> {\r\n const staged = await this.#run(git, ['diff', '--cached', '--name-only', '--'], cwd, GIT_TIMEOUT_MS)\r\n if (staged.exitCode !== 0 || staged.lossy) throw new RepositoryActionError('repository-unavailable', 'Staged files could not be verified.')\r\n if (staged.stdout.split(/\\r?\\n/u).some(path => path.length > 0 && isProtectedWarpPath(path))) {\r\n throw new RepositoryActionError('protected-warp-file', 'WARP.md files cannot be committed. Unstage them before continuing.')\r\n }\r\n }\r\n\r\n async #push(git: string, cwd: string, branch: string, forceWithLease = false): Promise<void> {\r\n const upstream = await this.#run(git, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'], cwd, GIT_TIMEOUT_MS)\r\n const args = upstream.exitCode === 0 ? ['push', ...(forceWithLease ? ['--force-with-lease'] : [])] : ['push', '--set-upstream', 'origin', branch]\r\n await this.#mustRun(git, args, cwd, REMOTE_TIMEOUT_MS, 'push-failed', 'Git push failed.')\r\n }\r\n\r\n #git(): Promise<string> {\r\n this.#gitExecutable ??= this.#runtime.resolveExecutable('git')\r\n return this.#gitExecutable\r\n }\r\n\r\n #gh(): Promise<string> {\r\n this.#ghExecutable ??= this.#runtime.resolveExecutable('gh').catch(() => { throw new RepositoryActionError('gh-unavailable', 'GitHub CLI is unavailable.') })\r\n return this.#ghExecutable\r\n }\r\n\r\n async #mustRun(executable: string, args: readonly string[], cwd: string, timeoutMs: number, code: string, message: string): Promise<CommandResult> {\r\n const result = await this.#run(executable, args, cwd, timeoutMs)\r\n if (result.exitCode !== 0 || result.lossy) throw new RepositoryActionError(code, message)\r\n return result\r\n }\r\n\r\n #run(executable: string, args: readonly string[], cwd: string, timeoutMs: number, maxBytes = MAX_OUTPUT_BYTES): Promise<CommandResult> {\r\n return collect(this.#runtime.spawn({\r\n argv: [executable, ...args],\r\n cwd,\r\n stdio: { stdin: 'ignore', stdout: { maxBytes }, stderr: { maxBytes: MAX_OUTPUT_BYTES } },\r\n graceMs: 1_000,\r\n signal: AbortSignal.timeout(timeoutMs),\r\n env: {},\r\n }))\r\n }\r\n}\r\n","import type { ServerResponse } from 'node:http'\r\nimport type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REPOSITORY_SETUP_PATH } from './constants.ts'\r\nimport { json, registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport {\r\n RepositorySetupError,\r\n type RepositorySetupResult,\r\n type RepositorySetupService,\r\n type RepositorySetupStage,\r\n} from './repository-setup.ts'\r\n\r\nconst MAX_BODY_BYTES = 16 * 1024\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n ? value as Record<string, unknown>\r\n : undefined\r\n}\r\n\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\r\n let parsed: unknown\r\n try {\r\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\r\n } catch (error) {\r\n if (error instanceof SyntaxError) throw error\r\n throw new RepositorySetupError('body-too-large', 'The request body is too large.')\r\n }\r\n const value = record(parsed)\r\n if (value === undefined) throw new RepositorySetupError('invalid-request', 'The request body is invalid.')\r\n return value\r\n}\r\n\r\nfunction string(input: Record<string, unknown>, key: string): string {\r\n const value = input[key]\r\n if (typeof value !== 'string') throw new RepositorySetupError('invalid-request', `The ${key} field is required.`)\r\n return value\r\n}\r\n\r\nfunction optionalString(input: Record<string, unknown>, key: string): string | undefined {\r\n const value = input[key]\r\n if (value === undefined) return undefined\r\n if (typeof value !== 'string') throw new RepositorySetupError('invalid-request', `The ${key} field must be a string.`)\r\n return value\r\n}\r\n\r\nfunction ndjsonHeaders(res: ServerResponse): void {\r\n res.writeHead(200, {\r\n 'content-type': 'application/x-ndjson; charset=utf-8',\r\n 'cache-control': 'no-store',\r\n 'x-content-type-options': 'nosniff',\r\n })\r\n res.flushHeaders?.()\r\n}\r\n\r\nfunction ndjson(res: ServerResponse, value: unknown): void {\r\n res.write(`${JSON.stringify(value)}\\n`)\r\n}\r\n\r\n// `RepositorySetupService.setup` takes no signal, so the route's disconnect\r\n// abort cannot reach the Git work it drives; the stream registration is still\r\n// what bounds how many of these may be live at once.\r\nasync function streamSetup(\r\n res: ServerResponse,\r\n service: RepositorySetupService,\r\n input: Record<string, unknown>,\r\n): Promise<void> {\r\n ndjsonHeaders(res)\r\n let ended = false\r\n try {\r\n const result: RepositorySetupResult = await service.setup(\r\n string(input, 'cwd'),\r\n string(input, 'branch'),\r\n input.worktree as boolean,\r\n optionalString(input, 'branchName'),\r\n (stage: RepositorySetupStage) => { if (!ended) ndjson(res, { type: 'progress', stage }) },\r\n optionalString(input, 'intent'),\r\n )\r\n ndjson(res, { type: 'complete', result })\r\n } catch (error) {\r\n const setupError = error instanceof RepositorySetupError ? error : undefined\r\n ndjson(res, {\r\n type: 'error',\r\n code: setupError?.code ?? 'repository-setup-unavailable',\r\n message: setupError?.message ?? 'Repository setup is unavailable.',\r\n })\r\n } finally {\r\n ended = true\r\n res.end()\r\n }\r\n}\r\n\r\n/** Register trusted browser routes for safe pre-session Git setup.\r\n *\r\n * The prefix is registered as a stream because the setup POST holds its\r\n * connection open for the whole worktree build; the short sibling paths ride\r\n * the same registration and answer with `json` before releasing it. */\r\nexport function registerRepositorySetupRoute(\r\n ctx: Context,\r\n service: RepositorySetupService,\r\n /** Kick the worktree/workspace reconciliation, when the Host exposes one. */\r\n sweep?: () => void,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'stream',\r\n kind: 'prefix',\r\n path: CLAUDE_REPOSITORY_SETUP_PATH,\r\n methods: ['GET', 'POST'],\r\n maxConcurrent: 2,\r\n // Only the branch paths name their checkout in the URL; the setup POST\r\n // carries it in the body, so it keys on its path alone and a reopen\r\n // supersedes the response it is replacing.\r\n streamKey: url => `${url.pathname}?${url.searchParams.get('cwd') ?? url.searchParams.get('branch') ?? ''}`,\r\n handler: async (res, io) => {\r\n const pathname = io.url.pathname\r\n try {\r\n // Not a GET: --prune rewrites this checkout's remote-tracking refs.\r\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/branches/refresh`) {\r\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\r\n const input = await readJson(io)\r\n return json(res, 200, await service.refreshBranches(string(input, 'cwd')))\r\n }\r\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/branches`) {\r\n if (io.method !== 'GET') return json(res, 405, { error: 'method not allowed' })\r\n const cwd = io.url.searchParams.get('cwd')\r\n if (cwd === null) throw new RepositorySetupError('invalid-request', 'The cwd query parameter is required.')\r\n return json(res, 200, await service.listBranches(cwd))\r\n }\r\n if (pathname === CLAUDE_REPOSITORY_SETUP_PATH) {\r\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\r\n const input = await readJson(io)\r\n if (typeof input.worktree !== 'boolean') throw new RepositorySetupError('invalid-request', 'The worktree field is required.')\r\n await streamSetup(res, service, input)\r\n return\r\n }\r\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/cleanup`) {\r\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\r\n const input = await readJson(io)\r\n return json(res, 200, await service.cleanupMerged(string(input, 'path'), string(input, 'baseBranch')))\r\n }\r\n // The Host's own workspace deletion publishes no server-side event, so\r\n // the Client kicks the sweep the moment a workspace leaves its list.\r\n // Carries no payload: the sweep re-reads the registry itself.\r\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/sweep`) {\r\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\r\n sweep?.()\r\n return json(res, 200, { ok: true })\r\n }\r\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/bind`) {\r\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\r\n const input = await readJson(io)\r\n await service.bindLease(string(input, 'leaseId'), string(input, 'sessionId'))\r\n return json(res, 200, { ok: true })\r\n }\r\n return json(res, 404, { error: 'not found' })\r\n } catch (error) {\r\n if (error instanceof RepositorySetupError) return json(res, 409, { error: error.code, message: error.message })\r\n if (error instanceof SyntaxError) return json(res, 400, { error: 'invalid json' })\r\n return json(res, 500, { error: 'repository setup unavailable' })\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REPOSITORY_ACTION_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport {\r\n RepositoryActionError,\r\n type RepositoryActionKind,\r\n type RepositoryActionRequest,\r\n type RepositoryMergeMethod,\r\n type RepositoryActionService,\r\n} from './repository-actions.ts'\r\n\r\nconst MAX_BODY_BYTES = 16 * 1024\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\nconst ACTIONS = new Set<RepositoryActionKind>(['commit', 'commit-push', 'push', 'create-pr', 'merge-pr', 'update-branch', 'resolve-continue', 'resolve-abort'])\r\n/** Actions that commit nothing of their own, so the panel sends no message. */\r\nconst MESSAGELESS = new Set<RepositoryActionKind>(['push', 'merge-pr', 'update-branch', 'resolve-continue', 'resolve-abort'])\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\r\n let parsed: unknown\r\n try {\r\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\r\n } catch (error) {\r\n // Malformed JSON keeps its own 400; the cap is the only other refusal the\r\n // transport raises, and the panel already knows that code.\r\n if (error instanceof SyntaxError) throw error\r\n throw new RepositoryActionError('body-too-large', 'The request body is too large.')\r\n }\r\n const value = record(parsed)\r\n if (value === undefined) throw new RepositoryActionError('invalid-request', 'The request body is invalid.')\r\n return value\r\n}\r\n\r\nfunction sessionId(url: URL): string {\r\n const value = url.searchParams.get('sessionId')\r\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) {\r\n throw new RepositoryActionError('invalid-session', 'The session is invalid.')\r\n }\r\n return value\r\n}\r\n\r\nfunction string(input: Record<string, unknown>, key: string): string {\r\n const value = input[key]\r\n if (typeof value !== 'string') throw new RepositoryActionError('invalid-request', `The ${key} field is required.`)\r\n return value\r\n}\r\n\r\nfunction optionalString(input: Record<string, unknown>, key: string): string | undefined {\r\n const value = input[key]\r\n if (value === undefined) return undefined\r\n if (typeof value !== 'string') throw new RepositoryActionError('invalid-request', `The ${key} field must be a string.`)\r\n return value\r\n}\r\n\r\nfunction actionRequest(input: Record<string, unknown>): RepositoryActionRequest {\r\n const action = input.action\r\n if (typeof action !== 'string' || !ACTIONS.has(action as RepositoryActionKind)\r\n || typeof input.includeUnstaged !== 'boolean') {\r\n throw new RepositoryActionError('invalid-request', 'The repository action is invalid.')\r\n }\r\n return {\r\n action: action as RepositoryActionKind,\r\n fingerprint: string(input, 'fingerprint'),\r\n message: MESSAGELESS.has(action as RepositoryActionKind) ? optionalString(input, 'message') ?? '' : string(input, 'message'),\r\n includeUnstaged: input.includeUnstaged,\r\n ...(optionalString(input, 'prTitle') === undefined ? {} : { prTitle: optionalString(input, 'prTitle')! }),\r\n ...(optionalString(input, 'prBody') === undefined ? {} : { prBody: optionalString(input, 'prBody')! }),\r\n ...(optionalString(input, 'baseBranch') === undefined ? {} : { baseBranch: optionalString(input, 'baseBranch')! }),\r\n ...(input.draft === undefined ? {} : typeof input.draft === 'boolean' ? { draft: input.draft } : (() => { throw new RepositoryActionError('invalid-request', 'The draft field must be a boolean.') })()),\r\n ...(input.push === undefined ? {} : typeof input.push === 'boolean' ? { push: input.push } : (() => { throw new RepositoryActionError('invalid-request', 'The push field must be a boolean.') })()),\r\n ...(input.mergeMethod === undefined\r\n ? {}\r\n : input.mergeMethod === 'merge' || input.mergeMethod === 'squash' || input.mergeMethod === 'rebase'\r\n ? { mergeMethod: input.mergeMethod as RepositoryMergeMethod }\r\n : (() => { throw new RepositoryActionError('invalid-request', 'The mergeMethod field is invalid.') })()),\r\n }\r\n}\r\n\r\n/** One prefix serves the local-Git preview and the POST arms that push, open\r\n * and merge pull requests, so the registration takes the wider of the two\r\n * budgets: a `remote` arm cut short at the `git` deadline would abandon work\r\n * that had already reached GitHub. */\r\nexport function registerRepositoryActionRoute(\r\n ctx: Context,\r\n service: RepositoryActionService,\r\n cwdForSession: (sessionId: string) => string | undefined,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'prefix',\r\n path: CLAUDE_REPOSITORY_ACTION_PATH,\r\n methods: ['GET', 'POST'],\r\n budget: 'remote',\r\n handler: async io => {\r\n const url = io.url\r\n try {\r\n const id = sessionId(url)\r\n const cwd = cwdForSession(id)\r\n if (cwd === undefined) throw new RepositoryActionError('session-unavailable', 'The Claude session is unavailable.')\r\n if (url.pathname === `${CLAUDE_REPOSITORY_ACTION_PATH}/preview`) {\r\n if (io.method !== 'GET') return { status: 405, value: { error: 'method not allowed' } }\r\n return { status: 200, value: await service.preview(cwd) }\r\n }\r\n if (url.pathname === `${CLAUDE_REPOSITORY_ACTION_PATH}/message`) {\r\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\r\n const input = await readJson(io)\r\n return { status: 200, value: { message: await service.generateMessage(cwd, string(input, 'fingerprint')) } }\r\n }\r\n if (url.pathname === CLAUDE_REPOSITORY_ACTION_PATH) {\r\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\r\n return { status: 200, value: await service.execute(cwd, actionRequest(await readJson(io))) }\r\n }\r\n return { status: 404, value: { error: 'not found' } }\r\n } catch (error) {\r\n if (error instanceof RepositoryActionError) {\r\n return {\r\n status: 409,\r\n value: {\r\n error: error.code,\r\n message: error.message,\r\n ...(error.commit === undefined ? {} : { commit: error.commit }),\r\n },\r\n }\r\n }\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 500, value: { error: 'repository-action-unavailable', message: 'Repository action is unavailable.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\n\r\nconst MAX_OUTPUT_BYTES = 8 * 1024\r\n/** Long enough for a launcher shim to fail loudly, short enough that the\r\n * request returns while the IDE is still booting. On Windows and Linux the\r\n * IDE binary IS the launched process, so still running past this is success. */\r\nconst SETTLE_MS = 1_500\r\n\r\nexport type EditorId = 'cursor' | 'idea'\r\nexport const EDITOR_IDS: ReadonlySet<string> = new Set<EditorId>(['cursor', 'idea'])\r\n\r\n/** Launch commands tried in order, first success wins. macOS keeps `open -a`\r\n * behind the CLI shim because both shims are opt-in installs there, while\r\n * `open -a` finds the bundle wherever Toolbox or the DMG dropped it. */\r\nconst LAUNCHERS: Record<EditorId, Partial<Record<NodeJS.Platform, readonly (readonly string[])[]>>> = {\r\n cursor: {\r\n darwin: [['cursor'], ['open', '-a', 'Cursor']],\r\n win32: [['cursor']],\r\n linux: [['cursor']],\r\n },\r\n idea: {\r\n darwin: [['idea'], ['open', '-a', 'IntelliJ IDEA'], ['open', '-a', 'IntelliJ IDEA CE']],\r\n win32: [['idea'], ['idea64.exe']],\r\n linux: [['idea'], ['idea.sh']],\r\n },\r\n}\r\n\r\n/** cmd.exe re-interprets these, and a mis-parsed path opens the wrong project\r\n * rather than failing. Refuse instead of guessing. */\r\nconst WINDOWS_UNSAFE = /[\"&|<>^%]/u\r\n\r\nexport class EditorOpenError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'EditorOpenError'\r\n this.code = code\r\n }\r\n}\r\n\r\n/** Open a session's working directory in a desktop editor. */\r\nexport class EditorOpenService {\r\n readonly #runtime: Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\r\n readonly #platform: NodeJS.Platform\r\n readonly #settleMs: number\r\n\r\n constructor(\r\n runtime: Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>,\r\n platform: NodeJS.Platform = process.platform,\r\n settleMs: number = SETTLE_MS,\r\n ) {\r\n this.#runtime = runtime\r\n this.#platform = platform\r\n this.#settleMs = settleMs\r\n }\r\n\r\n async open(cwd: string, editor: EditorId): Promise<void> {\r\n if (this.#platform === 'win32' && WINDOWS_UNSAFE.test(cwd)) {\r\n throw new EditorOpenError('unsupported-path', 'The project path cannot be opened through the Windows shell.')\r\n }\r\n const candidates = LAUNCHERS[editor][this.#platform] ?? LAUNCHERS[editor].linux ?? []\r\n let found = false\r\n for (const candidate of candidates) {\r\n const argv = await this.#argv(candidate, cwd)\r\n if (argv === undefined) continue\r\n found = true\r\n if (await this.#launch(argv, cwd)) return\r\n }\r\n throw found\r\n ? new EditorOpenError('launch-failed', 'The editor refused to open the project.')\r\n : new EditorOpenError('editor-unavailable', 'The editor was not found on PATH.')\r\n }\r\n\r\n async #argv(candidate: readonly string[], cwd: string): Promise<readonly string[] | undefined> {\r\n const [program, ...rest] = candidate\r\n if (program === undefined) return undefined\r\n // Windows launcher shims are `.cmd` files, which Node refuses to spawn\r\n // directly; cmd.exe runs those and plain `.exe` entries alike, and does\r\n // its own PATH/PATHEXT lookup — so no resolution step here.\r\n if (this.#platform === 'win32') return ['cmd.exe', '/d', '/s', '/c', program, ...rest, cwd]\r\n try {\r\n return [await this.#runtime.resolveExecutable(program), ...rest, cwd]\r\n } catch {\r\n return undefined\r\n }\r\n }\r\n\r\n /** True once the editor is launched: either the shim exited cleanly or the\r\n * process is still alive past the settle window. */\r\n async #launch(argv: readonly string[], cwd: string): Promise<boolean> {\r\n let handle: SubprocessHandle\r\n try {\r\n // No abort signal on purpose — the editor must outlive this request.\r\n // ponytail: on platforms whose launcher does not fork (idea64.exe) the\r\n // IDE stays a child of the host; detach if that ever orphans badly.\r\n handle = this.#runtime.spawn({\r\n argv,\r\n cwd,\r\n stdio: { stdin: 'ignore', stdout: { maxBytes: MAX_OUTPUT_BYTES }, stderr: { maxBytes: MAX_OUTPUT_BYTES } },\r\n graceMs: 1_000,\r\n env: {},\r\n })\r\n } catch {\r\n return false\r\n }\r\n return await Promise.race([\r\n handle.done.then(outcome => outcome.exitCode === 0),\r\n new Promise<boolean>(resolve => {\r\n const timer = setTimeout(() => resolve(true), this.#settleMs)\r\n timer.unref?.()\r\n }),\r\n ])\r\n }\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_EDITOR_OPEN_PATH } from './constants.ts'\r\nimport { registerPluginRoute } from './http.ts'\r\nimport { EDITOR_IDS, EditorOpenError, type EditorId, type EditorOpenService } from './editor-open.ts'\r\n\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\n\r\n/** Open the session's working directory in a desktop editor. Query-only: the\r\n * request carries two enum-ish values, so there is no body to parse. */\r\nexport function registerEditorOpenRoute(\r\n ctx: Context,\r\n service: Pick<EditorOpenService, 'open'>,\r\n cwdForSession: (sessionId: string) => string | undefined,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_EDITOR_OPEN_PATH,\r\n methods: ['POST'],\r\n budget: 'fast',\r\n handler: async io => {\r\n const params = io.url.searchParams\r\n const id = params.get('sessionId')\r\n const editor = params.get('editor')\r\n if (id === null || id.length === 0 || id.length > MAX_SESSION_ID_CHARS) {\r\n return { status: 400, value: { error: 'invalid-session', message: 'The session is invalid.' } }\r\n }\r\n if (editor === null || !EDITOR_IDS.has(editor)) {\r\n return { status: 400, value: { error: 'invalid-editor', message: 'The editor is invalid.' } }\r\n }\r\n const cwd = cwdForSession(id)\r\n if (cwd === undefined) return { status: 409, value: { error: 'session-unavailable', message: 'The Claude session is unavailable.' } }\r\n try {\r\n await service.open(cwd, editor as EditorId)\r\n return { status: 200, value: { opened: true } }\r\n } catch (error) {\r\n if (error instanceof EditorOpenError) return { status: 409, value: { error: error.code, message: error.message } }\r\n return { status: 500, value: { error: 'editor-open-unavailable', message: 'The editor could not be launched.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import { homedir } from 'node:os'\nimport { mkdir, opendir, readFile, writeFile } from 'node:fs/promises'\nimport { extname, join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { CLAUDE_PROMPTS_PATH, CLAUDE_PROMPT_NAME_PATH, CLAUDE_PROMPT_REFINE_PATH } from './constants.ts'\nimport { redactText } from './events.ts'\nimport { registerPluginRoute } from './http.ts'\n\n/** One prompt file as the composer menu sees it: the file name is the menu\n * row, the body is what lands in the composer verbatim. */\nexport interface ClaudePromptView {\n name: string\n description: string\n body: string\n /** Where the file sits, written for a human to read rather than to open:\n * the home directory collapses to `~`, so the confirmation that a prompt\n * was saved can name the file without spilling the whole absolute path. */\n location: string\n}\n\nconst MAX_PROMPT_FILES = 256\nconst MAX_PROMPT_BYTES = 16 * 1024\nconst MAX_DESCRIPTION_CHARS = 120\nconst MAX_REQUEST_BYTES = 32 * 1024\n\n/**\n * The same shape as the output-style name in `global-settings.ts`, plus\n * `\\p{M}` so a macOS-decomposed name survives. Two properties matter and both\n * are load-bearing: no member of the class is a path separator, and the first\n * character can be neither a dot nor a separator — so `join(dir, name + '.md')`\n * cannot address anything outside `dir`. Nothing else validates the path.\n */\nconst PROMPT_NAME = /^[\\p{L}\\p{N}][\\p{L}\\p{M}\\p{N} ._()\\[\\]-]{0,127}$/u\n\n/** Prompt snippets live beside the rest of the user's Claude Code state. */\nexport function claudePromptsDir(): string {\n return join(homedir(), '.claude', 'prompts')\n}\n\n/** `~/.claude/prompts/x.md` rather than the absolute path it expands to.\n * Windows joins with backslashes; the display form is the same on every OS. */\nexport function displayPath(file: string): string {\n const home = homedir()\n const separator = file.charAt(home.length)\n if (!file.startsWith(home) || (separator !== '/' && separator !== '\\\\')) return file\n return `~${file.slice(home.length).replaceAll('\\\\', '/')}`\n}\n\n/** The menu's second row: the first non-empty line, collapsed and bounded. */\nfunction summarize(body: string): string {\n const line = body.split('\\n').map(text => text.trim()).find(text => text.length > 0) ?? ''\n return redactText(line.replace(/\\s+/gu, ' '), MAX_DESCRIPTION_CHARS)\n}\n\n/**\n * Every `.md` file in the prompts directory, sorted by name.\n *\n * A missing directory is the ordinary state before the user saves anything,\n * and one unreadable file must not empty the whole menu — both answer with\n * what is there rather than throwing.\n */\nexport async function readClaudePrompts(directory: string): Promise<readonly ClaudePromptView[]> {\n const prompts: ClaudePromptView[] = []\n let entries\n try {\n entries = await opendir(directory)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return prompts\n throw error\n }\n for await (const entry of entries) {\n if (prompts.length >= MAX_PROMPT_FILES) break\n if (!entry.isFile() || extname(entry.name).toLowerCase() !== '.md') continue\n const name = entry.name.slice(0, -3)\n if (!PROMPT_NAME.test(name)) continue\n try {\n const file = join(directory, entry.name)\n const body = await readFile(file, 'utf8')\n if (body.trim().length === 0 || Buffer.byteLength(body) > MAX_PROMPT_BYTES) continue\n prompts.push({ name, description: summarize(body), body, location: displayPath(file) })\n } catch {\n // Ignore unreadable prompt files.\n }\n }\n return prompts.sort((left, right) => left.name.localeCompare(right.name))\n}\n\nexport type ClaudePromptWriteCode = 'invalid-name' | 'invalid-body' | 'name-taken'\n\nexport class ClaudePromptWriteError extends Error {\n readonly code: ClaudePromptWriteCode\n\n constructor(code: ClaudePromptWriteCode, message: string) {\n super(message)\n this.name = 'ClaudePromptWriteError'\n this.code = code\n }\n}\n\n/**\n * Save one prompt, refusing to clobber an existing file.\n *\n * `wx` is the whole collision policy: a name the user already uses is theirs\n * to resolve, and overwriting a prompt they keep is not something they can\n * undo from inside DSH.\n */\nexport async function writeClaudePrompt(directory: string, name: unknown, body: unknown): Promise<ClaudePromptView> {\n if (typeof name !== 'string' || !PROMPT_NAME.test(name)) {\n throw new ClaudePromptWriteError('invalid-name', 'The prompt name is invalid.')\n }\n if (typeof body !== 'string' || body.trim().length === 0 || Buffer.byteLength(body) > MAX_PROMPT_BYTES) {\n throw new ClaudePromptWriteError('invalid-body', 'The prompt text is empty or too large.')\n }\n const text = body.endsWith('\\n') ? body : `${body}\\n`\n const file = join(directory, `${name}.md`)\n await mkdir(directory, { recursive: true, mode: 0o700 })\n try {\n await writeFile(file, text, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n throw new ClaudePromptWriteError('name-taken', 'A prompt with that name already exists.')\n }\n throw error\n }\n return { name, description: summarize(text), body: text, location: displayPath(file) }\n}\n\n\nconst MAX_NAME_DRAFT_CHARS = 4_000\nconst MAX_NAME_OUTPUT_BYTES = 4 * 1024\nconst MAX_SUGGESTED_NAME_CHARS = 48\nconst MAX_REFINE_DRAFT_CHARS = 16_000\nconst MAX_REFINED_BYTES = 32 * 1024\nconst ASSIST_TIMEOUT_MS = 40_000\n\n/**\n * Ask for a file name and nothing else, with the draft fenced as data.\n *\n * Two things here were measured rather than guessed. The instruction travels\n * in the user turn, not in `--system-prompt`: a saved prompt is itself an\n * instruction and a system prompt does not outrank it, so the model reads the\n * draft as its task and answers it instead of naming it. And the default\n * system prompt is left in place even though it is large, because the CLI\n * sends it as a cache read (~6.5k cached tokens); replacing it with a short\n * one costs a fresh 3.5k-token prefill and measured slower end to end.\n *\n * The naming spec is this specific because a vaguer one (\"describe what the\n * template does, at most 40 characters\") produced names that were both\n * inconsistent in style and stripped of the detail that tells two similar\n * templates apart.\n */\nexport function promptNamePrompt(draft: string): string {\n const text = draft.trim().slice(0, MAX_NAME_DRAFT_CHARS)\n return [\n 'Below is a reusable prompt template a user is saving to a file. Name it.',\n '',\n `\"\"\"\\n${text.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`,\n '',\n 'Answer with the file name alone: no quotes, no explanation, no extension, no leading dot, no slashes.',\n 'Write it in English however the template is written, as lower-case words joined by hyphens.',\n 'Name the task the template performs, keeping whatever detail distinguishes it from a',\n 'similar template. At most 6 words.',\n ].join('\\n')\n}\n\n/**\n * Rewrite the draft into something an agent can act on, with the draft fenced\n * as data for the same reason the naming prompt fences it.\n *\n * The rule about people and places is not politeness. Asked to rewrite\n * \"后端 assign 给我\", the model reached into Claude Code's ambient system\n * prompt and substituted the operator's actual email address — inventing a\n * detail the original never carried, and putting a personal address into a\n * message the user had not written it into. Naming the failure explicitly is\n * what stopped it; stripping the ambient context with `--system-prompt` also\n * stopped it but cost a fresh prefill and produced looser rewrites.\n */\nexport function promptRefinePrompt(draft: string): string {\n const text = draft.trim().slice(0, MAX_REFINE_DRAFT_CHARS)\n return [\n 'Below is a prompt a user is about to send to a coding agent. Rewrite it so the agent can act on it without coming back with questions.',\n '',\n `\"\"\"\\n${text.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`,\n '',\n 'Keep the intent and every concrete detail exactly as given — names, paths, branches, identifiers, numbers.',\n 'Leave every reference to a person or place as the original wrote it (\"me\", \"我\", \"the usual branch\");',\n 'you do not know who or what they resolve to, and guessing puts a wrong name in the user\\'s message.',\n 'Do not invent requirements the original does not imply, do not answer the prompt, do not add a preamble or sign-off.',\n 'Write the rewrite in the same language the original is written in.',\n 'Reply with the rewritten prompt alone.',\n ].join('\\n')\n}\n\n/** One turn, no tools, no MCP: neither of these tasks needs them, and both\n * cost seconds of cold start. Variadic `--tools` stays last. */\nexport function promptAssistArguments(): readonly string[] {\n return [\n '-p', '--output-format', 'text',\n '--model', 'haiku',\n '--strict-mcp-config', '--mcp-config', '{\"mcpServers\":{}}',\n '--tools', '',\n ]\n}\n\n/** The rewrite in a model reply, or undefined when the reply is unusable.\n *\n * A model told to answer with the text alone still sometimes wraps it in a\n * markdown fence, so one is peeled off; anything else is the user's to read\n * and edit, and is passed through untouched. */\nexport function refinedPrompt(output: string): string | undefined {\n const trimmed = output.trim()\n const fenced = /^```[^\\n]*\\n([\\s\\S]*?)\\n?```$/u.exec(trimmed)\n const text = (fenced?.[1] ?? trimmed).trim()\n return text.length === 0 || Buffer.byteLength(text) > MAX_REFINED_BYTES ? undefined : text\n}\n\n/**\n * The usable name in a model reply, or undefined when there is none.\n *\n * A one-line answer is what the prompt asks for and usually what comes back,\n * but \"usually\" is not a contract: the reply is scrubbed to what a file name\n * may hold and then held to the same {@link PROMPT_NAME} guard the write path\n * uses, so a chatty or malformed answer is dropped rather than offered.\n */\nexport function suggestedName(output: string): string | undefined {\n const line = output.split('\\n').map(text => text.trim()).find(text => text.length > 0) ?? ''\n const bare = line.replace(/^[\"'`]+|[\"'`]+$/gu, '').replace(/\\.md$/iu, '')\n const scrubbed = wordBounded(bare\n .replace(/[^\\p{L}\\p{M}\\p{N} ._()\\[\\]-]/gu, ' ')\n .replace(/\\s+/gu, ' ')\n .trim())\n return PROMPT_NAME.test(scrubbed) ? scrubbed : undefined\n}\n\n/** Cut a long name at its last word boundary. A name the user has to repair\n * (\"analyze-frontend-backend-create-jira-tic\") is worse than a shorter one. */\nfunction wordBounded(name: string): string {\n if (name.length <= MAX_SUGGESTED_NAME_CHARS) return name\n const cut = name.slice(0, MAX_SUGGESTED_NAME_CHARS)\n const boundary = cut.search(/[\\s\\-_][^\\s\\-_]*$/u)\n return (boundary > 0 ? cut.slice(0, boundary) : cut).trim()\n}\n\n/** Runs Claude Code's cheapest model over the draft: names it, or rewrites it. */\nexport class PromptAssistService {\n readonly #runtime: Pick<SubprocessRuntime, 'spawn'>\n readonly #executablePath: () => string\n\n constructor(runtime: Pick<SubprocessRuntime, 'spawn'>, executablePath: () => string) {\n this.#runtime = runtime\n this.#executablePath = executablePath\n }\n\n /** One bounded, tool-less turn; undefined whenever it cannot be had. */\n async #ask(prompt: string, maxOutputBytes: number, signal?: AbortSignal): Promise<string | undefined> {\n const executablePath = this.#executablePath()\n if (executablePath.length === 0) return undefined\n const timeout = AbortSignal.timeout(ASSIST_TIMEOUT_MS)\n try {\n const handle = this.#runtime.spawn({\n argv: [executablePath, ...promptAssistArguments()],\n // Nowhere in particular: no tool can reach the file system, and a\n // project directory would only pull that project's CLAUDE.md in.\n cwd: homedir(),\n stdio: {\n stdin: { data: prompt },\n stdout: { maxBytes: maxOutputBytes },\n stderr: { maxBytes: MAX_NAME_OUTPUT_BYTES },\n },\n graceMs: 1_000,\n signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),\n // Extended thinking was 340 of the naming call's 358 output tokens and\n // most of its ten seconds, spent deliberating over a file name.\n // Turning it off takes that call from ~10s to ~3s. A CLI that stops\n // honouring the variable is slow again, never wrong.\n env: { MAX_THINKING_TOKENS: '0' },\n })\n const outcome = await handle.done\n if (outcome.exitCode !== 0) return undefined\n return handle.collected.stdout?.readFrom(0).text ?? ''\n } catch {\n return undefined\n }\n }\n\n /** The suggested file name, or undefined whenever one cannot be had. The\n * caller already has a name derived locally, so every failure here is a\n * non-event: nothing is reported, and nothing is retried. */\n async suggest(draft: string, signal?: AbortSignal): Promise<string | undefined> {\n if (draft.trim().length === 0) return undefined\n const output = await this.#ask(promptNamePrompt(draft), MAX_NAME_OUTPUT_BYTES, signal)\n return output === undefined ? undefined : suggestedName(output)\n }\n\n /** The rewritten draft, or undefined when the rewrite could not be had.\n * Unlike naming, this failure is worth reporting: the user asked for it and\n * is waiting on it. */\n async refine(draft: string, signal?: AbortSignal): Promise<string | undefined> {\n if (draft.trim().length === 0) return undefined\n const output = await this.#ask(promptRefinePrompt(draft), MAX_REFINED_BYTES, signal)\n return output === undefined ? undefined : refinedPrompt(output)\n }\n}\n\n/** List the user's prompt snippets, and save the composer draft as a new one. */\nexport function registerClaudePromptsRoute(ctx: Context, directory: string = claudePromptsDir()): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_PROMPTS_PATH,\n methods: ['GET', 'POST'],\n budget: 'fast',\n handler: async (io) => {\n if (io.method === 'GET') return { status: 200, value: { prompts: await readClaudePrompts(directory) } }\n const payload = await io.body<{ name?: unknown; body?: unknown }>(MAX_REQUEST_BYTES)\n try {\n const prompt = await writeClaudePrompt(directory, payload.name, payload.body)\n return { status: 200, value: { saved: true, prompt } }\n } catch (error) {\n if (error instanceof ClaudePromptWriteError) {\n return { status: error.code === 'name-taken' ? 409 : 400, value: { error: error.code, message: error.message } }\n }\n return { status: 500, value: { error: 'prompt-write-failed', message: 'The prompt could not be saved.' } }\n }\n },\n })\n}\n\n/** Suggest a file name for a draft. Answers `{}` when no name could be had:\n * the caller keeps the name it derived locally, so this is never an error. */\nexport function registerClaudePromptNameRoute(ctx: Context, service: Pick<PromptAssistService, 'suggest'>): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_PROMPT_NAME_PATH,\n methods: ['POST'],\n // Not Git, but the same order of magnitude: one cold Claude Code start.\n budget: 'git',\n handler: async (io) => {\n const payload = await io.body<{ draft?: unknown }>(MAX_REQUEST_BYTES)\n const draft = typeof payload.draft === 'string' ? payload.draft : ''\n const name = await service.suggest(draft, io.signal)\n return { status: 200, value: name === undefined ? {} : { name } }\n },\n })\n}\n\n/** Rewrite a draft into something an agent can act on. */\nexport function registerClaudePromptRefineRoute(ctx: Context, service: Pick<PromptAssistService, 'refine'>): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_PROMPT_REFINE_PATH,\n methods: ['POST'],\n // Not Git, but the same order of magnitude: one cold Claude Code start.\n budget: 'git',\n handler: async (io) => {\n const payload = await io.body<{ draft?: unknown }>(MAX_REQUEST_BYTES)\n const draft = typeof payload.draft === 'string' ? payload.draft : ''\n if (draft.trim().length === 0) {\n return { status: 400, value: { error: 'empty-draft', message: 'There is nothing to rewrite.' } }\n }\n const text = await service.refine(draft, io.signal)\n return text === undefined\n ? { status: 503, value: { error: 'refine-unavailable', message: 'Claude could not rewrite the prompt.' } }\n : { status: 200, value: { text } }\n },\n })\n}\n","/** Only GitHub's own image hosts; the browser loads these directly, so a URL\r\n * the API did not vouch for must never become an outbound request. */\r\nexport function githubAvatarUrl(value: unknown): string | undefined {\r\n if (typeof value !== 'string' || value.length === 0 || value.length > 1_024) return undefined\r\n try {\r\n const url = new URL(value)\r\n const allowed = url.hostname === 'github.com' || url.hostname === 'githubusercontent.com' || url.hostname.endsWith('.githubusercontent.com')\r\n return url.protocol === 'https:' && allowed ? url.href : undefined\r\n } catch {\r\n return undefined\r\n }\r\n}\r\n","import type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\nimport { githubAvatarUrl } from './github-url.ts'\r\nimport { parseGitHubRemote } from './repository-status.ts'\r\n\r\nexport { githubAvatarUrl } from './github-url.ts'\r\n\r\nconst MAX_OUTPUT_BYTES = 512 * 1024\r\nconst GIT_TIMEOUT_MS = 10_000\r\nconst GH_TIMEOUT_MS = 60_000\r\nconst MAX_COMMENTS = 100\r\nconst MAX_THREADS = 100\r\nconst MAX_MENTIONABLE_USERS = 20\r\nconst MAX_REPLY_CHARS = 2_000\r\nconst MAX_COMMENT_CHARS = 4_096\r\nconst MAX_FAILING_CHECKS = 3\r\nconst MAX_LOG_CHARS = 8 * 1024\r\n\r\ntype FeedbackRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\r\n\r\ninterface CommandResult {\r\n readonly exitCode: number | null\r\n readonly stdout: string\r\n readonly lossy: boolean\r\n}\r\n\r\nexport interface PullRequestReviewComment {\r\n readonly id: number\r\n readonly path: string\r\n readonly line?: number\r\n readonly side: 'new' | 'old'\r\n readonly author: string\r\n /** GitHub-hosted avatar of the comment's author, when the API named one. */\r\n readonly avatarUrl?: string\r\n readonly body: string\r\n readonly url: string\r\n /** ISO timestamp GitHub reports; the panel shows it the way GitHub does. */\r\n readonly createdAt?: string\r\n /** App account. GraphQL reports it as an actor type; REST spells the login\r\n * `name[bot]`. Either way the panel shows a Bot pill, like GitHub. */\r\n readonly bot?: boolean\r\n}\r\n\r\n/** One GitHub review conversation: the comments share an anchor, and Resolve\r\n * acts on the thread rather than on any single comment. */\r\nexport interface PullRequestReviewThread {\r\n /** GraphQL node id — the only handle the resolve mutations accept. */\r\n readonly id: string\r\n readonly path: string\r\n readonly line?: number\r\n readonly side: 'new' | 'old'\r\n readonly resolved: boolean\r\n readonly outdated: boolean\r\n readonly comments: readonly PullRequestReviewComment[]\r\n}\r\n\r\n/** A user GitHub will notify when the reply names them. */\r\nexport interface MentionableUser {\r\n readonly login: string\r\n readonly avatarUrl?: string\r\n}\r\n\r\nexport interface FailingCheck {\r\n readonly name: string\r\n readonly link?: string\r\n readonly description?: string\r\n readonly log?: string\r\n}\r\n\r\nexport class PullRequestFeedbackError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'PullRequestFeedbackError'\r\n this.code = code\r\n }\r\n}\r\n\r\n/** Threads carry the anchor; comments carry the prose. `isOutdated` marks a\r\n * thread whose lines the branch has since moved past. */\r\nconst REVIEW_THREADS_QUERY = `query($owner:String!,$name:String!,$number:Int!){\r\n repository(owner:$owner,name:$name){\r\n pullRequest(number:$number){\r\n reviewThreads(first:100){\r\n nodes{\r\n id isResolved isOutdated path line originalLine diffSide\r\n comments(first:50){ nodes{ databaseId body url createdAt author{ __typename login avatarUrl } } }\r\n }\r\n }\r\n }\r\n }\r\n}`\r\n\r\nconst RESOLVE_MUTATION = `mutation($threadId:ID!){\r\n resolveReviewThread(input:{threadId:$threadId}){ thread{ isResolved } }\r\n}`\r\n\r\nconst UNRESOLVE_MUTATION = `mutation($threadId:ID!){\r\n unresolveReviewThread(input:{threadId:$threadId}){ thread{ isResolved } }\r\n}`\r\n\r\nconst MENTIONABLE_USERS_QUERY = `query($owner:String!,$name:String!,$q:String!){\r\n repository(owner:$owner,name:$name){\r\n mentionableUsers(first:20,query:$q){ nodes{ login avatarUrl } }\r\n }\r\n}`\r\n\r\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\r\n const outcome = await handle.done\r\n const stdout = handle.collected.stdout?.readFrom(0)\r\n return { exitCode: outcome.exitCode, stdout: stdout?.text ?? '', lossy: stdout?.lossy === true }\r\n}\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\n/** Read `repository.pullRequest.reviewThreads.nodes` out of a GraphQL response.\r\n * A payload carrying `errors` instead of data yields nothing rather than\r\n * throwing: the caller distinguishes \"no threads\" from \"call failed\" by the\r\n * process exit code. */\r\nexport function parseReviewThreads(value: unknown): readonly PullRequestReviewThread[] {\r\n const nodes = record(record(record(record(record(value)?.data)?.repository)?.pullRequest)?.reviewThreads)?.nodes\r\n if (!Array.isArray(nodes)) return []\r\n const threads: PullRequestReviewThread[] = []\r\n let total = 0\r\n for (const item of nodes) {\r\n const input = record(item)\r\n if (input === undefined || typeof input.id !== 'string' || input.id.length === 0) continue\r\n const path = typeof input.path === 'string' ? input.path : ''\r\n if (path.length === 0) continue\r\n const line = Number.isSafeInteger(input.line)\r\n ? Number(input.line)\r\n : Number.isSafeInteger(input.originalLine) ? Number(input.originalLine) : undefined\r\n const side = input.diffSide === 'LEFT' ? 'old' as const : 'new' as const\r\n const anchor = { path, ...(line === undefined ? {} : { line }), side }\r\n const comments: PullRequestReviewComment[] = []\r\n const commentNodes = record(input.comments)?.nodes\r\n for (const node of Array.isArray(commentNodes) ? commentNodes : []) {\r\n if (total >= MAX_COMMENTS) break\r\n const comment = record(node)\r\n if (comment === undefined || !Number.isSafeInteger(comment.databaseId)) continue\r\n const body = typeof comment.body === 'string' ? comment.body.trim() : ''\r\n if (body.length === 0) continue\r\n const author = record(comment.author)\r\n const avatarUrl = githubAvatarUrl(author?.avatarUrl)\r\n const login = typeof author?.login === 'string' ? author.login : 'unknown'\r\n comments.push({\r\n id: Number(comment.databaseId),\r\n ...anchor,\r\n author: login,\r\n ...(author?.__typename === 'Bot' || login.endsWith('[bot]') ? { bot: true } : {}),\r\n ...(avatarUrl === undefined ? {} : { avatarUrl }),\r\n body: body.slice(0, MAX_COMMENT_CHARS),\r\n url: typeof comment.url === 'string' ? comment.url : '',\r\n ...(typeof comment.createdAt === 'string' ? { createdAt: comment.createdAt } : {}),\r\n })\r\n total += 1\r\n }\r\n // A thread with nothing readable left is not worth an anchor in the diff.\r\n if (comments.length === 0) continue\r\n threads.push({\r\n id: input.id,\r\n ...anchor,\r\n resolved: input.isResolved === true,\r\n outdated: input.isOutdated === true,\r\n comments,\r\n })\r\n if (threads.length >= MAX_THREADS || total >= MAX_COMMENTS) break\r\n }\r\n return threads\r\n}\r\n\r\n/** One posted reply, shaped like the thread comments it joins. */\r\nexport function parseReplyComment(value: unknown, anchor: { path: string; line?: number; side: 'new' | 'old' }): PullRequestReviewComment | undefined {\r\n const input = record(value)\r\n if (input === undefined || !Number.isSafeInteger(input.id)) return undefined\r\n const body = typeof input.body === 'string' ? input.body.trim() : ''\r\n if (body.length === 0) return undefined\r\n const user = record(input.user)\r\n const avatarUrl = githubAvatarUrl(user?.avatar_url)\r\n const login = typeof user?.login === 'string' ? user.login : 'unknown'\r\n return {\r\n id: Number(input.id),\r\n ...anchor,\r\n author: login,\r\n ...(user?.type === 'Bot' || login.endsWith('[bot]') ? { bot: true } : {}),\r\n ...(avatarUrl === undefined ? {} : { avatarUrl }),\r\n body: body.slice(0, MAX_COMMENT_CHARS),\r\n url: typeof input.html_url === 'string' ? input.html_url : '',\r\n ...(typeof input.created_at === 'string' ? { createdAt: input.created_at } : {}),\r\n }\r\n}\r\n\r\nexport function parseMentionableUsers(value: unknown): readonly MentionableUser[] {\r\n const nodes = record(record(record(record(value)?.data)?.repository)?.mentionableUsers)?.nodes\r\n if (!Array.isArray(nodes)) return []\r\n const users: MentionableUser[] = []\r\n for (const item of nodes) {\r\n const input = record(item)\r\n if (input === undefined || typeof input.login !== 'string' || input.login.length === 0) continue\r\n const avatarUrl = githubAvatarUrl(input.avatarUrl)\r\n users.push({ login: input.login, ...(avatarUrl === undefined ? {} : { avatarUrl }) })\r\n if (users.length >= MAX_MENTIONABLE_USERS) break\r\n }\r\n return users\r\n}\r\n\r\n/** Extract the Actions job id from a check run link, when it is one. */\r\nexport function actionsJobId(link: string | undefined): string | undefined {\r\n if (link === undefined) return undefined\r\n return /\\/actions\\/runs\\/\\d+\\/jobs?\\/(\\d+)/u.exec(link)?.[1]\r\n}\r\n\r\nexport function parseFailingChecks(value: unknown): readonly FailingCheck[] {\r\n if (!Array.isArray(value)) return []\r\n const failing: FailingCheck[] = []\r\n for (const item of value) {\r\n const input = record(item)\r\n if (input === undefined || input.bucket !== 'fail' || typeof input.name !== 'string') continue\r\n failing.push({\r\n name: input.name,\r\n ...(typeof input.link === 'string' && input.link.length > 0 ? { link: input.link } : {}),\r\n ...(typeof input.description === 'string' && input.description.length > 0 ? { description: input.description } : {}),\r\n })\r\n }\r\n return failing\r\n}\r\n\r\n/** Keep the informative end of a failed-job log within the size budget. */\r\nexport function boundedLogTail(value: string): string {\r\n const text = value.replaceAll('\\0', '').trimEnd()\r\n return text.length <= MAX_LOG_CHARS ? text : text.slice(text.length - MAX_LOG_CHARS)\r\n}\r\n\r\nexport class PullRequestFeedbackService {\r\n readonly #runtime: FeedbackRuntime\r\n #gitExecutable?: Promise<string>\r\n #ghExecutable?: Promise<string>\r\n\r\n constructor(runtime: FeedbackRuntime) {\r\n this.#runtime = runtime\r\n }\r\n\r\n async threads(cwd: string, pullNumber: number): Promise<readonly PullRequestReviewThread[]> {\r\n const { owner, name } = await this.#repositoryParts(cwd)\r\n const gh = await this.#gh()\r\n const result = await this.#run(gh, [\r\n 'api', 'graphql',\r\n '-f', `owner=${owner}`, '-f', `name=${name}`, '-F', `number=${pullNumber}`,\r\n '-f', `query=${REVIEW_THREADS_QUERY}`,\r\n ], cwd, GH_TIMEOUT_MS)\r\n if (result.exitCode !== 0) throw new PullRequestFeedbackError('comments-unavailable', 'Pull request comments could not be loaded.')\r\n try {\r\n return parseReviewThreads(JSON.parse(result.stdout))\r\n } catch {\r\n throw new PullRequestFeedbackError('comments-unavailable', 'Pull request comments could not be parsed.')\r\n }\r\n }\r\n\r\n /** Post a reply into the thread the given comment belongs to. GitHub parses\r\n * `@login` in the body server-side, so mentions need nothing from us. */\r\n async reply(cwd: string, pullNumber: number, commentId: number, body: string): Promise<PullRequestReviewComment> {\r\n const text = body.trim()\r\n if (text.length === 0 || text.length > MAX_REPLY_CHARS) {\r\n throw new PullRequestFeedbackError('invalid-request', 'The reply body is invalid.')\r\n }\r\n const repository = await this.#repository(cwd)\r\n const gh = await this.#gh()\r\n const result = await this.#run(\r\n gh,\r\n ['api', '-X', 'POST', `repos/${repository}/pulls/${pullNumber}/comments/${commentId}/replies`, '--input', '-'],\r\n cwd,\r\n GH_TIMEOUT_MS,\r\n JSON.stringify({ body: text }),\r\n )\r\n if (result.exitCode !== 0) throw new PullRequestFeedbackError('reply-failed', 'The reply could not be posted.')\r\n let posted: PullRequestReviewComment | undefined\r\n try {\r\n const parsed = JSON.parse(result.stdout) as unknown\r\n const path = typeof record(parsed)?.path === 'string' ? String(record(parsed)?.path) : ''\r\n const line = Number.isSafeInteger(record(parsed)?.line) ? Number(record(parsed)?.line) : undefined\r\n posted = parseReplyComment(parsed, {\r\n path,\r\n ...(line === undefined ? {} : { line }),\r\n side: record(parsed)?.side === 'LEFT' ? 'old' : 'new',\r\n })\r\n } catch {\r\n posted = undefined\r\n }\r\n if (posted === undefined) throw new PullRequestFeedbackError('reply-failed', 'The posted reply could not be read back.')\r\n return posted\r\n }\r\n\r\n /** Resolve or reopen a thread. Returns the state GitHub reports afterwards. */\r\n async setResolved(cwd: string, threadId: string, resolved: boolean): Promise<boolean> {\r\n const gh = await this.#gh()\r\n const result = await this.#run(gh, [\r\n 'api', 'graphql',\r\n '-f', `threadId=${threadId}`,\r\n '-f', `query=${resolved ? RESOLVE_MUTATION : UNRESOLVE_MUTATION}`,\r\n ], cwd, GH_TIMEOUT_MS)\r\n if (result.exitCode !== 0) throw new PullRequestFeedbackError('resolve-failed', 'The thread could not be updated.')\r\n try {\r\n const data = record(record(JSON.parse(result.stdout) as unknown)?.data)\r\n const thread = record(record(data?.[resolved ? 'resolveReviewThread' : 'unresolveReviewThread'])?.thread)\r\n if (typeof thread?.isResolved !== 'boolean') throw new Error('missing state')\r\n return thread.isResolved\r\n } catch {\r\n throw new PullRequestFeedbackError('resolve-failed', 'The thread state could not be read back.')\r\n }\r\n }\r\n\r\n /** Logins GitHub would notify from this repository, for the reply composer. */\r\n async mentionables(cwd: string, query: string): Promise<readonly MentionableUser[]> {\r\n const { owner, name } = await this.#repositoryParts(cwd)\r\n const gh = await this.#gh()\r\n const result = await this.#run(gh, [\r\n 'api', 'graphql',\r\n '-f', `owner=${owner}`, '-f', `name=${name}`, '-f', `q=${query}`,\r\n '-f', `query=${MENTIONABLE_USERS_QUERY}`,\r\n ], cwd, GH_TIMEOUT_MS)\r\n if (result.exitCode !== 0) return []\r\n try {\r\n return parseMentionableUsers(JSON.parse(result.stdout))\r\n } catch {\r\n return []\r\n }\r\n }\r\n\r\n /** `signal` bounds the log fetches below: each is capped on its own, but they\r\n * run one after another, so the honest worst case is their sum rather than\r\n * any single ceiling — more than a route is allowed to hold a connection. */\r\n async failingChecks(cwd: string, pullNumber: number, signal?: AbortSignal): Promise<readonly FailingCheck[]> {\r\n const gh = await this.#gh()\r\n const result = await this.#run(gh, [\r\n 'pr', 'checks', String(pullNumber), '--json', 'name,state,link,description,bucket',\r\n ], cwd, GH_TIMEOUT_MS)\r\n // gh pr checks exits non-zero when checks are failing; that IS our case.\r\n let checks: readonly FailingCheck[]\r\n try {\r\n checks = parseFailingChecks(JSON.parse(result.stdout))\r\n } catch {\r\n throw new PullRequestFeedbackError('checks-unavailable', 'Pull request checks could not be loaded.')\r\n }\r\n const detailed: FailingCheck[] = []\r\n for (const check of checks) {\r\n const jobId = detailed.length < MAX_FAILING_CHECKS ? actionsJobId(check.link) : undefined\r\n if (jobId === undefined) {\r\n detailed.push(check)\r\n continue\r\n }\r\n if (signal?.aborted === true) {\r\n detailed.push(check)\r\n continue\r\n }\r\n const log = await this.#run(gh, ['run', 'view', '--job', jobId, '--log-failed'], cwd, GH_TIMEOUT_MS)\r\n detailed.push(log.exitCode === 0 && log.stdout.trim().length > 0 ? { ...check, log: boundedLogTail(log.stdout) } : check)\r\n }\r\n return detailed\r\n }\r\n\r\n async #repository(cwd: string): Promise<string> {\r\n const git = await this.#git()\r\n const remote = await this.#run(git, ['remote', 'get-url', 'origin'], cwd, GIT_TIMEOUT_MS)\r\n const repository = remote.exitCode === 0 ? parseGitHubRemote(remote.stdout) : undefined\r\n if (repository === undefined) throw new PullRequestFeedbackError('no-github-remote', 'The repository has no GitHub origin remote.')\r\n return repository\r\n }\r\n\r\n /** GraphQL takes the owner and the name as separate variables, so they never\r\n * reach the query text itself. */\r\n async #repositoryParts(cwd: string): Promise<{ owner: string; name: string }> {\r\n const [owner, name] = (await this.#repository(cwd)).split('/')\r\n if (owner === undefined || name === undefined || owner.length === 0 || name.length === 0) {\r\n throw new PullRequestFeedbackError('no-github-remote', 'The repository has no GitHub origin remote.')\r\n }\r\n return { owner, name }\r\n }\r\n\r\n #git(): Promise<string> {\r\n this.#gitExecutable ??= this.#runtime.resolveExecutable('git')\r\n return this.#gitExecutable\r\n }\r\n\r\n #gh(): Promise<string> {\r\n this.#ghExecutable ??= this.#runtime.resolveExecutable('gh').catch(() => {\r\n throw new PullRequestFeedbackError('gh-unavailable', 'GitHub CLI is unavailable.')\r\n })\r\n return this.#ghExecutable\r\n }\r\n\r\n #run(executable: string, args: readonly string[], cwd: string, timeoutMs: number, input?: string): Promise<CommandResult> {\r\n const handle = this.#runtime.spawn({\r\n argv: [executable, ...args],\r\n cwd,\r\n stdio: {\r\n stdin: input === undefined ? 'ignore' : 'pipe',\r\n stdout: { maxBytes: MAX_OUTPUT_BYTES },\r\n stderr: { maxBytes: 64 * 1024 },\r\n },\r\n graceMs: 1_000,\r\n signal: AbortSignal.timeout(timeoutMs),\r\n env: {},\r\n })\r\n if (input !== undefined) handle.stdin?.end(input)\r\n return collect(handle)\r\n }\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REPOSITORY_FEEDBACK_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport { PullRequestFeedbackError, type PullRequestFeedbackService } from './pr-feedback.ts'\r\n\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\nconst MAX_BODY_BYTES = 16 * 1024\r\nconst MAX_REPLY_CHARS = 2_000\r\nconst MAX_THREAD_ID_CHARS = 512\r\nconst MAX_MENTION_QUERY_CHARS = 64\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\r\n let parsed: unknown\r\n try {\r\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\r\n } catch (error) {\r\n // Malformed JSON keeps its own 400; the cap is the only other refusal the\r\n // transport raises, and the panel already knows that code.\r\n if (error instanceof SyntaxError) throw error\r\n throw new PullRequestFeedbackError('body-too-large', 'The request body is too large.')\r\n }\r\n const value = record(parsed)\r\n if (value === undefined) throw new PullRequestFeedbackError('invalid-request', 'The request body is invalid.')\r\n return value\r\n}\r\n\r\nfunction replyBody(input: Record<string, unknown>): string {\r\n const body = typeof input.body === 'string' ? input.body.trim() : ''\r\n if (body.length === 0 || body.length > MAX_REPLY_CHARS || body.includes('\\0')) {\r\n throw new PullRequestFeedbackError('invalid-request', 'The reply body is invalid.')\r\n }\r\n return body\r\n}\r\n\r\nfunction commentId(input: Record<string, unknown>): number {\r\n const value = input.commentId\r\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0) {\r\n throw new PullRequestFeedbackError('invalid-request', 'The comment id is invalid.')\r\n }\r\n return value\r\n}\r\n\r\nfunction threadId(input: Record<string, unknown>): string {\r\n const value = input.threadId\r\n if (typeof value !== 'string' || value.length === 0 || value.length > MAX_THREAD_ID_CHARS) {\r\n throw new PullRequestFeedbackError('invalid-request', 'The thread id is invalid.')\r\n }\r\n return value\r\n}\r\n\r\nfunction sessionId(url: URL): string {\r\n const value = url.searchParams.get('sessionId')\r\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) {\r\n throw new PullRequestFeedbackError('invalid-session', 'The session is invalid.')\r\n }\r\n return value\r\n}\r\n\r\nfunction pullNumber(url: URL): number {\r\n const value = Number(url.searchParams.get('number'))\r\n if (!Number.isSafeInteger(value) || value <= 0 || value > 1_000_000_000) {\r\n throw new PullRequestFeedbackError('invalid-request', 'The pull request number is invalid.')\r\n }\r\n return value\r\n}\r\n\r\n/** Every arm shells out to `gh`, so the whole prefix carries the network budget. */\r\nexport function registerPullRequestFeedbackRoute(\r\n ctx: Context,\r\n service: PullRequestFeedbackService,\r\n cwdForSession: (sessionId: string) => string | undefined,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'prefix',\r\n path: CLAUDE_REPOSITORY_FEEDBACK_PATH,\r\n methods: ['GET', 'POST'],\r\n budget: 'remote',\r\n handler: async io => {\r\n const url = io.url\r\n const reads = io.method === 'GET'\r\n const writes = io.method === 'POST'\r\n try {\r\n const cwd = cwdForSession(sessionId(url))\r\n if (cwd === undefined) throw new PullRequestFeedbackError('session-unavailable', 'The Claude session is unavailable.')\r\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/comments`) {\r\n if (!reads) return { status: 405, value: { error: 'method not allowed' } }\r\n return { status: 200, value: { threads: await service.threads(cwd, pullNumber(url)) } }\r\n }\r\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/checks`) {\r\n if (!reads) return { status: 405, value: { error: 'method not allowed' } }\r\n return { status: 200, value: { checks: await service.failingChecks(cwd, pullNumber(url), io.signal) } }\r\n }\r\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/mentionables`) {\r\n if (!reads) return { status: 405, value: { error: 'method not allowed' } }\r\n const query = (url.searchParams.get('q') ?? '').slice(0, MAX_MENTION_QUERY_CHARS)\r\n return { status: 200, value: { users: await service.mentionables(cwd, query) } }\r\n }\r\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/reply`) {\r\n if (!writes) return { status: 405, value: { error: 'method not allowed' } }\r\n const input = await readJson(io)\r\n const comment = await service.reply(cwd, pullNumber(url), commentId(input), replyBody(input))\r\n return { status: 200, value: { comment } }\r\n }\r\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/resolve`) {\r\n if (!writes) return { status: 405, value: { error: 'method not allowed' } }\r\n const input = await readJson(io)\r\n if (typeof input.resolved !== 'boolean') {\r\n throw new PullRequestFeedbackError('invalid-request', 'The resolved field is required.')\r\n }\r\n return { status: 200, value: { resolved: await service.setResolved(cwd, threadId(input), input.resolved) } }\r\n }\r\n return { status: 404, value: { error: 'not found' } }\r\n } catch (error) {\r\n if (error instanceof PullRequestFeedbackError) {\r\n return { status: 409, value: { error: error.code, message: error.message } }\r\n }\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 500, value: { error: 'pr-feedback-unavailable', message: 'Pull request feedback is unavailable.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import { isAbsolute } from 'node:path'\r\nimport type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REPOSITORY_STATUS_PATH } from './constants.ts'\r\nimport { registerPluginRoute } from './http.ts'\r\nimport type { RepositoryStatusService } from './repository-status.ts'\r\n\r\nconst MAX_PATH_CHARS = 4_096\r\n\r\n/** Read-only repository status for an arbitrary directory (the overview panel\r\n * aggregates every Claude session's checkout through this).\r\n *\r\n * The route signal is threaded into the service because this is the one read\r\n * the overview polls per distinct checkout every 30 seconds: freeing the\r\n * socket at the budget while the Host kept scanning would just grow a queue\r\n * of work nobody is waiting for any more. */\r\nexport function registerRepositoryStatusRoute(ctx: Context, service: RepositoryStatusService): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_REPOSITORY_STATUS_PATH,\r\n methods: ['GET'],\r\n budget: 'git',\r\n handler: async io => {\r\n const cwd = io.url.searchParams.get('cwd')\r\n if (cwd === null || cwd.length === 0 || cwd.length > MAX_PATH_CHARS || !isAbsolute(cwd) || cwd.includes('\\0')) {\r\n return { status: 400, value: { error: 'invalid-request', message: 'The cwd query parameter is invalid.' } }\r\n }\r\n try {\r\n return { status: 200, value: await service.inspect(cwd, io.signal) }\r\n } catch {\r\n return { status: 500, value: { error: 'repository-status-unavailable', message: 'Repository status is unavailable.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import { isAbsolute } from 'node:path'\r\nimport type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REPOSITORY_FILE_PATH } from './constants.ts'\r\nimport { registerPluginRoute } from './http.ts'\r\nimport { RepositoryFileError, type RepositoryStatusService } from './repository-status.ts'\r\n\r\nconst MAX_PATH_CHARS = 4_096\r\n\r\n/** Read-only slice of a working-tree file so the diff panel can expand unmodified lines around hunks. */\r\nexport function registerRepositoryFileRoute(ctx: Context, service: Pick<RepositoryStatusService, 'fileLines'>): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_REPOSITORY_FILE_PATH,\r\n methods: ['GET'],\r\n // One bounded read of a file already on disk.\r\n budget: 'git',\r\n handler: async io => {\r\n const params = io.url.searchParams\r\n const cwd = params.get('cwd')\r\n const path = params.get('path')\r\n const from = Number(params.get('from'))\r\n const to = Number(params.get('to'))\r\n if (cwd === null || cwd.length === 0 || cwd.length > MAX_PATH_CHARS || !isAbsolute(cwd) || cwd.includes('\\0')) {\r\n return { status: 400, value: { error: 'invalid-request', message: 'The cwd query parameter is invalid.' } }\r\n }\r\n if (path === null || path.length === 0 || path.length > MAX_PATH_CHARS) {\r\n return { status: 400, value: { error: 'invalid-request', message: 'The path query parameter is invalid.' } }\r\n }\r\n try {\r\n return { status: 200, value: await service.fileLines(cwd, path, from, to) }\r\n } catch (error) {\r\n if (error instanceof RepositoryFileError) {\r\n return { status: error.code === 'invalid-request' ? 400 : 409, value: { error: error.code, message: error.message } }\r\n }\r\n return { status: 500, value: { error: 'repository-file-unavailable', message: 'The file could not be read.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import { randomUUID } from 'node:crypto'\r\nimport { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\r\nimport { dirname } from 'node:path'\r\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\r\n\r\nconst REQUEST_TIMEOUT_MS = 15_000\r\nconst MAX_RESULTS = 20\r\nconst MAX_QUERY_CHARS = 200\r\nconst MAX_STORE_BYTES = 64 * 1024\r\n\r\nexport interface JiraConnectionInput {\r\n readonly siteUrl: string\r\n readonly email: string\r\n readonly apiToken: string\r\n}\r\n\r\ninterface JiraStore extends JiraConnectionInput {\r\n readonly displayName?: string\r\n readonly accountId?: string\r\n}\r\n\r\n/** Connection state exposed to the browser; never carries the token. */\r\nexport interface JiraStatus {\r\n readonly connected: boolean\r\n readonly siteUrl?: string\r\n readonly email?: string\r\n readonly displayName?: string\r\n}\r\n\r\nexport interface JiraTicket {\r\n readonly key: string\r\n readonly summary: string\r\n readonly url: string\r\n readonly status?: string\r\n readonly type?: string\r\n}\r\n\r\nexport interface JiraServiceOptions {\r\n readonly storePath?: string\r\n readonly fetch?: typeof fetch\r\n}\r\n\r\nexport class JiraError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'JiraError'\r\n this.code = code\r\n }\r\n}\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\n/** Jira Cloud sites are origins; Data Center may carry a context path. */\r\nexport function normalizeSiteUrl(value: string): string {\r\n let url: URL\r\n try {\r\n url = new URL(value.trim())\r\n } catch {\r\n throw new JiraError('invalid-site', 'The Jira site URL is invalid.')\r\n }\r\n if (url.protocol !== 'https:') throw new JiraError('invalid-site', 'The Jira site URL must use https.')\r\n return `${url.origin}${url.pathname.replace(/\\/+$/u, '')}`\r\n}\r\n\r\nexport function ticketKeyOf(query: string): string | undefined {\r\n const match = /^([A-Za-z][A-Za-z0-9_]*)-(\\d+)$/u.exec(query.trim())\r\n return match === null ? undefined : `${match[1]!.toUpperCase()}-${match[2]!}`\r\n}\r\n\r\n/** Jira's text index carries summary, description and comments -- never the\r\n * issue key -- so a bare ticket number (\"5697\") can never reach PSOS-5697\r\n * through `text ~`. The issue picker is the endpoint behind Jira's own quick\r\n * search and does match keys; its hits become the key filter the normal\r\n * search then reads the display fields from. */\r\nexport function pickerKeys(value: unknown, number: string): readonly string[] {\r\n const sections = record(value)?.sections\r\n if (!Array.isArray(sections)) return []\r\n const keys: string[] = []\r\n for (const section of sections) {\r\n const issues = record(section)?.issues\r\n if (!Array.isArray(issues)) continue\r\n for (const issue of issues) {\r\n const raw = record(issue)?.key\r\n const key = ticketKeyOf(typeof raw === 'string' ? raw : '')\r\n if (key !== undefined && key.endsWith(`-${number}`) && !keys.includes(key)) keys.push(key)\r\n }\r\n }\r\n return keys\r\n}\r\n\r\n/** Keys arrive validated by `ticketKeyOf`, so they cannot break out of the quotes. */\r\nexport function keyJql(keys: readonly string[]): string {\r\n return `key in (${keys.map(key => `\"${key}\"`).join(', ')}) ORDER BY updated DESC`\r\n}\r\n\r\nexport function buildJql(query: string): string {\r\n const trimmed = query.trim().slice(0, MAX_QUERY_CHARS)\r\n if (trimmed.length === 0) return 'statusCategory != Done ORDER BY updated DESC'\r\n const key = ticketKeyOf(trimmed)\r\n if (key !== undefined) return `key = \"${key}\"`\r\n const escaped = trimmed.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"')\r\n return `text ~ \"${escaped}*\" ORDER BY updated DESC`\r\n}\r\n\r\nexport function parseTickets(value: unknown, siteUrl: string): readonly JiraTicket[] {\r\n const issues = record(value)?.issues\r\n if (!Array.isArray(issues)) return []\r\n const tickets: JiraTicket[] = []\r\n for (const item of issues) {\r\n const issue = record(item)\r\n const fields = record(issue?.fields)\r\n if (issue === undefined || typeof issue.key !== 'string' || fields === undefined) continue\r\n const status = record(fields.status)?.name\r\n const type = record(fields.issuetype)?.name\r\n tickets.push({\r\n key: issue.key,\r\n summary: typeof fields.summary === 'string' ? fields.summary.slice(0, 256) : '',\r\n url: `${siteUrl}/browse/${issue.key}`,\r\n ...(typeof status === 'string' ? { status } : {}),\r\n ...(typeof type === 'string' ? { type } : {}),\r\n })\r\n if (tickets.length >= MAX_RESULTS) break\r\n }\r\n return tickets\r\n}\r\n\r\nfunction statusOf(store: JiraStore | undefined): JiraStatus {\r\n if (store === undefined) return { connected: false }\r\n return {\r\n connected: true,\r\n siteUrl: store.siteUrl,\r\n email: store.email,\r\n ...(store.displayName === undefined ? {} : { displayName: store.displayName }),\r\n }\r\n}\r\n\r\n/** Jira Cloud access through the user's API token (Basic auth). */\r\nexport class JiraService {\r\n readonly #storePath: string\r\n readonly #fetch: typeof fetch\r\n\r\n constructor(options: JiraServiceOptions = {}) {\r\n this.#storePath = options.storePath ?? dshHomePath('plugins', 'dsh-claude', 'jira.json')\r\n this.#fetch = options.fetch ?? globalThis.fetch\r\n }\r\n\r\n async status(): Promise<JiraStatus> {\r\n return statusOf(await this.#read())\r\n }\r\n\r\n async connect(input: JiraConnectionInput): Promise<JiraStatus> {\r\n const siteUrl = normalizeSiteUrl(input.siteUrl)\r\n const email = input.email.trim()\r\n const apiToken = input.apiToken.trim()\r\n if (email.length === 0 || email.length > 320 || apiToken.length === 0 || apiToken.length > 4_096) {\r\n throw new JiraError('invalid-credentials', 'An account email and API token are required.')\r\n }\r\n const connection = { siteUrl, email, apiToken }\r\n const myself = record(await this.#json(connection, '/rest/api/3/myself'))\r\n const displayName = typeof myself?.displayName === 'string' ? myself.displayName : undefined\r\n const accountId = typeof myself?.accountId === 'string' ? myself.accountId : undefined\r\n const store: JiraStore = {\r\n ...connection,\r\n ...(displayName === undefined ? {} : { displayName }),\r\n ...(accountId === undefined ? {} : { accountId }),\r\n }\r\n await this.#write(store)\r\n return statusOf(store)\r\n }\r\n\r\n /** Assign a ticket to the connected account (used once a ticket's worktree exists). */\r\n async assignToMe(key: string): Promise<void> {\r\n const store = await this.#read()\r\n if (store === undefined) throw new JiraError('not-connected', 'Connect Jira in Settings first.')\r\n const ticket = ticketKeyOf(key)\r\n if (ticket === undefined) throw new JiraError('invalid-request', 'The ticket key is invalid.')\r\n let accountId = store.accountId\r\n if (accountId === undefined) {\r\n const myself = record(await this.#json(store, '/rest/api/3/myself'))\r\n if (typeof myself?.accountId !== 'string') throw new JiraError('jira-failed', 'The Jira account id is unavailable.')\r\n accountId = myself.accountId\r\n await this.#write({ ...store, accountId })\r\n }\r\n await this.#json(store, `/rest/api/3/issue/${ticket}/assignee`, { method: 'PUT', body: { accountId } })\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n await rm(this.#storePath, { force: true })\r\n }\r\n\r\n async search(query: string): Promise<readonly JiraTicket[]> {\r\n const store = await this.#read()\r\n if (store === undefined) throw new JiraError('not-connected', 'Connect Jira in Settings first.')\r\n const params = new URLSearchParams({\r\n jql: await this.#searchJql(store, query.trim().slice(0, MAX_QUERY_CHARS)),\r\n maxResults: String(MAX_RESULTS),\r\n fields: 'summary,status,issuetype',\r\n })\r\n let body: unknown\r\n try {\r\n body = await this.#json(store, `/rest/api/3/search/jql?${params.toString()}`)\r\n } catch (error) {\r\n // Older deployments only serve the classic search endpoint.\r\n if (!(error instanceof JiraError && error.code === 'not-found')) throw error\r\n body = await this.#json(store, `/rest/api/3/search?${params.toString()}`)\r\n }\r\n return parseTickets(body, store.siteUrl)\r\n }\r\n\r\n /** A bare ticket number resolves through the picker; everything else is JQL.\r\n * A site that cannot serve the picker falls back to the text search rather\r\n * than failing the whole lookup. */\r\n async #searchJql(store: JiraStore, query: string): Promise<string> {\r\n if (!/^\\d+$/u.test(query)) return buildJql(query)\r\n const keys = await this.#json(store, `/rest/api/3/issue/picker?query=${encodeURIComponent(query)}`)\r\n .then(body => pickerKeys(body, query), () => [])\r\n return keys.length === 0 ? buildJql(query) : keyJql(keys)\r\n }\r\n\r\n async #json(connection: JiraConnectionInput, path: string, init: { method?: 'GET' | 'PUT'; body?: unknown } = {}): Promise<unknown> {\r\n let response: Response\r\n try {\r\n response = await this.#fetch(`${connection.siteUrl}${path}`, {\r\n method: init.method ?? 'GET',\r\n headers: {\r\n accept: 'application/json',\r\n authorization: `Basic ${Buffer.from(`${connection.email}:${connection.apiToken}`).toString('base64')}`,\r\n ...(init.body === undefined ? {} : { 'content-type': 'application/json' }),\r\n },\r\n ...(init.body === undefined ? {} : { body: JSON.stringify(init.body) }),\r\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\r\n })\r\n } catch {\r\n throw new JiraError('unreachable', 'The Jira site could not be reached.')\r\n }\r\n if (response.status === 401 || response.status === 403) throw new JiraError('unauthorized', 'Jira rejected the credentials.')\r\n if (response.status === 404) throw new JiraError('not-found', 'The Jira endpoint was not found.')\r\n if (!response.ok) throw new JiraError('jira-failed', `Jira responded with HTTP ${response.status}.`)\r\n if (response.status === 204) return undefined\r\n try {\r\n return await response.json() as unknown\r\n } catch {\r\n throw new JiraError('jira-failed', 'Jira returned an invalid response.')\r\n }\r\n }\r\n\r\n async #read(): Promise<JiraStore | undefined> {\r\n let text: string\r\n try {\r\n text = await readFile(this.#storePath, 'utf8')\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\r\n throw error\r\n }\r\n if (Buffer.byteLength(text) > MAX_STORE_BYTES) return undefined\r\n const input = record(JSON.parse(text))\r\n if (input === undefined || typeof input.siteUrl !== 'string' || typeof input.email !== 'string' || typeof input.apiToken !== 'string') return undefined\r\n return {\r\n siteUrl: input.siteUrl,\r\n email: input.email,\r\n apiToken: input.apiToken,\r\n ...(typeof input.displayName === 'string' ? { displayName: input.displayName } : {}),\r\n ...(typeof input.accountId === 'string' ? { accountId: input.accountId } : {}),\r\n }\r\n }\r\n\r\n async #write(store: JiraStore): Promise<void> {\r\n await mkdir(dirname(this.#storePath), { recursive: true, mode: 0o700 })\r\n const temporary = `${this.#storePath}.${process.pid}.${randomUUID()}.tmp`\r\n try {\r\n await writeFile(temporary, `${JSON.stringify(store, null, 2)}\\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\r\n await chmod(temporary, 0o600)\r\n await rename(temporary, this.#storePath)\r\n } finally {\r\n await rm(temporary, { force: true }).catch(() => undefined)\r\n }\r\n }\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_JIRA_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport { JiraError, type JiraService } from './jira.ts'\r\n\r\nconst MAX_BODY_BYTES = 8 * 1024\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\n/** The wrapper enforces the byte cap; its plain rejection is translated back\r\n * into the JiraError shape the panel already knows how to render. */\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\r\n let body: unknown\r\n try {\r\n body = await io.body(MAX_BODY_BYTES)\r\n } catch (error) {\r\n if (error instanceof SyntaxError) throw error\r\n throw new JiraError('body-too-large', 'The request body is too large.')\r\n }\r\n const value = record(body)\r\n if (value === undefined) throw new JiraError('invalid-request', 'The request body is invalid.')\r\n return value\r\n}\r\n\r\nfunction string(input: Record<string, unknown>, key: string): string {\r\n const value = input[key]\r\n if (typeof value !== 'string') throw new JiraError('invalid-request', `The ${key} field is required.`)\r\n return value\r\n}\r\n\r\nexport function registerJiraRoute(ctx: Context, service: JiraService): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'prefix',\r\n path: CLAUDE_JIRA_PATH,\r\n methods: ['GET', 'POST'],\r\n budget: 'git',\r\n handler: async io => {\r\n const url = io.url\r\n try {\r\n if (url.pathname === `${CLAUDE_JIRA_PATH}/status`) {\r\n if (io.method !== 'GET') return { status: 405, value: { error: 'method not allowed' } }\r\n return { status: 200, value: await service.status() }\r\n }\r\n if (url.pathname === `${CLAUDE_JIRA_PATH}/connect`) {\r\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\r\n const input = await readJson(io)\r\n return {\r\n status: 200,\r\n value: await service.connect({\r\n siteUrl: string(input, 'siteUrl'),\r\n email: string(input, 'email'),\r\n apiToken: string(input, 'apiToken'),\r\n }),\r\n }\r\n }\r\n if (url.pathname === `${CLAUDE_JIRA_PATH}/disconnect`) {\r\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\r\n await service.disconnect()\r\n return { status: 200, value: { connected: false } }\r\n }\r\n if (url.pathname === `${CLAUDE_JIRA_PATH}/assign`) {\r\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\r\n const input = await readJson(io)\r\n await service.assignToMe(string(input, 'key'))\r\n return { status: 200, value: { assigned: true } }\r\n }\r\n if (url.pathname === `${CLAUDE_JIRA_PATH}/search`) {\r\n if (io.method !== 'GET') return { status: 405, value: { error: 'method not allowed' } }\r\n return { status: 200, value: { tickets: await service.search(url.searchParams.get('query') ?? '') } }\r\n }\r\n return { status: 404, value: { error: 'not found' } }\r\n } catch (error) {\r\n if (error instanceof JiraError) return { status: 409, value: { error: error.code, message: error.message } }\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 500, value: { error: 'jira-unavailable', message: 'Jira is unavailable.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import { StringDecoder } from 'node:string_decoder'\r\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\n\r\nconst MAX_SELECTION_CHARS = 8_000\r\nconst MAX_CONTEXT_CHARS = 16_000\r\nconst MAX_QUESTION_CHARS = 2_000\r\nconst ASK_TIMEOUT_MS = 180_000\r\nconst MAX_STDERR_BYTES = 64 * 1024\r\nconst MAX_TOOL_SUMMARY_CHARS = 160\r\nexport const READ_ONLY_TOOLS = ['Read', 'Grep', 'Glob'] as const\r\n\r\ntype AskRuntime = Pick<SubprocessRuntime, 'spawn'>\r\n\r\nexport interface AskRequest {\r\n readonly selection: string\r\n readonly context?: string\r\n readonly question: string\r\n}\r\n\r\n/** Model and effort the session last ran with; mirrored onto the side query. */\r\nexport interface AskPreferences {\r\n readonly model?: string\r\n readonly thinkingMode?: string\r\n}\r\n\r\nexport class AskError extends Error {\r\n readonly code: string\r\n\r\n constructor(code: string, message: string) {\r\n super(message)\r\n this.name = 'AskError'\r\n this.code = code\r\n }\r\n}\r\n\r\nfunction fence(value: string): string {\r\n return `\"\"\"\\n${value.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`\r\n}\r\n\r\nexport function askPrompt(request: AskRequest): string {\r\n const selection = request.selection.trim().slice(0, MAX_SELECTION_CHARS)\r\n const context = (request.context ?? '').trim().slice(0, MAX_CONTEXT_CHARS)\r\n const question = request.question.trim().slice(0, MAX_QUESTION_CHARS)\r\n return [\r\n 'You are answering a follow-up question about part of an earlier assistant reply in this project.',\r\n '',\r\n 'Selected passage:',\r\n fence(selection),\r\n ...(context.length === 0 || context === selection ? [] : ['', 'Surrounding reply, for context only:', fence(context)]),\r\n '',\r\n `Question: ${question}`,\r\n '',\r\n 'Answer the question directly and concisely, in the same language as the question. Use Markdown.',\r\n 'Only the read-only tools Read, Grep, and Glob are available; use them when the answer depends on project code, otherwise answer from the passage.',\r\n ].join('\\n')\r\n}\r\n\r\n/** CLI effort for a session thinking mode; `off` and unknown modes send nothing. */\r\nexport function effortFor(thinkingMode: string | undefined): string | undefined {\r\n if (thinkingMode === undefined || thinkingMode === 'off') return undefined\r\n if (thinkingMode === 'ultracode') return 'max'\r\n return ['low', 'medium', 'high', 'max'].includes(thinkingMode) ? thinkingMode : undefined\r\n}\r\n\r\nexport function askArguments(preferences: AskPreferences): readonly string[] {\r\n const effort = effortFor(preferences.thinkingMode)\r\n return [\r\n '-p', '--output-format', 'stream-json', '--verbose', '--include-partial-messages',\r\n // No MCP servers: a follow-up question never needs them and connecting\r\n // them roughly doubles cold start.\r\n '--strict-mcp-config', '--mcp-config', '{\"mcpServers\":{}}',\r\n ...(preferences.model === undefined || preferences.model === 'default' ? [] : ['--model', preferences.model]),\r\n ...(effort === undefined ? [] : ['--effort', effort]),\r\n // Read-only inspection only; both flags are variadic, so they stay last\r\n // and the prompt travels over stdin.\r\n '--tools', ...READ_ONLY_TOOLS, '--allowedTools', ...READ_ONLY_TOOLS,\r\n ]\r\n}\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\n/** What one stream-json line contributes: streamed answer text, streamed\r\n * thinking, or the final result (used only when no text streamed). */\r\nexport type AskToolPhase = 'start' | 'input' | 'done'\r\n\r\nexport type AskStreamEvent =\r\n | { readonly type: 'text'; readonly text: string }\r\n | { readonly type: 'thinking'; readonly text: string }\r\n | { readonly type: 'status'; readonly text: string }\r\n | { readonly type: 'tool'; readonly id: string; readonly phase: AskToolPhase; readonly name?: string; readonly summary?: string; readonly error?: boolean }\r\n | { readonly type: 'result'; readonly text: string }\r\n\r\n/** One-line description of a tool call, mirroring the main window's step titles. */\r\nexport function toolSummary(input: unknown): string | undefined {\r\n const fields = record(input)\r\n if (fields === undefined) return undefined\r\n const candidate = [fields.command, fields.pattern, fields.file_path, fields.path, fields.query].find(value => typeof value === 'string' && value.length > 0)\r\n const text = typeof candidate === 'string' ? candidate : JSON.stringify(fields)\r\n return text.replaceAll(/\\s+/gu, ' ').trim().slice(0, MAX_TOOL_SUMMARY_CHARS)\r\n}\r\n\r\nexport function eventsOfStreamLine(line: string): readonly AskStreamEvent[] {\r\n let parsed: Record<string, unknown> | undefined\r\n try {\r\n parsed = record(JSON.parse(line))\r\n } catch {\r\n return []\r\n }\r\n if (parsed === undefined) return []\r\n if (parsed.type === 'system' && parsed.subtype === 'init') return [{ type: 'status', text: 'ready' }]\r\n if (parsed.type === 'stream_event') {\r\n const event = record(parsed.event)\r\n if (event?.type === 'content_block_start') {\r\n const block = record(event.content_block)\r\n if (block?.type === 'tool_use' && typeof block.id === 'string' && typeof block.name === 'string') {\r\n return [{ type: 'tool', id: block.id, phase: 'start', name: block.name }]\r\n }\r\n return []\r\n }\r\n const delta = record(event?.delta)\r\n if (event?.type !== 'content_block_delta' || delta === undefined) return []\r\n if (delta.type === 'text_delta' && typeof delta.text === 'string') return [{ type: 'text', text: delta.text }]\r\n if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') return [{ type: 'thinking', text: delta.thinking }]\r\n return []\r\n }\r\n if (parsed.type === 'assistant' || parsed.type === 'user') {\r\n const content = record(parsed.message)?.content\r\n if (!Array.isArray(content)) return []\r\n const events: AskStreamEvent[] = []\r\n for (const item of content) {\r\n const block = record(item)\r\n if (block?.type === 'tool_use' && typeof block.id === 'string' && typeof block.name === 'string') {\r\n const summary = toolSummary(block.input)\r\n events.push({ type: 'tool', id: block.id, phase: 'input', name: block.name, ...(summary === undefined ? {} : { summary }) })\r\n } else if (block?.type === 'tool_result' && typeof block.tool_use_id === 'string') {\r\n events.push({ type: 'tool', id: block.tool_use_id, phase: 'done', ...(block.is_error === true ? { error: true } : {}) })\r\n }\r\n }\r\n return events\r\n }\r\n if (parsed.type === 'result' && typeof parsed.result === 'string') return [{ type: 'result', text: parsed.result }]\r\n return []\r\n}\r\n\r\nexport type AskProgressEvent = Exclude<AskStreamEvent, { type: 'result' }>\r\n\r\n/** One-shot Claude Code query answering a question about selected reply text. */\r\nexport class AskService {\r\n readonly #runtime: AskRuntime\r\n readonly #executablePath: string\r\n\r\n constructor(runtime: AskRuntime, executablePath: string) {\r\n this.#runtime = runtime\r\n this.#executablePath = executablePath\r\n }\r\n\r\n async ask(cwd: string, request: AskRequest, preferences: AskPreferences, onEvent: (event: AskProgressEvent) => void, signal?: AbortSignal): Promise<void> {\r\n if (request.question.trim().length === 0 || request.selection.trim().length === 0) {\r\n throw new AskError('invalid-request', 'A selection and a question are required.')\r\n }\r\n if (this.#executablePath.length === 0) throw new AskError('claude-unavailable', 'Claude Code is unavailable.')\r\n const timeout = AbortSignal.timeout(ASK_TIMEOUT_MS)\r\n // The prompt rides stdin: `--tools ''` is variadic and would swallow a\r\n // trailing positional prompt argument.\r\n const handle = this.#runtime.spawn({\r\n argv: [this.#executablePath, ...askArguments(preferences)],\r\n cwd,\r\n stdio: { stdin: { data: askPrompt(request) }, stdout: 'pipe', stderr: { maxBytes: MAX_STDERR_BYTES } },\r\n graceMs: 1_000,\r\n signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),\r\n env: {},\r\n })\r\n const stdout = handle.stdout\r\n if (stdout === undefined) throw new AskError('ask-failed', 'Claude output is unavailable.')\r\n const decoder = new StringDecoder('utf8')\r\n let buffer = ''\r\n let emitted = false\r\n let result: string | undefined\r\n const consume = (line: string): void => {\r\n for (const event of eventsOfStreamLine(line)) {\r\n if (event.type === 'result') {\r\n result = event.text\r\n continue\r\n }\r\n if (event.type !== 'tool' && event.text.length === 0) continue\r\n if (event.type === 'text') emitted = true\r\n onEvent(event)\r\n }\r\n }\r\n for await (const chunk of stdout) {\r\n buffer += typeof chunk === 'string' ? chunk : decoder.write(chunk as Buffer)\r\n const lines = buffer.split('\\n')\r\n buffer = lines.pop() ?? ''\r\n for (const line of lines) if (line.trim().length > 0) consume(line)\r\n }\r\n buffer += decoder.end()\r\n if (buffer.trim().length > 0) consume(buffer)\r\n const outcome = await handle.done\r\n if (!emitted && result !== undefined && result.length > 0) {\r\n emitted = true\r\n onEvent({ type: 'text', text: result })\r\n }\r\n if (!emitted) {\r\n if (signal?.aborted === true) throw new AskError('aborted', 'The question was cancelled.')\r\n if (timeout.aborted) throw new AskError('timeout', 'Claude took too long to answer.')\r\n const stderr = handle.collected.stderr?.readFrom(0).text.trim().split(/\\r?\\n/u).filter(line => line.length > 0).at(-1)\r\n throw new AskError('ask-failed', stderr !== undefined && stderr.length > 0 ? stderr : `Claude exited with code ${String(outcome.exitCode)}.`)\r\n }\r\n }\r\n}\r\n","import type { ServerResponse } from 'node:http'\r\nimport type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { AskError, type AskPreferences, type AskRequest, type AskService } from './ask.ts'\r\nimport { CLAUDE_ASK_PATH } from './constants.ts'\r\nimport { json, registerPluginRoute } from './http.ts'\r\n\r\nconst MAX_BODY_BYTES = 128 * 1024\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\n/** Two sessions may await an answer at once; a third evicts the oldest. */\r\nconst MAX_CONCURRENT_ASKS = 2\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\nfunction askRequest(input: Record<string, unknown>): AskRequest {\r\n if (typeof input.selection !== 'string' || typeof input.question !== 'string' || (input.context !== undefined && typeof input.context !== 'string')) {\r\n throw new AskError('invalid-request', 'The selection and question fields are required.')\r\n }\r\n return { selection: input.selection, question: input.question, ...(typeof input.context === 'string' ? { context: input.context } : {}) }\r\n}\r\n\r\nfunction ndjson(res: ServerResponse, value: unknown): void {\r\n res.write(`${JSON.stringify(value)}\\n`)\r\n}\r\n\r\n/** A stream route rather than a unary one: the answer is written as it arrives,\r\n * so the deadline stays where the work is — `ASK_TIMEOUT_MS` inside the\r\n * service, fused there with the disconnect signal — instead of a route budget\r\n * that would cut a legitimate long answer off mid-sentence. */\r\nexport function registerAskRoute(\r\n ctx: Context,\r\n service: AskService,\r\n cwdForSession: (sessionId: string) => string | undefined,\r\n preferencesFor: (sessionId: string) => AskPreferences | undefined,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'stream',\r\n kind: 'exact',\r\n path: CLAUDE_ASK_PATH,\r\n methods: ['POST'],\r\n maxConcurrent: MAX_CONCURRENT_ASKS,\r\n streamKey: url => url.searchParams.get('sessionId') ?? '',\r\n handler: async (res, io) => {\r\n let cwd: string\r\n let request: AskRequest\r\n let sessionId: string\r\n try {\r\n const value = io.url.searchParams.get('sessionId')\r\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) throw new AskError('invalid-session', 'The session is invalid.')\r\n sessionId = value\r\n const resolved = cwdForSession(sessionId)\r\n if (resolved === undefined) throw new AskError('session-unavailable', 'The Claude session is unavailable.')\r\n cwd = resolved\r\n const body = record(await io.body(MAX_BODY_BYTES))\r\n if (body === undefined) throw new AskError('invalid-request', 'The request body is invalid.')\r\n request = askRequest(body)\r\n } catch (error) {\r\n if (error instanceof AskError) return json(res, 409, { error: error.code, message: error.message })\r\n if (error instanceof SyntaxError) return json(res, 400, { error: 'invalid-json' })\r\n return json(res, 500, { error: 'ask-unavailable', message: 'The question could not be sent.' })\r\n }\r\n res.writeHead(200, {\r\n 'content-type': 'application/x-ndjson; charset=utf-8',\r\n 'cache-control': 'no-store',\r\n 'x-content-type-options': 'nosniff',\r\n })\r\n res.flushHeaders?.()\r\n try {\r\n await service.ask(cwd, request, preferencesFor(sessionId) ?? {}, event => { ndjson(res, event.type === 'text' ? { type: 'delta', text: event.text } : event) }, io.signal)\r\n ndjson(res, { type: 'done' })\r\n } catch (error) {\r\n ndjson(res, {\r\n type: 'error',\r\n code: error instanceof AskError ? error.code : 'ask-unavailable',\r\n message: error instanceof AskError ? error.message : 'The question could not be answered.',\r\n })\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REVIEW_COMMENT_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport { ReviewCommentError, type ReviewCommentStore } from './review-comments.ts'\r\n\r\nconst MAX_BODY_BYTES = 16 * 1024\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\r\n let parsed: unknown\r\n try {\r\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\r\n } catch (error) {\r\n if (error instanceof SyntaxError) throw error\r\n throw new ReviewCommentError('body-too-large', 'The request body is too large.')\r\n }\r\n const value = record(parsed)\r\n if (value === undefined) throw new ReviewCommentError('invalid-request', 'The request body is invalid.')\r\n return value\r\n}\r\n\r\nfunction sessionIdFromUrl(url: URL): string {\r\n const value = url.searchParams.get('sessionId')\r\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) {\r\n throw new ReviewCommentError('invalid-session', 'The session is invalid.')\r\n }\r\n return value\r\n}\r\n\r\nexport function registerReviewCommentRoute(\r\n ctx: Context,\r\n store: ReviewCommentStore,\r\n ownsSession: (sessionId: string) => boolean,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'prefix',\r\n path: CLAUDE_REVIEW_COMMENT_PATH,\r\n methods: ['POST'],\r\n // The comment store is in memory; only reading the body can wait.\r\n budget: 'fast',\r\n handler: async io => {\r\n try {\r\n const sessionId = sessionIdFromUrl(io.url)\r\n if (!ownsSession(sessionId)) throw new ReviewCommentError('session-unavailable', 'The Claude session is unavailable.')\r\n const pathname = io.url.pathname\r\n if (pathname === CLAUDE_REVIEW_COMMENT_PATH) {\r\n const input = await readJson(io)\r\n const comment = store.add(sessionId, {\r\n path: input.path,\r\n line: input.line,\r\n startLine: input.startLine,\r\n side: input.side,\r\n text: input.text,\r\n })\r\n return { status: 200, value: { comment } }\r\n }\r\n if (pathname === `${CLAUDE_REVIEW_COMMENT_PATH}/clear`) {\r\n return { status: 200, value: { removed: store.drain(sessionId).length } }\r\n }\r\n if (pathname === `${CLAUDE_REVIEW_COMMENT_PATH}/remove`) {\r\n const input = await readJson(io)\r\n if (typeof input.id !== 'string' || input.id.length === 0 || input.id.length > 128) {\r\n throw new ReviewCommentError('invalid-request', 'The comment id is invalid.')\r\n }\r\n return { status: 200, value: { removed: store.remove(sessionId, input.id) } }\r\n }\r\n return { status: 404, value: { error: 'not found' } }\r\n } catch (error) {\r\n if (error instanceof ReviewCommentError) return { status: 409, value: { error: error.code, message: error.message } }\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 500, value: { error: 'review-comment-unavailable', message: 'Review comments are unavailable.' } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_PLAN_FEEDBACK_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport { PlanFeedbackError, planNotesOf, type PlanFeedbackGate } from './plan-feedback.ts'\r\n\r\nconst MAX_BODY_BYTES = 64 * 1024\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\nconst MAX_TOOL_USE_ID_CHARS = 256\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\r\n let parsed: unknown\r\n try {\r\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\r\n } catch (error) {\r\n if (error instanceof SyntaxError) throw error\r\n throw new PlanFeedbackError('body-too-large', 'The request body is too large.')\r\n }\r\n const value = record(parsed)\r\n if (value === undefined) throw new PlanFeedbackError('invalid-request', 'The request body is invalid.')\r\n return value\r\n}\r\n\r\n/** Send one plan back for changes.\r\n *\r\n * Unary rather than a stream: the panel hands over what the reviewer wrote\r\n * and the turn carries on in the transcript it was already watching. Answers\r\n * 409 when nothing is waiting, which is what the panel shows if the approval\r\n * dialog was answered while the reviewer was still typing. */\r\nexport function registerPlanFeedbackRoute(\r\n ctx: Context,\r\n gate: PlanFeedbackGate,\r\n ownsSession: (sessionId: string) => boolean,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n budget: 'fast',\r\n kind: 'exact',\r\n path: CLAUDE_PLAN_FEEDBACK_PATH,\r\n methods: ['POST'],\r\n handler: async io => {\r\n try {\r\n const sessionId = io.url.searchParams.get('sessionId')\r\n if (sessionId === null || sessionId.length === 0 || sessionId.length > MAX_SESSION_ID_CHARS) {\r\n return { status: 400, value: { error: 'invalid-session' } }\r\n }\r\n if (!ownsSession(sessionId)) return { status: 409, value: { error: 'session-unavailable' } }\r\n const body = await readJson(io)\r\n const toolUseId = body.toolUseId\r\n if (typeof toolUseId !== 'string' || toolUseId.length === 0 || toolUseId.length > MAX_TOOL_USE_ID_CHARS) {\r\n return { status: 400, value: { error: 'invalid-request' } }\r\n }\r\n const notes = planNotesOf(body.notes)\r\n // A plan that is no longer open was decided in the dialog while the\r\n // reviewer was writing; saying so beats silently dropping their notes.\r\n if (!gate.submit(toolUseId, notes)) return { status: 409, value: { error: 'plan-settled' } }\r\n return { status: 200, value: { ok: true } }\r\n } catch (error) {\r\n if (error instanceof PlanFeedbackError) return { status: 400, value: { error: error.code, message: error.message } }\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 500, value: { error: 'plan-feedback-unavailable' } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_CLIENT_DIAGNOSTICS_PATH } from './constants.ts'\r\nimport { redactText } from './events.ts'\r\nimport { registerPluginRoute } from './http.ts'\r\n\r\n/** Enough for a message plus a trimmed stack; the client caps its own volume. */\r\nconst MAX_DIAGNOSTIC_BYTES = 8 * 1024\r\nconst MAX_DETAIL_CHARS = 2_000\r\nconst MAX_KIND_CHARS = 60\r\n\r\n/** `POST <path>` with `{ kind, detail }`: write one renderer finding to the Host log.\r\n *\r\n * The renderer has no other way to speak. A Slot entry that throws is caught\r\n * by the Host's Slot system and dropped, the shipped Desktop opens no\r\n * DevTools, and startup still reports `rendererStatus: \"healthy\"` — so a\r\n * plugin whose UI died silently is indistinguishable from a working one.\r\n * Every finding here is data written by this package's own client half, but\r\n * it is still bounded and redacted like any other untrusted input. */\r\nexport function registerClaudeClientDiagnosticsRoute(ctx: Context): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_CLIENT_DIAGNOSTICS_PATH,\r\n methods: ['POST'],\r\n budget: 'fast',\r\n handler: async io => {\r\n try {\r\n const body = await io.body<{ kind?: unknown; detail?: unknown } | null>(MAX_DIAGNOSTIC_BYTES)\r\n const kind = typeof body?.kind === 'string' ? body.kind.slice(0, MAX_KIND_CHARS) : 'unknown'\r\n const detail = typeof body?.detail === 'string' ? body.detail : ''\r\n if (detail === '') return { status: 400, value: { error: 'invalid-request' } }\r\n ctx.logger.warn(`dsh-claude client [${kind}]: ${redactText(detail, MAX_DETAIL_CHARS)}`)\r\n return { status: 200, value: { ok: true } }\r\n } catch (error) {\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 400, value: { error: 'invalid-request' } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type { SessionEvent } from '@deepseek-ai/dsh-session'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_REWIND_PATH } from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\nimport { EMPTY_REWIND_STATE, planRewind, rewindRestoreTree, turnAtOrAfter } from './rewind.ts'\r\nimport type { ClaudeSidecarRepository } from './sidecar.ts'\r\n\r\nconst MAX_BODY_BYTES = 4 * 1024\r\nconst MAX_SESSION_ID_CHARS = 1_024\r\n\r\nexport interface ClaudeRewindSessionAccess {\r\n /** The session log of one plugin-owned session, or undefined for any other. */\r\n eventsFor: (sessionId: string) => readonly SessionEvent[] | undefined\r\n /** Whether a turn is in flight; rewinding one would cut it mid-run. */\r\n busy: (sessionId: string) => boolean\r\n /** Drop the live Claude process so the next turn resumes at the fork target. */\r\n reset: (sessionId: string) => Promise<void>\r\n /** Put the session's checkout back to a captured tree, reporting whether it\r\n * landed. Absent when the Host offers no way to run git. */\r\n restoreFiles?: (sessionId: string, tree: string) => Promise<boolean>\r\n}\r\n\r\nfunction record(value: unknown): Record<string, unknown> | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\r\n}\r\n\r\n/** An oversized body fails the same field checks as a missing one; only\r\n * malformed JSON is worth reporting separately. */\r\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown> | undefined> {\r\n try {\r\n return record(await io.body<unknown>(MAX_BODY_BYTES))\r\n } catch (error) {\r\n if (error instanceof SyntaxError) throw error\r\n return undefined\r\n }\r\n}\r\n\r\n/** `POST <path>` with `{ sessionId, seq, restoreFiles? }`: hide that surface\r\n * event and every later one, and arm Claude to resume before the turn it\r\n * opened. With `restoreFiles`, the checkout is also put back to the tree that\r\n * turn was admitted against.\r\n *\r\n * The conversation rewind is what the user confirmed, so it lands first and\r\n * stands on its own; a checkout that cannot be restored — no snapshot, a\r\n * collected tree, no git — reports `filesRestored: false` rather than\r\n * failing the rewind. */\r\nexport function registerClaudeRewindRoute(\r\n ctx: Context,\r\n sidecar: ClaudeSidecarRepository,\r\n access: ClaudeRewindSessionAccess,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_REWIND_PATH,\r\n methods: ['POST'],\r\n // The session log is already in memory; the sidecar write is local.\r\n budget: 'git',\r\n handler: async io => {\r\n try {\r\n const input = await readJson(io)\r\n const sessionId = input?.sessionId\r\n const seq = input?.seq\r\n if (typeof sessionId !== 'string' || sessionId.length === 0 || sessionId.length > MAX_SESSION_ID_CHARS\r\n || typeof seq !== 'number' || !Number.isSafeInteger(seq) || seq < 0) {\r\n return { status: 400, value: { error: 'invalid-request' } }\r\n }\r\n const events = access.eventsFor(sessionId)\r\n if (events === undefined) return { status: 409, value: { error: 'session-unavailable' } }\r\n if (access.busy(sessionId)) return { status: 409, value: { error: 'session-busy' } }\r\n const current = (await sidecar.read(sessionId)).rewind ?? EMPTY_REWIND_STATE\r\n const planned = planRewind(current, events, seq)\r\n if (planned === undefined) return { status: 409, value: { error: 'seq-unavailable' } }\r\n const tree = input?.restoreFiles === true ? rewindRestoreTree(current, events, seq) : undefined\r\n // The first turn the rewind discards, so the projection drops its\r\n // activity alongside the hidden seq ranges. Undefined when the cut\r\n // lands past the last turn, which discards no turn at all.\r\n await sidecar.writeRewind(sessionId, planned, turnAtOrAfter(events, seq))\r\n await access.reset(sessionId)\r\n const filesRestored = tree === undefined || access.restoreFiles === undefined\r\n ? false\r\n : await access.restoreFiles(sessionId, tree).catch(() => false)\r\n return { status: 200, value: { ranges: planned.ranges, filesRestored } }\r\n } catch (error) {\r\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\r\n return { status: 500, value: { error: 'rewind-unavailable' } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\r\nimport { resolveDshHome } from '@deepseek-ai/dsh-home-paths'\r\nimport { opendir, readFile, realpath } from 'node:fs/promises'\r\nimport { dirname, join, resolve } from 'node:path'\r\nimport { fileURLToPath } from 'node:url'\r\nimport { CLAUDE_UPDATE_CHECK_PATH, CLAUDE_UPDATE_PATH } from './constants.ts'\r\nimport { redactText } from './events.ts'\r\nimport { registerPluginRoute, type PluginMethod } from './http.ts'\r\n\r\nexport const PLUGIN_PACKAGE_NAME = '@norman-else/dsh-claude'\r\nconst MAX_MANIFEST_BYTES = 256 * 1024\r\nconst MAX_UPDATE_OUTPUT_BYTES = 32 * 1024\r\nconst SEMVER = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/\r\nconst PROFILE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/\r\n\r\nexport type InstallSource = 'registry' | 'link' | 'unsupported' | 'unknown'\r\nexport type UpdateState = 'current' | 'available' | 'linked' | 'unsupported' | 'unavailable' | 'error'\r\n\r\nexport interface PluginUpdateStatus {\r\n currentVersion: string\r\n latestVersion?: string\r\n source: InstallSource\r\n state: UpdateState\r\n canUpdate: boolean\r\n restartRequired: boolean\r\n message?: string\r\n}\r\n\r\ninterface PackageManifest {\r\n name?: unknown\r\n version?: unknown\r\n dependencies?: unknown\r\n}\r\n\r\nexport interface Installation {\r\n profile: string\r\n profileDir: string\r\n source: InstallSource\r\n spec: string\r\n}\r\n\r\nexport interface UpdateDependencies {\r\n packageDir?: string\r\n dshHome?: string\r\n fetchLatest?: (signal: AbortSignal) => Promise<string>\r\n resolveExecutable?: (name: string, env?: Readonly<Record<string, string>>, signal?: AbortSignal) => Promise<string>\r\n spawn?: SubprocessRuntime['spawn']\r\n requestRestart?: () => void\r\n}\r\n\r\n/** The route owns the deadline now. A direct caller with nothing to cancel\r\n * against gets a signal that never fires, rather than a second timeout\r\n * competing with the budget the route already declared. */\r\nconst NEVER_ABORTS = new AbortController().signal\r\n\r\nfunction safeMessage(error: unknown): string {\r\n return redactText(error instanceof Error ? error.message : String(error), 500)\r\n}\r\n\r\nasync function readManifest(path: string): Promise<PackageManifest> {\r\n const text = await readFile(path, 'utf8')\r\n if (Buffer.byteLength(text) > MAX_MANIFEST_BYTES) throw new Error('package manifest is too large')\r\n const value = JSON.parse(text) as unknown\r\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('package manifest is invalid')\r\n return value as PackageManifest\r\n}\r\n\r\nfunction dependencySpec(manifest: PackageManifest): string | undefined {\r\n if (typeof manifest.dependencies !== 'object' || manifest.dependencies === null || Array.isArray(manifest.dependencies)) return undefined\r\n const value = (manifest.dependencies as Record<string, unknown>)[PLUGIN_PACKAGE_NAME]\r\n return typeof value === 'string' && value.length <= 2_000 ? value : undefined\r\n}\r\n\r\nexport function classifyInstallSpec(spec: string): InstallSource {\r\n if (/^(?:link|file|workspace):/i.test(spec)) return 'link'\r\n if (/^(?:git(?:\\+[^:]+)?:|github:|https?:|npm:)/i.test(spec) || /\\.git(?:#|$)/i.test(spec)) return 'unsupported'\r\n return /^(?:\\^|~|>=?|<=?|=)?\\s*v?\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\s*\\|\\|\\s*(?:\\^|~|>=?|<=?|=)?\\s*v?\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)*$/.test(spec.trim())\r\n ? 'registry'\r\n : 'unsupported'\r\n}\r\n\r\nasync function samePath(left: string, right: string): Promise<boolean> {\r\n try {\r\n const [a, b] = await Promise.all([realpath(left), realpath(right)])\r\n return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nfunction linkedTarget(profileDir: string, spec: string): string | undefined {\r\n const match = /^(?:link|file):(.*)$/i.exec(spec)\r\n return match?.[1] === undefined ? undefined : resolve(profileDir, match[1])\r\n}\r\n\r\nexport async function discoverInstallation(dshHome: string, packageDir: string): Promise<Installation | undefined> {\r\n const profilesDir = join(dshHome, 'profiles')\r\n const matches: Installation[] = []\r\n let profiles\r\n try {\r\n profiles = await opendir(profilesDir)\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\r\n throw error\r\n }\r\n for await (const entry of profiles) {\r\n if (!entry.isDirectory() || !PROFILE_NAME.test(entry.name)) continue\r\n const profileDir = join(profilesDir, entry.name)\r\n let manifest: PackageManifest\r\n try {\r\n manifest = await readManifest(join(profileDir, 'package.json'))\r\n } catch {\r\n continue\r\n }\r\n const spec = dependencySpec(manifest)\r\n if (spec === undefined) continue\r\n const source = classifyInstallSpec(spec)\r\n const matchesPackage = source === 'link'\r\n ? linkedTarget(profileDir, spec) !== undefined && await samePath(linkedTarget(profileDir, spec)!, packageDir)\r\n : await samePath(join(profileDir, 'node_modules', ...PLUGIN_PACKAGE_NAME.split('/')), packageDir)\r\n if (matchesPackage) matches.push({ profile: entry.name, profileDir, source, spec })\r\n }\r\n return matches.length === 1 ? matches[0] : undefined\r\n}\r\n\r\nfunction parseVersion(version: string): RegExpExecArray {\r\n const match = SEMVER.exec(version)\r\n if (match === null) throw new Error('package version is not valid semver')\r\n return match\r\n}\r\n\r\nexport function compareVersions(left: string, right: string): number {\r\n const a = parseVersion(left)\r\n const b = parseVersion(right)\r\n for (const index of [1, 2, 3]) {\r\n const difference = Number(a[index]) - Number(b[index])\r\n if (difference !== 0) return Math.sign(difference)\r\n }\r\n const aPre = a[4]\r\n const bPre = b[4]\r\n if (aPre === undefined) return bPre === undefined ? 0 : 1\r\n if (bPre === undefined) return -1\r\n return aPre.localeCompare(bPre, 'en', { numeric: true })\r\n}\r\n\r\nasync function registryLatest(signal: AbortSignal): Promise<string> {\r\n const response = await fetch('https://registry.npmjs.org/%40norman-else%2Fdsh-claude', {\r\n headers: { accept: 'application/vnd.npm.install-v1+json' },\r\n signal,\r\n })\r\n if (!response.ok) throw new Error(`npm registry returned HTTP ${response.status}`)\r\n const payload = await response.json() as { 'dist-tags'?: { latest?: unknown } }\r\n const latest = payload['dist-tags']?.latest\r\n if (typeof latest !== 'string') throw new Error('npm registry response has no latest version')\r\n parseVersion(latest)\r\n return latest\r\n}\r\n\r\nasync function resolvePackageContextDir(configured?: string): Promise<{ packageDir: string; manifest: PackageManifest }> {\r\n const moduleDir = dirname(fileURLToPath(import.meta.url))\r\n const candidates = configured === undefined ? [moduleDir, dirname(moduleDir)] : [configured]\r\n for (const packageDir of candidates) {\r\n try {\r\n const manifest = await readManifest(join(packageDir, 'package.json'))\r\n if (manifest.name === PLUGIN_PACKAGE_NAME) return { packageDir, manifest }\r\n } catch {\r\n // Continue until the owning package manifest is found.\r\n }\r\n }\r\n throw new Error('plugin package manifest is invalid')\r\n}\r\n\r\nasync function packageContext(deps: UpdateDependencies): Promise<{ version: string; installation?: Installation }> {\r\n const { packageDir, manifest } = await resolvePackageContextDir(deps.packageDir)\r\n if (typeof manifest.version !== 'string') throw new Error('plugin package manifest is invalid')\r\n parseVersion(manifest.version)\r\n const home = deps.dshHome ?? resolveDshHome()\r\n const installation = await discoverInstallation(home, packageDir)\r\n return { version: manifest.version, ...(installation === undefined ? {} : { installation }) }\r\n}\r\n\r\nexport async function checkPluginUpdate(deps: UpdateDependencies = {}, signal: AbortSignal = NEVER_ABORTS): Promise<PluginUpdateStatus> {\r\n try {\r\n const { version, installation } = await packageContext(deps)\r\n if (installation === undefined) return { currentVersion: version, source: 'unknown', state: 'unavailable', canUpdate: false, restartRequired: false, message: 'Active DSH profile could not be identified uniquely' }\r\n if (installation.source === 'link') return { currentVersion: version, source: 'link', state: 'linked', canUpdate: false, restartRequired: false, message: 'Local development link; updates come from the linked checkout' }\r\n if (installation.source !== 'registry') return { currentVersion: version, source: installation.source, state: 'unsupported', canUpdate: false, restartRequired: false, message: 'This installation source cannot be updated from the npm registry' }\r\n const latest = await (deps.fetchLatest ?? registryLatest)(signal)\r\n const comparison = compareVersions(version, latest)\r\n return {\r\n currentVersion: version,\r\n latestVersion: latest,\r\n source: 'registry',\r\n state: comparison < 0 ? 'available' : 'current',\r\n canUpdate: comparison < 0,\r\n restartRequired: comparison < 0,\r\n }\r\n } catch (error) {\r\n return { currentVersion: 'unknown', source: 'unknown', state: 'error', canUpdate: false, restartRequired: false, message: safeMessage(error) }\r\n }\r\n}\r\n\r\nasync function verifyInstalledVersion(installation: Installation, expectedVersion: string): Promise<void> {\r\n const profileManifest = await readManifest(join(installation.profileDir, 'package.json'))\r\n if (dependencySpec(profileManifest) !== expectedVersion) {\r\n throw new Error('DSH plugin update completed without updating the profile dependency')\r\n }\r\n const installedManifest = await readManifest(join(\r\n installation.profileDir,\r\n 'node_modules',\r\n ...PLUGIN_PACKAGE_NAME.split('/'),\r\n 'package.json',\r\n ))\r\n if (installedManifest.name !== PLUGIN_PACKAGE_NAME || installedManifest.version !== expectedVersion) {\r\n throw new Error('DSH plugin update completed without installing the requested version')\r\n }\r\n}\r\n\r\nexport async function updatePlugin(deps: UpdateDependencies = {}, signal: AbortSignal = NEVER_ABORTS): Promise<PluginUpdateStatus> {\r\n const { version, installation } = await packageContext(deps)\r\n if (installation === undefined || installation.source !== 'registry') throw new Error('Plugin update is unavailable for this installation')\r\n const latest = await (deps.fetchLatest ?? registryLatest)(signal)\r\n if (compareVersions(version, latest) >= 0) return { currentVersion: version, latestVersion: latest, source: 'registry', state: 'current', canUpdate: false, restartRequired: false }\r\n const resolveExecutable = deps.resolveExecutable\r\n const spawn = deps.spawn\r\n if (resolveExecutable === undefined || spawn === undefined) throw new Error('DSH update runtime is unavailable')\r\n const executable = await resolveExecutable('dsh', {}, signal)\r\n const handle = spawn({\r\n argv: [executable, 'plugin', '--profile', installation.profile, 'add', `${PLUGIN_PACKAGE_NAME}@${latest}`],\r\n cwd: installation.profileDir,\r\n env: {},\r\n stdio: { stdin: 'ignore', stdout: { maxBytes: MAX_UPDATE_OUTPUT_BYTES }, stderr: { maxBytes: MAX_UPDATE_OUTPUT_BYTES } },\r\n graceMs: 2_000,\r\n signal,\r\n })\r\n const outcome = await handle.done\r\n if (outcome.exitCode !== 0) {\r\n const detail = handle.collected.stderr?.readFrom(0).text ?? ''\r\n throw new Error(`DSH plugin update failed (${outcome.exitCode ?? outcome.signal ?? 'unknown exit'}): ${safeMessage(detail)}`)\r\n }\r\n await verifyInstalledVersion(installation, latest)\r\n if (deps.requestRestart !== undefined) setTimeout(() => deps.requestRestart?.(), 100).unref?.()\r\n return {\r\n currentVersion: latest,\r\n latestVersion: latest,\r\n source: 'registry',\r\n state: 'current',\r\n canUpdate: false,\r\n restartRequired: deps.requestRestart === undefined,\r\n message: deps.requestRestart === undefined\r\n ? 'Update installed; restart DSH Desktop to load it'\r\n : 'Update installed; DSH Desktop is restarting to load it',\r\n }\r\n}\r\n\r\nexport function registerClaudeUpdateRoutes(ctx: Context, runtime: Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>, deps: UpdateDependencies = {}): void {\r\n const shared: UpdateDependencies = { ...deps, resolveExecutable: runtime.resolveExecutable.bind(runtime), spawn: runtime.spawn.bind(runtime) }\r\n const routes: readonly { path: string; method: PluginMethod; run: (signal: AbortSignal) => Promise<PluginUpdateStatus> }[] = [\r\n { path: CLAUDE_UPDATE_CHECK_PATH, method: 'GET', run: signal => checkPluginUpdate(shared, signal) },\r\n { path: CLAUDE_UPDATE_PATH, method: 'POST', run: signal => updatePlugin(shared, signal) },\r\n ]\r\n for (const route of routes) {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: route.path,\r\n methods: [route.method],\r\n // The npm registry, then `dsh plugin add`, then a manifest re-read.\r\n budget: 'remote',\r\n handler: async io => {\r\n try {\r\n return { status: 200, value: await route.run(io.signal) }\r\n } catch (error) {\r\n return { status: 500, value: { error: safeMessage(error) } }\r\n }\r\n },\r\n })\r\n }\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { CLAUDE_USAGE_PATH } from './constants.ts'\r\nimport { redactText } from './events.ts'\r\nimport { registerPluginRoute } from './http.ts'\r\nimport { latestPlanUsage, recordPlanUsage, type PlanUsageReport } from './plan-usage.ts'\r\n\r\nconst EMPTY: PlanUsageReport = { available: false, windows: [], fetchedAt: 0 }\r\n\r\nfunction safeMessage(error: unknown): string {\r\n return redactText(error instanceof Error ? error.message : String(error), 1_000)\r\n}\r\n\r\n/** Plan usage: GET serves the value the metadata bridge last cached (free —\r\n * it rides an already-running session), POST reads fresh numbers from a\r\n * throwaway probe process so a refresh never depends on, or disturbs, a live\r\n * Claude session. */\r\nexport function registerPlanUsageRoute(\r\n ctx: Context,\r\n probe: (fetchedAt: number) => Promise<PlanUsageReport>,\r\n now: () => number = Date.now,\r\n): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_USAGE_PATH,\r\n methods: ['GET', 'POST'],\r\n // The probe spawns a throwaway CLI; the cached GET answers from memory.\r\n budget: 'git',\r\n handler: async io => {\r\n if (io.method === 'GET') return { status: 200, value: latestPlanUsage() ?? EMPTY }\r\n try {\r\n const report = await probe(now())\r\n recordPlanUsage(report)\r\n return { status: 200, value: report }\r\n } catch (error) {\r\n return { status: 500, value: { error: safeMessage(error) } }\r\n }\r\n },\r\n })\r\n}\r\n","import { randomUUID } from 'node:crypto'\r\nimport { homedir } from 'node:os'\r\nimport { chmod, mkdir, opendir, readFile, rename, rm, writeFile } from 'node:fs/promises'\r\nimport { dirname, extname, join } from 'node:path'\r\nimport type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\r\nimport {\r\n CLAUDE_GLOBAL_SETTINGS_PATH,\r\n CLAUDE_ALERT_MODES,\r\n CLAUDE_RENDER_MODES,\r\n CLAUDE_PROSE_MODES,\r\n DEFAULT_CLAUDE_ALERT_MODE,\r\n DEFAULT_CLAUDE_PROSE_MODE,\r\n DEFAULT_CLAUDE_RENDER_MODE,\r\n isClaudeAlertMode,\r\n isClaudeProseMode,\r\n isClaudeRenderMode,\r\n type ClaudeRenderMode,\r\n} from './constants.ts'\r\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\r\n\r\nconst MAX_SETTINGS_BYTES = 256 * 1024\r\nconst MAX_REQUEST_BYTES = 8 * 1024\r\nconst MAX_STYLE_BYTES = 64 * 1024\r\nconst MAX_STYLE_FILES = 256\r\nconst BUILTIN_OUTPUT_STYLES = ['Default', 'Proactive', 'Concise', 'Explanatory', 'Learning'] as const\r\nconst STYLE_NAME = /^[\\p{L}\\p{N}][\\p{L}\\p{N} ._()\\[\\]-]{0,127}$/u\r\nconst DEFAULT_WORKTREE_BRANCH_PREFIX = 'claude'\r\nconst MAX_BRANCH_PREFIX_CHARS = 128\r\nconst MAX_PROCESSES_LIMIT = 16\r\nconst MAX_IDLE_TIMEOUT_MINUTES = 24 * 60\r\nconst DEFAULT_LIMITS: SupervisorLimits = { maxProcesses: 4, idleTimeoutMs: 30 * 60_000 }\r\n\r\ntype JsonObject = Record<string, unknown>\r\nexport type GlobalSettingEffect = 'immediate' | 'new-session' | 'next-turn' | 'next-worktree' | 'restart'\r\n\r\nexport interface GlobalSettingOption {\r\n value: string\r\n label: string\r\n source: 'built-in' | 'user' | 'configured'\r\n}\r\n\r\nexport type GlobalSettingView = {\r\n key: string\r\n kind: 'select'\r\n value: string\r\n options: readonly GlobalSettingOption[]\r\n effect: GlobalSettingEffect\r\n} | {\r\n key: string\r\n kind: 'text'\r\n value: string\r\n maxLength: number\r\n effect: GlobalSettingEffect\r\n}\r\n\r\nexport interface GlobalSettingsView {\r\n settings: readonly GlobalSettingView[]\r\n}\r\n\r\ninterface GlobalSettingsPaths {\r\n settingsFile: string\r\n outputStylesDir: string\r\n pluginSettingsFile: string\r\n}\r\n\r\n/** Effective supervisor limits: the plugin config values unless overridden in Settings. */\r\nexport interface SupervisorLimits {\r\n maxProcesses: number\r\n idleTimeoutMs: number\r\n}\r\n\r\nexport interface GlobalSettingsDependencies {\r\n paths?: Partial<GlobalSettingsPaths>\r\n /** Limits from the plugin config, shown when Settings holds no override. */\r\n defaultLimits?: SupervisorLimits\r\n /** Invoked after a successful update so live runtime state can follow. */\r\n onUpdated?: () => void | Promise<void>\r\n}\r\n\r\ninterface SelectSettingDescriptor {\r\n key: string\r\n kind: 'select'\r\n document: 'claude' | 'plugin'\r\n effect: GlobalSettingEffect\r\n options(paths: GlobalSettingsPaths): Promise<readonly GlobalSettingOption[]>\r\n read(document: JsonObject, options: readonly GlobalSettingOption[]): string\r\n apply(document: JsonObject, value: unknown, options: readonly GlobalSettingOption[]): void\r\n}\r\n\r\ninterface TextSettingDescriptor {\r\n key: string\r\n kind: 'text'\r\n document: 'claude' | 'plugin'\r\n effect: GlobalSettingEffect\r\n maxLength: number\r\n read(document: JsonObject, defaults?: SupervisorLimits): string\r\n apply(document: JsonObject, value: unknown): void\r\n}\r\n\r\ntype SettingDescriptor = SelectSettingDescriptor | TextSettingDescriptor\r\n\r\nfunction pathsFor(deps: GlobalSettingsDependencies): GlobalSettingsPaths {\r\n const root = join(homedir(), '.claude')\r\n return {\r\n settingsFile: deps.paths?.settingsFile ?? join(root, 'settings.json'),\r\n outputStylesDir: deps.paths?.outputStylesDir ?? join(root, 'output-styles'),\r\n pluginSettingsFile: deps.paths?.pluginSettingsFile ?? dshHomePath('plugins', 'dsh-claude', 'settings.json'),\r\n }\r\n}\r\n\r\nfunction object(value: unknown): JsonObject | undefined {\r\n return value !== null && typeof value === 'object' && !Array.isArray(value)\r\n ? value as JsonObject\r\n : undefined\r\n}\r\n\r\nasync function readDocument(path: string): Promise<JsonObject> {\r\n try {\r\n const text = await readFile(path, 'utf8')\r\n if (Buffer.byteLength(text) > MAX_SETTINGS_BYTES) throw new Error('Claude Code settings file is too large')\r\n const parsed = object(JSON.parse(text))\r\n if (parsed === undefined) throw new Error('Claude Code settings file must contain a JSON object')\r\n return parsed\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {}\r\n throw error\r\n }\r\n}\r\n\r\nfunction frontmatterName(text: string): string | undefined {\r\n if (!text.startsWith('---\\n') && !text.startsWith('---\\r\\n')) return undefined\r\n const normalized = text.replaceAll('\\r\\n', '\\n')\r\n const end = normalized.indexOf('\\n---\\n', 4)\r\n if (end < 0) return undefined\r\n for (const line of normalized.slice(4, end).split('\\n')) {\r\n const match = /^name:\\s*(.+?)\\s*$/.exec(line)\r\n if (match?.[1] === undefined) continue\r\n const raw = match[1]\r\n const value = (raw.startsWith('\"') && raw.endsWith('\"')) || (raw.startsWith(\"'\") && raw.endsWith(\"'\"))\r\n ? raw.slice(1, -1)\r\n : raw\r\n return STYLE_NAME.test(value) ? value : undefined\r\n }\r\n return undefined\r\n}\r\n\r\nasync function userOutputStyleOptions(directory: string): Promise<GlobalSettingOption[]> {\r\n const options: GlobalSettingOption[] = []\r\n let entries\r\n try {\r\n entries = await opendir(directory)\r\n } catch (error) {\r\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return options\r\n throw error\r\n }\r\n for await (const entry of entries) {\r\n if (options.length >= MAX_STYLE_FILES) break\r\n if (!entry.isFile() || extname(entry.name).toLowerCase() !== '.md') continue\r\n try {\r\n const text = await readFile(join(directory, entry.name), 'utf8')\r\n if (Buffer.byteLength(text) > MAX_STYLE_BYTES) continue\r\n const name = frontmatterName(text) ?? entry.name.slice(0, -3)\r\n if (STYLE_NAME.test(name)) options.push({ value: name, label: name, source: 'user' })\r\n } catch {\r\n // Ignore unreadable or malformed optional style files.\r\n }\r\n }\r\n return options\r\n}\r\n\r\nconst OUTPUT_STYLE: SettingDescriptor = {\r\n key: 'outputStyle',\r\n kind: 'select',\r\n document: 'claude',\r\n effect: 'new-session',\r\n async options(paths) {\r\n const builtIn = BUILTIN_OUTPUT_STYLES.map(value => ({ value, label: value, source: 'built-in' as const }))\r\n const user = await userOutputStyleOptions(paths.outputStylesDir)\r\n const seen = new Set<string>(builtIn.map(option => option.value))\r\n return [...builtIn, ...user.filter(option => !seen.has(option.value)).sort((a, b) => a.label.localeCompare(b.label))]\r\n },\r\n read(document, options) {\r\n const value = document.outputStyle\r\n return typeof value === 'string' && STYLE_NAME.test(value) ? value : 'Default'\r\n },\r\n apply(document, value, options) {\r\n if (typeof value !== 'string' || !options.some(option => option.value === value)) {\r\n throw new Error('Invalid value for global setting outputStyle')\r\n }\r\n if (value === 'Default') delete document.outputStyle\r\n else document.outputStyle = value\r\n },\r\n}\r\n\r\nexport function isValidWorktreeBranchPrefix(value: string): boolean {\r\n return value.length > 0\r\n && value.length <= MAX_BRANCH_PREFIX_CHARS\r\n && value.trim() === value\r\n && !value.startsWith('/')\r\n && !value.endsWith('/')\r\n && !value.includes('//')\r\n && !value.includes('..')\r\n && !value.includes('@{')\r\n && !/[\\0-\\x20\\x7f~^:?*[\\\\]/u.test(value)\r\n && value.split('/').every(segment => segment.length > 0 && !segment.startsWith('.') && !segment.endsWith('.lock'))\r\n}\r\n\r\nconst WORKTREE_BRANCH_PREFIX: TextSettingDescriptor = {\r\n key: 'worktreeBranchPrefix',\r\n kind: 'text',\r\n document: 'plugin',\r\n effect: 'next-worktree',\r\n maxLength: MAX_BRANCH_PREFIX_CHARS,\r\n read(document) {\r\n const value = document.worktreeBranchPrefix\r\n return typeof value === 'string' && isValidWorktreeBranchPrefix(value) ? value : DEFAULT_WORKTREE_BRANCH_PREFIX\r\n },\r\n apply(document, value) {\r\n if (typeof value !== 'string' || !isValidWorktreeBranchPrefix(value)) {\r\n throw new Error('Invalid value for global setting worktreeBranchPrefix')\r\n }\r\n if (value === DEFAULT_WORKTREE_BRANCH_PREFIX) delete document.worktreeBranchPrefix\r\n else document.worktreeBranchPrefix = value\r\n },\r\n}\r\n\r\n/** Which renderer draws Claude's visible output. Plugin settings, not Claude's:\r\n * the CLI has no opinion about how DSH paints a turn. The option labels stay\r\n * machine-readable ids; the Client translates the two known values. */\r\nconst RENDERER: SelectSettingDescriptor = {\r\n key: 'renderer',\r\n kind: 'select',\r\n document: 'plugin',\r\n // The Host reads this per message and stamps every record it writes with the\r\n // renderer that produced it, so the switch lands on the next turn and a turn\r\n // already recorded keeps the renderer it was recorded with.\r\n effect: 'next-turn',\r\n async options() {\r\n return CLAUDE_RENDER_MODES.map(value => ({ value, label: value, source: 'built-in' as const }))\r\n },\r\n read(document) {\r\n const value = document.renderer\r\n return isClaudeRenderMode(value) ? value : DEFAULT_CLAUDE_RENDER_MODE\r\n },\r\n apply(document, value) {\r\n if (!isClaudeRenderMode(value)) throw new Error('Invalid value for global setting renderer')\r\n if (value === DEFAULT_CLAUDE_RENDER_MODE) delete document.renderer\r\n else document.renderer = value\r\n },\r\n}\r\n\r\n/** Whether Claude's prose gets the highlight palette. Presentation only: no\r\n * record carries it and nothing on the server reads it back, so unlike\r\n * {@link RENDERER} the switch lands the moment the Client rewrites its own\r\n * stylesheet — hence 'immediate' rather than 'next-turn'. */\r\nconst PROSE: SelectSettingDescriptor = {\r\n key: 'prose',\r\n kind: 'select',\r\n document: 'plugin',\r\n effect: 'immediate',\r\n async options() {\r\n return CLAUDE_PROSE_MODES.map(value => ({ value, label: value, source: 'built-in' as const }))\r\n },\r\n read(document) {\r\n const value = document.prose\r\n return isClaudeProseMode(value) ? value : DEFAULT_CLAUDE_PROSE_MODE\r\n },\r\n apply(document, value) {\r\n if (!isClaudeProseMode(value)) throw new Error('Invalid value for global setting prose')\r\n if (value === DEFAULT_CLAUDE_PROSE_MODE) delete document.prose\r\n else document.prose = value\r\n },\r\n}\r\n\r\n/** Whether a session that needs the user interrupts them. Presentation only,\r\n * and read by the Client at delivery time, so like {@link PROSE} the switch\r\n * lands the moment it is saved. */\r\nconst ALERTS: SelectSettingDescriptor = {\r\n key: 'alerts',\r\n kind: 'select',\r\n document: 'plugin',\r\n effect: 'immediate',\r\n async options() {\r\n return CLAUDE_ALERT_MODES.map(value => ({ value, label: value, source: 'built-in' as const }))\r\n },\r\n read(document) {\r\n const value = document.alerts\r\n return isClaudeAlertMode(value) ? value : DEFAULT_CLAUDE_ALERT_MODE\r\n },\r\n apply(document, value) {\r\n if (!isClaudeAlertMode(value)) throw new Error('Invalid value for global setting alerts')\r\n if (value === DEFAULT_CLAUDE_ALERT_MODE) delete document.alerts\r\n else document.alerts = value\r\n },\r\n}\r\n\r\nfunction isBoundedInteger(value: unknown, min: number, max: number): value is number {\r\n return typeof value === 'number' && Number.isInteger(value) && value >= min && value <= max\r\n}\r\n\r\nfunction integerSetting(\n key: 'maxProcesses' | 'idleTimeoutMinutes',\n min: number,\n max: number,\n defaultFor: (limits: SupervisorLimits) => number,\n effect: GlobalSettingEffect = 'new-session',\n): TextSettingDescriptor {\n return {\r\n key,\r\n kind: 'text',\r\n document: 'plugin',\r\n effect,\n maxLength: String(max).length,\r\n read(document, defaults = DEFAULT_LIMITS) {\r\n const value = document[key]\r\n return String(isBoundedInteger(value, min, max) ? value : defaultFor(defaults))\r\n },\r\n apply(document, value) {\r\n const parsed = typeof value === 'string' && /^\\d{1,6}$/u.test(value.trim()) ? Number(value.trim()) : value\r\n if (!isBoundedInteger(parsed, min, max)) throw new Error(`Invalid value for global setting ${key}`)\r\n document[key] = parsed\r\n },\r\n }\r\n}\r\n\r\nconst MAX_PROCESSES = integerSetting('maxProcesses', 1, MAX_PROCESSES_LIMIT, limits => limits.maxProcesses, 'immediate')\nconst IDLE_TIMEOUT_MINUTES = integerSetting('idleTimeoutMinutes', 1, MAX_IDLE_TIMEOUT_MINUTES, limits => Math.max(1, Math.round(limits.idleTimeoutMs / 60_000)))\r\n\r\nconst DESCRIPTORS: readonly SettingDescriptor[] = [OUTPUT_STYLE, RENDERER, PROSE, ALERTS, WORKTREE_BRANCH_PREFIX, MAX_PROCESSES, IDLE_TIMEOUT_MINUTES]\r\nconst DESCRIPTOR_BY_KEY = new Map(DESCRIPTORS.map(descriptor => [descriptor.key, descriptor]))\r\nlet pendingWrite: Promise<unknown> = Promise.resolve()\r\n\r\nfunction documentFor(descriptor: SettingDescriptor, documents: { claude: JsonObject; plugin: JsonObject }): JsonObject {\r\n return documents[descriptor.document]\r\n}\r\n\r\nasync function views(documents: { claude: JsonObject; plugin: JsonObject }, paths: GlobalSettingsPaths, defaults: SupervisorLimits): Promise<GlobalSettingsView> {\r\n return {\r\n settings: await Promise.all(DESCRIPTORS.map(async descriptor => {\r\n const document = documentFor(descriptor, documents)\r\n if (descriptor.kind === 'text') {\r\n return {\r\n key: descriptor.key,\r\n kind: descriptor.kind,\r\n value: descriptor.read(document, defaults),\r\n maxLength: descriptor.maxLength,\r\n effect: descriptor.effect,\r\n }\r\n }\r\n const discovered = await descriptor.options(paths)\r\n const value = descriptor.read(document, discovered)\r\n const options = discovered.some(option => option.value === value)\r\n ? discovered\r\n : [...discovered, { value, label: value, source: 'configured' as const }]\r\n return {\r\n key: descriptor.key,\r\n kind: descriptor.kind,\r\n value,\r\n options,\r\n effect: descriptor.effect,\r\n }\r\n })),\r\n }\r\n}\r\n\r\nasync function readDocuments(paths: GlobalSettingsPaths): Promise<{ claude: JsonObject; plugin: JsonObject }> {\r\n const [claude, plugin] = await Promise.all([readDocument(paths.settingsFile), readDocument(paths.pluginSettingsFile)])\r\n return { claude, plugin }\r\n}\r\n\r\nexport async function readGlobalSettings(deps: GlobalSettingsDependencies = {}): Promise<GlobalSettingsView> {\r\n const paths = pathsFor(deps)\r\n return views(await readDocuments(paths), paths, deps.defaultLimits ?? DEFAULT_LIMITS)\r\n}\r\n\r\n/** Supervisor limits the user overrode in Settings; absent keys fall back to the plugin config. */\r\nexport async function readSupervisorLimitOverrides(deps: GlobalSettingsDependencies = {}): Promise<Partial<SupervisorLimits>> {\r\n let document: JsonObject\r\n try {\r\n document = await readDocument(pathsFor(deps).pluginSettingsFile)\r\n } catch {\r\n return {}\r\n }\r\n const maxProcesses = document.maxProcesses\r\n const idleTimeoutMinutes = document.idleTimeoutMinutes\r\n return {\r\n ...(isBoundedInteger(maxProcesses, 1, MAX_PROCESSES_LIMIT) ? { maxProcesses } : {}),\r\n ...(isBoundedInteger(idleTimeoutMinutes, 1, MAX_IDLE_TIMEOUT_MINUTES) ? { idleTimeoutMs: idleTimeoutMinutes * 60_000 } : {}),\r\n }\r\n}\r\n\r\n/** The renderer the Host should produce output for. A missing, unreadable, or\r\n * malformed plugin settings file keeps today's plugin-owned transcript. */\r\nexport async function readRenderMode(deps: GlobalSettingsDependencies = {}): Promise<ClaudeRenderMode> {\r\n let document: JsonObject\r\n try {\r\n document = await readDocument(pathsFor(deps).pluginSettingsFile)\r\n } catch {\r\n return DEFAULT_CLAUDE_RENDER_MODE\r\n }\r\n return isClaudeRenderMode(document.renderer) ? document.renderer : DEFAULT_CLAUDE_RENDER_MODE\r\n}\r\n\r\nexport async function readWorktreeBranchPrefix(deps: GlobalSettingsDependencies = {}): Promise<string> {\r\n const paths = pathsFor(deps)\r\n return WORKTREE_BRANCH_PREFIX.read(await readDocument(paths.pluginSettingsFile))\r\n}\r\n\r\nasync function atomicWrite(path: string, document: JsonObject): Promise<void> {\r\n await mkdir(dirname(path), { recursive: true, mode: 0o700 })\r\n const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`\r\n try {\r\n await writeFile(temporary, `${JSON.stringify(document, null, 2)}\\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\r\n await chmod(temporary, 0o600)\r\n await rename(temporary, path)\r\n await chmod(path, 0o600)\r\n } finally {\r\n await rm(temporary, { force: true }).catch(() => undefined)\r\n }\r\n}\r\n\r\nexport function updateGlobalSettings(changes: unknown, deps: GlobalSettingsDependencies = {}): Promise<GlobalSettingsView> {\r\n const changeObject = object(changes)\r\n if (changeObject === undefined || Object.keys(changeObject).length === 0) {\r\n return Promise.reject(new Error('Global settings changes must be a non-empty object'))\r\n }\r\n for (const key of Object.keys(changeObject)) {\r\n if (!DESCRIPTOR_BY_KEY.has(key)) return Promise.reject(new Error(`Unsupported global setting: ${key}`))\r\n }\r\n const paths = pathsFor(deps)\r\n const operation = pendingWrite.catch(() => undefined).then(async () => {\r\n const documents = await readDocuments(paths)\r\n const changedDocuments = new Set<'claude' | 'plugin'>()\r\n for (const [key, value] of Object.entries(changeObject)) {\r\n const descriptor = DESCRIPTOR_BY_KEY.get(key)!\r\n const document = documentFor(descriptor, documents)\r\n if (descriptor.kind === 'select') descriptor.apply(document, value, await descriptor.options(paths))\r\n else descriptor.apply(document, value)\r\n changedDocuments.add(descriptor.document)\r\n }\r\n if (changedDocuments.has('claude')) await atomicWrite(paths.settingsFile, documents.claude)\r\n if (changedDocuments.has('plugin')) await atomicWrite(paths.pluginSettingsFile, documents.plugin)\r\n return views(documents, paths, deps.defaultLimits ?? DEFAULT_LIMITS)\r\n })\r\n pendingWrite = operation\r\n return operation\r\n}\r\n\r\nasync function requestJson(io: PluginRouteIo): Promise<unknown> {\r\n const body = object(await io.body(MAX_REQUEST_BYTES))\r\n if (body === undefined || Object.keys(body).some(key => key !== 'changes')) throw new Error('Invalid global settings request')\r\n return body.changes\r\n}\r\n\r\nexport function registerClaudeGlobalSettingsRoute(ctx: Context, deps: GlobalSettingsDependencies = {}): void {\r\n registerPluginRoute(ctx, {\r\n mode: 'unary',\r\n kind: 'exact',\r\n path: CLAUDE_GLOBAL_SETTINGS_PATH,\r\n methods: ['GET', 'PATCH'],\r\n // Reads and writes two small JSON files under the home directory.\r\n budget: 'fast',\r\n handler: async io => {\r\n try {\r\n const result = io.method === 'GET'\r\n ? await readGlobalSettings(deps)\r\n : await updateGlobalSettings(await requestJson(io), deps)\r\n if (io.method === 'PATCH') await deps.onUpdated?.()\r\n return { status: 200, value: result }\r\n } catch (error) {\r\n return { status: 400, value: { error: error instanceof Error ? error.message : 'Invalid global settings request' } }\r\n }\r\n },\r\n })\r\n}\r\n","import type { Context } from '@deepseek-ai/cordis'\r\nimport type {} from '@deepseek-ai/dsh-attachment'\r\nimport z from '@deepseek-ai/schemastery'\r\nimport type { Agent } from '@deepseek-ai/dsh-agent'\r\nimport type {} from '@deepseek-ai/dsh-commands'\r\nimport type {} from '@deepseek-ai/dsh-agent-presets'\r\nimport type {} from '@deepseek-ai/dsh-host-webserver'\r\nimport type {} from '@deepseek-ai/dsh-subprocess'\r\nimport type {} from '@deepseek-ai/dsh-user-approval'\r\nimport type {} from '@deepseek-ai/dsh-user-questions'\r\nimport { CLAUDE_CODE_PRESET_ID, CLAUDE_CODE_PROVIDER_IDS } from './constants.ts'\r\nimport { CLAUDE_COMMANDS_SERVICE, projectClaudeCommands, type ClaudeAgentCommandService, type ClaudeCommandView } from './command-bridge.ts'\r\nimport { ClaudeSidecarRepository } from './sidecar.ts'\r\nimport { resolveClaudeExecutable } from './executable.ts'\r\nimport { ClaudeSupervisor } from './supervisor.ts'\r\nimport { createClaudeCodeAdapter } from './adapter.ts'\r\nimport { ensureManagedPreset, ManagedPresetConflictError } from './preset-installer.ts'\r\nimport { claudeBridgeDiagnostics, registerClaudeDoctorRoutes, type ClaudeBridgeDiagnostic } from './doctor-routes.ts'\r\nimport { registerClaudeProjectionRoute } from './projection-routes.ts'\r\nimport { RepositoryStatusService } from './repository-status.ts'\r\nimport { comparablePath, RepositorySetupService } from './repository-setup.ts'\r\nimport { summarizeBranchSlug } from './branch-name.ts'\r\nimport { summarizeSessionTitle } from './session-title.ts'\r\nimport { RepositoryActionService } from './repository-actions.ts'\r\nimport { registerRepositorySetupRoute } from './repository-setup-routes.ts'\r\nimport { registerRepositoryActionRoute } from './repository-action-routes.ts'\r\nimport { registerEditorOpenRoute } from './editor-open-routes.ts'\r\nimport { PromptAssistService, registerClaudePromptNameRoute, registerClaudePromptRefineRoute, registerClaudePromptsRoute } from './prompts.ts'\r\nimport { EditorOpenService } from './editor-open.ts'\r\nimport { PullRequestFeedbackService } from './pr-feedback.ts'\r\nimport { registerPullRequestFeedbackRoute } from './pr-feedback-routes.ts'\r\nimport { registerRepositoryStatusRoute } from './repository-status-routes.ts'\r\nimport { registerRepositoryFileRoute } from './repository-file-routes.ts'\r\nimport { JiraService } from './jira.ts'\r\nimport { registerJiraRoute } from './jira-routes.ts'\r\nimport { AskService } from './ask.ts'\r\nimport { registerAskRoute } from './ask-routes.ts'\r\nimport { registerReviewCommentRoute } from './review-comment-routes.ts'\r\nimport { registerPlanFeedbackRoute } from './plan-feedback-routes.ts'\r\nimport { registerClaudeClientDiagnosticsRoute } from './client-diagnostics-routes.ts'\r\nimport { registerClaudeRewindRoute } from './rewind-routes.ts'\r\nimport { restoreWorktreeTree } from './worktree-snapshot.ts'\r\nimport { ReviewCommentStore } from './review-comments.ts'\r\nimport { registerClaudeUpdateRoutes } from './update-routes.ts'\r\nimport { claudeModelValue, probeClaudeModels } from './model-catalog.ts'\r\nimport { normalizePlanUsage, probePlanUsage, recordPlanUsage } from './plan-usage.ts'\r\nimport { registerPlanUsageRoute } from './plan-usage-routes.ts'\r\nimport { readRenderMode, readSupervisorLimitOverrides, readWorktreeBranchPrefix, registerClaudeGlobalSettingsRoute } from './global-settings.ts'\r\n\r\nexport const name = 'llm-claude'\r\nexport const inject = ['llm', 'agents', 'agentPresets', 'commands', 'subprocess', 'approval', 'userQuestions', 'attachments']\r\n\r\nexport interface Config {\r\n executablePath?: string\r\n model?: string\r\n idleTimeoutMs?: number\r\n maxProcesses?: number\r\n}\r\n\r\nexport const Config: z<Config> = z.object({\r\n executablePath: z.string().default(''),\r\n model: z.string().default('default'),\r\n idleTimeoutMs: z.number().min(1_000).max(2_147_483_647).default(30 * 60 * 1_000),\r\n maxProcesses: z.number().step(1).min(1).default(4),\r\n})\r\n\r\nconst CLAUDE_SCOPE_UNAVAILABLE_MESSAGE = 'agent command scope unavailable (preset route not mounted?)'\r\nconst CATALOG_RETRY_MS = 5_000\r\nconst SCOPE_RETRY_MS = 500\r\nconst MAX_CATALOG_RETRIES = 3\r\nconst MAX_SCOPE_RETRIES = 24\r\n\r\nexport function mountClaudeMetadata(\r\n ctx: Context,\r\n supervisor: ClaudeSupervisor,\r\n agent: Agent,\r\n model: string,\r\n sidecar: ClaudeSidecarRepository,\r\n publishCommands: (commands: readonly ClaudeCommandView[]) => void = () => {},\r\n // IMPORTANT: call through the injected agentPresets SERVICE, never an\r\n // imported serviceForAgent() — a linked plugin resolves peer packages from\r\n // its own node_modules, which creates a second module instance with empty\r\n // module-level mount state. The service method runs on the app's instance.\r\n resolveCommands: () => ClaudeAgentCommandService | undefined =\r\n () => ctx.agentPresets.serviceFor(agent, CLAUDE_COMMANDS_SERVICE),\r\n): (() => Promise<void>) | undefined {\r\n if (ctx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID) return undefined\r\n\r\n let stopped = false\r\n let pending = Promise.resolve()\r\n let commandScope: ClaudeAgentCommandService | undefined\r\n\r\n // The commands service is unreachable from this host view of agent.ctx;\r\n // the preset route plugin provides it as an isolated per-session service.\r\n const scopedCommands = () => {\r\n const scoped = commandScope ?? resolveCommands()\r\n if (scoped === undefined) throw new Error(CLAUDE_SCOPE_UNAVAILABLE_MESSAGE)\r\n commandScope = scoped\r\n return scoped\r\n }\r\n\r\n const commandTarget = {\r\n list: () => scopedCommands().list(agent),\r\n }\r\n\r\n const warn = (area: string, error: unknown) => {\r\n ctx.logger.warn(`dsh-claude: ${area} refresh failed for ${String(agent.id)}: ${error instanceof Error ? error.message : String(error)}`)\r\n }\r\n\r\n const isScopeUnavailable = (error: unknown): boolean => {\r\n if (error instanceof Error) return error.message === CLAUDE_SCOPE_UNAVAILABLE_MESSAGE\r\n return String(error) === CLAUDE_SCOPE_UNAVAILABLE_MESSAGE\r\n }\r\n\r\n const diagnostic: ClaudeBridgeDiagnostic = claudeBridgeDiagnostics.get(agent) ?? { attempts: 0 }\r\n claudeBridgeDiagnostics.set(agent, diagnostic)\r\n\r\n // A fresh session's first catalog fetch races CLI startup (skills/plugins\r\n // can make init slow); retry with backoff so the command palette still\r\n // populates without waiting for the first completed turn.\r\n let catalogRetries = 0\r\n let scopeRetries = 0\r\n let retryTimer: ReturnType<typeof setTimeout> | undefined\r\n\r\n const scheduleRetry = (area: 'command catalog' | 'command scope', attempt: number) => {\r\n if (retryTimer !== undefined) clearTimeout(retryTimer)\r\n const delay = area === 'command catalog' ? CATALOG_RETRY_MS * attempt : Math.min(SCOPE_RETRY_MS * 2 ** attempt, 5_000)\r\n retryTimer = setTimeout(() => {\r\n if (!stopped) refresh()\r\n }, delay)\r\n retryTimer.unref?.()\r\n }\r\n\r\n const refresh = () => {\r\n pending = pending.then(async () => {\r\n if (stopped) return\r\n diagnostic.attempts += 1\r\n\r\n let catalog: Awaited<ReturnType<ClaudeSupervisor['supportedCommands']>> | undefined\r\n\r\n try {\r\n const result = await supervisor.supportedCommands(agent, model)\r\n catalog = result\r\n catalogRetries = 0\r\n scopeRetries = 0\r\n diagnostic.lastCatalog = catalog.length\r\n delete diagnostic.lastError\r\n } catch (error) {\r\n diagnostic.lastError = error instanceof Error ? error.message : String(error)\r\n warn('command catalog', error)\r\n if (!stopped && catalogRetries < MAX_CATALOG_RETRIES) {\r\n catalogRetries += 1\r\n scheduleRetry('command catalog', catalogRetries)\r\n }\r\n }\r\n\r\n if (stopped || catalog === undefined) return\r\n\r\n try {\r\n const commands = projectClaudeCommands(catalog, commandTarget)\r\n publishCommands(commands)\r\n diagnostic.registered = commands.map(view => view.publicName)\r\n if (!stopped) scopeRetries = 0\r\n } catch (error) {\r\n diagnostic.lastError = error instanceof Error ? error.message : String(error)\r\n warn('command catalog', error)\r\n if (!stopped && isScopeUnavailable(error) && scopeRetries < MAX_SCOPE_RETRIES) {\r\n scopeRetries += 1\r\n scheduleRetry('command scope', scopeRetries)\r\n }\r\n }\r\n\r\n if (stopped) return\r\n try {\r\n const usage = await supervisor.contextUsage(agent, model)\r\n if (!stopped) await sidecar.writeContextUsage(agent.id as string, usage)\r\n } catch (error) {\r\n warn('context usage', error)\r\n }\r\n\r\n if (stopped) return\r\n // Plan limits belong to the account, not the session, so any idle Claude\r\n // agent can refresh the cache the (session-less) settings page reads.\r\n try {\r\n const plan = await supervisor.planUsage(agent, model)\r\n if (!stopped) recordPlanUsage(normalizePlanUsage(plan, Date.now()))\r\n } catch (error) {\r\n warn('plan usage', error)\r\n }\r\n })\r\n }\r\n\r\n return agent.ctx.effect(() => {\r\n const stopStatus = agent.ctx.on('agent/status', ({ status }) => {\r\n if (status === 'idle') refresh()\r\n })\r\n\r\n refresh()\r\n\r\n return async () => {\r\n stopped = true\r\n publishCommands([])\r\n if (retryTimer !== undefined) clearTimeout(retryTimer)\r\n stopStatus()\r\n await pending\r\n }\r\n }, 'dsh-claude: agent metadata bridge')\r\n}\r\n\r\nexport async function installManagedPresetCompatibility(\r\n logger: Pick<Context['logger'], 'warn'>,\r\n install: typeof ensureManagedPreset = ensureManagedPreset,\r\n): Promise<'installed' | 'unchanged' | 'conflict'> {\r\n try {\r\n return await install()\r\n } catch (error) {\r\n if (!(error instanceof ManagedPresetConflictError)) throw error\r\n logger.warn(`dsh-claude: preserving user-modified preset at ${error.path}`)\r\n return 'conflict'\r\n }\r\n}\r\n\r\nexport async function apply(ctx: Context, config: Config): Promise<void> {\r\n // DSH Desktop 2.0.4 does not retain third-party preset roots from bundle\r\n // patches, so keep a guarded user-root copy. Its bare route specifier resolves\r\n // through the profile package factory and does not create a second Loader source.\r\n await installManagedPresetCompatibility(ctx.logger)\r\n const defaultLimits = {\r\n idleTimeoutMs: config.idleTimeoutMs ?? 30 * 60 * 1_000,\r\n maxProcesses: config.maxProcesses ?? 4,\r\n }\r\n const supervisorConfig = {\r\n executablePath: '',\r\n defaultModel: config.model ?? 'default',\r\n ...defaultLimits,\r\n }\r\n // Settings overrides win over the plugin config; the supervisor reads the\r\n // shared config object on every admission and idle schedule, so updates take\r\n // effect without a restart. The renderer is not kept here: the adapter reads\r\n // its file at the start of each turn and pins the answer to that turn, so\r\n // both halves of a turn -- the records the supervisor stamps and the blocks\r\n // the adapter streams -- agree about who is drawing it, and a settings file\r\n // edited outside the Settings dialog lands on the next turn all the same.\r\n const applySettingsOverrides = async (): Promise<void> => {\r\n const overrides = await readSupervisorLimitOverrides()\r\n supervisorConfig.idleTimeoutMs = overrides.idleTimeoutMs ?? defaultLimits.idleTimeoutMs\r\n supervisorConfig.maxProcesses = overrides.maxProcesses ?? defaultLimits.maxProcesses\r\n }\r\n await applySettingsOverrides()\r\n const sidecar = new ClaudeSidecarRepository()\r\n const repositoryStatus = new RepositoryStatusService(ctx.subprocess)\r\n const repositorySetup = new RepositorySetupService(ctx.subprocess, {\r\n branchPrefix: () => readWorktreeBranchPrefix(),\r\n // Read at call time: the executable is resolved after this service exists.\r\n summarizeBranch: intent => summarizeBranchSlug(supervisorConfig.executablePath, intent),\r\n })\r\n const reviewComments = new ReviewCommentStore()\r\n const commandCatalogs = new Map<string, readonly ClaudeCommandView[]>()\r\n const supervisor = new ClaudeSupervisor({\r\n runtime: ctx.subprocess,\r\n approval: ctx.approval,\r\n userQuestions: ctx.userQuestions,\r\n config: supervisorConfig,\r\n runDetached: operation => ctx.agents.withoutInitiator(operation),\r\n sidecar,\r\n })\r\n let resolutionError: unknown\r\n try {\r\n const resolution = await resolveClaudeExecutable(\r\n ctx.subprocess,\r\n config.executablePath === undefined || config.executablePath.length === 0\r\n ? undefined\r\n : config.executablePath,\r\n )\r\n supervisorConfig.executablePath = resolution.path\r\n ctx.llm.registerAdapter(\r\n [...CLAUDE_CODE_PROVIDER_IDS],\r\n createClaudeCodeAdapter(supervisor, ctx.agents, ctx.attachments, agent => ctx.agentPresets.composedPreset(agent.ctx), sessionId => reviewComments.drain(sessionId), () => readRenderMode(), request => summarizeSessionTitle(supervisorConfig.executablePath, request), () => probeClaudeModels(supervisorConfig.executablePath)),\r\n )\r\n ctx.effect(() => {\r\n const mounted = new Map<Agent, () => Promise<void>>()\r\n const pending = new Set<Agent>()\r\n const MOUNT_RETRY_MS = 200\r\n const MOUNT_RETRY_LIMIT = 50\r\n const mount = (agent: Agent) => {\r\n if (mounted.has(agent)) return\r\n const sessionId = agent.id as string\r\n const dispose = mountClaudeMetadata(\r\n ctx,\r\n supervisor,\r\n agent,\r\n supervisorConfig.defaultModel,\r\n sidecar,\r\n commands => {\r\n if (commands.length === 0) commandCatalogs.delete(sessionId)\r\n else commandCatalogs.set(sessionId, commands)\r\n },\r\n )\r\n if (dispose !== undefined) mounted.set(agent, dispose)\r\n pending.delete(agent)\r\n }\r\n // The standing preset mount lands AFTER agent/created (the PresetTree is\r\n // applied asynchronously), so composedPreset is still undefined at that\r\n // point. Poll briefly until the join settles, then decide.\r\n const mountWhenPresetSettles = (agent: Agent) => {\r\n if (mounted.has(agent) || pending.has(agent)) return\r\n if (ctx.agentPresets.composedPreset(agent.ctx) !== undefined) {\r\n mount(agent)\r\n return\r\n }\r\n pending.add(agent)\r\n let attempts = 0\r\n const retry = () => {\r\n if (mounted.has(agent) || !pending.has(agent)) return\r\n if (ctx.agentPresets.composedPreset(agent.ctx) !== undefined) {\r\n mount(agent)\r\n return\r\n }\r\n attempts += 1\r\n if (attempts >= MOUNT_RETRY_LIMIT) {\r\n pending.delete(agent)\r\n return\r\n }\r\n const timer = setTimeout(retry, MOUNT_RETRY_MS)\r\n timer.unref?.()\r\n }\r\n const timer = setTimeout(retry, MOUNT_RETRY_MS)\r\n timer.unref?.()\r\n }\r\n const stopCreated = ctx.on('agent/created', ({ agent }) => { mountWhenPresetSettles(agent) })\r\n // Belt and suspenders: the session records its preset selection as a\r\n // durable event, which agent-presets republishes as agent-preset/selected.\r\n // agent-preset/selected is emitted by dsh-agent-presets but is not part\r\n // of the typed host event map yet; subscribe through a typed escape hatch.\r\n const onPresetSelected = ctx.on as (event: 'agent-preset/selected', handler: (sessionId: string, preset: string) => void) => () => void\r\n const stopSelected = onPresetSelected('agent-preset/selected', (sessionId, preset) => {\r\n if (preset !== CLAUDE_CODE_PRESET_ID) return\r\n const agent = ctx.agents.get(sessionId as never)\r\n if (agent !== undefined) mountWhenPresetSettles(agent)\r\n })\r\n for (const agent of ctx.agents.list()) mountWhenPresetSettles(agent)\r\n return async () => {\r\n stopCreated()\r\n stopSelected()\r\n pending.clear()\r\n await Promise.allSettled([...mounted.values()].map(dispose => dispose()))\r\n mounted.clear()\r\n }\r\n }, 'dsh-claude: metadata bridges')\r\n } catch (error) {\r\n resolutionError = error\r\n }\r\n ctx.on('agent/disposed', async ({ agent }) => {\r\n reviewComments.disposeSession(agent.id as string)\r\n await supervisor.disposeSession(agent.id as string)\r\n })\r\n // Set once the reconciliation below is wired; the Client's sweep route kicks\r\n // it so a deleted workspace does not wait out the interval.\r\n let sweepWorktrees: (() => void) | undefined\r\n // Deleting a workspace from the sidebar is a durable-registry mutation with\r\n // no agent lifecycle edge, so worktree cleanup reconciles leases against\r\n // the workspace registry instead: unreferenced clean worktrees are removed\r\n // on boot, on the Client's deletion kick, and on a slow interval.\r\n // workspaceRegistry is not part of this plugin's typed host surface yet;\r\n // inject through an untyped escape hatch so older Hosts without the service\r\n // simply never start the sweep.\r\n const injectWorkspaceRegistry = ctx.inject as unknown as (\r\n deps: readonly string[],\r\n callback: (sweepCtx: Context & {\r\n workspaceRegistry: {\r\n list(): readonly { readonly path: string }[]\r\n archiveSession(sessionId: string): Promise<void>\r\n }\r\n }) => void,\r\n ) => void\r\n injectWorkspaceRegistry(['workspaceRegistry'], sweepCtx => {\r\n // Deleting a workspace only drops its registration: the Host keeps every\r\n // session log, and rebuilds the workspace from those headers on the next\r\n // boot. Archiving the sessions that lived in the worktree is what makes\r\n // the deletion stick. Resolved per sweep rather than injected so a Host\r\n // without the service still gets worktree cleanup.\r\n const archiveSessions = async (worktreePath: string): Promise<void> => {\r\n const persistence = sweepCtx.get('sessionPersistence') as {\r\n list(): Promise<readonly { readonly id?: unknown; readonly cwd?: unknown }[]>\r\n } | undefined\r\n if (persistence === undefined) return\r\n const target = comparablePath(worktreePath)\r\n for (const header of await persistence.list()) {\r\n if (typeof header.id !== 'string' || typeof header.cwd !== 'string') continue\r\n if (comparablePath(header.cwd) !== target) continue\r\n await sweepCtx.workspaceRegistry.archiveSession(header.id).catch(() => undefined)\r\n }\r\n }\r\n const sweep = (): void => {\r\n try {\r\n const paths = sweepCtx.workspaceRegistry.list().map(workspace => workspace.path)\r\n void repositorySetup.cleanupOrphans(paths, archiveSessions).catch(() => undefined)\r\n } catch {\r\n // The registry can be mid-teardown; skip this pass.\r\n }\r\n }\r\n sweepCtx.effect(() => {\r\n sweep()\r\n sweepWorktrees = sweep\r\n // The kick covers the deletion the user is watching; this poll is the\r\n // backstop for a Client that never sent one. A pass with nothing to\r\n // reconcile is one small file read.\r\n const timer = setInterval(sweep, 60_000)\r\n timer.unref?.()\r\n return () => {\r\n sweepWorktrees = undefined\r\n clearInterval(timer)\r\n }\r\n }, 'dsh-claude: worktree reconciliation')\r\n })\r\n ctx.effect(() => () => reviewComments.dispose(), 'dsh-claude: review comments store')\r\n ctx.effect(() => () => supervisor.dispose(), 'dsh-claude: process supervisor')\r\n ctx.effect(() => () => repositoryStatus.dispose(), 'dsh-claude: repository status cache')\r\n ctx.inject(['webServer'], webCtx => {\r\n registerClaudeClientDiagnosticsRoute(webCtx)\r\n registerClaudeDoctorRoutes(webCtx, webCtx.subprocess, supervisor, supervisorConfig, resolutionError)\r\n const desktopActions = webCtx.get('desktopActions') as { requestRestart?: () => void } | undefined\r\n registerClaudeUpdateRoutes(webCtx, webCtx.subprocess, {\r\n ...(typeof desktopActions?.requestRestart === 'function'\r\n ? { requestRestart: desktopActions.requestRestart.bind(desktopActions) }\r\n : {}),\r\n })\r\n registerClaudeGlobalSettingsRoute(webCtx, {\r\n defaultLimits,\r\n onUpdated: async () => {\r\n await applySettingsOverrides()\r\n supervisor.limitsChanged()\r\n },\r\n })\r\n registerRepositorySetupRoute(webCtx, repositorySetup, () => sweepWorktrees?.())\r\n registerRepositoryStatusRoute(webCtx, repositoryStatus)\r\n registerRepositoryFileRoute(webCtx, repositoryStatus)\r\n registerJiraRoute(webCtx, new JiraService())\r\n const repositoryActions = new RepositoryActionService(webCtx.subprocess, supervisorConfig.executablePath, cwd => repositoryStatus.invalidate(cwd))\r\n const cwdForClaudeSession = (sessionId: string): string | undefined => {\r\n const agent = webCtx.agents.get(sessionId as never)\r\n if (agent === undefined || webCtx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID) return undefined\r\n return agent.session.header.cwd\r\n }\r\n registerRepositoryActionRoute(webCtx, repositoryActions, cwdForClaudeSession)\r\n registerEditorOpenRoute(webCtx, new EditorOpenService(webCtx.subprocess), cwdForClaudeSession)\r\n registerClaudePromptsRoute(webCtx)\r\n const promptAssist = new PromptAssistService(webCtx.subprocess, () => supervisorConfig.executablePath)\r\n registerClaudePromptNameRoute(webCtx, promptAssist)\r\n registerClaudePromptRefineRoute(webCtx, promptAssist)\r\n registerPullRequestFeedbackRoute(webCtx, new PullRequestFeedbackService(webCtx.subprocess), cwdForClaudeSession)\r\n registerAskRoute(webCtx, new AskService(webCtx.subprocess, supervisorConfig.executablePath), cwdForClaudeSession, sessionId => {\r\n const snapshot = supervisor.snapshots().find(item => item.sessionId === sessionId)\r\n return snapshot === undefined ? undefined : { model: claudeModelValue(snapshot.model), ...(snapshot.thinkingMode === undefined ? {} : { thinkingMode: snapshot.thinkingMode }) }\r\n })\r\n const ownsClaudeSession = (sessionId: string): boolean => {\r\n const agent = webCtx.agents.get(sessionId as never)\r\n return agent !== undefined && webCtx.agentPresets.composedPreset(agent.ctx) === CLAUDE_CODE_PRESET_ID\r\n }\r\n registerReviewCommentRoute(webCtx, reviewComments, ownsClaudeSession)\r\n registerPlanFeedbackRoute(webCtx, supervisor.planFeedback, ownsClaudeSession)\r\n registerClaudeRewindRoute(webCtx, sidecar, {\r\n eventsFor: sessionId => {\r\n const agent = webCtx.agents.get(sessionId as never)\r\n return agent === undefined || webCtx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID\r\n ? undefined\r\n : agent.session.snapshotEvents()\r\n },\r\n busy: sessionId => supervisor.snapshots().some(item => (\r\n item.sessionId === sessionId && (item.state === 'running' || item.state === 'interrupting')\r\n )),\r\n reset: sessionId => supervisor.disposeSession(sessionId),\r\n restoreFiles: async (sessionId, tree) => {\r\n const agent = webCtx.agents.get(sessionId as never)\r\n const cwd = agent?.session.header.cwd\r\n return cwd === undefined ? false : restoreWorktreeTree(ctx.subprocess, cwd, tree)\r\n },\r\n })\r\n registerPlanUsageRoute(webCtx, fetchedAt => probePlanUsage(supervisorConfig.executablePath, fetchedAt))\r\n registerClaudeProjectionRoute(webCtx, sidecar, ownsClaudeSession, sessionId => commandCatalogs.get(sessionId) ?? [], async sessionId => {\r\n const agent = webCtx.agents.get(sessionId as never)\r\n if (agent === undefined || webCtx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID) return undefined\r\n const cwd = agent.session.header.cwd\r\n return cwd === undefined ? undefined : repositoryStatus.inspect(cwd)\r\n }, sessionId => reviewComments.list(sessionId))\r\n })\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["record","string","record","string","latest","claudeQuery","query","record","claudeQuery","query","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","collect","run","claudeQuery","MAX_TEXT_CHARS","MAX_PATH_CHARS","claudeQuery","safeMessage","MAX_SESSION_ID_CHARS","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","GH_TIMEOUT_MS","collect","record","MAX_REPLY_CHARS","claudeQuery","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","MAX_PATH_CHARS","collect","MAX_OUTPUT_BYTES","GIT_TIMEOUT_MS","collect","MAX_BODY_BYTES","record","readJson","string","optionalString","ndjson","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","readJson","sessionId","string","MAX_OUTPUT_BYTES","MAX_SESSION_ID_CHARS","MAX_REQUEST_BYTES","MAX_REPLY_CHARS","record","MAX_SESSION_ID_CHARS","MAX_BODY_BYTES","record","readJson","MAX_PATH_CHARS","record","MAX_BODY_BYTES","record","readJson","record","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","readJson","MAX_BODY_BYTES","MAX_SESSION_ID_CHARS","record","readJson","safeMessage"],"sources":["../src/rewind.ts","../src/sidecar.ts","../src/async-queue.ts","../src/plan-feedback.ts","../src/permission.ts","../src/user-question.ts","../src/sdk-messages.ts","../src/model-catalog.ts","../src/plan-usage.ts","../src/spawn.ts","../src/worktree-snapshot.ts","../src/supervisor.ts","../src/review-comments.ts","../src/session-title.ts","../src/adapter.ts","../src/plugin-budget.ts","../src/http.ts","../src/doctor-routes.ts","../src/projection-routes.ts","../src/diff-funcname.ts","../src/repository-status.ts","../src/branch-name.ts","../src/repository-setup.ts","../src/repository-actions.ts","../src/repository-setup-routes.ts","../src/repository-action-routes.ts","../src/editor-open.ts","../src/editor-open-routes.ts","../src/prompts.ts","../src/github-url.ts","../src/pr-feedback.ts","../src/pr-feedback-routes.ts","../src/repository-status-routes.ts","../src/repository-file-routes.ts","../src/jira.ts","../src/jira-routes.ts","../src/ask.ts","../src/ask-routes.ts","../src/review-comment-routes.ts","../src/plan-feedback-routes.ts","../src/client-diagnostics-routes.ts","../src/rewind-routes.ts","../src/touched-repositories.ts","../src/update-routes.ts","../src/plan-usage-routes.ts","../src/global-settings.ts","../src/index.ts"],"sourcesContent":["/** Rewind: drop one user message and everything after it.\n *\n * Two halves, because the two sides of a Claude session are owned by\n * different processes:\n *\n * - Claude's own transcript is rewound for real. Every completed DSH turn\n * records the last chain-entry uuid Claude emitted for it, so the next\n * spawn resumes at the kept turn's anchor (`resumeSessionAt`) and the model\n * genuinely forgets the discarded turns.\n * - The DSH session log is append-only and the Host renders every event it\n * holds — even compaction keeps the shadowed conversation on screen — so the\n * discarded rows are recorded here as hidden seq ranges and suppressed by\n * the browser instead of deleted.\n *\n * The files are a third half, and an optional one: every turn is admitted\n * against a captured working tree, so a rewind can put the checkout back to\n * where the discarded turns found it rather than leaving Claude to resume\n * against edits it no longer remembers making.\n */\nimport type { SessionEvent } from '@deepseek-ai/dsh-session'\n\n/** One inclusive span of hidden surface seqs. */\nexport interface ClaudeRewindRange {\n readonly start: number\n readonly end: number\n}\n\n/** The last Claude chain entry of one completed DSH turn. */\nexport interface ClaudeRewindAnchor {\n readonly turn: number\n readonly uuid: string\n}\n\n/** The git tree one DSH turn was admitted against. */\nexport interface ClaudeRewindSnapshot {\n readonly turn: number\n readonly tree: string\n}\n\n/** Fork target for the next Claude spawn; `fresh` starts an empty session. */\nexport type ClaudeRewindResume = { readonly resumeAt: string } | { readonly fresh: true }\n\nexport interface ClaudeRewindState {\n /** Hidden seq ranges, ascending and non-overlapping. */\n readonly ranges: readonly ClaudeRewindRange[]\n /** Chain anchors of the turns Claude still holds, ascending by turn. */\n readonly anchors: readonly ClaudeRewindAnchor[]\n /** Working trees the surviving turns started from, ascending by turn. */\n readonly snapshots: readonly ClaudeRewindSnapshot[]\n /** Armed once by a rewind, consumed by the next Claude spawn. */\n readonly pending?: ClaudeRewindResume\n}\n\nexport const EMPTY_REWIND_STATE: ClaudeRewindState = { ranges: [], anchors: [], snapshots: [] }\n\n/** Sessions outlive their rewinds; every list stays bounded. */\nexport const MAX_REWIND_RANGES = 200\nexport const MAX_REWIND_ANCHORS = 2_000\n/** Shorter than the anchors: each entry pins a whole tree in the object\n * database, and a rewind reaches back turns rather than hundreds of them. */\nexport const MAX_REWIND_SNAPSHOTS = 100\n\n/** Absorb one span into an ascending, non-overlapping range list. Adjacent\n * spans merge so a rewind of a rewind reads as one hidden block. */\nexport function mergeRewindRanges(\n ranges: readonly ClaudeRewindRange[],\n addition: ClaudeRewindRange,\n): ClaudeRewindRange[] {\n const merged: ClaudeRewindRange[] = []\n let { start, end } = addition\n for (const range of [...ranges].sort((left, right) => left.start - right.start)) {\n if (range.end + 1 < start) merged.push(range)\n else if (range.start > end + 1) {\n merged.push({ start, end })\n start = range.start\n end = range.end\n } else {\n start = Math.min(start, range.start)\n end = Math.max(end, range.end)\n }\n }\n merged.push({ start, end })\n return merged.slice(-MAX_REWIND_RANGES)\n}\n\nexport function isRewound(ranges: readonly ClaudeRewindRange[], seq: number): boolean {\n return ranges.some(range => seq >= range.start && seq <= range.end)\n}\n\n/** Record one completed turn's last chain entry, replacing a re-run turn. */\nexport function recordRewindAnchor(\n state: ClaudeRewindState,\n anchor: ClaudeRewindAnchor,\n): ClaudeRewindState {\n const anchors = [...state.anchors.filter(item => item.turn !== anchor.turn), anchor]\n .sort((left, right) => left.turn - right.turn)\n .slice(-MAX_REWIND_ANCHORS)\n return { ...state, anchors }\n}\n\n/** Record the working tree one turn was admitted against, replacing a re-run\n * turn's. */\nexport function recordRewindSnapshot(\n state: ClaudeRewindState,\n snapshot: ClaudeRewindSnapshot,\n): ClaudeRewindState {\n const snapshots = [...state.snapshots.filter(item => item.turn !== snapshot.turn), snapshot]\n .sort((left, right) => left.turn - right.turn)\n .slice(-MAX_REWIND_SNAPSHOTS)\n return { ...state, snapshots }\n}\n\n/** The turn a surface seq belongs to: the first turn opened at or after it.\n * A message accepted but never run belongs to no logged turn, so nothing\n * Claude holds is discarded and every anchor stays valid. */\nexport function turnAtOrAfter(events: readonly SessionEvent[], seq: number): number | undefined {\n for (const event of events) {\n if (event.seq >= seq && event.type === 'turn/start') return event.data.turn\n }\n return undefined\n}\n\n/** The working tree a rewind at `seq` restores: the snapshot of the first turn\n * it discards. Undefined when nothing is discarded, or when that turn ran\n * before this session captured trees. */\nexport function rewindRestoreTree(\n state: ClaudeRewindState,\n events: readonly SessionEvent[],\n seq: number,\n): string | undefined {\n const turn = turnAtOrAfter(events, seq)\n return turn === undefined ? undefined : state.snapshots.find(item => item.turn === turn)?.tree\n}\n\n/** Plan one rewind at `seq`, or undefined when the seq is not in the log.\n * Anchors and snapshots of the discarded turns go with them: after this\n * rewind Claude no longer holds those entries, so a later rewind must never\n * fork at one — nor restore a tree for a turn that no longer exists. */\nexport function planRewind(\n state: ClaudeRewindState,\n events: readonly SessionEvent[],\n seq: number,\n): ClaudeRewindState | undefined {\n const last = events.at(-1)?.seq\n if (last === undefined || seq > last) return undefined\n const turn = turnAtOrAfter(events, seq) ?? Number.MAX_SAFE_INTEGER\n const anchors = state.anchors.filter(anchor => anchor.turn < turn)\n const kept = anchors.at(-1)\n return {\n ranges: mergeRewindRanges(state.ranges, { start: seq, end: last }),\n anchors,\n snapshots: state.snapshots.filter(item => item.turn < turn),\n pending: kept === undefined ? { fresh: true } : { resumeAt: kept.uuid },\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\nimport type { SessionEvent } from '@deepseek-ai/dsh-session'\nimport {\n latestClaudeContextUsage,\n latestClaudeSessionBinding,\n latestClaudeTasks,\n normalizeActivity,\n normalizeContextUsage,\n normalizeTasksEvent,\n redactText,\n type ClaudeActivityEvent,\n type ClaudeActivityInput,\n type ClaudeContextUsageEvent,\n type ClaudeContextUsageInput,\n type ClaudeSessionBoundEvent,\n type ClaudeTaskInfo,\n type ClaudeTasksEvent,\n} from './events.ts'\nimport { CLAUDE_ACTIVITY_EVENT, SDK_VERSION, type ClaudeRenderMode } from './constants.ts'\nimport {\n EMPTY_REWIND_STATE,\n MAX_REWIND_ANCHORS,\n MAX_REWIND_RANGES,\n MAX_REWIND_SNAPSHOTS,\n recordRewindAnchor,\n recordRewindSnapshot,\n type ClaudeRewindAnchor,\n type ClaudeRewindRange,\n type ClaudeRewindSnapshot,\n type ClaudeRewindState,\n} from './rewind.ts'\n\nconst SIDECAR_SCHEMA_VERSION = 1\nconst MAX_ACTIVITIES = 10_000\n/** Trailing window that coalesces per-token transcript persistence into one\n * atomic disk write; live subscribers are notified synchronously regardless. */\nconst TEXT_FLUSH_MS = 150\n\nexport interface ClaudeSidecarProjection {\n readonly schemaVersion: typeof SIDECAR_SCHEMA_VERSION\n readonly revision: number\n readonly binding?: ClaudeSessionBoundEvent\n readonly activities: readonly ClaudeActivityEvent[]\n readonly contextUsage?: ClaudeContextUsageEvent\n readonly tasks?: ClaudeTasksEvent\n readonly rewind?: ClaudeRewindState\n}\n\n/** Change notification published to live subscribers after each accepted write.\n *\n * `checkpoint` is the one kind that carries no change: it restates where the\n * stream stands so a reader can notice it is behind. See {@link ClaudeSidecarRepository.checkpoint}. */\nexport type ClaudeSidecarDelta =\n | { kind: 'text'; turn: number; step: number; ordinal: number; append?: string; text?: string; renderer?: ClaudeRenderMode }\n | { kind: 'activity'; activity: ClaudeActivityEvent }\n | { kind: 'contextUsage'; value: ClaudeContextUsageEvent }\n | { kind: 'tasks'; value: ClaudeTasksEvent }\n | { kind: 'sync' }\n | { kind: 'checkpoint' }\n\n/** One delta as subscribers see it: numbered, so a reader that applies them in\n * order can tell a missing one from a slow one.\n *\n * The projection's own `revision` cannot do this job. Streaming prose notifies\n * subscribers without touching disk (see {@link ClaudeSidecarRepository.appendTranscriptText}),\n * so revisions and notifications advance on different clocks; this counter\n * advances once per notification and nothing else reads it. */\nexport type ClaudeSidecarNotification = ClaudeSidecarDelta & { readonly seq: number }\n\nexport interface ClaudeSidecarRepositoryOptions {\n readonly root?: string\n readonly legacyRoot?: string\n}\n\nfunction emptyProjection(): ClaudeSidecarProjection {\n return { schemaVersion: SIDECAR_SCHEMA_VERSION, revision: 0, activities: [] }\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined\n}\n\nfunction finiteInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0\n}\n\nfunction string(value: unknown, max: number): value is string {\n return typeof value === 'string' && value.length > 0 && value.length <= max\n}\n\nfunction binding(value: unknown): ClaudeSessionBoundEvent | undefined {\n const input = record(value)\n if (input === undefined\n || !string(input.claudeSessionId, 512)\n || !string(input.sdkVersion, 128)\n || !string(input.cwd, 4_096)\n || (input.cliVersion !== undefined && !string(input.cliVersion, 128))) return undefined\n return {\n claudeSessionId: input.claudeSessionId,\n sdkVersion: input.sdkVersion,\n cwd: input.cwd,\n ...(input.cliVersion === undefined ? {} : { cliVersion: input.cliVersion }),\n }\n}\n\nconst ACTIVITY_KINDS = new Set(['text', 'status', 'compaction', 'thinking', 'tool-call', 'tool-result', 'permission', 'question', 'subagent', 'usage', 'warning', 'error'])\nconst ACTIVITY_PHASES = new Set(['started', 'updated', 'completed', 'denied', 'failed'])\n\nfunction activity(value: unknown): ClaudeActivityEvent | undefined {\n const input = record(value)\n if (input === undefined\n || !finiteInteger(input.turn)\n || !finiteInteger(input.step)\n || !finiteInteger(input.ordinal)\n || typeof input.kind !== 'string'\n || !ACTIVITY_KINDS.has(input.kind)\n || (input.phase !== undefined && (typeof input.phase !== 'string' || !ACTIVITY_PHASES.has(input.phase)))) return undefined\n return normalizeActivity(input as unknown as ClaudeActivityEvent)\n}\n\nfunction contextUsage(value: unknown): ClaudeContextUsageEvent | undefined {\n const input = record(value)\n if (input === undefined || !Array.isArray(input.categories)) return undefined\n return normalizeContextUsage(input as unknown as ClaudeContextUsageInput)\n}\n\nfunction rewind(value: unknown): ClaudeRewindState | undefined {\n const input = record(value)\n if (input === undefined\n || !Array.isArray(input.ranges) || input.ranges.length > MAX_REWIND_RANGES\n || !Array.isArray(input.anchors) || input.anchors.length > MAX_REWIND_ANCHORS) return undefined\n const ranges: ClaudeRewindRange[] = []\n for (const item of input.ranges) {\n const range = record(item)\n if (range === undefined || !finiteInteger(range.start) || !finiteInteger(range.end) || range.end < range.start) return undefined\n ranges.push({ start: range.start, end: range.end })\n }\n const anchors: ClaudeRewindAnchor[] = []\n for (const item of input.anchors) {\n const anchor = record(item)\n if (anchor === undefined || !finiteInteger(anchor.turn) || !string(anchor.uuid, 128)) return undefined\n anchors.push({ turn: anchor.turn, uuid: anchor.uuid })\n }\n // Documents written before working-tree snapshots existed carry no list;\n // they read as a session that simply has no tree to restore.\n const snapshots: ClaudeRewindSnapshot[] = []\n if (input.snapshots !== undefined) {\n if (!Array.isArray(input.snapshots) || input.snapshots.length > MAX_REWIND_SNAPSHOTS) return undefined\n for (const item of input.snapshots) {\n const snapshot = record(item)\n if (snapshot === undefined || !finiteInteger(snapshot.turn) || !string(snapshot.tree, 64)) return undefined\n snapshots.push({ turn: snapshot.turn, tree: snapshot.tree })\n }\n }\n const pending = record(input.pending)\n if (input.pending !== undefined && pending === undefined) return undefined\n if (pending === undefined) return { ranges, anchors, snapshots }\n if (pending.fresh === true) return { ranges, anchors, snapshots, pending: { fresh: true } }\n if (!string(pending.resumeAt, 128)) return undefined\n return { ranges, anchors, snapshots, pending: { resumeAt: pending.resumeAt } }\n}\n\nfunction tasks(value: unknown): ClaudeTasksEvent | undefined {\n const input = record(value)\n if (input === undefined || !Array.isArray(input.tasks)) return undefined\n return normalizeTasksEvent(input.tasks as ClaudeTaskInfo[])\n}\n\nexport function parseClaudeSidecar(value: unknown): ClaudeSidecarProjection {\n const input = record(value)\n if (input === undefined\n || input.schemaVersion !== SIDECAR_SCHEMA_VERSION\n || !finiteInteger(input.revision)\n || !Array.isArray(input.activities)\n || input.activities.length > MAX_ACTIVITIES) {\n throw new Error('dsh-claude: invalid sidecar document')\n }\n const activities = input.activities.map(activity)\n if (activities.some(item => item === undefined)) throw new Error('dsh-claude: invalid sidecar activity')\n const parsedBinding = input.binding === undefined ? undefined : binding(input.binding)\n const parsedUsage = input.contextUsage === undefined ? undefined : contextUsage(input.contextUsage)\n const parsedTasks = input.tasks === undefined ? undefined : tasks(input.tasks)\n const parsedRewind = input.rewind === undefined ? undefined : rewind(input.rewind)\n if ((input.binding !== undefined && parsedBinding === undefined)\n || (input.contextUsage !== undefined && parsedUsage === undefined)\n || (input.tasks !== undefined && parsedTasks === undefined)\n || (input.rewind !== undefined && parsedRewind === undefined)) {\n throw new Error('dsh-claude: invalid sidecar projection')\n }\n return {\n schemaVersion: SIDECAR_SCHEMA_VERSION,\n revision: input.revision,\n activities: activities as ClaudeActivityEvent[],\n ...(parsedBinding === undefined ? {} : { binding: parsedBinding }),\n ...(parsedUsage === undefined ? {} : { contextUsage: parsedUsage }),\n ...(parsedTasks === undefined ? {} : { tasks: parsedTasks }),\n ...(parsedRewind === undefined ? {} : { rewind: parsedRewind }),\n }\n}\n\nfunction compareActivity(left: ClaudeActivityEvent, right: ClaudeActivityEvent): number {\n return left.turn - right.turn || left.step - right.step || left.ordinal - right.ordinal\n}\n\nfunction activityKey(value: ClaudeActivityEvent): string {\n return `${value.turn}:${value.step}:${value.ordinal}`\n}\n\nfunction mergeActivities(\n existing: readonly ClaudeActivityEvent[],\n additions: readonly ClaudeActivityEvent[],\n): ClaudeActivityEvent[] {\n const merged = new Map(existing.map(item => [activityKey(item), item]))\n for (const item of additions) merged.set(activityKey(item), item)\n return [...merged.values()].sort(compareActivity).slice(-MAX_ACTIVITIES)\n}\n\nfunction normalizeBinding(\n input: Omit<ClaudeSessionBoundEvent, 'sdkVersion'> & { sdkVersion?: string },\n): ClaudeSessionBoundEvent {\n return {\n claudeSessionId: redactText(input.claudeSessionId, 512),\n sdkVersion: redactText(input.sdkVersion ?? SDK_VERSION, 128),\n cwd: redactText(input.cwd, 4_096),\n ...(input.cliVersion === undefined ? {} : { cliVersion: redactText(input.cliVersion, 128) }),\n }\n}\n\nexport class ClaudeSidecarRepository {\n readonly root: string\n readonly legacyRoot: string | undefined\n readonly #pending = new Map<string, Promise<unknown>>()\n /** Latest durable projection per session; disk is read once and written through. */\n readonly #latest = new Map<string, ClaudeSidecarProjection>()\n readonly #listeners = new Map<string, Set<(delta: ClaudeSidecarNotification) => void>>()\n /** Notifications published per session, so a reader can spot a hole. */\n readonly #seq = new Map<string, number>()\n /** Streaming transcript segments not yet persisted, keyed by activity key. */\n readonly #live = new Map<string, Map<string, ClaudeActivityEvent>>()\n /** Monotonic revision boost so merged reads advance while text stays in memory. */\n readonly #boost = new Map<string, number>()\n readonly #flushTimers = new Map<string, ReturnType<typeof setTimeout>>()\n\n constructor(options: ClaudeSidecarRepositoryOptions = {}) {\n this.root = options.root ?? dshHomePath('plugins', 'dsh-claude', 'sessions')\n this.legacyRoot = options.legacyRoot\n ?? (options.root === undefined ? dshHomePath('plugins', 'dsh-claude-code', 'sessions') : undefined)\n }\n\n async read(sessionId: string): Promise<ClaudeSidecarProjection> {\n await this.#pending.get(sessionId)?.catch(() => undefined)\n return this.#merged(sessionId, await this.#base(sessionId))\n }\n\n /** Observe accepted changes for one session; returns the unsubscriber. */\n subscribe(sessionId: string, listener: (delta: ClaudeSidecarNotification) => void): () => void {\n let set = this.#listeners.get(sessionId)\n if (set === undefined) {\n set = new Set()\n this.#listeners.set(sessionId, set)\n }\n set.add(listener)\n return () => {\n set.delete(listener)\n if (set.size === 0) this.#listeners.delete(sessionId)\n }\n }\n\n /** Record streaming assistant prose without touching the disk on the hot\n * path: subscribers are notified synchronously (as an append when the\n * redacted text grows in place) and persistence is coalesced. */\n appendTranscriptText(\n sessionId: string,\n value: { turn: number; step: number; ordinal: number; text: string; renderer?: ClaudeRenderMode },\n ): void {\n const normalized = normalizeActivity({ kind: 'text', phase: 'updated', ...value })\n const key = activityKey(normalized)\n let overlay = this.#live.get(sessionId)\n if (overlay === undefined) {\n overlay = new Map()\n this.#live.set(sessionId, overlay)\n }\n const previous = overlay.get(key)\n overlay.set(key, normalized)\n this.#boost.set(sessionId, (this.#boost.get(sessionId) ?? 0) + 1)\n const text = normalized.text ?? ''\n const base = {\n turn: normalized.turn,\n step: normalized.step,\n ordinal: normalized.ordinal,\n ...(normalized.renderer === undefined ? {} : { renderer: normalized.renderer }),\n }\n // Redaction may rewrite earlier characters once a secret completes, so a\n // non-prefix update falls back to a full-text replacement.\n this.#notify(sessionId, previous?.text !== undefined && text.startsWith(previous.text)\n ? { kind: 'text', ...base, append: text.slice(previous.text.length) }\n : { kind: 'text', ...base, text })\n this.#scheduleTextFlush(sessionId)\n }\n\n /** Persist any pending streaming transcript now (segment close, turn end). */\n flushTranscriptText(sessionId: string): Promise<void> {\n const timer = this.#flushTimers.get(sessionId)\n if (timer !== undefined) {\n clearTimeout(timer)\n this.#flushTimers.delete(sessionId)\n }\n return this.#flushLive(sessionId)\n }\n\n /** How many notifications this session has published. */\n sequence(sessionId: string): number {\n return this.#seq.get(sessionId) ?? 0\n }\n\n /** Restate where the stream stands without changing anything.\n *\n * A reader detects a lost delta from the hole the NEXT one leaves, which\n * never comes when the lost delta was the last of a turn -- exactly the\n * case that leaves a finished tool group pulsing forever. Called at turn\n * settlement, this gives that reader the one line it needs to disagree. */\n checkpoint(sessionId: string): void {\n this.#deliver(sessionId, { kind: 'checkpoint', seq: this.sequence(sessionId) })\n }\n\n #notify(sessionId: string, delta: ClaudeSidecarDelta): void {\n const seq = this.sequence(sessionId) + 1\n this.#seq.set(sessionId, seq)\n this.#deliver(sessionId, { ...delta, seq } as ClaudeSidecarNotification)\n }\n\n #deliver(sessionId: string, notification: ClaudeSidecarNotification): void {\n const set = this.#listeners.get(sessionId)\n if (set === undefined) return\n for (const listener of [...set]) {\n try {\n listener(notification)\n } catch {\n // A subscriber failure must never affect durable state.\n }\n }\n }\n\n #merged(sessionId: string, base: ClaudeSidecarProjection): ClaudeSidecarProjection {\n const overlay = this.#live.get(sessionId)\n const boost = this.#boost.get(sessionId) ?? 0\n if ((overlay === undefined || overlay.size === 0) && boost === 0) return base\n return {\n ...base,\n revision: base.revision + boost,\n ...(overlay === undefined || overlay.size === 0\n ? {}\n : { activities: mergeActivities(base.activities, [...overlay.values()]) }),\n }\n }\n\n async #base(sessionId: string): Promise<ClaudeSidecarProjection> {\n const cached = this.#latest.get(sessionId)\n if (cached !== undefined) return cached\n const loaded = await this.#readNow(sessionId)\n this.#latest.set(sessionId, loaded)\n return loaded\n }\n\n #scheduleTextFlush(sessionId: string): void {\n if (this.#flushTimers.has(sessionId)) return\n const timer = setTimeout(() => {\n this.#flushTimers.delete(sessionId)\n void this.#flushLive(sessionId)\n }, TEXT_FLUSH_MS)\n timer.unref?.()\n this.#flushTimers.set(sessionId, timer)\n }\n\n async #flushLive(sessionId: string): Promise<void> {\n const overlay = this.#live.get(sessionId)\n if (overlay === undefined || overlay.size === 0) return\n const entries = [...overlay.entries()]\n try {\n await this.#update(sessionId, current => ({\n ...current,\n activities: mergeActivities(current.activities, entries.map(([, value]) => value)),\n }))\n } catch {\n // Keep the overlay; the next append or flush retries persistence.\n return\n }\n for (const [key, value] of entries) {\n if (overlay.get(key) === value) overlay.delete(key)\n }\n if (overlay.size === 0) this.#live.delete(sessionId)\n }\n\n writeBinding(\n sessionId: string,\n value: Omit<ClaudeSessionBoundEvent, 'sdkVersion'> & { sdkVersion?: string },\n ): Promise<ClaudeSidecarProjection> {\n const normalized = normalizeBinding(value)\n return this.#update(sessionId, current => ({ ...current, binding: normalized }))\n }\n\n appendActivity(\n sessionId: string,\n value: ClaudeActivityInput & { turn: number; step: number; ordinal: number },\n ): Promise<ClaudeSidecarProjection> {\n const normalized = normalizeActivity(value)\n return this.#update(sessionId, current => ({\n ...current,\n activities: mergeActivities(current.activities, [normalized]),\n }), false, { kind: 'activity', activity: normalized })\n }\n\n writeContextUsage(sessionId: string, value: ClaudeContextUsageInput): Promise<ClaudeSidecarProjection> {\n const normalized = normalizeContextUsage(value)\n return this.#update(sessionId, current => ({ ...current, contextUsage: normalized }), false, { kind: 'contextUsage', value: normalized })\n }\n\n writeTasks(sessionId: string, value: readonly ClaudeTaskInfo[]): Promise<ClaudeSidecarProjection> {\n const normalized = normalizeTasksEvent(value)\n return this.#update(sessionId, current => ({ ...current, tasks: normalized }), false, { kind: 'tasks', value: normalized })\n }\n\n /** Land one planned rewind: hidden ranges, surviving anchors, and the fork\n * target the next Claude spawn consumes.\n *\n * `droppedFromTurn` also drops the discarded turns' activity. The hidden\n * ranges are surface seqs and activity records carry none, so a reader that\n * works in turns — the plan panel, the task board — has nothing to filter\n * on and would go on showing a plan the session no longer contains. This\n * projection is rebuildable from the session log, so trimming it is not\n * losing anything the log still holds. */\n writeRewind(sessionId: string, value: ClaudeRewindState, droppedFromTurn?: number): Promise<ClaudeSidecarProjection> {\n return this.#update(sessionId, current => ({\n ...current,\n rewind: value,\n ...(droppedFromTurn === undefined ? {} : {\n activities: current.activities.filter(activity => activity.turn < droppedFromTurn),\n }),\n }), false, { kind: 'sync' })\n }\n\n /** Remember where Claude's chain ended for one completed DSH turn. */\n recordRewindAnchor(sessionId: string, turn: number, uuid: string): Promise<ClaudeSidecarProjection> {\n return this.#update(sessionId, current => ({\n ...current,\n rewind: recordRewindAnchor(current.rewind ?? EMPTY_REWIND_STATE, { turn, uuid }),\n }))\n }\n\n /** Remember the working tree one DSH turn was admitted against. */\n recordRewindSnapshot(sessionId: string, turn: number, tree: string): Promise<ClaudeSidecarProjection> {\n return this.#update(sessionId, current => ({\n ...current,\n rewind: recordRewindSnapshot(current.rewind ?? EMPTY_REWIND_STATE, { turn, tree }),\n }))\n }\n\n /** Disarm the fork target once a Claude process has resumed at it, so a\n * later respawn continues the rewound session instead of re-truncating it. */\n clearRewindPending(sessionId: string): Promise<ClaudeSidecarProjection> {\n return this.#update(sessionId, current => (current.rewind?.pending === undefined ? current : {\n ...current,\n rewind: { ranges: current.rewind.ranges, anchors: current.rewind.anchors, snapshots: current.rewind.snapshots },\n }))\n }\n\n importLegacy(sessionId: string, events: readonly SessionEvent[]): Promise<ClaudeSidecarProjection> {\n const importedActivities = events\n .filter(event => event.type === CLAUDE_ACTIVITY_EVENT)\n .map(event => activity(event.data))\n .filter((item): item is ClaudeActivityEvent => item !== undefined)\n const importedBinding = latestClaudeSessionBinding(events)\n const importedUsage = latestClaudeContextUsage(events)\n const importedTasks = latestClaudeTasks(events)\n return this.#update(sessionId, current => ({\n ...current,\n activities: mergeActivities(importedActivities, current.activities),\n ...(current.binding !== undefined || importedBinding === undefined ? {} : { binding: normalizeBinding(importedBinding) }),\n ...(current.contextUsage !== undefined || importedUsage === undefined ? {} : { contextUsage: normalizeContextUsage(importedUsage) }),\n ...(current.tasks !== undefined || importedTasks === undefined ? {} : { tasks: normalizeTasksEvent(importedTasks.tasks) }),\n }), true, { kind: 'sync' })\n }\n\n #path(sessionId: string, root = this.root): string {\n if (sessionId.length === 0 || sessionId.length > 1_024) throw new Error('dsh-claude: invalid session id')\n return join(root, `${Buffer.from(sessionId).toString('base64url')}.json`)\n }\n\n #update(\n sessionId: string,\n change: (current: ClaudeSidecarProjection) => Omit<ClaudeSidecarProjection, 'revision' | 'schemaVersion'> & Partial<Pick<ClaudeSidecarProjection, 'revision' | 'schemaVersion'>>,\n skipUnchanged = false,\n delta?: ClaudeSidecarDelta,\n ): Promise<ClaudeSidecarProjection> {\n const previous = this.#pending.get(sessionId) ?? Promise.resolve()\n const operation = previous.catch(() => undefined).then(async () => {\n const current = await this.#base(sessionId)\n const changed = parseClaudeSidecar({\n ...change(current),\n schemaVersion: SIDECAR_SCHEMA_VERSION,\n revision: current.revision,\n })\n if (skipUnchanged && JSON.stringify(changed) === JSON.stringify(current)) return current\n const next = { ...changed, revision: current.revision + 1 }\n await this.#writeNow(sessionId, next)\n this.#latest.set(sessionId, next)\n if (delta !== undefined) this.#notify(sessionId, delta)\n return next\n })\n this.#pending.set(sessionId, operation)\n void operation.finally(() => {\n if (this.#pending.get(sessionId) === operation) this.#pending.delete(sessionId)\n }).catch(() => undefined)\n return operation\n }\n\n async #readNow(sessionId: string): Promise<ClaudeSidecarProjection> {\n try {\n return parseClaudeSidecar(JSON.parse(await readFile(this.#path(sessionId), 'utf8')))\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error\n }\n if (this.legacyRoot === undefined) return emptyProjection()\n try {\n return parseClaudeSidecar(JSON.parse(await readFile(this.#path(sessionId, this.legacyRoot), 'utf8')))\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return emptyProjection()\n throw error\n }\n }\n\n async #writeNow(sessionId: string, projection: ClaudeSidecarProjection): Promise<void> {\n await mkdir(this.root, { recursive: true, mode: 0o700 })\n await chmod(this.root, 0o700)\n const target = this.#path(sessionId)\n const temporary = `${target}.${process.pid}.${randomUUID()}.tmp`\n try {\n await writeFile(temporary, `${JSON.stringify(projection)}\\n`, { mode: 0o600, flag: 'wx' })\n await chmod(temporary, 0o600)\n await rename(temporary, target)\n await chmod(target, 0o600)\n } finally {\n await rm(temporary, { force: true }).catch(() => undefined)\n }\n }\n}\n","export class AsyncQueueClosedError extends Error {\n constructor() {\n super('Async queue is closed')\n this.name = 'AsyncQueueClosedError'\n }\n}\n\ninterface Pending<T> {\n resolve: (result: IteratorResult<T>) => void\n reject: (error: unknown) => void\n}\n\nexport class AsyncQueue<T> implements AsyncIterable<T>, AsyncIterator<T> {\n readonly #values: T[] = []\n readonly #pending: Pending<T>[] = []\n #closed = false\n #failure: unknown\n\n get closed(): boolean {\n return this.#closed\n }\n\n push(value: T): void {\n if (this.#closed) throw new AsyncQueueClosedError()\n const waiter = this.#pending.shift()\n if (waiter !== undefined) waiter.resolve({ value, done: false })\n else this.#values.push(value)\n }\n\n close(): void {\n if (this.#closed) return\n this.#closed = true\n for (const waiter of this.#pending.splice(0)) waiter.resolve({ value: undefined, done: true })\n }\n\n fail(error: unknown): void {\n if (this.#closed) return\n this.#closed = true\n this.#failure = error\n for (const waiter of this.#pending.splice(0)) waiter.reject(error)\n }\n\n discard(error?: unknown): void {\n this.#values.splice(0)\n if (this.#closed) return\n this.#closed = true\n if (error === undefined) {\n for (const waiter of this.#pending.splice(0)) waiter.resolve({ value: undefined, done: true })\n return\n }\n this.#failure = error\n for (const waiter of this.#pending.splice(0)) waiter.resolve({ value: undefined, done: true })\n }\n\n next(): Promise<IteratorResult<T>> {\n const value = this.#values.shift()\n if (value !== undefined) return Promise.resolve({ value, done: false })\n if (this.#closed) {\n return this.#failure === undefined\n ? Promise.resolve({ value: undefined, done: true })\n : Promise.reject(this.#failure)\n }\n return new Promise<IteratorResult<T>>((resolve, reject) => {\n this.#pending.push({ resolve, reject })\n })\n }\n\n return(): Promise<IteratorResult<T>> {\n this.close()\n return Promise.resolve({ value: undefined, done: true })\n }\n\n [Symbol.asyncIterator](): AsyncIterator<T> {\n return this\n }\n}\n","/** One note the reviewer left on a plan: what they said, and the passage they\n * said it about. */\nexport interface PlanNote {\n /** The exact passage the note is anchored to, absent for a whole-plan note. */\n readonly quote?: string\n readonly text: string\n}\n\nconst MAX_NOTES = 30\nconst MAX_NOTE_CHARS = 2_000\nconst MAX_QUOTE_CHARS = 1_000\n\nexport class PlanFeedbackError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'PlanFeedbackError'\n this.code = code\n }\n}\n\n/** Validate and bound one submission's notes. */\nexport function planNotesOf(value: unknown): readonly PlanNote[] {\n if (!Array.isArray(value) || value.length === 0 || value.length > MAX_NOTES) {\n throw new PlanFeedbackError('invalid-request', 'The review notes are invalid.')\n }\n return value.map(item => {\n const note = item !== null && typeof item === 'object' ? item as Record<string, unknown> : undefined\n const text = typeof note?.text === 'string' ? note.text.trim() : ''\n if (text.length === 0 || text.length > MAX_NOTE_CHARS) {\n throw new PlanFeedbackError('invalid-request', 'A review note is empty or too long.')\n }\n const quote = typeof note?.quote === 'string' ? note.quote.trim().slice(0, MAX_QUOTE_CHARS) : ''\n return quote.length === 0 ? { text } : { quote, text }\n })\n}\n\n/** What Claude is told when the reviewer asks for changes.\n *\n * Addressed to Claude rather than logged at it: a rejection it cannot act on\n * is the thing this whole path exists to replace. The quotes are fenced as\n * block quotes so a passage containing its own Markdown cannot be mistaken\n * for the reviewer's instruction. */\nexport function planFeedbackMessage(notes: readonly PlanNote[]): string {\n const body = notes.map(note => note.quote === undefined\n ? note.text\n : `On this part of the plan:\\n${note.quote.split('\\n').map(line => `> ${line}`).join('\\n')}\\n\\n${note.text}`)\n return [\n 'The user reviewed the plan in DeepSeek Harness and asked for changes rather than approving or rejecting it.',\n '',\n body.join('\\n\\n---\\n\\n'),\n '',\n 'Revise the plan accordingly and propose it again.',\n ].join('\\n')\n}\n\n/** The seam between the panel's \"send for changes\" and the permission bridge\n * waiting on that plan's approval.\n *\n * The approval promise lives inside the bridge and cannot be resolved from\n * outside, so the bridge races it against this gate instead: whichever\n * answers first decides, and the loser is aborted. One waiter per tool use —\n * a plan is approved once. */\nexport class PlanFeedbackGate {\n readonly #waiting = new Map<string, (notes: readonly PlanNote[]) => void>()\n\n /** Notes for the plan under `toolUseId`, or undefined when the wait is\n * abandoned because the approval surface answered first. */\n wait(toolUseId: string, signal: AbortSignal): Promise<readonly PlanNote[] | undefined> {\n return new Promise(resolve => {\n const settle = (notes: readonly PlanNote[] | undefined): void => {\n if (this.#waiting.get(toolUseId) === deliver) this.#waiting.delete(toolUseId)\n signal.removeEventListener('abort', onAbort)\n resolve(notes)\n }\n const deliver = (notes: readonly PlanNote[]): void => { settle(notes) }\n const onAbort = (): void => { settle(undefined) }\n if (signal.aborted) {\n resolve(undefined)\n return\n }\n signal.addEventListener('abort', onAbort, { once: true })\n this.#waiting.set(toolUseId, deliver)\n })\n }\n\n /** Hand notes to a waiting plan approval. False when nothing is waiting —\n * the plan was already decided, or never existed. */\n submit(toolUseId: string, notes: readonly PlanNote[]): boolean {\n const deliver = this.#waiting.get(toolUseId)\n if (deliver === undefined) return false\n deliver(notes)\n return true\n }\n\n /** Whether a plan is currently open for review. */\n pending(toolUseId: string): boolean {\n return this.#waiting.has(toolUseId)\n }\n}\n","import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk'\nimport type { Agent } from '@deepseek-ai/dsh-agent'\nimport type { ApprovalOutcome, ApprovalService } from '@deepseek-ai/dsh-user-approval'\nimport {\n boundText,\n safeDetail,\n type ClaudeActivityInput,\n type ClaudeActivityCursor,\n} from './events.ts'\nimport type { UserQuestionBridge } from './user-question.ts'\nimport { planFeedbackMessage, type PlanFeedbackGate } from './plan-feedback.ts'\n\nexport type ApprovalRequester = Pick<ApprovalService, 'request'>\n\nexport interface ActivePermissionContext {\n agent: Agent\n cursor: ClaudeActivityCursor\n markActivity?: () => void\n recordDenial?: (toolUseId: string) => void\n hasFullAccess?: () => Promise<boolean>\n appendActivity: (activity: ClaudeActivityInput) => Promise<void>\n}\n\nexport type ActivePermissionContextProvider = () => ActivePermissionContext | undefined\n\nfunction denialMessage(outcome: ApprovalOutcome): string {\n switch (outcome) {\n case 'rejected': return 'The user rejected this action in DeepSeek Harness.'\n case 'cancelled': return 'The permission request was cancelled in DeepSeek Harness.'\n case 'unavailable': return 'No DeepSeek Harness approval surface was available; the action was denied.'\n case 'allowed-once': return ''\n }\n}\n\n/** Claude leaving plan mode is not an ordinary tool call: its argument is the\n * plan, written for the user, and the approval that follows is the user\n * agreeing to it. Everything else reads better as a prompt plus its input. */\nconst PLAN_TOOL = 'ExitPlanMode'\nconst MAX_REASON_CHARS = 1_200\n\n/** What the approval dialog says instead of the plan.\n *\n * A plan is written to be read at length, and the approval dialog is a\n * cramped modal that renders its reason as plain text: pasting the plan there\n * turned a document into an unreadable wall. The decision stays with the Host\n * — this is still an ordinary tool approval — and the plan itself is drawn by\n * the plugin's own panel, where Markdown and the reader's chosen prose\n * palette both apply. The dialog only has to say what is being decided and\n * where to read it. */\nconst PLAN_APPROVAL_PROMPT = 'Claude proposed a plan. Read it in the Plan panel, then approve or reject here.'\n\n/** The plan an `ExitPlanMode` call carries, if it carries one.\n *\n * Travels to the client on the permission activity's `text` field: `summary`\n * is capped at 1k and `detail` at 4k, both of which truncate a real plan,\n * while `text` holds 64k. Only `kind: 'text'` activities are drawn as prose\n * by the transcript, so a plan riding a `kind: 'permission'` record reaches\n * the panel without being painted twice. */\nexport function planText(toolName: string, input: Readonly<Record<string, unknown>>): string | undefined {\n if (toolName !== PLAN_TOOL) return undefined\n return typeof input.plan === 'string' && input.plan.length > 0 ? input.plan : undefined\n}\n\n/** The session's approval-policy override, or undefined when it never switched.\n *\n * The same fold the approval service does — the last `approval/policy` event\n * wins, because replaying the log IS the state. Read here rather than\n * imported so this package keeps its runtime surface to the Host services it\n * is actually handed. */\nexport function approvalPolicyOf(events: readonly { type: string; data: unknown }[]): string | undefined {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index]\n if (event?.type !== 'approval/policy') continue\n const policy = (event.data as { policy?: unknown }).policy\n return typeof policy === 'string' ? policy : undefined\n }\n return undefined\n}\n\n/** The policy that answers every request with `rejected` before reaching an\n * answerer, so no approval surface is ever shown. DSH writes it alongside\n * `sandbox/mode: danger-full-access` — Full access means \"stop asking\". */\nconst SILENT_POLICY = 'never'\nconst ASKING_POLICY = 'ask'\n\nexport function permissionReason(\n toolName: string,\n input: Readonly<Record<string, unknown>>,\n options: Parameters<CanUseTool>[2],\n): string {\n if (planText(toolName, input) !== undefined) return PLAN_APPROVAL_PROMPT\n const prompt = options.title ?? options.description ?? options.decisionReason ?? `Claude Code wants to use ${toolName}.`\n const detail = safeDetail(input)\n return boundText(detail === undefined ? prompt : `${prompt}\\nInput: ${detail}`, MAX_REASON_CHARS)\n}\n\nexport function mapApprovalOutcome(\n outcome: ApprovalOutcome,\n input: Record<string, unknown>,\n toolUseID: string,\n): PermissionResult {\n if (outcome === 'allowed-once') {\n return {\n behavior: 'allow',\n updatedInput: input,\n toolUseID,\n decisionClassification: 'user_temporary',\n }\n }\n return {\n behavior: 'deny',\n message: denialMessage(outcome),\n toolUseID,\n decisionClassification: 'user_reject',\n }\n}\n\nexport function createPermissionBridge(\n approval: ApprovalRequester,\n activeContext: ActivePermissionContextProvider,\n userQuestion?: UserQuestionBridge,\n planFeedback?: PlanFeedbackGate,\n): CanUseTool {\n return async (toolName, input, options) => {\n if (toolName === 'AskUserQuestion') {\n return userQuestion === undefined\n ? {\n behavior: 'deny',\n message: 'DeepSeek Harness user questions are unavailable; the question was cancelled.',\n toolUseID: options.toolUseID,\n decisionClassification: 'user_reject',\n }\n : userQuestion(input, options)\n }\n const active = activeContext()\n if (active === undefined) {\n return {\n behavior: 'deny',\n message: 'No active DeepSeek Harness turn owns this Claude Code action.',\n toolUseID: options.toolUseID,\n decisionClassification: 'user_reject',\n }\n }\n\n active.markActivity?.()\n const reason = permissionReason(toolName, input, options)\n const plan = planText(toolName, input)\n const session = active.agent.session\n // Tracked outside the try so a throw anywhere below still puts the\n // session's own policy back; a failed ask must not leave Full access\n // asking about everything else.\n let silenced = false\n try {\n await active.appendActivity({\n kind: 'permission',\n phase: 'started',\n toolUseId: options.toolUseID,\n toolName,\n title: options.displayName ?? toolName,\n summary: options.title ?? options.description ?? reason,\n detail: input,\n // The plan panel reads this; see planText.\n ...(plan === undefined ? {} : { text: plan }),\n })\n // Full access says \"stop asking me before you act\". A plan is not an\n // action: it is the decision the user asked Claude to bring back, and\n // answering it on their behalf hands the plan straight back to Claude\n // before anyone has read it. So it is the one approval Full access does\n // not stand in for — a user who wanted the plan waived would not have\n // asked for a plan.\n //\n // Full access does not merely pre-answer the request, it silences it:\n // DSH writes `approval/policy: never` next to the access mode, and the\n // approval service returns `rejected` from that policy alone, before any\n // answerer runs, so no surface is ever shown. Waiving the short-circuit\n // below is therefore not enough — the ask has to be un-silenced for as\n // long as it is open, and put back exactly as it was afterwards.\n const userDecides = plan !== undefined\n silenced = userDecides && approvalPolicyOf(session.snapshotEvents()) === SILENT_POLICY\n if (silenced) session.append('approval/policy', { policy: ASKING_POLICY })\n const alreadyFullAccess = !userDecides && await active.hasFullAccess?.() === true\n // Approving and rejecting are the only answers the approval dialog has,\n // and neither is \"change this\". A reviewer who wants an edit can only\n // reject, which reaches Claude as a bare refusal it cannot act on. So a\n // plan's approval is raced against the panel: the dialog and the panel's\n // notes are two answers to the same question, and whichever arrives\n // first ends it. The loser is aborted rather than left hanging, so a\n // dialog nobody answered does not outlive the plan it was asking about.\n const revision = new AbortController()\n const notes = plan === undefined || planFeedback === undefined\n ? undefined\n : planFeedback.wait(options.toolUseID, AbortSignal.any([options.signal, revision.signal]))\n const decided = new AbortController()\n const asked = alreadyFullAccess\n ? Promise.resolve<ApprovalOutcome>('allowed-once')\n : approval.request({\n agent: active.agent,\n toolName,\n reason,\n signal: notes === undefined ? options.signal : AbortSignal.any([options.signal, decided.signal]),\n })\n const answer = notes === undefined\n ? { outcome: await asked }\n : await Promise.race([\n asked.then(outcome => { revision.abort(); return { outcome } }),\n notes.then(value => value === undefined ? undefined : { revisions: value }),\n ]).then(async first => {\n if (first !== undefined && 'revisions' in first) decided.abort()\n // `notes` resolving undefined means the wait was abandoned, which\n // only happens once the dialog has answered.\n return first ?? { outcome: await asked }\n })\n if ('revisions' in answer) {\n const message = planFeedbackMessage(answer.revisions)\n active.recordDenial?.(options.toolUseID)\n await active.appendActivity({\n kind: 'permission',\n phase: 'denied',\n toolUseId: options.toolUseID,\n toolName,\n title: options.displayName ?? toolName,\n summary: 'Sent back for changes in DeepSeek Harness',\n text: message,\n })\n return {\n behavior: 'deny',\n message,\n toolUseID: options.toolUseID,\n decisionClassification: 'user_reject',\n }\n }\n const outcome = answer.outcome\n // The access selector can change while the approval UI is open. Re-read\n // its durable state so an explicit Full access choice wins over the stale\n // request being closed as rejected/cancelled by that mode transition.\n // Not for a plan: there the user's answer IS the decision, and a Full\n // access switch mid-read must not overturn a rejection they just made.\n const fullAccess = alreadyFullAccess || (!userDecides && await active.hasFullAccess?.() === true)\n const effectiveOutcome = fullAccess ? 'allowed-once' : outcome\n const result = mapApprovalOutcome(effectiveOutcome, input, options.toolUseID)\n if (result.behavior === 'deny') active.recordDenial?.(options.toolUseID)\n await active.appendActivity({\n kind: 'permission',\n phase: effectiveOutcome === 'allowed-once' ? 'completed' : 'denied',\n toolUseId: options.toolUseID,\n toolName,\n title: options.displayName ?? toolName,\n summary: fullAccess\n ? 'Allowed by Full access in DeepSeek Harness'\n : effectiveOutcome === 'allowed-once'\n ? 'Allowed once in DeepSeek Harness'\n : denialMessage(effectiveOutcome),\n })\n return result\n } catch (error) {\n const message = options.signal.aborted\n ? 'The permission request was cancelled in DeepSeek Harness.'\n : 'DeepSeek Harness could not record or answer the permission request; the action was denied.'\n try {\n await active.appendActivity({\n kind: 'permission',\n phase: 'failed',\n toolUseId: options.toolUseID,\n toolName,\n title: options.displayName ?? toolName,\n summary: message,\n isError: true,\n detail: error,\n })\n } catch {\n // The permission path is already fail-closed; a second audit failure cannot widen it.\n }\n return {\n behavior: 'deny',\n message,\n toolUseID: options.toolUseID,\n decisionClassification: 'user_reject',\n }\n } finally {\n // Best effort: an append that fails here cannot be reported without\n // overwriting the decision this call already reached.\n try {\n if (silenced) session.append('approval/policy', { policy: SILENT_POLICY })\n } catch {\n // The session log is the only place this could be recorded, and it is\n // the thing that just failed.\n }\n }\n }\n}\n","import type { CanUseTool, PermissionResult } from '@anthropic-ai/claude-agent-sdk'\nimport type { Agent } from '@deepseek-ai/dsh-agent'\nimport type {\n AskUserQuestionAnswerItem,\n AskUserQuestionItem,\n UserQuestionService,\n} from '@deepseek-ai/dsh-user-questions'\nimport type { ClaudeActivityInput, ClaudeActivityCursor } from './events.ts'\n\nexport type UserQuestionRequester = Pick<UserQuestionService, 'ask'>\n\nexport interface ActiveUserQuestionContext {\n agent: Agent\n cursor: ClaudeActivityCursor\n markActivity?: () => void\n appendActivity: (activity: ClaudeActivityInput) => Promise<void>\n}\n\nexport type ActiveUserQuestionContextProvider = () => ActiveUserQuestionContext | undefined\nexport type UserQuestionBridge = (\n input: Record<string, unknown>,\n options: Parameters<CanUseTool>[2],\n) => Promise<PermissionResult>\n\nconst FAILURE_MESSAGE = 'DeepSeek Harness could not collect an answer; the question was cancelled.'\nconst INVALID_MESSAGE = 'Claude Code sent an invalid user-question request; the question was cancelled.'\n\nfunction failureMessage(error: unknown): string {\n const code = error !== null && typeof error === 'object' && 'code' in error\n ? (error as { code?: unknown }).code\n : undefined\n return typeof code === 'string' && /^[A-Z][A-Z0-9_]*$/.test(code)\n ? `${FAILURE_MESSAGE} (${code})`\n : FAILURE_MESSAGE\n}\n\nfunction deny(message: string, toolUseID: string): PermissionResult {\n return {\n behavior: 'deny',\n message,\n toolUseID,\n decisionClassification: 'user_reject',\n }\n}\n\nfunction optionalText(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction parseQuestions(input: Record<string, unknown>, toolUseID: string): AskUserQuestionItem[] | undefined {\n if (!Array.isArray(input.questions) || input.questions.length === 0 || input.questions.length > 20) return undefined\n const seen = new Set<string>()\n const questions: AskUserQuestionItem[] = []\n for (const [index, value] of input.questions.entries()) {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\n const item = value as Record<string, unknown>\n if (typeof item.question !== 'string' || item.question.length === 0 || seen.has(item.question)) return undefined\n seen.add(item.question)\n if (item.options !== undefined && !Array.isArray(item.options)) return undefined\n const options = (item.options ?? []).map(option => {\n if (option === null || typeof option !== 'object' || Array.isArray(option)) return undefined\n const record = option as Record<string, unknown>\n if (typeof record.label !== 'string' || record.label.length === 0) return undefined\n const description = optionalText(record.description)\n return { label: record.label, ...(description === undefined ? {} : { description }) }\n })\n if (options.some(option => option === undefined)) return undefined\n const header = optionalText(item.header)\n questions.push({\n id: `${toolUseID}:${index}`,\n question: item.question,\n ...(header === undefined ? {} : { header }),\n options: options as NonNullable<AskUserQuestionItem['options']>,\n multiSelect: item.multiSelect === true,\n })\n }\n return questions\n}\n\nfunction answerText(answer: AskUserQuestionAnswerItem | undefined, multiSelect: boolean): string {\n if (answer === undefined) return ''\n const custom = optionalText(answer.custom)\n if (!multiSelect && custom !== undefined) return custom\n return [...answer.selected, ...(custom === undefined ? [] : [custom])].join(', ')\n}\n\nexport function createUserQuestionBridge(\n userQuestions: UserQuestionRequester,\n activeContext: ActiveUserQuestionContextProvider,\n): UserQuestionBridge {\n return async (input, options) => {\n const active = activeContext()\n if (active === undefined) return deny('No active DeepSeek Harness turn owns this Claude Code question.', options.toolUseID)\n\n const questions = parseQuestions(input, options.toolUseID)\n if (questions === undefined) return deny(INVALID_MESSAGE, options.toolUseID)\n\n active.markActivity?.()\n try {\n await active.appendActivity({\n kind: 'question',\n phase: 'started',\n toolUseId: options.toolUseID,\n toolName: 'AskUserQuestion',\n title: 'Claude asked a question',\n summary: questions.length === 1 ? questions[0]!.question : `Claude asked ${questions.length} questions`,\n })\n const response = await userQuestions.ask({\n questions,\n agent: active.agent,\n signal: options.signal,\n })\n const answersById = new Map(response.answers.map(answer => [answer.id, answer]))\n const answers = Object.fromEntries(questions.map(question => [\n question.question,\n answerText(answersById.get(question.id), question.multiSelect === true),\n ]))\n await active.appendActivity({\n kind: 'question',\n phase: 'completed',\n toolUseId: options.toolUseID,\n toolName: 'AskUserQuestion',\n title: 'Claude asked a question',\n summary: 'Answered in DeepSeek Harness',\n })\n return {\n behavior: 'allow',\n updatedInput: { ...input, answers },\n toolUseID: options.toolUseID,\n decisionClassification: 'user_temporary',\n }\n } catch (error) {\n const message = failureMessage(error)\n try {\n await active.appendActivity({\n kind: 'question',\n phase: 'failed',\n toolUseId: options.toolUseID,\n toolName: 'AskUserQuestion',\n title: 'Claude asked a question',\n summary: message,\n isError: true,\n })\n } catch {\n // The question path is fail-closed; a second audit failure cannot widen it.\n }\n return deny(message, options.toolUseID)\n }\n }\n}\n","import type { SDKMessage } from '@anthropic-ai/claude-agent-sdk'\nimport type { ClaudeUsage } from './events.ts'\n\nexport type NormalizedSdkMessage =\n | { kind: 'init'; sessionId: string; cliVersion: string; cwd: string }\n | { kind: 'text-delta'; text: string; parentToolUseId?: string }\n | { kind: 'assistant-text'; text: string; parentToolUseId?: string }\n | { kind: 'thinking'; text: string; phase: 'updated' | 'completed'; parentToolUseId?: string }\n | { kind: 'tool-call'; toolUseId: string; toolName: string; input: unknown; parentToolUseId?: string }\n | { kind: 'tool-result'; toolUseId: string; output: unknown; isError: boolean; parentToolUseId?: string }\n | {\n kind: 'subagent'\n title: string\n summary?: string\n detail?: unknown\n phase: 'started' | 'updated' | 'completed' | 'failed'\n /** Structured task-board fields for task_started/progress/updated/notification. */\n taskId?: string\n taskStatus?: 'running' | 'completed' | 'failed' | 'stopped' | 'killed'\n description?: string\n subagentType?: string\n taskType?: string\n lastToolName?: string\n usage?: { totalTokens?: number; toolUses?: number; durationMs?: number }\n /** Ambient/housekeeping task: hide from chat rows, keep on the task board. */\n skipTranscript?: boolean\n }\n | {\n /** Level signal: full live background-task set (REPLACE semantics). */\n kind: 'background-tasks'\n tasks: readonly { taskId: string; taskType?: string; description: string }[]\n }\n | {\n /** Context compaction boundary. The CLI compacts locally without running a\n * model turn, so this is the only evidence the conversation was rewritten;\n * `trigger` stays absent when the CLI does not name one. */\n kind: 'compaction'\n trigger?: 'manual' | 'auto'\n preTokens?: number\n postTokens?: number\n durationMs?: number\n }\n | {\n /** Prompt-side accounting for ONE provider call, read off an assistant\n * message. Distinct from the `result` usage, which sums every call the\n * turn made — see `ClaudeSupervisor#reportedUsage`. */\n kind: 'request-usage'\n usage: ClaudeUsage\n parentToolUseId?: string\n }\n | { kind: 'status'; title: string; summary?: string; detail?: unknown }\n | { kind: 'warning'; title: string; summary?: string; detail?: unknown }\n | { kind: 'permission-denied'; toolUseId: string; toolName: string; summary: string }\n | { kind: 'result'; success: boolean; text?: string; errors?: readonly string[]; usage: ClaudeUsage; sessionId: string; userMessageUuid?: string; terminalReason?: string; permissionDenials?: readonly { toolName: string; toolUseId: string }[] }\n | { kind: 'protocol-error'; title: string; detail: unknown }\n | { kind: 'unknown'; title: string; detail: unknown }\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' ? value as Record<string, unknown> : undefined\n}\n\nfunction string(value: unknown): string | undefined {\n return typeof value === 'string' ? value : undefined\n}\n\nfunction finiteNumber(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n\nfunction contentText(content: unknown): string {\n if (typeof content === 'string') return content\n if (!Array.isArray(content)) return ''\n return content.map(item => {\n const block = record(item)\n if (block?.type === 'text') return string(block.text) ?? ''\n return ''\n }).join('')\n}\n\nfunction taskUsageOf(usage: Record<string, unknown> | undefined): { totalTokens?: number; toolUses?: number; durationMs?: number } | undefined {\n if (usage === undefined) return undefined\n const normalized: { totalTokens?: number; toolUses?: number; durationMs?: number } = {}\n if (typeof usage.total_tokens === 'number') normalized.totalTokens = usage.total_tokens\n if (typeof usage.tool_uses === 'number') normalized.toolUses = usage.tool_uses\n if (typeof usage.duration_ms === 'number') normalized.durationMs = usage.duration_ms\n return Object.keys(normalized).length === 0 ? undefined : normalized\n}\n\n/** Read one Anthropic `usage` envelope. Shared by the per-call sample on an\n * assistant message and the turn total on a result message. */\nfunction usageOf(usage: Record<string, unknown> | undefined): ClaudeUsage {\n const normalized: ClaudeUsage = {}\n if (usage === undefined) return normalized\n if (typeof usage.input_tokens === 'number') normalized.inputTokens = usage.input_tokens\n if (typeof usage.output_tokens === 'number') normalized.outputTokens = usage.output_tokens\n if (typeof usage.cache_read_input_tokens === 'number') normalized.cacheReadTokens = usage.cache_read_input_tokens\n if (typeof usage.cache_creation_input_tokens === 'number') normalized.cacheCreationTokens = usage.cache_creation_input_tokens\n return normalized\n}\n\nfunction hasUsageCounts(usage: ClaudeUsage): boolean {\n return usage.inputTokens !== undefined\n || usage.outputTokens !== undefined\n || usage.cacheReadTokens !== undefined\n || usage.cacheCreationTokens !== undefined\n}\n\nfunction resultUsage(message: Record<string, unknown>): ClaudeUsage {\n const normalized = usageOf(record(message.usage))\n if (typeof message.total_cost_usd === 'number') normalized.cumulativeCostUsd = message.total_cost_usd\n return normalized\n}\n\nfunction normalizeAssistant(message: Record<string, unknown>): NormalizedSdkMessage[] {\n const envelope = record(message.message)\n const content = envelope?.content\n if (!Array.isArray(content)) return [{ kind: 'protocol-error', title: 'Malformed Claude assistant message', detail: message }]\n const parentToolUseId = string(message.parent_tool_use_id)\n const normalized: NormalizedSdkMessage[] = []\n for (const item of content) {\n const block = record(item)\n if (block === undefined) continue\n if (block.type === 'text') {\n const text = string(block.text)\n if (text !== undefined && text.length > 0) normalized.push({ kind: 'assistant-text', text, ...(parentToolUseId === undefined ? {} : { parentToolUseId }) })\n } else if (block.type === 'thinking') {\n const text = string(block.thinking)\n if (text !== undefined && text.length > 0) normalized.push({ kind: 'thinking', text, phase: 'completed', ...(parentToolUseId === undefined ? {} : { parentToolUseId }) })\n } else if (block.type === 'tool_use') {\n const toolUseId = string(block.id)\n const toolName = string(block.name)\n if (toolUseId !== undefined && toolName !== undefined) {\n normalized.push({\n kind: 'tool-call',\n toolUseId,\n toolName,\n input: block.input,\n ...(parentToolUseId === undefined ? {} : { parentToolUseId }),\n })\n }\n }\n }\n const usage = usageOf(record(envelope?.usage))\n if (hasUsageCounts(usage)) {\n normalized.push({ kind: 'request-usage', usage, ...(parentToolUseId === undefined ? {} : { parentToolUseId }) })\n }\n return normalized\n}\n\nfunction normalizeUser(message: Record<string, unknown>): NormalizedSdkMessage[] {\n // CLI ≥ 2.1.238 replays prior user messages (including local-command output\n // echoes with plain string content) when resuming a session. Replays and\n // block-less string echoes carry no tool results; they are not protocol\n // failures and must never kill the session.\n if (message.isReplay === true) return []\n const envelope = record(message.message)\n const content = envelope?.content\n if (typeof content === 'string') return []\n if (!Array.isArray(content)) return [{ kind: 'protocol-error', title: 'Malformed Claude user message', detail: message }]\n const parentToolUseId = string(message.parent_tool_use_id)\n const normalized: NormalizedSdkMessage[] = []\n for (const item of content) {\n const block = record(item)\n if (block?.type !== 'tool_result') continue\n const toolUseId = string(block.tool_use_id)\n if (toolUseId === undefined) continue\n normalized.push({\n kind: 'tool-result',\n toolUseId,\n output: message.tool_use_result ?? block.content,\n isError: block.is_error === true,\n ...(parentToolUseId === undefined ? {} : { parentToolUseId }),\n })\n }\n return normalized\n}\n\nfunction normalizeSystem(message: Record<string, unknown>): NormalizedSdkMessage[] {\n const subtype = string(message.subtype)\n if (subtype === 'init') {\n const sessionId = string(message.session_id)\n const cliVersion = string(message.claude_code_version)\n const cwd = string(message.cwd)\n return sessionId !== undefined && cliVersion !== undefined && cwd !== undefined\n ? [{ kind: 'init', sessionId, cliVersion, cwd }]\n : [{ kind: 'protocol-error', title: 'Malformed Claude initialization message', detail: message }]\n }\n if (subtype === 'status') {\n const status = message.status\n if (status === null) return [{ kind: 'status', title: 'Claude Code is ready' }]\n return [{ kind: 'status', title: `Claude Code ${String(status)}`, detail: message }]\n }\n if (subtype === 'session_state_changed') {\n return [{ kind: 'status', title: `Claude session ${String(message.state)}` }]\n }\n if (subtype === 'permission_denied') {\n const toolUseId = string(message.tool_use_id)\n const toolName = string(message.tool_name)\n if (toolUseId !== undefined && toolName !== undefined) {\n return [{\n kind: 'permission-denied',\n toolUseId,\n toolName,\n summary: string(message.message) ?? 'Claude Code denied the action',\n }]\n }\n }\n if (subtype === 'task_started') {\n const taskId = string(message.task_id)\n const description = string(message.description)\n const subagentType = string(message.subagent_type)\n const taskType = string(message.task_type)\n return [{\n kind: 'subagent',\n title: description ?? taskId ?? 'Claude subagent started',\n phase: 'started',\n detail: message,\n ...(taskId === undefined ? {} : { taskId }),\n taskStatus: 'running' as const,\n ...(description === undefined ? {} : { description }),\n ...(subagentType === undefined ? {} : { subagentType }),\n ...(taskType === undefined ? {} : { taskType }),\n ...(message.skip_transcript === true ? { skipTranscript: true } : {}),\n }]\n }\n if (subtype === 'task_progress') {\n const taskId = string(message.task_id)\n const description = string(message.description)\n const summary = string(message.summary)\n const subagentType = string(message.subagent_type)\n const lastToolName = string(message.last_tool_name)\n const usage = taskUsageOf(record(message.usage))\n return [{\n kind: 'subagent',\n title: summary ?? description ?? 'Claude subagent update',\n phase: 'updated',\n detail: message,\n ...(taskId === undefined ? {} : { taskId }),\n taskStatus: 'running' as const,\n ...(description === undefined ? {} : { description }),\n ...(subagentType === undefined ? {} : { subagentType }),\n ...(lastToolName === undefined ? {} : { lastToolName }),\n ...(summary === undefined ? {} : { summary }),\n ...(usage === undefined ? {} : { usage }),\n }]\n }\n if (subtype === 'task_updated') {\n const patch = record(message.patch)\n const status = string(patch?.status)\n const taskId = string(message.task_id)\n const description = string(patch?.description)\n const error = string(patch?.error)\n const taskStatus = status === undefined\n ? undefined\n : status === 'killed'\n ? 'killed' as const\n : status === 'completed'\n ? 'completed' as const\n : status === 'failed'\n ? 'failed' as const\n : 'running' as const\n return [{\n kind: 'subagent',\n title: description ?? 'Claude subagent update',\n phase: status === 'failed' || status === 'killed' ? 'failed' : status === 'completed' ? 'completed' : 'updated',\n detail: message,\n ...(taskId === undefined ? {} : { taskId }),\n ...(taskStatus === undefined ? {} : { taskStatus }),\n ...(description === undefined ? {} : { description }),\n ...(error === undefined ? {} : { summary: error }),\n }]\n }\n if (subtype === 'task_notification') {\n const failed = message.status === 'failed'\n const stopped = message.status === 'stopped' || message.status === 'cancelled'\n const taskId = string(message.task_id)\n const summary = string(message.summary)\n const taskStatus = failed ? 'failed' as const : stopped ? 'stopped' as const : 'completed' as const\n const usage = taskUsageOf(record(message.usage))\n return [{\n kind: 'subagent',\n title: summary ?? taskId ?? 'Claude subagent finished',\n phase: failed || stopped ? 'failed' : 'completed',\n detail: message,\n ...(taskId === undefined ? {} : { taskId }),\n taskStatus,\n ...(summary === undefined ? {} : { summary }),\n ...(usage === undefined ? {} : { usage }),\n }]\n }\n if (subtype === 'background_tasks_changed') {\n const tasks = Array.isArray(message.tasks) ? message.tasks : []\n return [{\n kind: 'background-tasks',\n tasks: tasks.flatMap(item => {\n const entry = record(item)\n const taskId = string(entry?.task_id)\n const description = string(entry?.description)\n const taskType = string(entry?.task_type)\n if (taskId === undefined || description === undefined) return []\n return [{\n taskId,\n description,\n ...(taskType === undefined ? {} : { taskType }),\n }]\n }),\n }]\n }\n if (subtype === 'api_retry') {\n return [{ kind: 'warning', title: 'Claude API retry', detail: message }]\n }\n if (subtype === 'compact_boundary') {\n // `/compact` runs entirely inside the CLI: no assistant turn, and the\n // `Compacted` echo arrives as a block-less user message that\n // `normalizeUser` drops. Without this branch the boundary fell through to\n // the generic fallback below and became audit-only 'status', so a\n // compacted conversation showed nothing at all.\n const metadata = record(message.compact_metadata)\n const trigger = metadata?.trigger === 'auto' || metadata?.trigger === 'manual' ? metadata.trigger : undefined\n const preTokens = finiteNumber(metadata?.pre_tokens)\n const postTokens = finiteNumber(metadata?.post_tokens)\n const durationMs = finiteNumber(metadata?.duration_ms)\n return [{\n kind: 'compaction',\n ...(trigger === undefined ? {} : { trigger }),\n ...(preTokens === undefined ? {} : { preTokens }),\n ...(postTokens === undefined ? {} : { postTokens }),\n ...(durationMs === undefined ? {} : { durationMs }),\n }]\n }\n if (subtype === 'informational' || subtype === 'notification' || subtype === 'local_command_output') {\n return [{\n kind: message.level === 'warning' ? 'warning' : 'status',\n title: string(message.content) ?? string(message.text) ?? 'Claude Code notice',\n detail: message,\n }]\n }\n if (subtype?.startsWith('hook_') === true || subtype === 'plugin_install') {\n return [{ kind: 'status', title: `Claude Code ${subtype.replaceAll('_', ' ')}`, detail: message }]\n }\n if (subtype !== undefined) {\n // Preserve unknown system lifecycle evidence (background tasks, resets,\n // worker/mirror lifecycle) as a bounded activity instead of silently\n // dropping it; the activity layer redacts and bounds the detail.\n return [{ kind: 'status', title: `Claude Code ${subtype.replaceAll('_', ' ')}`, detail: message }]\n }\n return []\n}\n\nconst RESULT_ERROR_SUBTYPES = new Set([\n 'error_during_execution',\n 'error_max_turns',\n 'error_max_budget_usd',\n 'error_max_structured_output_retries',\n])\n\nexport function normalizeSdkMessage(message: SDKMessage): NormalizedSdkMessage[] {\n const value = message as unknown as Record<string, unknown>\n if (value.type === 'stream_event') {\n const event = record(value.event)\n const parentToolUseId = string(value.parent_tool_use_id)\n if (event?.type === 'content_block_delta') {\n const delta = record(event.delta)\n if (delta?.type === 'text_delta') {\n const text = string(delta.text)\n return text === undefined ? [] : [{ kind: 'text-delta', text, ...(parentToolUseId === undefined ? {} : { parentToolUseId }) }]\n }\n if (delta?.type === 'thinking_delta') {\n const text = string(delta.thinking)\n return text === undefined ? [] : [{ kind: 'thinking', text, phase: 'updated', ...(parentToolUseId === undefined ? {} : { parentToolUseId }) }]\n }\n }\n return []\n }\n if (value.type === 'assistant') return normalizeAssistant(value)\n if (value.type === 'user') return normalizeUser(value)\n if (value.type === 'system') return normalizeSystem(value)\n if (value.type === 'result') {\n const sessionId = string(value.session_id)\n if (sessionId === undefined || (value.subtype !== 'success' && !RESULT_ERROR_SUBTYPES.has(String(value.subtype)))) {\n return [{ kind: 'protocol-error', title: 'Malformed Claude result message', detail: value }]\n }\n // A result is a success only when it is not flagged as an error. Local\n // 2.1.233 emits subtype:\"success\" with is_error:true for API/auth failures\n // (e.g. terminal_reason:\"api_error\"), so subtype alone is not authoritative.\n const success = value.subtype === 'success' && value.is_error !== true\n const errors = Array.isArray(value.errors)\n ? value.errors.filter((item): item is string => typeof item === 'string')\n : undefined\n const terminalReason = string(value.terminal_reason)\n const userMessageUuid = string(value.user_message_uuid)\n const permissionDenials = Array.isArray(value.permission_denials)\n ? value.permission_denials\n .map(item => record(item))\n .filter((item): item is Record<string, unknown> => item !== undefined)\n .map(item => {\n const toolName = string(item.tool_name)\n const toolUseId = string(item.tool_use_id)\n return toolName === undefined || toolUseId === undefined ? undefined : { toolName, toolUseId }\n })\n .filter((item): item is { toolName: string; toolUseId: string } => item !== undefined)\n .slice(0, 40)\n : undefined\n return [{\n kind: 'result',\n success,\n ...(success && typeof value.result === 'string' ? { text: value.result } : {}),\n ...(errors === undefined ? {} : { errors }),\n ...(terminalReason === undefined ? {} : { terminalReason }),\n ...(permissionDenials === undefined || permissionDenials.length === 0 ? {} : { permissionDenials }),\n usage: resultUsage(value),\n sessionId,\n ...(userMessageUuid === undefined ? {} : { userMessageUuid }),\n }]\n }\n if (value.type === 'auth_status') {\n return [{\n kind: value.error === undefined ? 'status' : 'warning',\n title: value.error === undefined ? 'Claude authentication status changed' : 'Claude authentication failed',\n detail: value.error ?? value.output,\n }]\n }\n if (value.type === 'rate_limit_event') {\n // The CLI pushes subscription-quota status after API activity. Every\n // update stays audit-only ('status' never enters the conversation flow);\n // a blocking state surfaces through the repository status bar badge that\n // reads these titles from the projection instead.\n const info = record(value.rate_limit_info)\n const status = string(info?.status)\n const blocking = status !== undefined && status !== 'allowed'\n return [{\n kind: 'status',\n title: blocking ? 'Claude rate limit is blocking requests' : 'Claude rate limit status changed',\n detail: value.rate_limit_info,\n }]\n }\n return [{ kind: 'unknown', title: `Unknown Claude SDK message: ${String(value.type)}`, detail: value }]\n}\n\nexport function extractSdkContentText(content: unknown): string {\n return contentText(content)\n}\n","/** The Claude Code model lineup, read from the running CLI instead of pinned\n * here.\n *\n * Anthropic ships models between releases of this plugin -- Fable arrived in a\n * CLI update, not in one of ours -- so a table maintained here is stale the day\n * it is written, and a model the user can already pick in `/model` is missing\n * from the DSH selector until someone edits an array. The CLI answers the same\n * question itself: every session's initialize response carries the lineup it\n * would show in `/model`, already narrowed to the logged-in account's plan and\n * to any `availableModels` restriction the settings cascade imposes.\n *\n * What DSH persists on a session, though, must NOT be a CLI model id. DSH\n * stores the selector row's id verbatim and matches it back by string\n * equality, so a concrete id (`claude-fable-5-1[1m]`) turns into a dangling\n * reference the moment Anthropic bumps the version -- the session keeps\n * pointing at a row nothing advertises any more, and the composer falls back\n * to printing the raw id. The selector therefore advertises an alias this\n * plugin owns (`fable[1m]`), derived from the row rather than tabulated, and\n * the CLI id it stands for is kept beside it and used only at dispatch.\n */\nimport {\n query as claudeQuery,\n type ModelInfo,\n type Options as ClaudeOptions,\n type Query,\n type SDKUserMessage,\n} from '@anthropic-ai/claude-agent-sdk'\n\n/** One selectable model, in the shape the adapter advertises to DSH. */\nexport interface ClaudeModelRow {\n /** Stable selector id, persisted by DSH on the session. An alias this plugin\n * owns -- never a CLI model id, which changes under it. */\n readonly id: string\n /** The spelling the CLI is actually given for this row. */\n readonly value: string\n readonly name: string\n readonly description: string\n readonly contextWindow?: number\n}\n\n/** A 1M-context route spells it in the id (`opus[1m]`, `claude-fable-5-1[1m]`). */\nconst WIDE_ROUTE = /\\[1m\\]$/u\n\n/** What the selector shows before the lineup is known -- the probe below failed\n * or has not answered yet. `default` is the only id that is valid on every\n * release and plan; the rest are the stable `/model` spellings Claude Code has\n * kept across releases, and every one of them is a spelling the CLI accepts,\n * so a session that persists one still dispatches. */\nconst SEED: readonly ClaudeModelRow[] = [\n { id: 'default', value: 'default', name: 'Default (recommended)', description: '' },\n { id: 'opus[1m]', value: 'opus[1m]', name: 'Opus (1M context)', description: '', contextWindow: 1_000_000 },\n { id: 'fable', value: 'fable', name: 'Fable', description: '' },\n { id: 'sonnet', value: 'sonnet', name: 'Sonnet', description: '' },\n { id: 'haiku', value: 'haiku', name: 'Haiku', description: '' },\n]\n\n/** A 1M-context route spells it in the id, so this needs no capacity table\n * either. It is only a floor: the supervisor overrides it with the window the\n * CLI reports once a turn has run. */\nfunction declaredContextWindow(row: ModelInfo): number | undefined {\n return WIDE_ROUTE.test(row.resolvedModel ?? row.value) ? 1_000_000 : undefined\n}\n\n/**\n * The selector id for one CLI row: the model's family, plus the `[1m]` marker\n * when the route carries one.\n *\n * Derived, never tabulated -- a family this plugin has never heard of gets its\n * id the same way, so a model Anthropic ships tomorrow lands in the selector\n * without an edit here, and a version bump (`claude-fable-5-1` ->\n * `claude-fable-5-2`) leaves an already-persisted selection pointing at the\n * same row. The family is the first non-numeric segment, which covers both\n * spellings Anthropic has used (`claude-fable-5-1`, `claude-3-5-sonnet-…`).\n *\n * Read off `value` alone, never the id it resolves to: `default` names a route\n * whose resolution moves with the account and the release, so folding the\n * resolved `[1m]` in would flip an already-persisted `default` to `default[1m]`\n * the day Anthropic repoints it.\n * @param value - the CLI's own id for the row.\n * @returns the alias to advertise.\n */\nexport function claudeModelAlias(value: string): string {\n const wide = WIDE_ROUTE.test(value)\n const bare = value.replace(WIDE_ROUTE, '').replace(/^claude-/u, '')\n const family = bare.split('-').find(segment => !/^\\d+$/u.test(segment)) ?? bare\n return wide ? `${family}[1m]` : family\n}\n\nfunction projectModel(row: ModelInfo, id: string): ClaudeModelRow {\n const contextWindow = declaredContextWindow(row)\n return {\n id,\n value: row.value,\n name: row.displayName,\n description: row.description,\n ...(contextWindow === undefined ? {} : { contextWindow }),\n }\n}\n\n// ponytail: a module-level latest-value cache, mirroring plan usage. The plugin\n// runs one supervisor per Host process and the lineup is account-wide, so\n// per-session state would buy nothing.\nlet latest: readonly ClaudeModelRow[] | undefined\nlet inflight: Promise<readonly ClaudeModelRow[]> | undefined\n\n/**\n * Learn the lineup from one session's initialize response.\n * @param models - the CLI's own `/model` rows; an empty list is ignored so a\n * CLI that answers without a catalog cannot blank the selector.\n */\nexport function recordClaudeModels(models: readonly ModelInfo[]): void {\n if (models.length === 0) return\n const taken = new Set<string>()\n latest = models.map(row => {\n const alias = claudeModelAlias(row.value)\n // Two rows of one family in the same lineup (a previous generation kept\n // alongside the current one) cannot share an id; the later row keeps the\n // CLI's own spelling rather than silently shadowing the first.\n const id = taken.has(alias) ? row.value : alias\n taken.add(id)\n return projectModel(row, id)\n })\n}\n\n/** The lineup to advertise: whatever the CLI last reported, else the seed. */\nexport function latestClaudeModels(): readonly ClaudeModelRow[] {\n return latest ?? SEED\n}\n\n/** A throwaway probe should not outlive a wedged CLI. */\nexport const CLAUDE_MODEL_PROBE_TIMEOUT_MS = 20_000\n\n/**\n * Read the lineup from a throwaway CLI process.\n *\n * Waiting for a session to start is too late: DSH loads the model catalog once\n * per Host generation, at connect, and does not reload it when this plugin\n * later learns the real lineup. A selector left on the seed until then hands\n * out seed ids, which is exactly how a session ends up persisting an id the\n * next launch cannot resolve. This query carries no tools, no permission\n * bridge and no session binding: it starts, reports what `/model` would show,\n * and is killed -- no prompt is ever sent, so it costs no tokens.\n * @param executablePath - the resolved CLI, or '' to let the SDK find it.\n * @param factory - test seam for the SDK query.\n * @returns the CLI's own `/model` rows.\n */\nexport async function probeClaudeModels(\n executablePath: string,\n factory: (params: { prompt: AsyncIterable<SDKUserMessage>; options: ClaudeOptions }) => Query = claudeQuery,\n): Promise<readonly ModelInfo[]> {\n const lifetime = new AbortController()\n const timer = setTimeout(() => lifetime.abort(), CLAUDE_MODEL_PROBE_TIMEOUT_MS)\n timer.unref?.()\n // The SDK ends a query as soon as its prompt stream closes, so hold the\n // stream open and let the abort below tear the process down instead.\n const prompt = (async function* (): AsyncGenerator<SDKUserMessage> {\n await new Promise<never>(() => {})\n })()\n const query = factory({\n prompt,\n options: {\n cwd: process.cwd(),\n abortController: lifetime,\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\n },\n })\n try {\n void (async () => { for await (const _ of query) { /* drain */ } })().catch(() => undefined)\n // Aborting tears the probe process down, but the SDK's pending\n // initialization is not documented to settle with it, and an unsettled one\n // would hang the catalog load (and the browser connection serving it) for\n // the life of the Host. The deadline is therefore enforced here too.\n const initialization = await Promise.race([\n query.initializationResult(),\n new Promise<never>((_resolve, reject) => {\n const deadline = setTimeout(\n () => reject(new Error('dsh-claude: the model lineup probe did not answer in time')),\n CLAUDE_MODEL_PROBE_TIMEOUT_MS,\n )\n deadline.unref?.()\n }),\n ])\n return initialization.models\n } finally {\n clearTimeout(timer)\n lifetime.abort()\n }\n}\n\n/**\n * The lineup, learning it from the CLI the first time DSH asks for the catalog.\n * @param probe - reads the CLI's rows; a failure leaves the seed in place and\n * is retried on the next catalog load.\n * @returns the rows to advertise, never rejecting.\n */\nexport function ensureClaudeModels(probe: () => Promise<readonly ModelInfo[]>): Promise<readonly ClaudeModelRow[]> {\n if (latest !== undefined) return Promise.resolve(latest)\n inflight ??= probe()\n .then(models => { recordClaudeModels(models) })\n .catch(() => undefined)\n .then(() => {\n inflight = undefined\n return latestClaudeModels()\n })\n return inflight\n}\n\n/**\n * Look one id up in the current lineup.\n * @param id - the id DSH persisted on the session, which may be an alias, a\n * concrete CLI id persisted before this plugin aliased anything, or a row the\n * running CLI no longer lists.\n * @returns the row, or undefined when the lineup does not cover the id.\n */\nexport function claudeModelRow(id: string): ClaudeModelRow | undefined {\n const rows = latestClaudeModels()\n return rows.find(row => row.id === id)\n ?? rows.find(row => row.value === id)\n ?? rows.find(row => row.id === claudeModelAlias(id))\n}\n\n/**\n * The spelling to hand the CLI for one selector id.\n * @param id - the id DSH persisted on the session.\n * @returns the CLI's own id, or the selector id itself when the lineup does not\n * cover it -- the seed vocabulary is made of spellings the CLI accepts, and a\n * session persisted before this plugin aliased anything already holds one.\n */\nexport function claudeModelValue(id: string): string {\n return claudeModelRow(id)?.value ?? id\n}\n\n/** Test seam: drop the learned lineup. */\nexport function resetClaudeModels(): void {\n latest = undefined\n inflight = undefined\n}\n","/** Claude.ai plan rate-limit windows behind the CLI's `/usage` panel.\n *\n * The Agent SDK exposes them through an experimental query method whose name\n * advertises its own instability, so every read is guarded: a missing method,\n * a shape change, or an API-key session all degrade to `available: false`\n * instead of breaking the settings page. */\nimport { query as claudeQuery, type Options as ClaudeOptions, type Query, type SDKUserMessage } from '@anthropic-ai/claude-agent-sdk'\n\n/** The SDK's own name for the unstable `/usage` control request; it is\n * documented to change when the API stabilizes, so it lives in one place. */\nexport const PLAN_USAGE_METHOD = 'usage_EXPERIMENTAL_MAY_CHANGE_DO_NOT_RELY_ON_THIS_API_YET'\n\n/** A throwaway probe should not outlive a wedged control request. */\nexport const PLAN_USAGE_TIMEOUT_MS = 20_000\n\n/** Invoke the experimental usage control request, or say why we cannot. */\nexport function readPlanUsageFrom(query: Query): Promise<unknown> {\n const read = (query as Partial<Record<typeof PLAN_USAGE_METHOD, () => Promise<unknown>>>)[PLAN_USAGE_METHOD]\n if (typeof read !== 'function') throw new Error('dsh-claude: this Claude Agent SDK build exposes no plan usage API')\n return read.call(query)\n}\n\n/** One utilization window. `label` is only set for server-named model buckets\n * (e.g. 'Fable'); the fixed windows are translated client-side from `id`. */\nexport interface PlanUsageWindow {\n readonly id: string\n readonly label?: string\n readonly utilization?: number\n readonly resetsAt?: string\n}\n\nexport interface PlanUsageReport {\n readonly available: boolean\n readonly subscription?: string\n readonly windows: readonly PlanUsageWindow[]\n readonly fetchedAt: number\n readonly message?: string\n}\n\n/** Fixed windows in display order; the SDK omits the ones a plan does not have. */\nconst FIXED_WINDOWS = ['five_hour', 'seven_day', 'seven_day_opus', 'seven_day_sonnet'] as const\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\n/** Utilization is documented as 0-100; clamp so a server glitch cannot render\n * a bar wider than its track or a negative width. */\nfunction utilization(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? Math.min(100, Math.max(0, value)) : undefined\n}\n\nfunction resetsAt(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction window(id: string, source: unknown, label?: string): PlanUsageWindow | undefined {\n const entry = record(source)\n if (entry === undefined) return undefined\n const used = utilization(entry.utilization)\n const reset = resetsAt(entry.resets_at)\n if (used === undefined && reset === undefined) return undefined\n return {\n id,\n ...(label === undefined ? {} : { label }),\n ...(used === undefined ? {} : { utilization: used }),\n ...(reset === undefined ? {} : { resetsAt: reset }),\n }\n}\n\n/** Project the SDK's `/usage` response onto the windows the settings card shows. */\nexport function normalizePlanUsage(value: unknown, fetchedAt: number): PlanUsageReport {\n const response = record(value)\n const subscription = typeof response?.subscription_type === 'string' ? response.subscription_type : undefined\n const limits = record(response?.rate_limits)\n if (response?.rate_limits_available !== true || limits === undefined) {\n return {\n available: false,\n ...(subscription === undefined ? {} : { subscription }),\n windows: [],\n fetchedAt,\n }\n }\n const windows = [\n ...FIXED_WINDOWS.map(id => window(id, limits[id])),\n ...(Array.isArray(limits.model_scoped) ? limits.model_scoped : []).map((entry: unknown, index: number) => {\n const name = record(entry)?.display_name\n return window(`model:${typeof name === 'string' ? name : index}`, entry, typeof name === 'string' ? name : undefined)\n }),\n ].filter((entry): entry is PlanUsageWindow => entry !== undefined)\n return {\n available: windows.length > 0,\n ...(subscription === undefined ? {} : { subscription }),\n windows,\n fetchedAt,\n }\n}\n\n/** Read plan limits from a throwaway Claude process.\n *\n * Deliberately NOT routed through the supervisor. Borrowing a session's\n * process fails outright while that session is mid-turn, and for a session\n * with no process yet it would resume the whole conversation — and possibly\n * evict another idle session to make room — just to read three numbers. This\n * query carries no tools, no permission bridge, and no session binding: it\n * starts, answers one control request, and is killed. */\nexport async function probePlanUsage(\n executablePath: string,\n fetchedAt: number,\n factory: (params: { prompt: AsyncIterable<SDKUserMessage>; options: ClaudeOptions }) => Query = claudeQuery,\n): Promise<PlanUsageReport> {\n const lifetime = new AbortController()\n const timer = setTimeout(() => lifetime.abort(), PLAN_USAGE_TIMEOUT_MS)\n timer.unref?.()\n // The SDK ends a query as soon as its prompt stream closes, so hold the\n // stream open and let the abort below tear the process down instead.\n const prompt = (async function* (): AsyncGenerator<SDKUserMessage> {\n await new Promise<never>(() => {})\n })()\n const query = factory({\n prompt,\n options: {\n cwd: process.cwd(),\n abortController: lifetime,\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\n },\n })\n try {\n // Control responses only arrive while the message stream is pumped.\n void (async () => { for await (const _ of query) { /* drain */ } })().catch(() => undefined)\n // Aborting tears the probe process down, but the SDK's pending control\n // request is not documented to settle with it — and an unsettled one hangs\n // the route (and the browser connection serving it) for the life of the\n // Host. The deadline is therefore enforced here too, not only on the\n // process.\n const read = await Promise.race([\n readPlanUsageFrom(query),\n new Promise<never>((_resolve, reject) => {\n const deadline = setTimeout(() => reject(new Error('dsh-claude: the plan usage request did not answer in time')), PLAN_USAGE_TIMEOUT_MS)\n deadline.unref?.()\n }),\n ])\n return normalizePlanUsage(read, fetchedAt)\n } finally {\n clearTimeout(timer)\n lifetime.abort()\n }\n}\n\n// ponytail: a module-level latest-value cache, not a store class. The plugin\n// runs one supervisor per Host process and the report is global to the Claude\n// account, so per-session state would buy nothing. Promote to a keyed store\n// only if the plugin ever serves more than one Claude account at a time.\nlet latest: PlanUsageReport | undefined\n\nexport function recordPlanUsage(report: PlanUsageReport): void {\n latest = report\n}\n\nexport function latestPlanUsage(): PlanUsageReport | undefined {\n return latest\n}\n\n/** Test seam: drop the cached report. */\nexport function resetPlanUsage(): void {\n latest = undefined\n}\n","import { EventEmitter } from 'node:events'\nimport type { Readable, Writable } from 'node:stream'\nimport type { SpawnOptions, SpawnedProcess } from '@anthropic-ai/claude-agent-sdk'\nimport {\n DSH_ENV_PREFIX,\n SENSITIVE_ENV_PATTERN,\n type SubprocessHandle,\n type SubprocessRuntime,\n} from '@deepseek-ai/dsh-subprocess'\n\nexport const CLAUDE_PROCESS_GRACE_MS = 2_000\nexport const CLAUDE_STDERR_TAIL_BYTES = 32 * 1024\n\nconst ADDITIONAL_SENSITIVE_ENV_PATTERN = /(?:authorization|cookie|credential|database[_-]?url|private[_-]?key|netrc)/iu\n\nexport function scrubClaudeSpawnEnv(env: Readonly<Record<string, string | undefined>>): NodeJS.ProcessEnv {\n const safe: NodeJS.ProcessEnv = {}\n for (const [key, value] of Object.entries(env)) {\n if (value === undefined) continue\n if (key.toUpperCase().startsWith(DSH_ENV_PREFIX)) continue\n if (SENSITIVE_ENV_PATTERN.test(key)) continue\n if (ADDITIONAL_SENSITIVE_ENV_PATTERN.test(key)) continue\n safe[key] = value\n }\n return safe\n}\n\nexport class ManagedClaudeProcess extends EventEmitter implements SpawnedProcess {\n readonly stdin: Writable\n readonly stdout: Readable\n readonly handle: SubprocessHandle\n #killed = false\n #exitCode: number | null = null\n #signalCode: NodeJS.Signals | null = null\n\n constructor(handle: SubprocessHandle) {\n super()\n if (handle.stdin === undefined || handle.stdout === undefined) {\n throw new Error('dsh-claude: managed Claude process requires piped stdin/stdout')\n }\n this.handle = handle\n this.stdin = handle.stdin\n this.stdout = handle.stdout\n void handle.done.then(\n outcome => {\n this.#exitCode = outcome.exitCode\n this.#signalCode = outcome.signal\n this.emit('exit', outcome.exitCode, outcome.signal)\n },\n error => {\n this.emit('error', error instanceof Error ? error : new Error(String(error)))\n },\n )\n }\n\n get killed(): boolean {\n return this.#killed\n }\n\n get exitCode(): number | null {\n return this.#exitCode\n }\n\n get signalCode(): NodeJS.Signals | null {\n return this.#signalCode\n }\n\n kill(signal: NodeJS.Signals): boolean {\n if (this.#exitCode !== null || this.#signalCode !== null) return false\n this.#killed = true\n this.handle.terminate()\n return true\n }\n\n stderrTail(): string {\n return this.handle.collected.stderr?.readFrom(0).text ?? ''\n }\n}\n\nexport type SpawnObserver = (process: ManagedClaudeProcess, options: SpawnOptions) => void\n\nexport function createManagedClaudeSpawner(\n runtime: Pick<SubprocessRuntime, 'spawn'>,\n executablePath: string,\n observe?: SpawnObserver,\n): (options: SpawnOptions) => SpawnedProcess {\n return options => {\n if (options.command !== executablePath) {\n throw new Error(`dsh-claude: SDK requested unexpected executable ${JSON.stringify(options.command)}`)\n }\n const handle = runtime.spawn({\n argv: [executablePath, ...options.args],\n cwd: options.cwd ?? process.cwd(),\n stdio: {\n stdin: 'pipe',\n stdout: 'pipe',\n stderr: { maxBytes: CLAUDE_STDERR_TAIL_BYTES },\n },\n graceMs: CLAUDE_PROCESS_GRACE_MS,\n signal: options.signal,\n env: scrubClaudeSpawnEnv(options.env),\n })\n const managed = new ManagedClaudeProcess(handle)\n observe?.(managed, options)\n return managed\n }\n}\n","/** Working-tree snapshots taken and restored with git's own plumbing.\n *\n * A rewind that only truncates Claude's transcript leaves the files Claude\n * wrote on disk, so the next turn resumes against a checkout the model no\n * longer remembers writing. Git already stores trees: a throwaway index turns\n * the working tree into one tree object without touching HEAD, the real\n * index, or the checkout, and a restore reads that tree back.\n *\n * Ignored files stay outside the snapshot in both directions. `git add -A`\n * honours `.gitignore`, so build output and `node_modules` are neither\n * captured nor removed.\n */\nimport { randomUUID } from 'node:crypto'\nimport { rm } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\n\nconst MAX_OUTPUT_BYTES = 64 * 1024\n/** `add -A` walks the whole checkout; a large repository needs more than the\n * status probes' five seconds, and this sits in front of every turn. */\nconst GIT_TIMEOUT_MS = 30_000\nconst OBJECT_NAME = /^[0-9a-f]{40}$|^[0-9a-f]{64}$/u\n/** A snapshot holds the bytes on disk, not git's line-ending translation of\n * them. Under `core.autocrlf=true` a plain `add` would store LF and the\n * restore would write CRLF, so a rewind on Windows would flip every LF file. */\nconst GIT_OPTIONS = ['-c', 'core.autocrlf=false'] as const\n\ntype SnapshotRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n\ninterface CommandResult {\n readonly exitCode: number | null\n readonly stdout: string\n}\n\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\n const outcome = await handle.done\n return { exitCode: outcome.exitCode, stdout: handle.collected.stdout?.readFrom(0).text ?? '' }\n}\n\nasync function run(\n runtime: SnapshotRuntime,\n git: string,\n args: readonly string[],\n cwd: string,\n env: Record<string, string> = {},\n): Promise<CommandResult> {\n return collect(runtime.spawn({\n argv: [git, ...GIT_OPTIONS, ...args],\n cwd,\n stdio: {\n stdin: 'ignore',\n stdout: { maxBytes: MAX_OUTPUT_BYTES },\n stderr: { maxBytes: MAX_OUTPUT_BYTES },\n },\n graceMs: 1_000,\n signal: AbortSignal.timeout(GIT_TIMEOUT_MS),\n env,\n }))\n}\n\n/** Capture the working tree as a git tree object.\n *\n * Undefined whenever git cannot answer -- no git, not a repository, a locked\n * or broken checkout. Snapshots are advisory: a turn without one simply\n * cannot offer a file rewind, and must never fail for it.\n *\n * ponytail: the tree is unreachable from any ref, so `git gc --prune` will\n * eventually collect it. Two weeks is git's default grace period and a rewind\n * happens minutes after the turn it undoes; anchor it to a real ref only if\n * snapshots ever need to outlive a gc.\n */\nexport async function captureWorktreeTree(runtime: SnapshotRuntime, cwd: string): Promise<string | undefined> {\n let git: string\n try {\n git = await runtime.resolveExecutable('git')\n } catch {\n return undefined\n }\n const indexFile = join(tmpdir(), `dsh-claude-index-${process.pid}-${randomUUID()}`)\n const env = { GIT_INDEX_FILE: indexFile }\n try {\n // Seeding from HEAD leaves `add -A` only the differences to record. An\n // unborn branch has no HEAD, and starting from the empty index is right.\n await run(runtime, git, ['read-tree', 'HEAD'], cwd, env)\n const staged = await run(runtime, git, ['add', '-A'], cwd, env)\n if (staged.exitCode !== 0) return undefined\n const written = await run(runtime, git, ['write-tree'], cwd, env)\n const tree = written.stdout.trim()\n return written.exitCode === 0 && OBJECT_NAME.test(tree) ? tree : undefined\n } catch {\n return undefined\n } finally {\n await rm(indexFile, { force: true }).catch(() => undefined)\n }\n}\n\n/** Put a captured tree back over the working tree, reporting whether it landed.\n *\n * Files the tree holds are rewritten, and files created after the snapshot are\n * removed. Nothing outside the snapshot's own scope is touched: ignored files\n * survive, because `clean` runs without `-x`.\n */\nexport async function restoreWorktreeTree(runtime: SnapshotRuntime, cwd: string, tree: string): Promise<boolean> {\n if (!OBJECT_NAME.test(tree)) return false\n let git: string\n try {\n git = await runtime.resolveExecutable('git')\n } catch {\n return false\n }\n try {\n // A tree a gc has already collected must fail here rather than halfway\n // through, with the checkout reset to nothing.\n const kind = await run(runtime, git, ['cat-file', '-t', tree], cwd)\n if (kind.exitCode !== 0 || kind.stdout.trim() !== 'tree') return false\n const read = await run(runtime, git, ['read-tree', '--reset', '-u', tree], cwd)\n if (read.exitCode !== 0) return false\n // Everything the snapshot held now sits in the index, so this removes\n // exactly what was created after it -- no more.\n await run(runtime, git, ['clean', '-fd'], cwd)\n // The snapshot flattened staged, unstaged, and untracked work into one\n // tree. Putting the index back on HEAD makes the restored files read as\n // the ordinary unstaged edits they were, at the cost of forgetting which\n // of them had been staged. An unborn branch has no HEAD and keeps the\n // flattened index; there is nothing else to reset to.\n await run(runtime, git, ['reset', '--mixed', 'HEAD'], cwd)\n return true\n } catch {\n return false\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport {\n query as claudeQuery,\n type EffortLevel,\n type Options as ClaudeOptions,\n type PermissionMode,\n type Query,\n type SDKControlGetContextUsageResponse,\n type SDKMessage,\n type SDKUserMessage,\n type Settings as ClaudeSettings,\n type SlashCommand,\n} from '@anthropic-ai/claude-agent-sdk'\nimport type { Agent } from '@deepseek-ai/dsh-agent'\nimport { ToolCallId, createToolResultMessage } from '@deepseek-ai/dsh-llm'\nimport type { ApprovalService } from '@deepseek-ai/dsh-user-approval'\nimport type { UserQuestionService } from '@deepseek-ai/dsh-user-questions'\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { AsyncQueue } from './async-queue.ts'\nimport { DEFAULT_CLAUDE_RENDER_MODE, TASK_TOOL_NAMES, type ClaudeRenderMode } from './constants.ts'\nimport {\n currentClaudeActivityCursor,\n redactText,\n safeDetail,\n type ClaudeActivityCursor,\n type ClaudeActivityInput,\n type ClaudeTaskInfo,\n type ClaudeUsage,\n} from './events.ts'\nimport { createPermissionBridge } from './permission.ts'\nimport { PlanFeedbackGate } from './plan-feedback.ts'\nimport { createUserQuestionBridge } from './user-question.ts'\nimport { ClaudeSidecarRepository } from './sidecar.ts'\nimport { CLAUDE_PRESENTER_NAMES, dynamicPresenterDefinition } from './presenters.ts'\nimport { normalizeSdkMessage, type NormalizedSdkMessage } from './sdk-messages.ts'\nimport { claudeModelValue, recordClaudeModels } from './model-catalog.ts'\nimport { readPlanUsageFrom } from './plan-usage.ts'\nimport { createManagedClaudeSpawner, type ManagedClaudeProcess } from './spawn.ts'\nimport { captureWorktreeTree } from './worktree-snapshot.ts'\n\nexport const CLAUDE_INITIALIZATION_TIMEOUT_MS = 30_000\nexport const CLAUDE_INTERRUPT_TIMEOUT_MS = 5_000\n/** Control requests must settle; a wedged one must not clog the metadata chain. */\nexport const CLAUDE_METADATA_TIMEOUT_MS = 15_000\n\nexport type ClaudeSupervisorState =\n | 'starting'\n | 'idle'\n | 'running'\n | 'interrupting'\n | 'disconnected'\n | 'outcome-unknown'\n | 'disposed'\n\nexport interface ClaudeSupervisorConfig {\n executablePath: string\n idleTimeoutMs: number\n maxProcesses: number\n defaultModel: string\n /** Which renderer the visible turn is produced for; read per message so a\n * Settings change lands on the next turn without a Host restart. */\n renderMode?: ClaudeRenderMode\n}\n\nexport type ClaudeTurnStreamEvent =\n | { type: 'text-delta'; text: string }\n /** One settled Claude thinking block, forwarded only for the native\n * renderer, which draws it as a DSH reasoning block. */\n | { type: 'thinking'; text: string }\n | { type: 'usage'; usage: ClaudeUsage }\n | { type: 'segment-complete'; text: string }\n | { type: 'complete'; text: string }\n\nexport type ClaudeThinkingMode = 'off' | 'ultracode' | EffortLevel\n\nexport type DshSandboxMode = 'read-only' | 'workspace-write' | 'danger-full-access'\n\nconst CLAUDE_MODE_BY_SANDBOX: Readonly<Record<DshSandboxMode, PermissionMode>> = {\n 'read-only': 'plan',\n 'workspace-write': 'acceptEdits',\n 'danger-full-access': 'bypassPermissions',\n}\n\n/** Fold DSH's native access selector into Claude Code's closest permission mode. */\nexport function claudePermissionMode(events: readonly { type: string; data: unknown }[]): PermissionMode {\n for (let index = events.length - 1; index >= 0; index -= 1) {\n const event = events[index]\n if (event?.type !== 'sandbox/mode') continue\n const mode = (event.data as { mode?: unknown }).mode\n return typeof mode === 'string' && mode in CLAUDE_MODE_BY_SANDBOX\n ? CLAUDE_MODE_BY_SANDBOX[mode as DshSandboxMode]\n : 'plan'\n }\n return 'plan'\n}\n\nexport interface ClaudeTurnRequest {\n agent: Agent\n prompt: SDKUserMessage['message']['content']\n model?: string\n thinkingMode?: ClaudeThinkingMode\n /** The renderer this turn is produced for, frozen by the caller before the\n * turn starts. The setting is live, so reading it per record would let a\n * mid-turn switch stamp one step's records with both renderers -- which the\n * Client reads as \"natively drawn\" for the whole step, while the adapter,\n * which froze its own answer at turn start, streamed nothing natively.\n * Omitted falls back to the shared config. */\n renderMode?: ClaudeRenderMode\n signal?: AbortSignal\n}\n\nexport interface ClaudeSupervisorSnapshot {\n sessionId: string\n claudeSessionId?: string\n state: ClaudeSupervisorState\n cwd: string\n model: string\n thinkingMode?: ClaudeThinkingMode\n lastUsedAt: number\n pid?: number\n}\n\nexport class ClaudeTurnBusyError extends Error {\n constructor(sessionId: string) {\n super(`Claude Code session ${sessionId} already has an active or interrupting turn`)\n this.name = 'ClaudeTurnBusyError'\n }\n}\n\nexport class ClaudeOutcomeUnknownError extends Error {\n constructor(message = 'Claude Code exited after activity; side-effect outcome is unknown and the prompt was not replayed') {\n super(message)\n this.name = 'ClaudeOutcomeUnknownError'\n }\n}\n\nexport class ClaudeProtocolError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'ClaudeProtocolError'\n }\n}\n\nexport class ClaudeProcessLimitError extends Error {\n constructor(maxProcesses: number) {\n super(`Claude Code process limit reached (${maxProcesses}) and no idle session can be evicted`)\n this.name = 'ClaudeProcessLimitError'\n }\n}\n\nexport type ClaudeQueryFactory = (params: {\n prompt: AsyncIterable<SDKUserMessage>\n options: ClaudeOptions\n}) => Query\n\ninterface ActiveTurn {\n agent: Agent\n cursor: ClaudeActivityCursor\n /** Whether this turn is produced for DSH's own renderer. Frozen at admission\n * so every record of the turn carries one answer. */\n native: boolean\n output: AsyncQueue<ClaudeTurnStreamEvent>\n promptUuid: ReturnType<typeof randomUUID>\n phase: 'primary' | 'waiting-tasks' | 'follow-up'\n sawActivity: boolean\n sawTextDelta: boolean\n text: string\n /** Visible prose for the current top-level assistant segment. */\n transcriptText: string\n /** Stable sidecar ordinal reused while the current assistant segment grows. */\n transcriptTextOrdinal: number | undefined\n thinking: string\n /** Newest single-call prompt accounting; what DSH's context meter divides. */\n requestUsage: ClaudeUsage | undefined\n /** When this turn was admitted, and when it first put a token on screen.\n * The transcript has no other clock: activities carry no timestamps. */\n startedAt: number\n firstOutputAt: number | undefined\n aborted: boolean\n deniedToolUseIds: Set<string>\n /** Root tool calls still waiting for their result, by toolUseId, with the\n * tool name a result carries none of. Emptied as results arrive, so what\n * remains when a turn ends is exactly what never got an answer. */\n openCalls: Map<string, string>\n signal?: AbortSignal\n abortListener?: () => void\n}\n\ninterface SupervisorEntry {\n sessionId: string\n ownerAgent: Agent\n cwd: string\n model: string\n thinkingMode: ClaudeThinkingMode | undefined\n permissionMode: PermissionMode\n state: ClaudeSupervisorState\n lastUsedAt: number\n input: AsyncQueue<SDKUserMessage>\n query: Query\n /** Official SDK initialization control request; no stdin nudge is required. */\n sdkInitialization: Promise<void>\n lifetime: AbortController\n process: ManagedClaudeProcess | undefined\n claudeSessionId: string | undefined\n active: ActiveTurn | undefined\n idleTimer: ReturnType<typeof setTimeout> | undefined\n /** Whether the message stream has emitted system/init for session binding. */\n initialized: boolean\n expectedResume: string | undefined\n /** Newest main-chain entry uuid Claude emitted; the anchor a rewind of the\n * next turn forks at. Sidechain (subagent) entries are not chain entries. */\n lastChainUuid: string | undefined\n /** Whether this process consumed an armed rewind fork target at spawn. */\n consumedRewind: boolean\n /** Live Claude task board (subagents and background tasks), keyed by task id. */\n tasks: Map<string, ClaudeTaskInfo>\n /** Last time a task snapshot was persisted (progress throttling). */\n taskSnapshotAt: number\n /** Pending throttled snapshot flush timer. */\n taskSnapshotTimer: ReturnType<typeof setTimeout> | undefined\n pump: Promise<void>\n}\n\nfunction abortFailure(): Error {\n const error = new Error('Claude Code turn aborted')\n error.name = 'AbortError'\n return error\n}\n\nfunction signalAborted(signal: AbortSignal | undefined): boolean {\n return signal?.aborted === true\n}\n\ninterface TurnAdmission {\n request: ClaudeTurnRequest\n resolve: (output: AsyncIterable<ClaudeTurnStreamEvent>) => void\n reject: (error: unknown) => void\n delivered: boolean\n admitting: boolean\n waitedForCapacity: boolean\n cancellation: AbortController\n completion: Promise<void>\n complete: () => void\n abortListener?: () => void\n}\n\ninterface MetadataAdmission {\n sessionId: string\n cancellation: AbortController\n started: boolean\n completion: Promise<void>\n complete: () => void\n}\n\nasync function withTimeout<T>(operation: Promise<T>, timeoutMs: number, label: string): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined\n try {\n return await Promise.race([\n operation,\n new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs}ms`)), timeoutMs)\n timer.unref?.()\n }),\n ])\n } finally {\n if (timer !== undefined) clearTimeout(timer)\n }\n}\n\nasync function withAbort<T>(operation: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n if (signal === undefined) return operation\n if (signal.aborted) throw abortFailure()\n let abortListener: (() => void) | undefined\n try {\n return await Promise.race([\n operation,\n new Promise<never>((_resolve, reject) => {\n abortListener = () => { reject(abortFailure()) }\n signal.addEventListener('abort', abortListener, { once: true })\n }),\n ])\n } finally {\n if (abortListener !== undefined) signal.removeEventListener('abort', abortListener)\n }\n}\n\n/** The uuid of one main-chain transcript entry, or undefined for anything a\n * rewind must not fork at: stream partials, results, and sidechain traffic. */\nfunction chainEntryUuid(message: SDKMessage): string | undefined {\n if (message.type !== 'assistant' && message.type !== 'user') return undefined\n const envelope = message as { uuid?: unknown; parent_tool_use_id?: unknown }\n if (typeof envelope.parent_tool_use_id === 'string') return undefined\n return typeof envelope.uuid === 'string' && envelope.uuid.length > 0 ? envelope.uuid : undefined\n}\n\nfunction sdkUserMessage(prompt: SDKUserMessage['message']['content'], uuid: ReturnType<typeof randomUUID>): SDKUserMessage {\n return {\n type: 'user',\n message: { role: 'user', content: prompt },\n parent_tool_use_id: null,\n uuid,\n }\n}\n\nconst BACKGROUND_TASK_REPORT_PROMPT = [\n 'The background tasks launched by your preceding response have now all settled.',\n 'Report their final completed or failed outcomes concisely to the user.',\n 'Do not start new tools or tasks, and do not repeat the earlier progress update.',\n].join(' ')\n\nfunction usageSummary(usage: ClaudeUsage): string {\n const input = usage.inputTokens ?? 0\n const output = usage.outputTokens ?? 0\n const cost = usage.cumulativeCostUsd === undefined\n ? ''\n : ` · $${usage.cumulativeCostUsd.toFixed(4)} cumulative`\n return `${input} input / ${output} output tokens${cost}`\n}\n\nfunction errorSummary(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\n/** Root-call activity summary; subagent dispatches lead with Claude's own task description. */\nfunction rootCallSummary(toolName: string, input: unknown): string {\n if (TASK_TOOL_NAMES.has(toolName)) {\n const description = input !== null && typeof input === 'object'\n ? (input as Record<string, unknown>).description\n : undefined\n if (typeof description === 'string' && description.length > 0) return description\n return 'Claude dispatched a subagent'\n }\n return `Claude called ${toolName}`\n}\n\nexport class ClaudeSupervisor {\n readonly #entries = new Map<string, SupervisorEntry>()\n readonly #interruptions = new Map<string, Promise<void>>()\n readonly #runtime: Pick<SubprocessRuntime, 'spawn' | 'resolveExecutable'>\n readonly #approval: Pick<ApprovalService, 'request'>\n readonly #userQuestions: Pick<UserQuestionService, 'ask'>\n /** Lets the plan panel answer a plan's approval with revisions. */\n readonly planFeedback = new PlanFeedbackGate()\n readonly #config: ClaudeSupervisorConfig\n readonly #queryFactory: ClaudeQueryFactory\n readonly #runDetached: <T>(operation: () => T) => T\n readonly #sidecar: ClaudeSidecarRepository\n readonly #dynamicPresenterNames = new WeakMap<Agent, Set<string>>()\n readonly #contextWindows = new Map<string, number>()\n #disposed = false\n #admissionGate: Promise<void> = Promise.resolve()\n /** FIFO user turns live outside the gate while capacity-blocked, so\n * best-effort metadata can still enter the serialized path and fail. */\n readonly #turnAdmissions: TurnAdmission[] = []\n readonly #metadataAdmissions = new Set<MetadataAdmission>()\n #admissionDrainScheduled = false\n /** Prevent a capacity change between a failed attempt and parking the head\n * from becoming a lost wake-up. */\n #admissionRevision = 0\n #blockedAdmissionRevision: number | undefined\n\n constructor(dependencies: {\n runtime: Pick<SubprocessRuntime, 'spawn' | 'resolveExecutable'>\n approval: Pick<ApprovalService, 'request'>\n userQuestions: Pick<UserQuestionService, 'ask'>\n config: ClaudeSupervisorConfig\n queryFactory?: ClaudeQueryFactory\n runDetached?: <T>(operation: () => T) => T\n sidecar?: ClaudeSidecarRepository\n }) {\n this.#runtime = dependencies.runtime\n this.#approval = dependencies.approval\n this.#userQuestions = dependencies.userQuestions\n this.#config = dependencies.config\n this.#queryFactory = dependencies.queryFactory ?? (params => claudeQuery(params))\n this.#runDetached = dependencies.runDetached ?? (operation => operation())\n this.#sidecar = dependencies.sidecar ?? new ClaudeSidecarRepository()\n }\n\n snapshots(): ClaudeSupervisorSnapshot[] {\n return [...this.#entries.values()].map(entry => ({\n sessionId: entry.sessionId,\n ...(entry.claudeSessionId === undefined ? {} : { claudeSessionId: entry.claudeSessionId }),\n state: entry.state,\n cwd: entry.cwd,\n model: entry.model,\n ...(entry.thinkingMode === undefined ? {} : { thinkingMode: entry.thinkingMode }),\n lastUsedAt: entry.lastUsedAt,\n ...(entry.process === undefined ? {} : { pid: entry.process.handle.pid }),\n }))\n }\n\n supportedCommands(agent: Agent, model = this.#config.defaultModel): Promise<readonly SlashCommand[]> {\n return this.#runMetadata(agent, model, query => query.supportedCommands())\n }\n\n async contextUsage(agent: Agent, model = this.#config.defaultModel): Promise<SDKControlGetContextUsageResponse> {\n return this.#runMetadata(agent, model, async (query, entry) => {\n const usage = await query.getContextUsage()\n this.#recordContextWindow(entry.model, usage)\n return usage\n })\n }\n\n /** Cache a window under both the selector id the caller asked for and the\n * concrete model the CLI reports, so either name resolves it later. */\n #recordContextWindow(model: string, usage: SDKControlGetContextUsageResponse): void {\n const contextWindow = usage.rawMaxTokens > 0 ? usage.rawMaxTokens : usage.maxTokens\n if (contextWindow <= 0) return\n this.#contextWindows.set(model, contextWindow)\n this.#contextWindows.set(usage.model, contextWindow)\n }\n\n /** Learn a model's context window the first time a turn finishes on it.\n *\n * DSH hides its context meter entirely unless the route publishes a\n * capacity, and these numbers move with Claude releases — so none are\n * hardcoded; the CLI is asked over the session's own live process.\n *\n * Turn completion is the earliest honest moment to ask. `entry.model` is\n * already the model that just ran, so no model switch is provoked — which\n * rules out asking from `resolveModel`, since DSH resolves every model in\n * the catalog to build its picker and `#metadataEntry` would switch the live\n * session once per entry. And nothing is lost by waiting: the meter needs a\n * usage sample too, and no turn has reported one before the first turn ends.\n *\n * Best-effort — a failure leaves the window unknown (the meter stays hidden,\n * exactly as before) and the next completed turn tries again. */\n async #learnContextWindow(entry: SupervisorEntry): Promise<void> {\n if (this.#contextWindows.has(entry.model)) return\n try {\n const usage = await withTimeout(\n entry.query.getContextUsage(),\n CLAUDE_METADATA_TIMEOUT_MS,\n 'Claude context window probe',\n )\n this.#recordContextWindow(entry.model, usage)\n } catch {\n // Intentionally silent: this is opportunistic chrome, never turn-critical.\n }\n }\n\n contextWindow(model: string): number | undefined {\n return this.#contextWindows.get(model)\n }\n\n /** Raw `/usage` payload, read over a session's existing process. Only the\n * idle-time metadata bridge uses this; a user-triggered refresh runs\n * probePlanUsage instead so it never waits on, or perturbs, a session. */\n planUsage(agent: Agent, model = this.#config.defaultModel): Promise<unknown> {\n return this.#runMetadata(agent, model, query => readPlanUsageFrom(query))\n }\n\n runTurn(request: ClaudeTurnRequest): Promise<AsyncIterable<ClaudeTurnStreamEvent>> {\n const interruption = this.#interruptions.get(request.agent.id as string)\n if (interruption !== undefined) return interruption.then(() => this.runTurn(request))\n return new Promise((resolve, reject) => {\n let complete: (() => void) | undefined\n const completion = new Promise<void>(done => { complete = done })\n const admission: TurnAdmission = {\n request,\n resolve,\n reject,\n delivered: false,\n admitting: false,\n waitedForCapacity: false,\n cancellation: new AbortController(),\n completion,\n complete: () => { complete?.() },\n }\n if (request.signal !== undefined) {\n const abortListener = () => {\n if (!admission.admitting) {\n this.#finishTurnAdmission(admission, { error: abortFailure() })\n } else if (admission.waitedForCapacity && !admission.delivered) {\n admission.delivered = true\n admission.reject(abortFailure())\n }\n this.#admissionRevision += 1\n this.#blockedAdmissionRevision = undefined\n this.#scheduleTurnAdmissions()\n }\n admission.abortListener = abortListener\n request.signal.addEventListener('abort', abortListener, { once: true })\n }\n this.#turnAdmissions.push(admission)\n this.#scheduleTurnAdmissions()\n })\n }\n\n async #drainTurnAdmissions(): Promise<void> {\n while (this.#turnAdmissions.length > 0) {\n const admission = this.#turnAdmissions[0]!\n if (signalAborted(admission.request.signal)) {\n this.#finishTurnAdmission(admission, { error: abortFailure() })\n continue\n }\n const attemptedRevision = this.#admissionRevision\n admission.admitting = true\n try {\n const output = await this.#runTurnAdmitted(\n admission.request,\n admission.waitedForCapacity,\n admission.cancellation.signal,\n )\n this.#finishTurnAdmission(admission, { output })\n } catch (error) {\n if (\n error instanceof ClaudeProcessLimitError\n && !signalAborted(admission.request.signal)\n && !admission.cancellation.signal.aborted\n && !this.#disposed\n ) {\n admission.admitting = false\n admission.waitedForCapacity = true\n if (attemptedRevision === this.#admissionRevision) {\n this.#blockedAdmissionRevision = attemptedRevision\n return\n }\n continue\n }\n this.#finishTurnAdmission(admission, { error })\n }\n }\n }\n\n #finishTurnAdmission(\n admission: TurnAdmission,\n outcome: { output: AsyncIterable<ClaudeTurnStreamEvent> } | { error: unknown },\n ): void {\n if (this.#turnAdmissions[0] === admission) this.#turnAdmissions.shift()\n else {\n const index = this.#turnAdmissions.indexOf(admission)\n if (index >= 0) this.#turnAdmissions.splice(index, 1)\n }\n admission.admitting = false\n if (admission.request.signal !== undefined && admission.abortListener !== undefined) {\n admission.request.signal.removeEventListener('abort', admission.abortListener)\n }\n if (!admission.delivered) {\n admission.delivered = true\n if ('error' in outcome) admission.reject(outcome.error)\n else admission.resolve(outcome.output)\n }\n admission.complete()\n }\n\n #scheduleTurnAdmissions(): void {\n if (\n this.#admissionDrainScheduled\n || this.#turnAdmissions.length === 0\n || this.#blockedAdmissionRevision === this.#admissionRevision\n ) return\n this.#admissionDrainScheduled = true\n const operation = this.#admissionGate.then(() => this.#drainTurnAdmissions())\n this.#admissionGate = operation.then(() => undefined, () => undefined)\n const finished = () => {\n this.#admissionDrainScheduled = false\n this.#scheduleTurnAdmissions()\n }\n void operation.then(finished, finished)\n }\n\n async #runTurnAdmitted(\n request: ClaudeTurnRequest,\n abortDuringAdmission: boolean,\n cancellationSignal: AbortSignal,\n ): Promise<AsyncIterable<ClaudeTurnStreamEvent>> {\n if (this.#disposed) throw new Error('dsh-claude: supervisor is disposed')\n if (cancellationSignal.aborted) throw abortFailure()\n if (signalAborted(request.signal)) throw abortFailure()\n const sessionId = request.agent.id as string\n let entry = this.#entries.get(sessionId)\n let createdForRequest: SupervisorEntry | undefined\n const throwIfUnavailable = async (): Promise<void> => {\n const failure = this.#disposed\n ? new Error('dsh-claude: supervisor is disposed')\n : cancellationSignal.aborted || (abortDuringAdmission && signalAborted(request.signal))\n ? abortFailure()\n : undefined\n if (failure === undefined) return\n if (createdForRequest !== undefined) {\n if (this.#entries.get(sessionId) === createdForRequest) this.#entries.delete(sessionId)\n await this.#disposeEntry(createdForRequest)\n createdForRequest = undefined\n }\n throw failure\n }\n if (entry?.state === 'disposed' || entry?.state === 'disconnected' || entry?.state === 'outcome-unknown') {\n this.#entries.delete(sessionId)\n await this.#disposeEntry(entry)\n await throwIfUnavailable()\n entry = undefined\n }\n if (entry === undefined) {\n await this.#makeRoom()\n await throwIfUnavailable()\n try {\n entry = await this.#createEntry(\n request.agent,\n request.model ?? this.#config.defaultModel,\n request.thinkingMode,\n abortDuringAdmission ? request.signal : undefined,\n cancellationSignal,\n )\n } catch (error) {\n await throwIfUnavailable()\n throw error\n }\n createdForRequest = entry\n await throwIfUnavailable()\n this.#entries.set(sessionId, entry)\n }\n if (entry.ownerAgent !== request.agent) {\n throw new Error(`dsh-claude: live agent identity changed for session ${sessionId}`)\n }\n if (entry.active !== undefined || entry.state === 'interrupting') throw new ClaudeTurnBusyError(sessionId)\n try {\n const initialization = withAbort(entry.sdkInitialization, cancellationSignal)\n await (abortDuringAdmission ? withAbort(initialization, request.signal) : initialization)\n } catch (error) {\n await throwIfUnavailable()\n throw error\n }\n await throwIfUnavailable()\n\n if (entry.idleTimer !== undefined) {\n clearTimeout(entry.idleTimer)\n entry.idleTimer = undefined\n }\n const model = request.model ?? this.#config.defaultModel\n if (request.thinkingMode !== entry.thinkingMode || model !== entry.model) {\n // The SDK only accepts effort/thinking at query start, and a live\n // setModel is not enough for the model either: the CLI freezes its\n // system prompt (including the \"you are powered by\" line) at the first\n // context-usage request, which the metadata refresh issues on every new\n // process, so a switched session answers as the old model. Rebuild the\n // query; the persisted Claude session binding keeps the context.\n this.#entries.delete(sessionId)\n await this.#disposeEntry(entry)\n if (createdForRequest === entry) createdForRequest = undefined\n await throwIfUnavailable()\n try {\n entry = await this.#createEntry(\n request.agent,\n model,\n request.thinkingMode,\n abortDuringAdmission ? request.signal : undefined,\n cancellationSignal,\n )\n } catch (error) {\n await throwIfUnavailable()\n throw error\n }\n createdForRequest = entry\n await throwIfUnavailable()\n this.#entries.set(sessionId, entry)\n try {\n const initialization = withAbort(entry.sdkInitialization, cancellationSignal)\n await (abortDuringAdmission ? withAbort(initialization, request.signal) : initialization)\n } catch (error) {\n await throwIfUnavailable()\n throw error\n }\n } else {\n await this.#syncPermissionMode(entry)\n }\n await throwIfUnavailable()\n\n const promptUuid = randomUUID()\n const cursor = currentClaudeActivityCursor(request.agent.session.snapshotEvents())\n const projection = await this.#sidecar.read(sessionId)\n await throwIfUnavailable()\n cursor.nextOrdinal = projection.activities.reduce((next, activity) => (\n activity.turn === cursor.turn && activity.step === cursor.step\n ? Math.max(next, activity.ordinal + 1)\n : next\n ), 0)\n const active: ActiveTurn = {\n agent: request.agent,\n cursor,\n native: (request.renderMode ?? this.#config.renderMode ?? DEFAULT_CLAUDE_RENDER_MODE) === 'native',\n output: new AsyncQueue<ClaudeTurnStreamEvent>(),\n promptUuid,\n phase: 'primary',\n sawActivity: false,\n sawTextDelta: false,\n text: '',\n transcriptText: '',\n transcriptTextOrdinal: undefined,\n thinking: '',\n requestUsage: undefined,\n startedAt: Date.now(),\n firstOutputAt: undefined,\n aborted: false,\n deniedToolUseIds: new Set(),\n openCalls: new Map(),\n ...(request.signal === undefined ? {} : { signal: request.signal }),\n }\n entry.active = active\n entry.state = 'running'\n entry.lastUsedAt = Date.now()\n await this.#captureWorktree(entry, cursor.turn)\n try {\n await this.#appendActivity(active, {\n kind: 'status',\n phase: 'started',\n title: 'Claude Code turn started',\n })\n } catch (error) {\n active.output.fail(error)\n entry.active = undefined\n if (this.#entries.get(sessionId) === entry) this.#entries.delete(sessionId)\n await this.#disposeEntry(entry)\n throw error\n }\n if (signalAborted(request.signal)) {\n active.aborted = true\n active.output.fail(abortFailure())\n await this.#appendActivity(active, {\n kind: 'status',\n phase: 'failed',\n title: 'Claude Code turn cancelled before submission',\n })\n entry.active = undefined\n if (!abortDuringAdmission || createdForRequest === undefined) {\n entry.state = 'idle'\n entry.lastUsedAt = Date.now()\n this.#armIdleTimer(entry)\n }\n await throwIfUnavailable()\n return active.output\n }\n if (request.signal !== undefined) {\n const abortListener = () => { void this.#startInterrupt(entry as SupervisorEntry) }\n active.abortListener = abortListener\n request.signal.addEventListener('abort', abortListener, { once: true })\n }\n entry.input.push(sdkUserMessage(request.prompt, promptUuid))\n return active.output\n }\n\n #runMetadata<T>(\n agent: Agent,\n model: string,\n operation: (query: Query, entry: SupervisorEntry) => Promise<T>,\n ): Promise<T> {\n if (this.#turnAdmissions.some(admission => admission.waitedForCapacity)) {\n return Promise.reject(new ClaudeProcessLimitError(this.#config.maxProcesses))\n }\n let complete: (() => void) | undefined\n const admission: MetadataAdmission = {\n sessionId: agent.id as string,\n cancellation: new AbortController(),\n started: false,\n completion: new Promise<void>(done => { complete = done }),\n complete: () => { complete?.() },\n }\n this.#metadataAdmissions.add(admission)\n const admitted = this.#admissionGate.then(async () => {\n admission.started = true\n if (this.#disposed) throw new Error('dsh-claude: supervisor is disposed')\n if (admission.cancellation.signal.aborted) throw abortFailure()\n if (this.#turnAdmissions.some(admission => admission.waitedForCapacity)) {\n throw new ClaudeProcessLimitError(this.#config.maxProcesses)\n }\n const entry = await this.#metadataEntry(agent, model, admission.cancellation.signal)\n try {\n // Use the SDK's initialize control request. system/init is emitted only\n // after the first real stdin message and is reserved for session binding.\n await withAbort(entry.sdkInitialization, admission.cancellation.signal)\n return await withAbort(\n this.#control(entry, operation(entry.query, entry), 'Claude metadata request'),\n admission.cancellation.signal,\n )\n } finally {\n entry.lastUsedAt = Date.now()\n if (entry.active === undefined && entry.state === 'idle') this.#armIdleTimer(entry)\n }\n }).finally(() => { this.#finishMetadataAdmission(admission) })\n this.#admissionGate = admitted.then(() => undefined, () => undefined)\n return withAbort(admitted, admission.cancellation.signal)\n }\n\n async #metadataEntry(\n agent: Agent,\n model: string,\n cancellationSignal: AbortSignal,\n ): Promise<SupervisorEntry> {\n if (cancellationSignal.aborted) throw abortFailure()\n const sessionId = agent.id as string\n let entry = this.#entries.get(sessionId)\n if (entry?.state === 'disposed' || entry?.state === 'disconnected' || entry?.state === 'outcome-unknown') {\n this.#entries.delete(sessionId)\n await this.#disposeEntry(entry)\n if (cancellationSignal.aborted) throw abortFailure()\n entry = undefined\n }\n if (entry === undefined) {\n await this.#makeRoom()\n if (cancellationSignal.aborted) throw abortFailure()\n entry = await this.#createEntry(agent, model, undefined, undefined, cancellationSignal)\n if (cancellationSignal.aborted) {\n await this.#disposeEntry(entry)\n throw abortFailure()\n }\n this.#entries.set(sessionId, entry)\n }\n if (entry.ownerAgent !== agent) {\n throw new Error(`dsh-claude: live agent identity changed for session ${sessionId}`)\n }\n if (entry.active !== undefined || entry.state === 'interrupting') throw new ClaudeTurnBusyError(sessionId)\n if (entry.idleTimer !== undefined) {\n clearTimeout(entry.idleTimer)\n entry.idleTimer = undefined\n }\n await withAbort(this.#syncPermissionMode(entry), cancellationSignal)\n if (cancellationSignal.aborted) throw abortFailure()\n // Never switch a live entry here: `model` is only the seed for a fresh\n // process. The idle metadata refresh runs with the plugin default, and\n // letting it call setModel raced runTurn's own switch -- a session the user\n // set to Fable answered on Opus whenever the refresh landed last.\n return entry\n }\n\n /** Run one SDK control request against a live entry, and discard the entry if\n * it does not answer.\n *\n * Turn admission attempts and metadata reads share one process-wide gate,\n * so an unbounded control request stalls every session until the Host restarts.\n * Bounding it is only half the cure: a timeout also proves this query has\n * stopped answering, and keeping the entry means the next caller reuses the\n * same dead process — timing out again, forever. Discarding it lets the next\n * attempt spawn a fresh one. Every control request goes through here so a\n * new call site cannot quietly reintroduce either half. */\n async #control<T>(\n entry: SupervisorEntry,\n operation: Promise<T>,\n label: string,\n timeoutMs = CLAUDE_METADATA_TIMEOUT_MS,\n ): Promise<T> {\n try {\n return await withTimeout(operation, timeoutMs, label)\n } catch (error) {\n if (this.#entries.get(entry.sessionId) === entry) this.#entries.delete(entry.sessionId)\n await this.#disposeEntry(entry)\n throw error\n }\n }\n\n async #syncPermissionMode(entry: SupervisorEntry): Promise<void> {\n const mode = claudePermissionMode(entry.ownerAgent.session.snapshotEvents())\n if (mode === entry.permissionMode) return\n await this.#control(entry, entry.query.setPermissionMode(mode), 'Claude Code permission mode switch')\n entry.permissionMode = mode\n }\n\n #finishMetadataAdmission(admission: MetadataAdmission): void {\n this.#metadataAdmissions.delete(admission)\n admission.complete()\n }\n\n #cancelMetadataAdmissions(\n predicate: (admission: MetadataAdmission) => boolean,\n ): Promise<void>[] {\n const cancelled = [...this.#metadataAdmissions].filter(predicate)\n for (const admission of cancelled) {\n admission.cancellation.abort()\n if (!admission.started) this.#finishMetadataAdmission(admission)\n }\n return cancelled.map(admission => admission.completion)\n }\n\n #cancelTurnAdmissions(\n predicate: (admission: TurnAdmission) => boolean,\n error: Error,\n ): Promise<void>[] {\n const cancelled = this.#turnAdmissions.filter(predicate)\n for (const admission of cancelled) {\n admission.cancellation.abort()\n if (!admission.delivered) {\n admission.delivered = true\n admission.reject(error)\n }\n if (!admission.admitting) this.#finishTurnAdmission(admission, { error })\n }\n if (cancelled.length > 0) {\n this.#admissionRevision += 1\n this.#blockedAdmissionRevision = undefined\n this.#scheduleTurnAdmissions()\n }\n return cancelled.map(admission => admission.completion)\n }\n\n limitsChanged(): void {\n if (this.#disposed) return\n this.#notifyCapacityChange()\n this.#scheduleLimitReconciliation()\n }\n\n async disposeSession(sessionId: string): Promise<void> {\n const pendingAdmissions = this.#cancelTurnAdmissions(\n admission => (admission.request.agent.id as string) === sessionId,\n abortFailure(),\n )\n const pendingMetadata = this.#cancelMetadataAdmissions(\n admission => admission.sessionId === sessionId,\n )\n const entry = this.#entries.get(sessionId)\n if (entry !== undefined) this.#entries.delete(sessionId)\n await Promise.allSettled([\n ...pendingAdmissions,\n ...pendingMetadata,\n ...(entry === undefined ? [] : [this.#disposeEntry(entry)]),\n ])\n }\n\n async dispose(): Promise<void> {\n if (this.#disposed) return\n this.#disposed = true\n const pendingAdmissions = this.#cancelTurnAdmissions(\n () => true,\n new Error('dsh-claude: supervisor is disposed'),\n )\n const pendingMetadata = this.#cancelMetadataAdmissions(() => true)\n const entries = [...this.#entries.values()]\n this.#entries.clear()\n this.#notifyCapacityChange()\n await Promise.allSettled([\n ...pendingAdmissions,\n ...pendingMetadata,\n ...entries.map(entry => this.#disposeEntry(entry)),\n ])\n }\n\n async #makeRoom(): Promise<void> {\n while (this.#entries.size >= this.#config.maxProcesses) {\n const idle = [...this.#entries.values()]\n .filter(entry => entry.active === undefined && entry.state === 'idle')\n .sort((left, right) => left.lastUsedAt - right.lastUsedAt)[0]\n if (idle === undefined) throw new ClaudeProcessLimitError(this.#config.maxProcesses)\n this.#entries.delete(idle.sessionId)\n await this.#disposeEntry(idle)\n }\n }\n\n async #trimExcessIdle(): Promise<void> {\n while (this.#entries.size > this.#config.maxProcesses) {\n const idle = [...this.#entries.values()]\n .filter(entry => entry.active === undefined && entry.state === 'idle')\n .sort((left, right) => left.lastUsedAt - right.lastUsedAt)[0]\n if (idle === undefined) return\n this.#entries.delete(idle.sessionId)\n await this.#disposeEntry(idle)\n }\n }\n\n #notifyCapacityChange(): void {\n this.#admissionRevision += 1\n this.#blockedAdmissionRevision = undefined\n this.#scheduleTurnAdmissions()\n }\n\n #scheduleLimitReconciliation(): void {\n const operation = this.#admissionGate.then(() => this.#trimExcessIdle())\n this.#admissionGate = operation.then(() => undefined, () => undefined)\n }\n\n async #createEntry(\n agent: Agent,\n model: string,\n thinkingMode?: ClaudeThinkingMode,\n signal?: AbortSignal,\n cancellationSignal?: AbortSignal,\n ): Promise<SupervisorEntry> {\n const sessionId = agent.id as string\n const cwd = agent.session.header.cwd ?? process.cwd()\n const input = new AsyncQueue<SDKUserMessage>()\n const lifetime = new AbortController()\n const projection = await this.#sidecar.importLegacy(sessionId, agent.session.snapshotEvents())\n if (signalAborted(signal) || signalAborted(cancellationSignal)) throw abortFailure()\n const binding = projection.binding\n // A rewound session resumes at the kept turn's chain anchor, or drops its\n // binding entirely when the rewind discarded every turn. The truncating\n // resume may land in a different Claude session id, so the identity guard\n // stands down for exactly this spawn and re-binds from system/init.\n const pendingRewind = projection.rewind?.pending\n const forkAt = pendingRewind !== undefined && 'resumeAt' in pendingRewind ? pendingRewind.resumeAt : undefined\n const startFresh = pendingRewind !== undefined && 'fresh' in pendingRewind\n const permissionMode = claudePermissionMode(agent.session.snapshotEvents())\n const entry = {\n sessionId,\n ownerAgent: agent,\n cwd,\n model,\n thinkingMode,\n permissionMode,\n state: 'starting' as ClaudeSupervisorState,\n lastUsedAt: Date.now(),\n input,\n lifetime,\n claudeSessionId: startFresh ? undefined : binding?.claudeSessionId,\n expectedResume: startFresh || forkAt !== undefined ? undefined : binding?.claudeSessionId,\n lastChainUuid: undefined,\n consumedRewind: pendingRewind !== undefined,\n initialized: false,\n idleTimer: undefined,\n tasks: new Map<string, ClaudeTaskInfo>(),\n taskSnapshotAt: 0,\n taskSnapshotTimer: undefined,\n } as SupervisorEntry\n\n const activeInteraction = () => {\n const active = entry.active\n return active === undefined ? undefined : {\n agent: active.agent,\n cursor: active.cursor,\n markActivity: () => { active.sawActivity = true },\n recordDenial: (toolUseId: string) => { active.deniedToolUseIds.add(toolUseId) },\n hasFullAccess: async () => {\n await this.#syncPermissionMode(entry)\n return entry.permissionMode === 'bypassPermissions'\n },\n appendActivity: (activity: ClaudeActivityInput) => this.#appendActivity(active, activity),\n }\n }\n const userQuestion = createUserQuestionBridge(this.#userQuestions, activeInteraction)\n const canUseTool = createPermissionBridge(this.#approval, activeInteraction, userQuestion, this.planFeedback)\n const options: ClaudeOptions = {\n pathToClaudeCodeExecutable: this.#config.executablePath,\n cwd,\n settingSources: ['user', 'project', 'local'],\n systemPrompt: { type: 'preset', preset: 'claude_code' },\n tools: { type: 'preset', preset: 'claude_code' },\n includePartialMessages: true,\n permissionMode,\n allowDangerouslySkipPermissions: true,\n canUseTool,\n abortController: lifetime,\n spawnClaudeCodeProcess: createManagedClaudeSpawner(this.#runtime, this.#config.executablePath, process => {\n entry.process = process\n }),\n ...(binding === undefined || startFresh ? {} : {\n resume: binding.claudeSessionId,\n ...(forkAt === undefined ? {} : { resumeSessionAt: forkAt }),\n }),\n // `model` is the selector alias DSH persists; the CLI is given the id\n // that alias currently stands for.\n model: claudeModelValue(model),\n ...(thinkingMode === undefined\n ? {}\n : thinkingMode === 'off'\n ? { thinking: { type: 'disabled' } as const }\n : thinkingMode === 'ultracode'\n ? { settings: { ultracode: true } satisfies ClaudeSettings }\n : { effort: thinkingMode }),\n }\n entry.query = this.#queryFactory({ prompt: input, options })\n entry.pump = this.#runDetached(() => this.#pump(entry))\n entry.sdkInitialization = withTimeout(\n entry.query.initializationResult(),\n CLAUDE_INITIALIZATION_TIMEOUT_MS,\n 'Claude SDK initialization',\n ).then((initialization) => {\n // The CLI's own /model lineup rides along on initialize, so the selector\n // tracks whatever Claude Code ships without a table in this plugin and\n // without a control request of its own.\n recordClaudeModels(initialization.models)\n if (entry.state === 'starting') entry.state = 'idle'\n })\n void entry.sdkInitialization.catch(error => this.#handleDisconnect(entry, error))\n return entry\n }\n\n async #pump(entry: SupervisorEntry): Promise<void> {\n try {\n for await (const sdkMessage of entry.query) {\n const chainUuid = chainEntryUuid(sdkMessage as SDKMessage)\n if (chainUuid !== undefined) entry.lastChainUuid = chainUuid\n for (const message of normalizeSdkMessage(sdkMessage as SDKMessage)) {\n await this.#handleMessage(entry, message)\n }\n }\n if (entry.state !== 'disposed') await this.#handleDisconnect(entry, new Error('Claude Code stream ended'))\n } catch (error) {\n if (entry.state !== 'disposed') await this.#handleDisconnect(entry, error)\n }\n }\n\n async #handleMessage(entry: SupervisorEntry, message: NormalizedSdkMessage): Promise<void> {\n if (message.kind === 'init') {\n // Claude Code can re-emit system/init across turns in long-lived\n // streaming-input mode (e.g. the auth-error path). Treat it idempotently:\n // refresh the session id/version and negotiated state, and only reject a\n // genuine identity/cwd mismatch.\n const firstInitialization = !entry.initialized\n if (entry.expectedResume !== undefined && message.sessionId !== entry.expectedResume) {\n throw new ClaudeProtocolError(`Claude Code resumed unexpected session ${message.sessionId}; expected ${entry.expectedResume}`)\n }\n if (message.cwd !== entry.cwd) {\n throw new ClaudeProtocolError(`Claude Code initialized in unexpected cwd ${message.cwd}; expected ${entry.cwd}`)\n }\n entry.initialized = true\n entry.claudeSessionId = message.sessionId\n entry.state = entry.active === undefined ? 'idle' : 'running'\n // A newly created Query cannot retain tasks from the previous process,\n // but repeated init messages from this same long-lived Query are only\n // protocol refreshes and must not erase background work still running.\n if (firstInitialization && entry.tasks.size > 0) {\n entry.tasks.clear()\n await this.#flushTasksSnapshot(entry)\n }\n await this.#sidecar.writeBinding(entry.sessionId, {\n claudeSessionId: message.sessionId,\n cliVersion: message.cliVersion,\n cwd: message.cwd,\n })\n // The fork target is spent the moment Claude resumes at it; leaving it\n // armed would re-truncate the session on the next respawn.\n if (entry.consumedRewind) {\n entry.consumedRewind = false\n await this.#sidecar.clearRewindPending(entry.sessionId)\n }\n return\n }\n\n // Task lifecycle is session-scoped, not turn-scoped: background tasks and\n // subagents settle while no DSH turn is active, and their notifications\n // must still reach the task board instead of being dropped with turn-less\n // messages below.\n const taskId = message.kind === 'subagent' ? message.taskId : undefined\n if (message.kind === 'subagent' && taskId !== undefined) {\n await this.#trackTask(entry, message, taskId, entry.active?.cursor.turn)\n } else if (message.kind === 'background-tasks') {\n await this.#trackBackgroundLevel(entry, message.tasks, entry.active?.cursor.turn)\n }\n\n const active = entry.active\n if (active === undefined) return\n if (message.kind === 'result') {\n if (entry.claudeSessionId === undefined) {\n throw new ClaudeProtocolError('Claude Code sent a result before initialization')\n }\n if (message.sessionId !== entry.claudeSessionId) {\n throw new ClaudeProtocolError(`Claude Code result session ${message.sessionId} does not match ${entry.claudeSessionId}`)\n }\n if (active.phase === 'waiting-tasks') {\n // The CLI may automatically react to each completed background task and\n // emit a top-level result, correlated or not. Publish that prose as a\n // completed progress block, but keep the original DSH turn open until\n // every owned task settles and the explicit final report returns.\n await this.#completeProgressSegment(active, message)\n return\n }\n if (message.userMessageUuid !== undefined && message.userMessageUuid !== active.promptUuid) {\n // A stale internal continuation must not settle the explicit final\n // report request. Primary-turn mismatches remain protocol failures.\n if (active.phase === 'follow-up') return\n throw new ClaudeProtocolError(`Claude Code result for user message ${message.userMessageUuid} does not match active request ${active.promptUuid}`)\n }\n await this.#completeTurn(entry, active, message)\n return\n }\n if (message.kind === 'protocol-error') {\n throw new ClaudeProtocolError(`${message.title}: ${JSON.stringify(message.detail).slice(0, 1_000)}`)\n }\n active.sawActivity = true\n\n switch (message.kind) {\n case 'text-delta':\n if (message.parentToolUseId !== undefined) return\n active.sawTextDelta = true\n active.text += message.text\n active.transcriptText += message.text\n await this.#upsertTranscriptText(active)\n active.firstOutputAt ??= Date.now()\n active.output.push({ type: 'text-delta', text: message.text })\n return\n case 'assistant-text':\n if (message.parentToolUseId !== undefined) return\n if (!active.sawTextDelta) {\n // Complete assistant text is the fallback when no partial text delta\n // streamed. Mark text-delta seen so that additional complete\n // assistant records sharing the same message.id (one per completed\n // content block) do not duplicate the text.\n active.sawTextDelta = true\n active.text += message.text\n active.transcriptText += message.text\n await this.#upsertTranscriptText(active)\n active.firstOutputAt ??= Date.now()\n active.output.push({ type: 'text-delta', text: message.text })\n }\n return\n case 'thinking':\n if (message.parentToolUseId !== undefined) return\n if (message.phase === 'updated') {\n active.thinking += message.text\n return\n }\n active.thinking = message.text\n await this.#appendActivity(active, {\n kind: 'thinking',\n phase: 'completed',\n title: 'Claude thinking',\n summary: message.text,\n })\n // The plugin transcript reads thinking off the sidecar; the native\n // renderer needs it on the stream to build a reasoning block.\n if (active.native) active.output.push({ type: 'thinking', text: message.text })\n return\n case 'tool-call':\n if (message.parentToolUseId === undefined) this.#closeTranscriptTextSegment(active)\n await this.#appendActivity(active, {\n kind: message.parentToolUseId === undefined ? 'tool-call' : 'subagent',\n phase: 'started',\n toolUseId: message.toolUseId,\n ...(message.parentToolUseId === undefined ? {} : { parentToolUseId: message.parentToolUseId }),\n toolName: message.toolName,\n title: message.toolName,\n summary: message.parentToolUseId === undefined ? rootCallSummary(message.toolName, message.input) : `Subagent called ${message.toolName}`,\n detail: message.input,\n })\n if (message.parentToolUseId === undefined) {\n active.openCalls.set(message.toolUseId, message.toolName)\n // Only root calls are mirrored: a subagent's nested tools belong to\n // the Task card that dispatched them, and the native channel has no\n // nesting to hang them under.\n if (active.native) {\n this.#ensureDynamicPresenter(active.agent, message.toolName)\n await this.#appendNativeToolCall(active, message)\n }\n }\n return\n case 'tool-result':\n active.openCalls.delete(message.toolUseId)\n await this.#appendActivity(active, {\n kind: message.parentToolUseId === undefined ? 'tool-result' : 'subagent',\n phase: message.isError ? 'failed' : 'completed',\n toolUseId: message.toolUseId,\n ...(message.parentToolUseId === undefined ? {} : { parentToolUseId: message.parentToolUseId }),\n title: message.isError ? 'Tool failed' : 'Tool completed',\n detail: message.output,\n isError: message.isError,\n })\n if (message.parentToolUseId === undefined && active.native) {\n await this.#appendNativeToolResult(active, message)\n }\n return\n case 'subagent':\n await this.#appendActivity(active, {\n kind: 'subagent',\n phase: message.phase,\n ...(message.taskId === undefined ? {} : { taskId: message.taskId }),\n title: message.title,\n summary: message.summary,\n detail: message.detail,\n isError: message.phase === 'failed',\n })\n return\n case 'request-usage':\n // A subagent call bills against its own context, so it never stands in\n // for the main conversation's size.\n if (message.parentToolUseId === undefined) active.requestUsage = message.usage\n return\n case 'compaction':\n // Close the open prose span first: compaction sits *between* what was\n // said before and after it, never inside one text segment.\n this.#closeTranscriptTextSegment(active)\n await this.#appendActivity(active, {\n kind: 'compaction',\n phase: 'completed',\n title: 'Claude compacted the conversation',\n detail: {\n ...(message.trigger === undefined ? {} : { trigger: message.trigger }),\n ...(message.preTokens === undefined ? {} : { preTokens: message.preTokens }),\n ...(message.postTokens === undefined ? {} : { postTokens: message.postTokens }),\n ...(message.durationMs === undefined ? {} : { durationMs: message.durationMs }),\n },\n })\n return\n case 'status':\n case 'warning':\n case 'unknown':\n // One-shot notices (an API retry, a hook echo) have no later event to\n // close them, so they must land settled: an 'updated' phase reads as\n // still running in the transcript forever.\n await this.#appendActivity(active, {\n kind: message.kind === 'status' ? 'status' : 'warning',\n phase: 'completed',\n title: message.title,\n ...('summary' in message ? { summary: message.summary } : {}),\n ...('detail' in message ? { detail: message.detail } : {}),\n })\n return\n case 'permission-denied':\n await this.#appendActivity(active, {\n kind: 'permission',\n phase: 'denied',\n toolUseId: message.toolUseId,\n toolName: message.toolName,\n title: message.toolName,\n summary: message.summary,\n })\n // A denied call never produces a tool result, so the native card would\n // stay pending forever. Settle it as the failure it is.\n if (active.native) {\n await this.#appendNativeToolResult(active, {\n kind: 'tool-result',\n toolUseId: message.toolUseId,\n output: message.summary,\n isError: true,\n })\n }\n return\n }\n }\n\n /** The turn's accounting with its wall clock attached. The transcript draws\n * this line itself under the plugin renderer: activities carry no\n * timestamps, so a duration it did not measure is a duration nobody has. */\n #timedUsage(active: ActiveTurn, usage: ClaudeUsage): ClaudeUsage {\n const now = Date.now()\n return {\n ...usage,\n durationMs: Math.max(0, now - active.startedAt),\n ...(active.firstOutputAt === undefined ? {} : { ttftMs: Math.max(0, active.firstOutputAt - active.startedAt) }),\n }\n }\n\n /** Register one presenter-only mirror for a tool name the static preset\n * registry does not cover (MCP tools, newly added built-ins). Runs in the\n * agent scope so the mirror is visible only to this preset's sessions and\n * unwinds with the agent; failure keeps the generic card, never the turn. */\n #ensureDynamicPresenter(agent: Agent, name: string): void {\n if (CLAUDE_PRESENTER_NAMES.has(name)) return\n let known = this.#dynamicPresenterNames.get(agent)\n if (known === undefined) {\n known = new Set<string>()\n this.#dynamicPresenterNames.set(agent, known)\n }\n if (known.has(name)) return\n try {\n agent.ctx.tools.register(dynamicPresenterDefinition(name))\n known.add(name)\n } catch {\n // A late or disposed agent keeps the generic card; presentation must\n // never unsettle the Claude turn.\n }\n }\n\n /** Mirror one root Claude tool call into the durable native tool channel so\n * the host's tool presentation renders it exactly like a DSH-executed call.\n * Presentation duplication is best-effort and never unsettles the turn. */\n async #appendNativeToolCall(\n active: ActiveTurn,\n message: Extract<NormalizedSdkMessage, { kind: 'tool-call' }>,\n ): Promise<void> {\n try {\n await active.agent.session.append('tool/call', {\n turn: active.cursor.turn,\n step: active.cursor.step,\n callId: ToolCallId(message.toolUseId),\n name: message.toolName,\n arguments: safeDetail(message.input) ?? '{}',\n })\n } catch {\n // Presentation duplication must never unsettle the Claude turn.\n }\n }\n\n async #appendNativeToolResult(\n active: ActiveTurn,\n message: Pick<Extract<NormalizedSdkMessage, { kind: 'tool-result' }>, 'kind' | 'toolUseId' | 'output' | 'isError'>,\n ): Promise<void> {\n const text = typeof message.output === 'string' ? redactText(message.output) : safeDetail(message.output) ?? ''\n try {\n await active.agent.session.append('tool/result', {\n turn: active.cursor.turn,\n step: active.cursor.step,\n message: createToolResultMessage({\n callId: ToolCallId(message.toolUseId),\n content: [{ type: 'text', text }],\n isError: message.isError,\n }),\n }, { surfaceOp: 'append' })\n } catch {\n // Presentation duplication must never unsettle the Claude turn.\n }\n }\n\n /** Merge one task lifecycle message into the session's task board. */\n async #trackTask(\n entry: SupervisorEntry,\n message: Extract<NormalizedSdkMessage, { kind: 'subagent' }>,\n taskId: string,\n originTurn: number | undefined,\n ): Promise<void> {\n const previous = entry.tasks.get(taskId)\n const next: ClaudeTaskInfo = {\n taskId,\n description: message.description ?? previous?.description ?? message.title,\n status: message.taskStatus ?? previous?.status ?? 'running',\n }\n const resolvedOriginTurn = previous?.originTurn ?? originTurn\n if (resolvedOriginTurn !== undefined) next.originTurn = resolvedOriginTurn\n const subagentType = message.subagentType ?? previous?.subagentType\n if (subagentType !== undefined) next.subagentType = subagentType\n const taskType = message.taskType ?? previous?.taskType\n if (taskType !== undefined) next.taskType = taskType\n const lastToolName = message.lastToolName ?? previous?.lastToolName\n if (lastToolName !== undefined) next.lastToolName = lastToolName\n const summary = message.summary ?? previous?.summary\n if (summary !== undefined) next.summary = summary\n const usage = message.usage ?? previous?.usage\n if (usage !== undefined) next.usage = usage\n if (previous?.backgrounded === true) next.backgrounded = true\n entry.tasks.set(taskId, next)\n const settled = next.status !== 'running'\n await this.#scheduleTasksSnapshot(entry, settled)\n if (settled) await this.#continueAfterTasks(entry)\n }\n\n /** Fold the background-task level signal into the board (REPLACE semantics\n * for the backgrounded flag: only the listed tasks are detached). */\n async #trackBackgroundLevel(\n entry: SupervisorEntry,\n tasks: readonly { taskId: string; taskType?: string; description: string }[],\n originTurn: number | undefined,\n ): Promise<void> {\n const live = new Set(tasks.map(task => task.taskId))\n let changed = false\n for (const task of tasks) {\n const existing = entry.tasks.get(task.taskId)\n if (existing === undefined) {\n entry.tasks.set(task.taskId, {\n taskId: task.taskId,\n description: task.description,\n status: 'running',\n ...(originTurn === undefined ? {} : { originTurn }),\n ...(task.taskType === undefined ? {} : { taskType: task.taskType }),\n backgrounded: true,\n })\n changed = true\n } else if (existing.backgrounded !== true || existing.status !== 'running') {\n entry.tasks.set(task.taskId, { ...existing, status: 'running', backgrounded: true })\n changed = true\n }\n }\n for (const task of entry.tasks.values()) {\n if (task.backgrounded === true && task.status === 'running' && !live.has(task.taskId)) {\n entry.tasks.set(task.taskId, { ...task, status: 'completed' })\n changed = true\n }\n }\n if (changed) {\n await this.#scheduleTasksSnapshot(entry, true)\n await this.#continueAfterTasks(entry)\n }\n }\n\n #hasRunningTasks(entry: SupervisorEntry, active: ActiveTurn): boolean {\n return [...entry.tasks.values()].some(task => (\n task.originTurn === active.cursor.turn && task.backgrounded === true && task.status === 'running'\n ))\n }\n\n async #continueAfterTasks(entry: SupervisorEntry): Promise<void> {\n const active = entry.active\n if (active === undefined || active.phase !== 'waiting-tasks' || this.#hasRunningTasks(entry, active)) return\n active.phase = 'follow-up'\n active.promptUuid = randomUUID()\n active.sawTextDelta = false\n active.text = ''\n this.#closeTranscriptTextSegment(active)\n active.thinking = ''\n await this.#appendSafely(active, {\n kind: 'status',\n phase: 'updated',\n title: 'Claude Code is reporting background task results',\n })\n entry.input.push(sdkUserMessage(BACKGROUND_TASK_REPORT_PROMPT, active.promptUuid))\n }\n\n /** Persist the task board. Settled transitions flush immediately; progress\n * ticks throttle to one snapshot per second to bound log volume. */\n async #scheduleTasksSnapshot(entry: SupervisorEntry, immediate: boolean): Promise<void> {\n const THROTTLE_MS = 1_000\n const elapsed = Date.now() - entry.taskSnapshotAt\n if (!immediate && elapsed < THROTTLE_MS) {\n if (entry.taskSnapshotTimer === undefined) {\n entry.taskSnapshotTimer = setTimeout(() => {\n entry.taskSnapshotTimer = undefined\n void this.#flushTasksSnapshot(entry)\n }, THROTTLE_MS - elapsed)\n entry.taskSnapshotTimer.unref?.()\n }\n return\n }\n await this.#flushTasksSnapshot(entry)\n }\n\n async #flushTasksSnapshot(entry: SupervisorEntry): Promise<void> {\n if (entry.taskSnapshotTimer !== undefined) {\n clearTimeout(entry.taskSnapshotTimer)\n entry.taskSnapshotTimer = undefined\n }\n entry.taskSnapshotAt = Date.now()\n // Snapshot persistence is best-effort: the in-memory board stays\n // authoritative and the next change re-flushes.\n await this.#sidecar.writeTasks(entry.sessionId, [...entry.tasks.values()]).catch(() => undefined)\n }\n\n /** What DSH is told about token usage: newest call's prompt, whole turn's output.\n *\n * `TokenUsage` is documented as \"token accounting for ONE model call\", and\n * DSH's token meter divides `uncachedInput + cacheRead + cacheWrite` by the\n * context window to draw context pressure. One Claude turn makes many calls\n * and the CLI's result usage sums all of them, so reporting that sum pinned\n * the meter at 100%: a 35-call turn reads the same prompt from cache 35\n * times, which sums past the window without the conversation ever growing.\n * The newest single call answers \"how big is this conversation now\".\n *\n * Output is deliberately excluded from that pressure sum, so the same\n * argument never applied to it — and taking it from the newest call reported\n * whatever the wrap-up message happened to cost, which is a couple of tokens\n * after a turn that wrote thousands. The turn total is the honest figure.\n *\n * The sidecar activity keeps the whole turn total for both — that is the\n * audit and cost record, and nothing divides it by a window. */\n #reportedUsage(\n active: ActiveTurn,\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\n ): ClaudeUsage {\n const prompt = active.requestUsage\n if (prompt === undefined) return result.usage\n return {\n ...prompt,\n ...(result.usage.outputTokens === undefined ? {} : { outputTokens: result.usage.outputTokens }),\n }\n }\n\n async #completeProgressSegment(\n active: ActiveTurn,\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\n ): Promise<void> {\n if (!active.sawTextDelta && active.text.length === 0 && result.text !== undefined) {\n active.text = result.text\n active.transcriptText = result.text\n await this.#upsertTranscriptText(active)\n active.output.push({ type: 'text-delta', text: result.text })\n }\n await this.#upsertTranscriptText(active)\n active.output.push({ type: 'segment-complete', text: active.text })\n active.sawTextDelta = false\n active.text = ''\n this.#closeTranscriptTextSegment(active)\n active.thinking = ''\n }\n\n /** The turn's accounting, recorded once the turn is actually over.\n *\n * A turn that hands off to background tasks passes through the same result\n * handling on its way to `waiting-tasks`, and recording there drew a closing\n * total under a turn that was still running. */\n async #recordTurnUsage(\n active: ActiveTurn,\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\n ): Promise<void> {\n if (result.usage.inputTokens === undefined && result.usage.outputTokens === undefined && result.usage.cumulativeCostUsd === undefined) return\n await this.#appendSafely(active, {\n kind: 'usage',\n phase: 'completed',\n title: 'Claude usage',\n summary: usageSummary(result.usage),\n usage: this.#timedUsage(active, result.usage),\n })\n active.output.push({ type: 'usage', usage: this.#reportedUsage(active, result) })\n }\n\n async #completeTurn(\n entry: SupervisorEntry,\n active: ActiveTurn,\n result: Extract<NormalizedSdkMessage, { kind: 'result' }>,\n ): Promise<void> {\n if (entry.active !== active) return\n if (active.aborted) {\n await this.#upsertTranscriptText(active)\n await this.#flushTranscript(active)\n await this.#settleOpenCalls(active, 'Cancelled with the turn')\n await this.#appendSafely(active, {\n kind: 'status',\n phase: 'failed',\n title: 'Claude Code turn cancelled',\n })\n entry.active = undefined\n entry.state = 'idle'\n entry.lastUsedAt = Date.now()\n await this.#recordChainAnchor(entry, active)\n this.#checkpointProjection(entry)\n this.#armIdleTimer(entry)\n this.#notifyCapacityChange()\n this.#scheduleLimitReconciliation()\n return\n }\n const unmatchedDenials = (result.permissionDenials ?? [])\n .filter(denial => !active.deniedToolUseIds.has(denial.toolUseId))\n if (unmatchedDenials.length > 0) {\n await this.#appendSafely(active, {\n kind: 'permission',\n phase: 'denied',\n title: 'Claude Code auto-denied tool calls',\n summary: unmatchedDenials.map(denial => denial.toolName).join(', '),\n })\n }\n if (!result.success) {\n await this.#recordTurnUsage(active, result)\n if (!active.sawTextDelta && active.text.length === 0 && result.text !== undefined) {\n active.text = result.text\n active.transcriptText = result.text\n await this.#upsertTranscriptText(active)\n active.output.push({ type: 'text-delta', text: result.text })\n }\n await this.#upsertTranscriptText(active)\n await this.#flushTranscript(active)\n const message = result.errors?.join('\\n')\n ?? (result.terminalReason !== undefined ? `Claude Code failed the turn (${result.terminalReason})` : 'Claude Code failed the turn')\n await this.#appendSafely(active, {\n kind: 'error',\n phase: 'failed',\n title: 'Claude Code turn failed',\n summary: message,\n isError: true,\n })\n active.output.fail(new Error(message))\n } else {\n if (!active.sawTextDelta && active.text.length === 0 && result.text !== undefined) {\n active.text = result.text\n active.transcriptText = result.text\n await this.#upsertTranscriptText(active)\n active.output.push({ type: 'text-delta', text: result.text })\n }\n await this.#upsertTranscriptText(active)\n if (active.phase === 'primary' && this.#hasRunningTasks(entry, active)) {\n active.phase = 'waiting-tasks'\n await this.#appendSafely(active, {\n kind: 'status',\n phase: 'updated',\n title: 'Claude Code is waiting for background tasks',\n })\n await this.#completeProgressSegment(active, result)\n return\n }\n await this.#recordTurnUsage(active, result)\n await this.#appendSafely(active, {\n kind: 'status',\n phase: 'completed',\n title: 'Claude Code turn completed',\n })\n await this.#flushTranscript(active)\n active.output.push({ type: 'complete', text: active.text })\n active.output.close()\n }\n if (active.signal !== undefined && active.abortListener !== undefined) {\n active.signal.removeEventListener('abort', active.abortListener)\n }\n entry.active = undefined\n entry.state = 'idle'\n entry.lastUsedAt = Date.now()\n await this.#recordChainAnchor(entry, active)\n this.#checkpointProjection(entry)\n this.#armIdleTimer(entry)\n this.#notifyCapacityChange()\n this.#scheduleLimitReconciliation()\n await this.#learnContextWindow(entry)\n }\n\n /** Tell every reader where this session's delta stream ended.\n *\n * A reader that lost the turn's last delta has nothing later to reveal the\n * hole, and a settled turn produces nothing further -- so a finished tool\n * group would keep pulsing until the session was reopened by hand. Last\n * line of the turn, best effort: presentation must never unsettle it. */\n #checkpointProjection(entry: SupervisorEntry): void {\n try {\n this.#sidecar.checkpoint(entry.sessionId)\n } catch {\n // A reader that misses the checkpoint is no worse off than before it.\n }\n }\n\n /** Pin the working tree this turn is about to change, so a rewind of it can\n * put the checkout back where the turn found it.\n *\n * Awaited, and deliberately: a snapshot taken after Claude's first edit\n * would restore to a state that never existed. It costs one `git add -A`\n * against a throwaway index per turn, and best effort throughout -- a\n * session with no repository simply never offers a file rewind. */\n async #captureWorktree(entry: SupervisorEntry, turn: number): Promise<void> {\n try {\n const tree = await captureWorktreeTree(this.#runtime, entry.cwd)\n if (tree === undefined) return\n await this.#sidecar.recordRewindSnapshot(entry.sessionId, turn, tree)\n } catch {\n // The snapshot is advisory; a failed capture never fails the turn.\n }\n }\n\n /** Pin where Claude's chain ended for the DSH turn that just settled, so a\n * later rewind of the following turn can fork exactly here. Best effort:\n * a missing anchor only makes a rewind fall back to an earlier turn. */\n async #recordChainAnchor(entry: SupervisorEntry, active: ActiveTurn): Promise<void> {\n const uuid = entry.lastChainUuid\n if (uuid === undefined) return\n try {\n await this.#sidecar.recordRewindAnchor(entry.sessionId, active.cursor.turn, uuid)\n } catch {\n // The sidecar is advisory; a failed anchor never fails the turn.\n }\n }\n\n async #upsertTranscriptText(active: ActiveTurn): Promise<void> {\n if (active.transcriptText.length === 0) return\n const ordinal = active.transcriptTextOrdinal ?? active.cursor.nextOrdinal++\n active.transcriptTextOrdinal = ordinal\n try {\n // Hot path: notify live subscribers synchronously; disk persistence is\n // coalesced inside the repository and flushed at segment/turn edges.\n this.#sidecar.appendTranscriptText(active.agent.id as string, {\n text: active.transcriptText,\n ...(active.native ? { renderer: 'native' as const } : {}),\n turn: active.cursor.turn,\n step: active.cursor.step,\n ordinal,\n })\n } catch {\n // Transcript persistence is presentational and must not change a Claude outcome.\n }\n }\n\n async #flushTranscript(active: ActiveTurn): Promise<void> {\n await this.#sidecar.flushTranscriptText(active.agent.id as string).catch(() => undefined)\n }\n\n #closeTranscriptTextSegment(active: ActiveTurn): void {\n void this.#flushTranscript(active)\n active.transcriptText = ''\n active.transcriptTextOrdinal = undefined\n }\n\n async #appendActivity(active: ActiveTurn, activity: ClaudeActivityInput): Promise<void> {\n const ordinal = active.cursor.nextOrdinal++\n await this.#sidecar.appendActivity(active.agent.id as string, {\n ...activity,\n // Stamp the renderer this record was produced for. The Client reads it\n // back per step, so a step drawn natively is never also drawn by the\n // plugin transcript -- and history keeps whichever renderer produced it.\n ...(active.native ? { renderer: 'native' as const } : {}),\n turn: active.cursor.turn,\n step: active.cursor.step,\n ordinal,\n })\n }\n\n /** Persist durable activity without letting a storage failure unsettle the\n * in-memory turn or leak process ownership. Audit failure is best-effort. */\n async #appendSafely(active: ActiveTurn, activity: ClaudeActivityInput): Promise<void> {\n await this.#appendActivity(active, activity).catch(() => undefined)\n }\n\n #startInterrupt(entry: SupervisorEntry): Promise<void> {\n const existing = this.#interruptions.get(entry.sessionId)\n if (existing !== undefined) return existing\n const interruption = this.#interrupt(entry).finally(() => {\n this.#interruptions.delete(entry.sessionId)\n })\n this.#interruptions.set(entry.sessionId, interruption)\n return interruption\n }\n\n /** Close out the root tool calls a turn is ending without answers for.\n *\n * A tool result is the only thing that ever settles a call, and a turn that\n * is cancelled or disconnected produces none: the transcript would keep\n * drawing those calls as running for as long as the session lives, and no\n * later event would ever correct it. Written as the failures they are. */\n async #settleOpenCalls(active: ActiveTurn, summary: string): Promise<void> {\n const open = [...active.openCalls]\n active.openCalls.clear()\n for (const [toolUseId, toolName] of open) {\n await this.#appendSafely(active, {\n kind: 'tool-result',\n phase: 'failed',\n toolUseId,\n toolName,\n title: 'Tool cancelled',\n summary,\n isError: true,\n })\n // The native card has the same hole, and the same fix as a denied call.\n if (active.native) {\n await this.#appendNativeToolResult(active, {\n kind: 'tool-result',\n toolUseId,\n output: summary,\n isError: true,\n })\n }\n }\n }\n\n async #interrupt(entry: SupervisorEntry): Promise<void> {\n const active = entry.active\n if (active === undefined || entry.state === 'interrupting') return\n entry.state = 'interrupting'\n active.aborted = true\n active.output.fail(abortFailure())\n await this.#upsertTranscriptText(active)\n let interruptError: unknown\n try {\n const receipt = await withTimeout(entry.query.interrupt(), CLAUDE_INTERRUPT_TIMEOUT_MS, 'Claude Code interrupt')\n const queued = receipt?.still_queued ?? []\n if (queued.includes(active.promptUuid)) {\n throw new Error(`Claude Code interrupt left submitted prompt ${active.promptUuid} queued`)\n }\n } catch (error) {\n interruptError = error\n }\n await this.#settleOpenCalls(active, 'Cancelled with the turn').catch(() => undefined)\n try {\n await this.#appendActivity(active, {\n kind: 'status',\n phase: 'failed',\n title: interruptError === undefined ? 'Claude Code turn cancelled' : 'Claude Code cancelled; process entry reset',\n ...(interruptError === undefined ? {} : { summary: errorSummary(interruptError) }),\n })\n } catch {\n // The active output is already aborted; process cleanup cannot wait for audit availability.\n }\n if (this.#entries.get(entry.sessionId) === entry) this.#entries.delete(entry.sessionId)\n await this.#disposeEntry(entry)\n }\n\n async #handleDisconnect(entry: SupervisorEntry, error: unknown): Promise<void> {\n const active = entry.active\n const stderr = entry.process?.stderrTail()\n if (active !== undefined) {\n await this.#upsertTranscriptText(active)\n await this.#flushTranscript(active)\n if (active.signal !== undefined && active.abortListener !== undefined) {\n active.signal.removeEventListener('abort', active.abortListener)\n }\n const unknown = active.sawActivity\n entry.state = unknown ? 'outcome-unknown' : 'disconnected'\n const failure = unknown\n ? new ClaudeOutcomeUnknownError(stderr === undefined || stderr.length === 0 ? undefined : `Claude Code exited after activity; outcome unknown. ${stderr}`)\n : new Error(stderr === undefined || stderr.length === 0 ? errorSummary(error) : stderr)\n await this.#settleOpenCalls(active, 'Claude Code stopped before the tool answered').catch(() => undefined)\n await this.#appendSafely(active, {\n kind: 'error',\n phase: 'failed',\n title: unknown ? 'Claude Code outcome unknown' : 'Claude Code disconnected',\n summary: failure.message,\n isError: true,\n detail: error,\n })\n active.output.fail(failure)\n entry.active = undefined\n } else {\n entry.state = 'disconnected'\n }\n this.#entries.delete(entry.sessionId)\n await this.#disposeEntry(entry)\n }\n\n #armIdleTimer(entry: SupervisorEntry): void {\n if (this.#config.idleTimeoutMs <= 0) return\n const timer = setTimeout(() => {\n if (entry.active !== undefined || entry.state !== 'idle') return\n this.#entries.delete(entry.sessionId)\n void this.#disposeEntry(entry)\n }, this.#config.idleTimeoutMs)\n timer.unref?.()\n entry.idleTimer = timer\n }\n\n async #disposeEntry(entry: SupervisorEntry): Promise<void> {\n if (entry.state === 'disposed') return\n if (entry.idleTimer !== undefined) clearTimeout(entry.idleTimer)\n entry.state = 'disposed'\n entry.input.discard(abortFailure())\n entry.query.close()\n entry.lifetime.abort()\n if (entry.active !== undefined) entry.active.output.fail(abortFailure())\n entry.process?.kill('SIGTERM')\n if (entry.process !== undefined) {\n try {\n await entry.process.handle.waitForExit(AbortSignal.timeout(5_000))\n } catch {\n // The DSH subprocess owner still holds the tree and will finish escalation.\n }\n }\n this.#notifyCapacityChange()\n }\n}\n","import { randomUUID } from 'node:crypto'\n\nconst MAX_COMMENTS_PER_SESSION = 50\nconst MAX_TEXT_CHARS = 2_000\nconst MAX_PATH_CHARS = 1_024\nconst MAX_LINE = 10_000_000\n\nexport type ReviewCommentSide = 'old' | 'new'\n\nexport interface ReviewComment {\n readonly id: string\n readonly path: string\n /** Last (anchor) line of the comment. */\n readonly line: number\n /** First line when the comment spans a range; absent for single-line comments. */\n readonly startLine?: number\n readonly side: ReviewCommentSide\n readonly text: string\n}\n\nexport class ReviewCommentError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'ReviewCommentError'\n this.code = code\n }\n}\n\nfunction validSide(value: unknown): value is ReviewCommentSide {\n return value === 'old' || value === 'new'\n}\n\n/** Pending line comments queued per session until the next user turn drains them. */\nexport class ReviewCommentStore {\n readonly #comments = new Map<string, ReviewComment[]>()\n\n add(sessionId: string, input: { path: unknown; line: unknown; startLine?: unknown; side: unknown; text: unknown }): ReviewComment {\n const path = typeof input.path === 'string' ? input.path.trim() : ''\n const text = typeof input.text === 'string' ? input.text.trim() : ''\n if (path.length === 0 || path.length > MAX_PATH_CHARS || /[\\0\\r\\n]/u.test(path)) {\n throw new ReviewCommentError('invalid-request', 'The comment path is invalid.')\n }\n if (text.length === 0 || text.length > MAX_TEXT_CHARS || text.includes('\\0')) {\n throw new ReviewCommentError('invalid-request', 'The comment text is invalid.')\n }\n if (typeof input.line !== 'number' || !Number.isSafeInteger(input.line) || input.line < 1 || input.line > MAX_LINE) {\n throw new ReviewCommentError('invalid-request', 'The comment line is invalid.')\n }\n if (!validSide(input.side)) throw new ReviewCommentError('invalid-request', 'The comment side is invalid.')\n const startLine = input.startLine === undefined || input.startLine === null ? undefined : input.startLine\n if (startLine !== undefined && (typeof startLine !== 'number' || !Number.isSafeInteger(startLine) || startLine < 1 || startLine > input.line)) {\n throw new ReviewCommentError('invalid-request', 'The comment start line is invalid.')\n }\n const existing = this.#comments.get(sessionId) ?? []\n if (existing.length >= MAX_COMMENTS_PER_SESSION) {\n throw new ReviewCommentError('too-many-comments', 'Too many pending review comments. Remove one before adding another.')\n }\n const comment: ReviewComment = { id: randomUUID(), path, line: input.line, ...(startLine === undefined || startLine === input.line ? {} : { startLine }), side: input.side, text }\n this.#comments.set(sessionId, [...existing, comment])\n return comment\n }\n\n remove(sessionId: string, id: string): boolean {\n const existing = this.#comments.get(sessionId)\n if (existing === undefined) return false\n const next = existing.filter(comment => comment.id !== id)\n if (next.length === existing.length) return false\n if (next.length === 0) this.#comments.delete(sessionId)\n else this.#comments.set(sessionId, next)\n return true\n }\n\n list(sessionId: string): readonly ReviewComment[] {\n return this.#comments.get(sessionId) ?? []\n }\n\n /** Remove and return every pending comment; called when a user turn consumes them. */\n drain(sessionId: string): readonly ReviewComment[] {\n const existing = this.#comments.get(sessionId) ?? []\n this.#comments.delete(sessionId)\n return existing\n }\n\n disposeSession(sessionId: string): void {\n this.#comments.delete(sessionId)\n }\n\n dispose(): void {\n this.#comments.clear()\n }\n}\n\n/** Render drained comments as the prompt block preceding the user's message text. */\nexport function formatReviewComments(comments: readonly ReviewComment[]): string {\n const lines = comments.map((comment, index) => (\n `${index + 1}. ${comment.path}:${comment.startLine === undefined ? comment.line : `${comment.startLine}-${comment.line}`}${comment.side === 'old' ? ' (old side)' : ''} — ${comment.text}`\n ))\n return [\n '<user-review-comments>',\n 'The user attached these code review comments to this message. Each references a file and line (or line range) from the current working tree diff:',\n ...lines,\n '</user-review-comments>',\n ].join('\\n')\n}\n","/** Answer DSH's auxiliary session-title request with a throwaway Haiku turn.\n *\n * DSH titles a session by asking the model behind the session's own route for\n * a summary of the first human message. That route is this plugin, and the\n * session's Claude process must not answer it: the title call carries a\n * plugin-authored system prompt and would land in the user's transcript. A\n * separate one-shot turn keeps it out, for the same reasons as the branch-name\n * summary and the plan-usage probe. Deployments that never installed a second\n * model provider still get a readable title, since the only model this plugin\n * needs is the one it already runs. */\nimport { query as claudeQuery, type Options as ClaudeOptions, type Query } from '@anthropic-ai/claude-agent-sdk'\n\n/** Cheapest model that can summarize a sentence in the language it was written in. */\nexport const SESSION_TITLE_MODEL = 'haiku'\n\n/** Backstop only. The title service wraps its own deadline (60s by default)\n * around the call and passes it as `signal`, so a shorter budget here just\n * kills a turn the caller was still happy to wait for — a cold CLI start plus\n * one Haiku reply routinely passes ten seconds. */\nexport const SESSION_TITLE_TIMEOUT_MS = 60_000\n\n/** DSH frames the messages as JSON under its own byte cap; this only bounds a\n * caller that does not. */\nconst MAX_INPUT_CHARS = 8_000\n/** Longer than any title DSH accepts (80 bytes), short enough to bound prose. */\nconst MAX_TITLE_CHARS = 200\n\nexport interface SessionTitleRequest {\n /** DSH's own title instruction, including its target length and language rule. */\n readonly system?: string\n /** The framed human messages to title. */\n readonly input: string\n /** Cancellation from the title service when a newer revision supersedes this one. */\n readonly signal?: AbortSignal\n}\n\n/** Carry DSH's instruction as the prompt's own preamble: a Claude Code turn has\n * no separate system slot this plugin can borrow without replacing the CLI's. */\nexport function sessionTitlePrompt(request: SessionTitleRequest): string {\n const input = request.input.trim().slice(0, MAX_INPUT_CHARS)\n return request.system === undefined || request.system.length === 0\n ? input\n : `${request.system}\\n\\n${input}`\n}\n\n/** The one line of the reply that is the title. DSH strips control characters\n * and truncates to its own byte cap, so nothing else is cleaned here. */\nexport function sessionTitleLine(reply: string): string {\n const line = reply.split('\\n').map(candidate => candidate.trim()).find(candidate => candidate.length > 0)\n return line === undefined ? '' : line.slice(0, MAX_TITLE_CHARS)\n}\n\n/**\n * Summarize the framed messages into one title line.\n *\n * Rejects rather than returning a placeholder: the title service logs the\n * failure and keeps the deterministic first-words fallback, which is a better\n * label than anything this function could invent.\n */\nexport async function summarizeSessionTitle(\n executablePath: string,\n request: SessionTitleRequest,\n factory: (params: { prompt: string; options: ClaudeOptions }) => Query = claudeQuery,\n): Promise<string> {\n const prompt = sessionTitlePrompt(request)\n if (prompt.length === 0) throw new Error('dsh-claude: the session-title request carried no text')\n const lifetime = new AbortController()\n const abort = (): void => { lifetime.abort() }\n request.signal?.addEventListener('abort', abort, { once: true })\n const timer = setTimeout(abort, SESSION_TITLE_TIMEOUT_MS)\n timer.unref?.()\n try {\n const query = factory({\n prompt,\n options: {\n cwd: process.cwd(),\n abortController: lifetime,\n model: SESSION_TITLE_MODEL,\n allowedTools: [],\n // Isolated from filesystem settings on purpose: a CLAUDE.md instruction\n // aimed at the coding session (\"always answer in English\", \"start every\n // reply with a checklist\") would be answering the wrong question here.\n settingSources: [],\n maxTurns: 1,\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\n },\n })\n for await (const message of query) {\n if (message.type !== 'result' || message.subtype !== 'success') continue\n const title = sessionTitleLine(message.result)\n if (title.length > 0) return title\n break\n }\n throw new Error('dsh-claude: the session-title turn produced no title')\n } finally {\n clearTimeout(timer)\n request.signal?.removeEventListener('abort', abort)\n lifetime.abort()\n }\n}\n","import {\n LlmAdapter,\n ReasoningEffortId,\n type GenerateOptions,\n type LlmModelInfo,\n type LlmProviderInfo,\n type LlmResolvedModelInfo,\n type PreparedAdapterCall,\n type ResolvedRetryPolicy,\n type StreamChunk,\n type TokenUsage,\n} from '@deepseek-ai/dsh-llm'\nimport type { Agent, AgentRegistry } from '@deepseek-ai/dsh-agent'\nimport type { AttachmentStore, ImageAttachmentRef, ImageMediaType } from '@deepseek-ai/dsh-attachment'\nimport type { ModelInfo, SDKUserMessage } from '@anthropic-ai/claude-agent-sdk'\nimport { CLAUDE_CODE_PRESET_ID, CLAUDE_CODE_PROVIDER, DEFAULT_CLAUDE_RENDER_MODE, type ClaudeRenderMode } from './constants.ts'\nimport type { ClaudeSupervisor, ClaudeThinkingMode } from './supervisor.ts'\nimport type { ClaudeUsage } from './events.ts'\nimport { claudeModelRow, ensureClaudeModels } from './model-catalog.ts'\nimport { formatReviewComments, type ReviewComment } from './review-comments.ts'\nimport { summarizeSessionTitle, type SessionTitleRequest } from './session-title.ts'\n\nconst THINKING_MODES = [\n { id: 'off', name: 'Off', description: 'No extended thinking.' },\n { id: 'low', name: 'Low', description: 'Minimal thinking, fastest responses.' },\n { id: 'medium', name: 'Medium', description: 'Moderate thinking.' },\n { id: 'high', name: 'High', description: 'Deep reasoning (Claude Code default).' },\n { id: 'xhigh', name: 'Extra High', description: 'Deeper than high; unsupported models silently downgrade to high.' },\n { id: 'max', name: 'Max', description: 'Maximum effort; unsupported models silently downgrade.' },\n { id: 'ultracode', name: 'Ultracode', description: 'Extra-high effort plus standing dynamic-workflow orchestration; requires an xhigh-capable model.' },\n] as const\n\nexport function thinkingModeFor(effort: ReasoningEffortId | undefined): ClaudeThinkingMode | undefined {\n if (effort === undefined) return undefined\n if (THINKING_MODES.some(mode => mode.id === (effort as string))) return effort as unknown as ClaudeThinkingMode\n throw new Error(`dsh-claude: unsupported reasoning effort ${JSON.stringify(effort)}`)\n}\n\nconst NO_RETRY_POLICY: ResolvedRetryPolicy = Object.freeze({\n mode: 'normal',\n maxRetries: 0,\n retryableCodes: Object.freeze([]),\n initialDelayMs: 500,\n maxDelayMs: 10_000,\n jitterRatio: 0.1,\n})\n\ntype ClaudePrompt = SDKUserMessage['message']['content']\ntype ClaudePromptBlock = Exclude<ClaudePrompt, string>[number]\ntype AttachmentReader = Pick<AttachmentStore, 'imageLimits' | 'readImage'>\n\nfunction abortIfRequested(signal: AbortSignal | undefined): void {\n if (signal?.aborted !== true) return\n if (signal.reason instanceof Error) throw signal.reason\n const error = new Error('Claude Code input resolution aborted')\n error.name = 'AbortError'\n throw error\n}\n\nfunction finiteNonNegative(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && value >= 0\n}\n\nfunction validateImageRef(ref: ImageAttachmentRef, attachments: AttachmentReader, imageIndex: number): void {\n const limits = attachments.imageLimits\n if (!limits.mediaTypes.includes(ref.mediaType)) {\n throw new Error(`dsh-claude: image ${imageIndex} has an unsupported media type`)\n }\n if (!finiteNonNegative(ref.bytes) || ref.bytes > limits.maxImageBytes) {\n throw new Error(`dsh-claude: image ${imageIndex} exceeds the configured byte limit`)\n }\n const maxDimension = 'maxImageDimension' in limits && finiteNonNegative(limits.maxImageDimension)\n ? limits.maxImageDimension\n : undefined\n if (!finiteNonNegative(ref.width) || !finiteNonNegative(ref.height)\n || ref.width * ref.height > limits.maxImagePixels\n || (maxDimension !== undefined && (ref.width > maxDimension || ref.height > maxDimension))) {\n throw new Error(`dsh-claude: image ${imageIndex} exceeds the configured dimension limit`)\n }\n}\n\n/**\n * Prepend the session's pending diff-review comments to the outgoing user\n * prompt. The comments are drained once per turn: they are formatted into one\n * `<user-review-comments>` block placed ahead of the user's own text (or as a\n * leading text block for multi-part prompts) so Claude reads them in the same\n * turn that consumed them.\n */\nexport function injectReviewComments(prompt: ClaudePrompt, comments: readonly ReviewComment[]): ClaudePrompt {\n if (comments.length === 0) return prompt\n const block = formatReviewComments(comments)\n if (typeof prompt === 'string') return `${block}\\n\\n${prompt}`\n return [{ type: 'text', text: block }, ...prompt]\n}\n\nfunction imageBlock(data: Uint8Array, mediaType: ImageMediaType): ClaudePromptBlock {\n return {\n type: 'image',\n source: {\n type: 'base64',\n media_type: mediaType,\n data: Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('base64'),\n },\n }\n}\n\n/** Resolve only the newest direct human message; Claude's session owns history. */\nexport async function resolveDirectUserPrompt(\n messages: GenerateOptions['messages'],\n attachments: AttachmentReader,\n signal?: AbortSignal,\n): Promise<ClaudePrompt> {\n const message = [...messages].reverse().find(candidate => (\n candidate.role === 'user' && candidate.source.kind === 'user'\n ))\n if (message === undefined) {\n throw new Error('dsh-claude: no direct human input was present in this model step')\n }\n\n const imageRefs = message.content\n .filter((block): block is Extract<typeof block, { type: 'image' }> => block.type === 'image')\n .map(block => block.attachment)\n const limits = attachments.imageLimits\n if (imageRefs.length > limits.maxImagesPerMessage) {\n throw new Error('dsh-claude: prompt exceeds the configured image-count limit')\n }\n let declaredBytes = 0\n imageRefs.forEach((ref, index) => {\n validateImageRef(ref, attachments, index + 1)\n declaredBytes += ref.bytes\n if (!Number.isSafeInteger(declaredBytes) || declaredBytes > limits.maxMessageImageBytes) {\n throw new Error('dsh-claude: prompt exceeds the configured aggregate image-byte limit')\n }\n })\n\n if (imageRefs.length === 0) {\n const text = message.content\n .filter((block): block is Extract<typeof block, { type: 'text' }> => block.type === 'text')\n .map(block => block.text)\n .join('\\n')\n .trim()\n if (text.length > 0) return text\n throw new Error('dsh-claude: the newest direct human message has no supported content')\n }\n\n const content: ClaudePromptBlock[] = []\n let imageIndex = 0\n let verifiedBytes = 0\n for (const block of message.content) {\n abortIfRequested(signal)\n if (block.type === 'text') {\n content.push({ type: 'text', text: block.text })\n continue\n }\n if (block.type !== 'image') continue\n imageIndex += 1\n let stored: Awaited<ReturnType<AttachmentStore['readImage']>>\n try {\n stored = await attachments.readImage(block.attachment, signal)\n } catch {\n abortIfRequested(signal)\n throw new Error(`dsh-claude: image ${imageIndex} could not be read or verified`)\n }\n abortIfRequested(signal)\n validateImageRef(stored.ref, attachments, imageIndex)\n if (stored.data.byteLength !== stored.ref.bytes || stored.ref.mediaType !== block.attachment.mediaType) {\n throw new Error(`dsh-claude: image ${imageIndex} failed attachment verification`)\n }\n verifiedBytes += stored.data.byteLength\n if (!Number.isSafeInteger(verifiedBytes) || verifiedBytes > limits.maxMessageImageBytes) {\n throw new Error('dsh-claude: prompt exceeds the configured aggregate image-byte limit')\n }\n content.push(imageBlock(stored.data, stored.ref.mediaType))\n }\n if (content.length === 0) {\n throw new Error('dsh-claude: the newest direct human message has no supported content')\n }\n return content\n}\n\nfunction tokenUsage(usage: ClaudeUsage): TokenUsage {\n const normalized: TokenUsage = {\n inputTokens: usage.inputTokens ?? 0,\n outputTokens: usage.outputTokens ?? 0,\n }\n if (usage.cacheReadTokens !== undefined) normalized.cacheReadTokens = usage.cacheReadTokens\n if (usage.cacheCreationTokens !== undefined) normalized.cacheWriteTokens = usage.cacheCreationTokens\n return normalized\n}\n\n/** Flatten a hand-built auxiliary request to text. Unlike a conversation turn\n * it has no images and no human-sourced message to single out: every message\n * in it was assembled by the plugin that asked the question. */\nfunction auxiliaryText(messages: GenerateOptions['messages']): string {\n return messages\n .flatMap(message => message.content\n .filter((block): block is Extract<typeof block, { type: 'text' }> => block.type === 'text')\n .map(block => block.text))\n .join('\\n')\n}\n\nfunction resolveAgent(agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>, options: GenerateOptions): Agent {\n const initiator = agents.currentInitiator()\n if (initiator !== undefined) return initiator\n if (options.sessionId !== undefined) {\n const agent = agents.get(options.sessionId)\n if (agent !== undefined) return agent\n }\n throw new Error('dsh-claude: the model request has no live owning DSH agent')\n}\n\nexport class ClaudeCodeAdapter extends LlmAdapter {\n readonly #supervisor: ClaudeSupervisor\n readonly #agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>\n readonly #attachments: AttachmentReader\n readonly #presetIdFor: (agent: Agent) => string | undefined\n readonly #drainReviewComments: (sessionId: string) => readonly ReviewComment[]\n /** The renderer setting, read from its file at the start of each turn. A\n * cached copy would go stale whenever the file is edited outside the\n * Settings dialog, and the read is dwarfed by the process the turn spawns. */\n readonly #renderMode: () => Promise<ClaudeRenderMode>\n readonly #summarizeTitle: (request: SessionTitleRequest) => Promise<string>\n /** Reads the CLI's own `/model` rows, so the selector never has to advertise\n * the seed vocabulary once the CLI can answer for itself. */\n readonly #probeModels: () => Promise<readonly ModelInfo[]>\n\n constructor(\n supervisor: ClaudeSupervisor,\n agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>,\n attachments: AttachmentReader,\n presetIdFor: (agent: Agent) => string | undefined,\n drainReviewComments: (sessionId: string) => readonly ReviewComment[] = () => [],\n renderMode: () => Promise<ClaudeRenderMode> = async () => DEFAULT_CLAUDE_RENDER_MODE,\n summarizeTitle: (request: SessionTitleRequest) => Promise<string> = request => summarizeSessionTitle('', request),\n probeModels: () => Promise<readonly ModelInfo[]> = async () => [],\n ) {\n super()\n this.#supervisor = supervisor\n this.#agents = agents\n this.#attachments = attachments\n this.#presetIdFor = presetIdFor\n this.#drainReviewComments = drainReviewComments\n this.#renderMode = renderMode\n this.#summarizeTitle = summarizeTitle\n this.#probeModels = probeModels\n }\n\n override providerInfo(provider: string): LlmProviderInfo {\n return { id: provider, name: 'Claude Code' }\n }\n\n override providerRetryPolicy(): ResolvedRetryPolicy {\n return NO_RETRY_POLICY\n }\n\n override async listModels(provider: string): Promise<readonly LlmModelInfo[]> {\n const models = await ensureClaudeModels(this.#probeModels)\n return models.map(model => ({\n provider,\n id: model.id,\n name: model.name,\n description: model.description,\n inputModalities: ['text', 'image'],\n }))\n }\n\n override async resolveModel(provider: string, model: string, _signal?: AbortSignal): Promise<LlmResolvedModelInfo> {\n const known = claudeModelRow(model)\n const contextWindow = this.#supervisor.contextWindow(model) ?? known?.contextWindow\n return {\n provider,\n id: model,\n name: known?.name ?? `Claude Code ${model}`,\n ...(known === undefined ? {} : { description: known.description }),\n ...(contextWindow === undefined ? {} : { context: { contextWindow } }),\n inputModalities: ['text', 'image'],\n reasoning: {\n efforts: THINKING_MODES.map(mode => ({\n id: ReasoningEffortId(mode.id),\n name: mode.name,\n description: mode.description,\n })),\n },\n }\n }\n\n override async prepareCall(\n provider: string,\n model: string,\n signal?: AbortSignal,\n ): Promise<PreparedAdapterCall> {\n return {\n model: await this.resolveModel(provider, model, signal),\n stream: options => this.stream(options),\n }\n }\n\n /** Title the session from its own provider without touching its process.\n *\n * DSH routes the title request at the session's model, which is this\n * adapter; a deployment with no second provider configured would otherwise\n * never get a title at all and keep the first five words of the first\n * message. A throwaway Haiku turn answers it, so the session's transcript,\n * context, and permission bridge stay out of it. */\n async *#titleStream(options: GenerateOptions): AsyncIterable<StreamChunk> {\n const title = await this.#summarizeTitle({\n ...(options.system === undefined ? {} : { system: options.system }),\n input: auxiliaryText(options.messages),\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n })\n yield { type: 'block-start', index: 0, blockType: 'text' }\n yield { type: 'text-delta', index: 0, text: title }\n yield { type: 'block-end', index: 0, block: { type: 'text', text: title } }\n yield { type: 'finish', reason: { kind: 'stop' } }\n }\n\n override async *stream(options: GenerateOptions): AsyncIterable<StreamChunk> {\n if (options.purpose === 'session-title') {\n yield* this.#titleStream(options)\n return\n }\n if (options.purpose !== undefined) {\n // Compaction stays out: Claude Code compacts its own context, and a DSH\n // summary of a transcript it does not own would be replayed at nobody.\n throw new Error(`dsh-claude: auxiliary ${options.purpose} calls are not routed into the Claude session`)\n }\n const agent = resolveAgent(this.#agents, options)\n if (this.#presetIdFor(agent) !== CLAUDE_CODE_PRESET_ID) {\n throw new Error(`dsh-claude: provider ${CLAUDE_CODE_PROVIDER} is available only to the ${CLAUDE_CODE_PRESET_ID} preset`)\n }\n const thinkingMode = thinkingModeFor(options.reasoningEffort)\n let prompt: ClaudePrompt\n try {\n prompt = await resolveDirectUserPrompt(options.messages, this.#attachments, options.signal)\n } catch (error) {\n if ((error as Error).name !== 'AbortError') throw error\n yield {\n type: 'finish',\n reason: {\n kind: 'aborted',\n failure: { code: 'aborted', message: error instanceof Error ? error.message : 'Claude Code input resolution aborted' },\n },\n }\n return\n }\n // The plugin renderer draws the visible transcript from the sidecar, so\n // prose and Claude tool groups share one exact ordinal stream and DSH\n // receives only an empty assistant completion anchor plus usage/lifecycle\n // metadata. The native renderer needs the opposite: every visible span\n // arrives as ordinary DSH content blocks.\n //\n // Read once, here, and handed to the supervisor: the setting is live, and\n // the two halves of a turn must agree. Deciding separately let a switch\n // mid-turn leave the prose buffered for a renderer that was no longer\n // drawing it, so the turn finished with nothing on screen.\n const renderMode = await this.#renderMode()\n const native = renderMode === 'native'\n const events = await this.#supervisor.runTurn({\n agent,\n prompt: injectReviewComments(prompt, this.#drainReviewComments(agent.id as string)),\n model: options.model,\n renderMode,\n ...(thinkingMode === undefined ? {} : { thinkingMode }),\n ...(options.signal === undefined ? {} : { signal: options.signal }),\n })\n let pendingUsage: TokenUsage | undefined\n let completed = false\n let blockIndex = 0\n let text = ''\n /** Settle the buffered prose as one text block. Each Claude result is one\n * block so tool activity stays ahead of the prose it explains and a\n * background-task report can follow in a block of its own. */\n function* flushText(): Generator<StreamChunk> {\n if (text.length === 0) return\n const settled = text\n text = ''\n yield { type: 'block-start', index: blockIndex, blockType: 'text' }\n yield { type: 'text-delta', index: blockIndex, text: settled }\n yield { type: 'block-end', index: blockIndex, block: { type: 'text', text: settled } }\n blockIndex += 1\n }\n try {\n for await (const event of events) {\n if (event.type === 'usage') {\n pendingUsage = tokenUsage(event.usage)\n continue\n }\n if (event.type === 'text-delta') {\n if (native) text += event.text\n continue\n }\n if (event.type === 'thinking') {\n if (!native) continue\n // Thinking settles before the prose it precedes, so nothing is\n // buffered yet; flush anyway to keep block order faithful when a\n // model interleaves the two.\n yield* flushText()\n yield { type: 'block-start', index: blockIndex, blockType: 'reasoning' }\n yield { type: 'reasoning-delta', index: blockIndex, text: event.text }\n yield { type: 'block-end', index: blockIndex, block: { type: 'reasoning', text: event.text } }\n blockIndex += 1\n continue\n }\n yield* flushText()\n if (event.type === 'segment-complete') continue\n completed = true\n if (pendingUsage !== undefined) yield { type: 'usage', usage: pendingUsage }\n yield { type: 'finish', reason: { kind: 'stop' } }\n }\n } catch (error) {\n if ((error as Error).name === 'AbortError') {\n completed = true\n yield* flushText()\n yield {\n type: 'finish',\n reason: {\n kind: 'aborted',\n failure: { code: 'aborted', message: error instanceof Error ? error.message : 'Claude Code turn aborted' },\n },\n }\n return\n }\n throw error\n }\n if (!completed) throw new Error('dsh-claude: Claude turn stream ended without a result')\n }\n}\n\nexport function createClaudeCodeAdapter(\n supervisor: ClaudeSupervisor,\n agents: Pick<AgentRegistry, 'currentInitiator' | 'get'>,\n attachments: AttachmentReader,\n presetIdFor: (agent: Agent) => string | undefined,\n drainReviewComments: (sessionId: string) => readonly ReviewComment[] = () => [],\n renderMode: () => Promise<ClaudeRenderMode> = async () => DEFAULT_CLAUDE_RENDER_MODE,\n summarizeTitle: (request: SessionTitleRequest) => Promise<string> = request => summarizeSessionTitle('', request),\n probeModels: () => Promise<readonly ModelInfo[]> = async () => [],\n): ClaudeCodeAdapter {\n return new ClaudeCodeAdapter(supervisor, agents, attachments, presetIdFor, drainReviewComments, renderMode, summarizeTitle, probeModels)\n}\n","/**\n * The plugin's connection budget, in one table.\n *\n * A browser opens a small fixed number of connections to one origin — six for\n * HTTP/1.1 in Chromium — and shares them with the Host's own traffic. Every\n * response this plugin holds open costs one of them for its lifetime, and a\n * request that cannot get one waits in the browser's queue where no server-side\n * deadline can reach it. When the pool is exhausted the panels that would\n * *diagnose* the problem are the first thing to stop answering, which is how\n * this failure has always presented: four settings cards timing out at once\n * against a Host that is demonstrably healthy.\n *\n * So the budget is a fixed constant rather than a function of how much work is\n * in flight. Steady state is one connection (the multiplexed projection\n * carrier); the peak is `PLUGIN_GLOBAL_PERMITS`, whatever the session count.\n *\n * Both halves read this file, which is the point: a route declares a budget\n * class and the client derives its wait from the same entry, so a server\n * deadline can never be quietly longer than the client's patience.\n */\n\n/** Server-side budget classes. A route declares a class, never a number. */\nexport const ROUTE_BUDGET_MS = {\n /** Answers from memory or a single bounded probe. */\n fast: 5_000,\n /** Chains local Git work. */\n git: 45_000,\n /** Reaches the network: remote Git, `gh`, the npm registry. */\n remote: 150_000,\n} as const\n\nexport type RouteBudget = keyof typeof ROUTE_BUDGET_MS\n\n/** The client waits one round trip longer, so the route's own 504 wins the\n * race and the caller learns which budget elapsed instead of guessing. */\nexport const CLIENT_GRACE_MS = 3_000\n\nexport function clientBudgetMs(budget: RouteBudget): number {\n return ROUTE_BUDGET_MS[budget] + CLIENT_GRACE_MS\n}\n\n/** A request that never got a permit fails fast and says so, rather than\n * spending its whole budget queued behind work it cannot see. */\nexport const QUEUE_WAIT_BUDGET_MS = 4_000\n\n/** Connections this plugin may hold at once, across every lane. */\nexport const PLUGIN_GLOBAL_PERMITS = 4\n\n/** Per-lane ceilings inside the global budget.\n *\n * The projection carrier holds a permanently reserved permit outside these,\n * so three remain. `write + stream <= 2` leaves one permit that only a read\n * can take: a diagnostic read always has somewhere to go, however many slow\n * actions are in flight. That invariant is what stops a 150s repository\n * action from reproducing the original symptom through a new mechanism. */\nexport const PLUGIN_LANE_CAPS = { read: 2, write: 1, stream: 1 } as const\n\nexport type PluginLane = keyof typeof PLUGIN_LANE_CAPS\n\n/** Both halves cap the multiplex at the same number. */\nexport const MAX_MULTIPLEX_SESSIONS = 16\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { WebRouteKind } from '@deepseek-ai/dsh-host-webserver'\nimport { deadline } from '@deepseek-ai/dsh-timeout'\nimport { ROUTE_BUDGET_MS, type RouteBudget } from './plugin-budget.ts'\n\n/** Accept only loopback, same-origin browser requests to plugin-private routes. */\nexport function trustedRequest(req: IncomingMessage): boolean {\n const remote = req.socket.remoteAddress\n if (remote !== '127.0.0.1' && remote !== '::1' && remote !== '::ffff:127.0.0.1') return false\n const site = req.headers['sec-fetch-site']\n if (site === 'cross-site') return false\n const host = req.headers.host\n if (host === undefined) return false\n const authority = /^(?:127\\.0\\.0\\.1|\\[?::1\\]?|localhost)(?::\\d+)?$/i\n if (!authority.test(host)) return false\n const origin = req.headers.origin\n if (origin === undefined) return true\n try {\n const originUrl = new URL(origin)\n return originUrl.host === host && authority.test(originUrl.host)\n } catch {\n return false\n }\n}\n\n/** Send a non-cacheable JSON response with MIME sniffing disabled. */\nexport function json(res: ServerResponse, status: number, value: unknown): void {\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n })\n res.end(JSON.stringify(value))\n}\n\nconst ROUTE_TIMEOUT_CODE = 'DSH_CLAUDE_ROUTE'\nconst DEFAULT_BODY_BYTES = 1024 * 1024\n\nexport type PluginMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\n/** What a route handler is given. Deliberately not the `ServerResponse`: a\n * unary handler that cannot reach the socket cannot hold it open. */\nexport interface PluginRouteIo {\n /** Aborts on client disconnect OR when the route's budget elapses. */\n readonly signal: AbortSignal\n readonly method: PluginMethod\n readonly url: URL\n /** Read the request body once, byte-capped, as JSON. */\n body<T = Record<string, unknown>>(maxBytes?: number): Promise<T>\n}\n\nexport interface PluginUnaryRoute {\n mode: 'unary'\n kind: WebRouteKind\n path: string\n methods: readonly PluginMethod[]\n budget: RouteBudget\n /** No `ServerResponse` in scope, by construction. */\n handler: (io: PluginRouteIo) => Promise<{ status: number; value: unknown }>\n}\n\nexport interface PluginStreamRoute {\n mode: 'stream'\n kind: WebRouteKind\n path: string\n methods: readonly PluginMethod[]\n /** Hard ceiling on live responses for this path; the oldest is evicted. */\n maxConcurrent: number\n /** Dedupe identity; a second open with the same key supersedes the first. */\n streamKey: (url: URL) => string\n handler: (res: ServerResponse, io: PluginRouteIo) => Promise<void>\n}\n\nexport type PluginRoute = PluginUnaryRoute | PluginStreamRoute\n\n/** Bounds live streaming responses per path, so a teardown bug cannot become a\n * permanent connection leak. Registration is per path, not global, because a\n * wedged projection stream must not evict an in-flight repository setup. */\nclass StreamRegistry {\n readonly #open = new Map<string, Map<string, () => void>>()\n\n admit(path: string, key: string, max: number, close: () => void): () => void {\n let live = this.#open.get(path)\n if (live === undefined) {\n live = new Map()\n this.#open.set(path, live)\n }\n // A reopen under the same identity is the client reconnecting; the older\n // response is the stale one, so it goes rather than the new arrival.\n live.get(key)?.()\n live.set(key, close)\n while (live.size > max) {\n const oldest = live.keys().next()\n if (oldest.done === true) break\n const evict = live.get(oldest.value)\n live.delete(oldest.value)\n evict?.()\n }\n return () => {\n const current = this.#open.get(path)\n if (current?.get(key) === close) current.delete(key)\n }\n }\n}\n\nconst streams = new StreamRegistry()\n\nfunction isPluginMethod(value: string | undefined): value is PluginMethod {\n return value === 'GET' || value === 'POST' || value === 'PATCH' || value === 'DELETE'\n}\n\n/** Distinguishable so the wrapper can answer 413 rather than folding an\n * oversized body into whatever generic failure the handler reports. */\nexport class PluginBodyTooLargeError extends Error {\n constructor() {\n super('Request body is too large')\n this.name = 'PluginBodyTooLargeError'\n }\n}\n\nasync function readBody(req: IncomingMessage, maxBytes: number): Promise<unknown> {\n const declared = Number(req.headers['content-length'] ?? 0)\n if (!Number.isFinite(declared) || declared < 0 || declared > maxBytes) throw new PluginBodyTooLargeError()\n const chunks: Buffer[] = []\n let bytes = 0\n for await (const chunk of req) {\n const data = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as Uint8Array)\n bytes += data.byteLength\n if (bytes > maxBytes) throw new PluginBodyTooLargeError()\n chunks.push(data)\n }\n if (bytes === 0) return {}\n return JSON.parse(Buffer.concat(chunks).toString('utf8')) as unknown\n}\n\nfunction rejectOn(signal: AbortSignal): Promise<never> {\n return new Promise((_resolve, reject) => {\n if (signal.aborted) {\n reject(signal.reason as Error)\n return\n }\n signal.addEventListener('abort', () => reject(signal.reason as Error), { once: true })\n })\n}\n\n/**\n * Register one plugin route.\n *\n * This is the only place in the package that calls `ctx.webServer.register`,\n * and the ordering inside it is the fix rather than an implementation detail:\n * the disconnect listeners are attached before the first `await`, so a client\n * that goes away while the handler is still assembling its first response\n * still tears the route's work down. The previous per-route code attached\n * `res.on('close')` after awaiting an unbounded repository probe, which is how\n * the projection stream reached 53 opens against 33 closes.\n */\nexport function registerPluginRoute(ctx: Context, route: PluginRoute): void {\n const label = `dsh-claude: ${route.path}`\n ctx.effect(() => ctx.webServer.register({\n kind: route.kind,\n path: route.path,\n handler: async (req, res) => {\n const method = req.method\n if (!isPluginMethod(method) || !route.methods.includes(method)) {\n return json(res, 405, { error: 'method not allowed' })\n }\n if (!trustedRequest(req)) return json(res, 403, { error: 'forbidden' })\n // Before any await: a disconnect during setup must still cancel.\n const aborted = new AbortController()\n const abort = (): void => { aborted.abort() }\n // `req` emits 'close' when the request is COMPLETE, not only when the\n // client vanishes — so reading a body fires it, and an unguarded abort\n // here cancels every POST route the instant it parses its own input.\n // `complete` is what tells the two apart.\n req.on('close', () => { if (!req.complete) abort() })\n res.on('close', abort)\n const url = new URL(req.url ?? '/', 'http://localhost')\n if (route.mode === 'stream') {\n const release = streams.admit(route.path, route.streamKey(url), route.maxConcurrent, abort)\n const io: PluginRouteIo = {\n signal: aborted.signal,\n method,\n url,\n body: async <T,>(maxBytes = DEFAULT_BODY_BYTES) => await readBody(req, maxBytes) as T,\n }\n try {\n await route.handler(res, io)\n } catch (error) {\n if (!res.headersSent) json(res, 500, { error: 'stream-failed' })\n ctx.logger.warn(`dsh-claude: ${route.path} stream failed: ${error instanceof Error ? error.message : String(error)}`)\n } finally {\n release()\n res.end()\n }\n return\n }\n const budgetMs = ROUTE_BUDGET_MS[route.budget]\n const bounded = deadline(aborted.signal, budgetMs, ROUTE_TIMEOUT_CODE)\n const io: PluginRouteIo = {\n signal: bounded.signal,\n method,\n url,\n body: async <T,>(maxBytes = DEFAULT_BODY_BYTES) => await readBody(req, maxBytes) as T,\n }\n try {\n const result = await Promise.race([route.handler(io), rejectOn(bounded.signal)])\n if (!res.writableEnded) json(res, result.status, result.value)\n } catch (error) {\n if (res.writableEnded || res.headersSent) return\n if (bounded.signal.aborted && !aborted.signal.aborted) {\n return json(res, 504, { error: 'deadline', budget: route.budget, ms: budgetMs })\n }\n if (aborted.signal.aborted) return\n if (error instanceof PluginBodyTooLargeError) {\n return json(res, 413, { error: 'body-too-large', message: 'The request body is too large.' })\n }\n json(res, 400, { error: error instanceof Error ? error.message : 'request failed' })\n } finally {\n bounded[Symbol.dispose]()\n }\n },\n }), label)\n}\n\n/**\n * Memoise an executable lookup with a deadline, dropping the cache when it\n * fails.\n *\n * A route budget frees the socket but does nothing about a cached promise that\n * never settles: one hung PATH probe otherwise poisons every later request for\n * the life of the process, and the route deadline just turns that into a\n * steady stream of 504s. Caching only the resolved value keeps the retry.\n */\nexport function memoizeExecutable(\n resolve: (signal: AbortSignal) => Promise<string>,\n timeoutMs: number,\n): () => Promise<string> {\n let pending: Promise<string> | undefined\n return () => {\n if (pending !== undefined) return pending\n const bounded = deadline(undefined, timeoutMs, ROUTE_TIMEOUT_CODE)\n const attempt = resolve(bounded.signal)\n .finally(() => { bounded[Symbol.dispose]() })\n .catch((error: unknown) => {\n pending = undefined\n throw error\n })\n pending = attempt\n return attempt\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type { Agent } from '@deepseek-ai/dsh-agent'\nimport type {} from '@deepseek-ai/dsh-agent-presets'\nimport type {} from '@deepseek-ai/dsh-commands'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_DOCTOR_PATH } from './constants.ts'\nimport { runClaudeDoctor, type ExecutableRuntime } from './executable.ts'\nimport type { ClaudeSupervisor, ClaudeSupervisorConfig } from './supervisor.ts'\nimport { redactText } from './events.ts'\nimport { registerPluginRoute } from './http.ts'\n\nexport const CLAUDE_DOCTOR_PROBE_TIMEOUT_MS = 15_000\n\n/** Live metadata-bridge state per agent, maintained by the host plugin. */\nexport interface ClaudeBridgeDiagnostic {\n attempts: number\n lastError?: string\n lastCatalog?: number\n registered?: string[]\n}\n\nexport const claudeBridgeDiagnostics = new WeakMap<Agent, ClaudeBridgeDiagnostic>()\n\nfunction safeMessage(error: unknown): string {\n return redactText(error instanceof Error ? error.message : String(error), 1_000)\n}\n\n/** Live command-bridge diagnostics: which agents exist, their presets, and how\n * many slash commands each agent's registry layer resolves. */\nfunction commandDiagnostics(ctx: Context): unknown {\n try {\n const agents = ctx.agents.list()\n return {\n total: agents.length,\n agents: agents.map(agent => {\n const info: { id: string; preset?: string; commandCount?: number; sample?: string[]; error?: string; bridge?: ClaudeBridgeDiagnostic } = { id: String(agent.id) }\n try {\n const preset = ctx.agentPresets.composedPreset(agent.ctx)\n if (preset !== undefined) info.preset = preset\n } catch (error) {\n info.error = safeMessage(error)\n }\n try {\n const list = ctx.commands.list(agent)\n info.commandCount = list.length\n info.sample = list.slice(0, 10).map(command => command.name)\n } catch (error) {\n info.error = info.error === undefined ? safeMessage(error) : `${info.error}; ${safeMessage(error)}`\n }\n const bridge = claudeBridgeDiagnostics.get(agent)\n if (bridge !== undefined) info.bridge = bridge\n return info\n }),\n }\n } catch (error) {\n return { error: safeMessage(error) }\n }\n}\n\nexport function registerClaudeDoctorRoutes(\n ctx: Context,\n runtime: ExecutableRuntime,\n supervisor: ClaudeSupervisor,\n config: ClaudeSupervisorConfig,\n resolutionError?: unknown,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_DOCTOR_PATH,\n methods: ['GET'],\n budget: 'git',\n handler: async io => {\n try {\n if (resolutionError !== undefined) {\n return { status: 200, value: {\n executable: {\n status: 'missing',\n searched: config.executablePath.length > 0 ? [config.executablePath] : ['claude', '~/.local/bin/claude', '/opt/homebrew/bin/claude', '/usr/local/bin/claude'],\n },\n version: { status: 'not-run' },\n authentication: { status: 'not-run' },\n handshake: 'not-run',\n message: safeMessage(resolutionError),\n limits: {\n idleTimeoutMs: config.idleTimeoutMs,\n maxProcesses: config.maxProcesses,\n },\n processes: { count: 0, active: 0 },\n } }\n }\n const report = await runClaudeDoctor(runtime, {\n configuredPath: config.executablePath,\n cwd: process.cwd(),\n // Threaded so freeing the socket also stops the probe, rather than\n // leaving a spawn nobody is waiting for; the ceiling stays its own.\n signal: AbortSignal.any([io.signal, AbortSignal.timeout(CLAUDE_DOCTOR_PROBE_TIMEOUT_MS)]),\n })\n const processes = supervisor.snapshots()\n if (processes.some(process => process.claudeSessionId !== undefined)) report.handshake = 'ok'\n return { status: 200, value: {\n ...report,\n limits: {\n idleTimeoutMs: config.idleTimeoutMs,\n maxProcesses: config.maxProcesses,\n },\n processes: {\n count: processes.length,\n active: processes.filter(process => process.state === 'running' || process.state === 'starting').length,\n },\n commandBridge: commandDiagnostics(ctx),\n } }\n } catch (error) {\n return { status: 500, value: { error: safeMessage(error) } }\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport type { ServerResponse } from 'node:http'\nimport { CLAUDE_PROJECTION_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport { MAX_MULTIPLEX_SESSIONS } from './plugin-budget.ts'\nimport type { ClaudeSidecarProjection, ClaudeSidecarRepository } from './sidecar.ts'\nimport type { ClaudeActivityEvent } from './events.ts'\nimport type { ClaudeCommandView } from './command-bridge.ts'\nimport type { RepositoryStatus } from './repository-status.ts'\nimport type { ReviewComment } from './review-comments.ts'\n\nconst MAX_SESSION_ID_CHARS = 1_024\n/** Slow-moving metadata refresh and stream heartbeat cadence; deliberately off\n * the transcript hot path so git/gh latency never delays visible text. */\nconst META_REFRESH_MS = 5_000\n/** The multiplexed carrier's path segment. Session ids are `session-<uuid>`,\n * so this cannot collide with one. */\nconst MULTI_SEGMENT = 'multi'\n\ntype ProjectionTarget =\n | { readonly kind: 'snapshot'; readonly sessionId: string }\n | { readonly kind: 'multi'; readonly sessionIds: readonly string[] }\n\nfunction validSessionId(value: string): boolean {\n return value.length > 0 && value.length <= MAX_SESSION_ID_CHARS\n}\n\nfunction targetFromUrl(url: URL): ProjectionTarget | undefined {\n const prefix = `${CLAUDE_PROJECTION_PATH}/`\n if (!url.pathname.startsWith(prefix)) return undefined\n const encoded = url.pathname.slice(prefix.length)\n if (encoded.length === 0 || encoded.includes('/')) return undefined\n if (encoded === MULTI_SEGMENT) {\n const raw = url.searchParams.get('sessions')\n if (raw === null) return undefined\n const sessionIds = [...new Set(raw.split(',').filter(id => id.length > 0))]\n if (sessionIds.length === 0 || sessionIds.length > MAX_MULTIPLEX_SESSIONS) return undefined\n if (!sessionIds.every(validSessionId)) return undefined\n return { kind: 'multi', sessionIds }\n }\n try {\n const sessionId = decodeURIComponent(encoded)\n return validSessionId(sessionId) ? { kind: 'snapshot', sessionId } : undefined\n } catch {\n return undefined\n }\n}\n\ninterface ProjectionMeta {\n readonly owned: boolean\n readonly commands: readonly ClaudeCommandView[]\n readonly repository?: RepositoryStatus\n /** Other checkouts the session wrote into; see touched-repositories.ts. */\n readonly repositories?: readonly RepositoryStatus[]\n readonly reviewComments: readonly ReviewComment[]\n}\n\nfunction envelope(projection: ClaudeSidecarProjection, meta: ProjectionMeta): Record<string, unknown> {\n return {\n schemaVersion: projection.schemaVersion,\n revision: projection.revision,\n owned: meta.owned,\n commands: meta.commands,\n activities: projection.activities,\n ...(projection.contextUsage === undefined ? {} : { contextUsage: projection.contextUsage }),\n ...(projection.tasks === undefined ? {} : { tasks: projection.tasks }),\n ...(meta.repository === undefined ? {} : { repository: meta.repository }),\n ...(meta.repositories === undefined ? {} : { repositories: meta.repositories }),\n reviewComments: meta.reviewComments,\n // Ranges only: the chain anchors behind a rewind are Claude transcript\n // identities and stay on this side of the boundary.\n ...(projection.rewind === undefined ? {} : { rewind: { ranges: projection.rewind.ranges } }),\n }\n}\n\n/** Register the browser-readable, credential-free sidecar projection endpoint.\n *\n * `GET <path>/:sessionId` returns one snapshot. `GET <path>/multi?sessions=a,b`\n * returns ONE NDJSON stream carrying every listed session, each line stamped\n * with its `session`.\n *\n * There is deliberately no per-session stream URL. The browser shares a small\n * fixed connection budget between this plugin and the Host, and a stream per\n * session spent it in proportion to how many Claude sessions existed — which\n * is what left the settings panel unable to get a connection at all. One\n * carrier is one connection, whatever the session count. */\nexport function registerClaudeProjectionRoute(\n ctx: Context,\n sidecar: ClaudeSidecarRepository,\n ownsSession: (sessionId: string) => boolean,\n commandsForSession: (sessionId: string) => readonly ClaudeCommandView[] = () => [],\n repositoryForSession: (sessionId: string) => Promise<RepositoryStatus | undefined> = async () => undefined,\n reviewCommentsForSession: (sessionId: string) => readonly ReviewComment[] = () => [],\n extraRepositoriesForSession: (sessionId: string, activities: readonly ClaudeActivityEvent[]) => Promise<readonly RepositoryStatus[]> = async () => [],\n): void {\n const info = (message: string): void => {\n ctx.logger?.info?.(message)\n }\n\n /** Everything the host already knows, without touching the repository. */\n const localMeta = (sessionId: string): ProjectionMeta => {\n const owned = ownsSession(sessionId)\n return {\n owned,\n commands: commandsForSession(sessionId),\n reviewComments: owned ? reviewCommentsForSession(sessionId) : [],\n }\n }\n\n const assembleMeta = async (sessionId: string, activities?: readonly ClaudeActivityEvent[]): Promise<ProjectionMeta> => {\n const meta = localMeta(sessionId)\n if (!meta.owned) return meta\n const [repository, repositories] = await Promise.all([\n repositoryForSession(sessionId),\n extraRepositoriesForSession(sessionId, activities ?? (await sidecar.read(sessionId)).activities),\n ])\n return {\n ...meta,\n ...(repository === undefined ? {} : { repository }),\n ...(repositories.length === 0 ? {} : { repositories }),\n }\n }\n\n const streamMulti = async (res: ServerResponse, io: PluginRouteIo, sessionIds: readonly string[]): Promise<void> => {\n info(`dsh-claude: projection stream opened for ${sessionIds.length} session(s)`)\n let textDeltas = 0\n let textBytes = 0\n let textSince = Date.now()\n // Headers first, before any await. One session whose repository probe is\n // slow must not delay every other session's first paint — and until the\n // headers are out the client cannot even tell the carrier is alive.\n // `no-transform` keeps a compressing proxy from buffering the sole carrier.\n res.writeHead(200, {\n 'content-type': 'application/x-ndjson; charset=utf-8',\n 'cache-control': 'no-store, no-transform',\n 'x-content-type-options': 'nosniff',\n })\n res.flushHeaders?.()\n let closed = false\n const writeLine = (value: unknown): void => {\n if (closed) return\n try {\n res.write(`${JSON.stringify(value)}\\n`)\n } catch {\n closed = true\n }\n }\n const metas = new Map<string, ProjectionMeta>()\n const writeMeta = (sessionId: string, meta: ProjectionMeta): void => {\n metas.set(sessionId, meta)\n writeLine({\n type: 'meta',\n session: sessionId,\n owned: meta.owned,\n commands: meta.commands,\n ...(meta.repository === undefined ? {} : { repository: meta.repository }),\n ...(meta.repositories === undefined ? {} : { repositories: meta.repositories }),\n reviewComments: meta.reviewComments,\n })\n }\n const writeSnapshot = async (sessionId: string): Promise<void> => {\n const projection = await sidecar.read(sessionId)\n // The repository probe runs a chain of git commands and a `gh pr view`\n // over the network -- seconds, where the transcript is already in\n // memory. It rides a later meta line so the prose paints first.\n const meta = metas.get(sessionId) ?? localMeta(sessionId)\n metas.set(sessionId, meta)\n // Where the notification stream stands as of this read, so the first\n // delta after this line has a number to be contiguous with.\n writeLine({ type: 'snapshot', session: sessionId, seq: sidecar.sequence(sessionId), ...envelope(projection, meta) })\n const probed = await assembleMeta(sessionId, projection.activities)\n if (closed || JSON.stringify(probed) === JSON.stringify(metas.get(sessionId))) return\n writeMeta(sessionId, probed)\n }\n // Subscribe every lane synchronously, before the first await: a delta that\n // lands while the snapshots are still assembling belongs to this carrier.\n const unsubscribes = sessionIds.map(sessionId => sidecar.subscribe(sessionId, delta => {\n switch (delta.kind) {\n case 'text':\n textDeltas += 1\n textBytes += (delta.append ?? delta.text ?? '').length\n if (textDeltas % 25 === 0) {\n const elapsed = Date.now() - textSince\n info(`dsh-claude: stream 25 text deltas ${textBytes}B in ${elapsed}ms`)\n textBytes = 0\n textSince = Date.now()\n }\n writeLine({\n type: 'text',\n session: sessionId,\n turn: delta.turn,\n step: delta.step,\n ordinal: delta.ordinal,\n ...(delta.append === undefined ? {} : { append: delta.append }),\n ...(delta.text === undefined ? {} : { text: delta.text }),\n ...(delta.renderer === undefined ? {} : { renderer: delta.renderer }),\n seq: delta.seq,\n })\n return\n case 'activity':\n writeLine({ type: 'activity', session: sessionId, activity: delta.activity, seq: delta.seq })\n return\n case 'contextUsage':\n writeLine({ type: 'contextUsage', session: sessionId, value: delta.value, seq: delta.seq })\n return\n case 'tasks':\n writeLine({ type: 'tasks', session: sessionId, value: delta.value, seq: delta.seq })\n return\n case 'checkpoint':\n writeLine({ type: 'checkpoint', session: sessionId, seq: delta.seq })\n return\n case 'sync':\n void writeSnapshot(sessionId).catch(() => undefined)\n }\n }))\n // Per-session, in parallel: a wedged repository probe costs its own lane\n // its first paint, not everyone else's.\n for (const sessionId of sessionIds) {\n void writeSnapshot(sessionId).catch(() => undefined)\n }\n // One sweep at a time. Each lane's probe chains git commands and a network\n // `gh pr view`, and the interval has no idea how long the last one took --\n // so a tick that lands on a sweep still in flight starts a second set of\n // the same probes rather than waiting. At a lane or two that never showed;\n // at a full carrier it is sixteen serial probes per tick, arriving faster\n // than they drain. Skipping a tick costs at most one refresh of metadata\n // that is deliberately off the transcript's hot path.\n let sweeping = false\n const timer = setInterval(() => {\n // The heartbeat leads, and does not ride the sweep. It is the only thing\n // keeping bytes on a carrier between turns, and an idle connection the\n // far end reaps is the ending that costs the Client its transcript.\n writeLine({ type: 'ping' })\n if (sweeping) return\n sweeping = true\n void (async () => {\n for (const sessionId of sessionIds) {\n if (closed) return\n const next = await assembleMeta(sessionId)\n if (closed) return\n if (JSON.stringify(next) === JSON.stringify(metas.get(sessionId))) continue\n writeMeta(sessionId, next)\n }\n })().catch(() => undefined).finally(() => { sweeping = false })\n }, META_REFRESH_MS)\n timer.unref?.()\n // Teardown rides the wrapper's signal, which is armed before any await —\n // the previous hand-written `res.on('close')` was attached only after the\n // first metadata probe resolved, so a client that gave up during that\n // window left the interval and every subscription running for good.\n await new Promise<void>(resolve => {\n const finish = (): void => {\n if (closed) return\n closed = true\n clearInterval(timer)\n for (const unsubscribe of unsubscribes) unsubscribe()\n info(`dsh-claude: projection stream closed after ${textDeltas} text deltas`)\n resolve()\n }\n if (io.signal.aborted) finish()\n else io.signal.addEventListener('abort', finish, { once: true })\n })\n }\n\n registerPluginRoute(ctx, {\n mode: 'stream',\n kind: 'prefix',\n path: CLAUDE_PROJECTION_PATH,\n methods: ['GET'],\n // One carrier. A reconnect supersedes the old one rather than stacking.\n maxConcurrent: 1,\n streamKey: () => MULTI_SEGMENT,\n handler: async (res, io) => {\n const target = targetFromUrl(io.url)\n if (target === undefined) {\n res.writeHead(400, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' })\n res.write(JSON.stringify({ error: 'invalid session id' }))\n return\n }\n if (target.kind === 'multi') return await streamMulti(res, io, target.sessionIds)\n // A steady 2s cadence here means a stale (pre-streaming) client bundle.\n info(`dsh-claude: projection poll for ${target.sessionId.slice(0, 64)}`)\n try {\n const projection = await sidecar.read(target.sessionId)\n const body = envelope(projection, await assembleMeta(target.sessionId, projection.activities))\n res.writeHead(200, {\n 'content-type': 'application/json; charset=utf-8',\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n })\n res.write(JSON.stringify(body))\n } catch {\n if (res.headersSent) return\n res.writeHead(500, { 'content-type': 'application/json; charset=utf-8', 'cache-control': 'no-store' })\n res.write(JSON.stringify({ error: 'projection unavailable' }))\n }\n },\n })\n}\n","import { mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\n\n/** Extensions mapped onto a funcname driver, so `@@` hunk headers name the\n * method a change sits in. Without one git falls back to \"the last line that\n * starts in column 0\", which in Java or Kotlin is always the class. */\nexport const DIFF_ATTRIBUTES = [\n '*.java diff=java',\n '*.kt diff=kotlin',\n '*.kts diff=kotlin',\n '*.py diff=python',\n '*.pyi diff=python',\n '*.js diff=dshweb',\n '*.jsx diff=dshweb',\n '*.mjs diff=dshweb',\n '*.cjs diff=dshweb',\n '*.ts diff=dshweb',\n '*.tsx diff=dshweb',\n '*.mts diff=dshweb',\n '*.cts diff=dshweb',\n '*.vue diff=dshweb',\n '*.svelte diff=dshweb',\n '*.css diff=css',\n '*.scss diff=css',\n '*.less diff=css',\n '',\n].join('\\n')\n\n/** git ships no JavaScript driver, so this is the one pattern we write ourselves.\n *\n * POSIX extended regexes, one per line, matched top-down: a leading `!` marks a\n * line that can never be a header, and the reported text is capture group 1 --\n * hence the outer parentheses around everything worth showing.\n *\n * Line 2 keeps git's own fallback (anything unindented), because a driver\n * replaces that fallback rather than extending it, and most of a frontend file's\n * declarations already live in column 0. Lines 3 and 4 add what the fallback\n * cannot see: nested declarations, and indented class or object methods.\n *\n * ponytail: a method line must end in `{`. Allowing `)` too would pick up every\n * bare `foo(bar)` statement, which reads as a header and hides the real one.\n */\nexport const DSHWEB_FUNCNAME = [\n '!^[ \\t]*(if|else|for|while|do|switch|case|catch|try|finally|return|await|new|throw|typeof)[^A-Za-z0-9_$]',\n '^([A-Za-z_$].*)$',\n '^[ \\t]*((export[ \\t]+)?(default[ \\t]+)?(declare[ \\t]+)?(abstract[ \\t]+)?(async[ \\t]+)?(function|class|interface|enum|namespace|module)[ \\t].*)$',\n '^[ \\t]*(((public|private|protected|static|readonly|abstract|async|get|set)[ \\t]+)*[A-Za-z_$#][A-Za-z0-9_$]*[ \\t]*[:=]?[ \\t]*(async[ \\t]+)?[(<][^;]*\\\\{)[ \\t]*$',\n].join('\\n')\n\nlet attributesFile: Promise<string | undefined> | undefined\n\nasync function writeAttributes(): Promise<string | undefined> {\n const path = dshHomePath('plugins', 'dsh-claude', 'diff-attributes')\n try {\n await mkdir(dirname(path), { recursive: true })\n await writeFile(path, DIFF_ATTRIBUTES, 'utf8')\n return path\n } catch {\n return undefined\n }\n}\n\n/** `-c` overrides to place in front of a `git diff`, teaching it which funcname\n * driver each extension uses.\n *\n * `core.attributesFile` is the lowest-precedence attribute source, so a\n * repository that already declares its own `.gitattributes` still wins. Better\n * hunk headers are cosmetic: a failed write drops the overrides and the diff\n * runs exactly as before.\n */\nexport async function diffFuncnameArgs(): Promise<readonly string[]> {\n attributesFile ??= writeAttributes()\n const path = await attributesFile\n if (path === undefined) return []\n return ['-c', `core.attributesFile=${path}`, '-c', `diff.dshweb.xfuncname=${DSHWEB_FUNCNAME}`]\n}\n","import { readFile, stat } from 'node:fs/promises'\nimport { isAbsolute, join, resolve, sep } from 'node:path'\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { diffFuncnameArgs } from './diff-funcname.ts'\n\nconst MAX_OUTPUT_BYTES = 64 * 1024\nconst MAX_DIFF_BYTES = 256 * 1024\nconst MAX_FILE_BYTES = 8 * 1024 * 1024\nexport const MAX_FILE_LINES_PER_REQUEST = 500\nconst MAX_UNTRACKED_DIFFS = 50\nconst GIT_TIMEOUT_MS = 5_000\nconst GH_TIMEOUT_MS = 8_000\nconst CACHE_TTL_MS = 5_000\nconst MAX_TEXT_CHARS = 1_024\nconst MAX_CONFLICT_PATHS = 100\n\n/** A git operation left half-finished in the working tree, waiting for the\n * user to resolve conflicts and continue -- or to abort. */\nexport type RepositoryOperation = 'rebase' | 'merge' | 'cherry-pick' | 'revert'\nexport type RepositoryCheckState = 'passing' | 'pending' | 'failing' | 'none'\nexport type RepositoryReviewState = 'approved' | 'changes-requested' | 'review-required' | 'none'\n\nexport interface RepositoryPullRequestStatus {\n readonly number: number\n readonly title: string\n readonly url: string\n readonly state: 'open' | 'closed' | 'merged'\n readonly draft: boolean\n readonly review: RepositoryReviewState\n readonly checks: RepositoryCheckState\n readonly mergeState?: string\n readonly author?: string\n readonly createdAt?: string\n readonly mergedAt?: string\n readonly baseBranch?: string\n}\n\nexport interface RepositoryDiffStatus {\n readonly additions: number\n readonly deletions: number\n readonly files: number\n readonly patch?: string\n readonly truncated: boolean\n}\n\nexport interface RepositoryStatus {\n readonly status: 'ready' | 'not-repository' | 'unavailable'\n readonly cwd: string\n readonly root?: string\n readonly branch?: string\n readonly detached?: boolean\n readonly worktree?: boolean\n readonly dirty?: boolean\n readonly upstream?: boolean\n readonly ahead?: number\n readonly behind?: number\n readonly remote?: string\n readonly pullRequest?: RepositoryPullRequestStatus\n readonly diff?: RepositoryDiffStatus\n /** Commits on origin/<base> that are not on HEAD, for open pull requests. */\n readonly baseBehind?: number\n /** Unmerged paths: the files a stopped merge or rebase is waiting on. */\n readonly conflicts?: readonly string[]\n /** The stopped operation itself, present even once every conflict is staged. */\n readonly operation?: RepositoryOperation\n}\n\ntype RepositoryRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n\ninterface CommandResult {\n readonly exitCode: number | null\n readonly stdout: string\n readonly lossy: boolean\n}\n\nfunction bounded(value: string): string {\n return value.trim().slice(0, MAX_TEXT_CHARS)\n}\n\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\n const outcome = await handle.done\n const stdout = handle.collected.stdout?.readFrom(0)\n return {\n exitCode: outcome.exitCode,\n stdout: stdout?.text ?? '',\n lossy: stdout?.lossy === true,\n }\n}\n\nasync function run(\n runtime: RepositoryRuntime,\n executable: string,\n args: readonly string[],\n cwd: string,\n timeoutMs: number,\n maxBytes = MAX_OUTPUT_BYTES,\n): Promise<CommandResult> {\n const signal = AbortSignal.timeout(timeoutMs)\n return collect(runtime.spawn({\n argv: [executable, ...args],\n cwd,\n stdio: {\n stdin: 'ignore',\n stdout: { maxBytes },\n stderr: { maxBytes: MAX_OUTPUT_BYTES },\n },\n graceMs: 1_000,\n signal,\n env: {},\n }))\n}\n\nfunction normalizedPath(value: string): string {\n return value.replaceAll('\\\\', '/').replace(/\\/+$/u, '').toLocaleLowerCase('en-US')\n}\n\nexport function parseGitStatus(output: string): {\n branch?: string\n detached: boolean\n dirty: boolean\n upstream: boolean\n ahead?: number\n behind?: number\n conflicts?: readonly string[]\n} {\n let branch: string | undefined\n let detached = false\n let dirty = false\n let upstream = false\n let ahead: number | undefined\n let behind: number | undefined\n const conflicts: string[] = []\n for (const line of output.split(/\\r?\\n/u)) {\n if (line.startsWith('# branch.head ')) {\n const head = bounded(line.slice('# branch.head '.length))\n if (head === '(detached)') detached = true\n else if (head.length > 0 && head !== '(unknown)') branch = head\n continue\n }\n if (line.startsWith('# branch.upstream ')) {\n upstream = true\n continue\n }\n if (line.startsWith('# branch.ab ')) {\n const counts = /^# branch\\.ab \\+(\\d+) -(\\d+)$/u.exec(line)\n if (counts !== null) {\n ahead = Number(counts[1])\n behind = Number(counts[2])\n }\n continue\n }\n // `u <XY> <sub> <m1> <m2> <m3> <mW> <h1> <h2> <h3> <path>`: unmerged paths\n // are the only conflict signal the status carries, and they also read as\n // dirty below -- a stopped merge owns the tree until it is resolved.\n if (line.startsWith('u ')) {\n const path = line.split(' ').slice(10).join(' ')\n if (path.length > 0 && conflicts.length < MAX_CONFLICT_PATHS) conflicts.push(bounded(path))\n }\n if (line.length > 0 && !line.startsWith('# ')) dirty = true\n }\n return {\n ...(branch === undefined ? {} : { branch }),\n detached,\n dirty,\n upstream,\n ...(ahead === undefined ? {} : { ahead }),\n ...(behind === undefined ? {} : { behind }),\n ...(conflicts.length === 0 ? {} : { conflicts }),\n }\n}\n\n/** Ordered so the rebase directories win: a conflicted rebase also writes\n * MERGE_HEAD-like state, and the two are resumed by different commands. */\nconst OPERATION_MARKERS: readonly (readonly [string, RepositoryOperation])[] = [\n ['rebase-merge', 'rebase'],\n ['rebase-apply', 'rebase'],\n ['MERGE_HEAD', 'merge'],\n ['CHERRY_PICK_HEAD', 'cherry-pick'],\n ['REVERT_HEAD', 'revert'],\n]\n\nexport interface RepositoryOperationState {\n readonly operation: RepositoryOperation\n /** The branch the rebase parked. Git status only reports `(detached)` while\n * it replays, so `head-name` is the only place the real branch survives. */\n readonly branch?: string\n}\n\n/** Reads the in-progress operation out of the worktree's own git dir -- linked\n * worktrees keep their own, so this must not be handed the common dir. */\nexport async function detectRepositoryOperation(gitDir: string): Promise<RepositoryOperationState | undefined> {\n for (const [marker, operation] of OPERATION_MARKERS) {\n const path = join(gitDir, marker)\n try {\n await stat(path)\n } catch {\n continue\n }\n const headName = operation === 'rebase' ? await readFile(join(path, 'head-name'), 'utf8').catch(() => '') : ''\n const branch = bounded(headName).replace(/^refs\\/heads\\//u, '')\n // A rebase started from a detached HEAD writes exactly that as the name.\n return { operation, ...(branch.length === 0 || branch.includes(' ') ? {} : { branch }) }\n }\n return undefined\n}\n\nexport function parseDiffNumstat(value: string): Omit<RepositoryDiffStatus, 'patch' | 'truncated'> {\n let additions = 0\n let deletions = 0\n let files = 0\n for (const line of value.split(/\\r?\\n/u)) {\n if (line.length === 0) continue\n const [added, deleted] = line.split('\\t')\n files += 1\n if (added !== undefined && /^\\d+$/u.test(added)) additions += Number(added)\n if (deleted !== undefined && /^\\d+$/u.test(deleted)) deletions += Number(deleted)\n }\n return { additions, deletions, files }\n}\n\nexport function parseGitHubRemote(value: string): string | undefined {\n const remote = bounded(value)\n const match = /^(?:https:\\/\\/github\\.com\\/|git@github\\.com:|ssh:\\/\\/git@github\\.com\\/)([^/\\s]+)\\/([^/\\s]+?)(?:\\.git)?$/iu.exec(remote)\n if (match?.[1] === undefined || match[2] === undefined) return undefined\n return `${match[1]}/${match[2]}`\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined\n}\n\nexport function aggregateChecks(value: unknown): RepositoryCheckState {\n if (!Array.isArray(value) || value.length === 0) return 'none'\n let pending = false\n for (const item of value) {\n const check = record(item)\n if (check === undefined) continue\n const conclusion = typeof check.conclusion === 'string' ? check.conclusion.toUpperCase() : undefined\n const status = typeof check.status === 'string' ? check.status.toUpperCase() : undefined\n const state = typeof check.state === 'string' ? check.state.toUpperCase() : undefined\n if (['FAILURE', 'ERROR', 'CANCELLED', 'TIMED_OUT', 'ACTION_REQUIRED'].includes(conclusion ?? state ?? '')) return 'failing'\n if (status !== undefined && status !== 'COMPLETED') pending = true\n if (['PENDING', 'EXPECTED'].includes(state ?? '')) pending = true\n }\n return pending ? 'pending' : 'passing'\n}\n\nfunction reviewState(value: unknown): RepositoryReviewState {\n if (value === 'APPROVED') return 'approved'\n if (value === 'CHANGES_REQUESTED') return 'changes-requested'\n if (value === 'REVIEW_REQUIRED') return 'review-required'\n return 'none'\n}\n\nexport function parsePullRequest(value: unknown): RepositoryPullRequestStatus | undefined {\n const input = record(value)\n if (input === undefined\n || !Number.isSafeInteger(input.number)\n || Number(input.number) <= 0\n || typeof input.title !== 'string'\n || typeof input.url !== 'string') return undefined\n let url: URL\n try {\n url = new URL(input.url)\n } catch {\n return undefined\n }\n if (url.protocol !== 'https:' || url.hostname !== 'github.com') return undefined\n const rawState = typeof input.state === 'string' ? input.state.toUpperCase() : ''\n const state = input.mergedAt !== undefined && input.mergedAt !== null\n ? 'merged'\n : rawState === 'OPEN' ? 'open' : rawState === 'CLOSED' ? 'closed' : undefined\n if (state === undefined) return undefined\n return {\n number: Number(input.number),\n title: bounded(input.title),\n url: url.href,\n state,\n draft: input.isDraft === true,\n review: reviewState(input.reviewDecision),\n checks: aggregateChecks(input.statusCheckRollup),\n ...(typeof input.mergeStateStatus === 'string'\n ? { mergeState: bounded(input.mergeStateStatus) }\n : {}),\n ...(typeof record(input.author)?.login === 'string'\n ? { author: bounded(String(record(input.author)?.login)) }\n : {}),\n ...(typeof input.createdAt === 'string' && Number.isFinite(Date.parse(input.createdAt))\n ? { createdAt: new Date(input.createdAt).toISOString() }\n : {}),\n ...(typeof input.mergedAt === 'string' && Number.isFinite(Date.parse(input.mergedAt))\n ? { mergedAt: new Date(input.mergedAt).toISOString() }\n : {}),\n ...(typeof input.baseRefName === 'string' && bounded(input.baseRefName).length > 0\n ? { baseBranch: bounded(input.baseRefName) }\n : {}),\n }\n}\n\nexport interface RepositoryFileLines {\n /** Requested 1-based inclusive slice of the working-tree file, clipped to its end. */\n readonly lines: readonly string[]\n /** Total line count of the file. */\n readonly total: number\n}\n\nexport class RepositoryFileError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'RepositoryFileError'\n this.code = code\n }\n}\n\nexport class RepositoryStatusService {\n readonly #runtime: RepositoryRuntime\n readonly #cacheTtlMs: number\n readonly #cache = new Map<string, { expiresAt: number; value: Promise<RepositoryStatus> }>()\n readonly #lastReady = new Map<string, RepositoryStatus>()\n #gitExecutable?: Promise<string>\n #ghExecutable?: Promise<string | undefined>\n readonly #roots = new Map<string, Promise<string | undefined>>()\n\n constructor(runtime: RepositoryRuntime, cacheTtlMs = CACHE_TTL_MS) {\n this.#runtime = runtime\n this.#cacheTtlMs = cacheTtlMs\n }\n\n /** `signal` bounds the scan itself, not just the caller's patience: the\n * untracked-file diff below is a serial spawn loop that can outlive any\n * route budget, and work nobody is waiting for still occupies the process. */\n inspect(cwd: string, signal?: AbortSignal): Promise<RepositoryStatus> {\n const current = this.#cache.get(cwd)\n if (current !== undefined && current.expiresAt > Date.now()) return current.value\n const value = this.#inspect(cwd, signal).then(next => this.#stabilize(cwd, next))\n this.#cache.set(cwd, { expiresAt: Date.now() + this.#cacheTtlMs, value })\n void value.catch(() => this.#cache.delete(cwd))\n return value\n }\n\n invalidate(cwd: string): void {\n this.#cache.delete(cwd)\n this.#lastReady.delete(cwd)\n }\n\n /** The repository holding `directory`, or undefined outside any. A root\n * does not move, so a settled answer is kept for the service's lifetime;\n * a probe that could not run is not an answer and is asked again. */\n rootOf(directory: string): Promise<string | undefined> {\n const known = this.#roots.get(directory)\n if (known !== undefined) return known\n const value = (async () => {\n const top = await run(this.#runtime, await this.#git(), ['rev-parse', '--path-format=absolute', '--show-toplevel'], directory, GIT_TIMEOUT_MS)\n return top.exitCode === 0 ? resolve(top.stdout.trim()) : undefined\n })().catch((): undefined => {\n this.#roots.delete(directory)\n return undefined\n })\n this.#roots.set(directory, value)\n return value\n }\n\n dispose(): void {\n this.#roots.clear()\n this.#cache.clear()\n this.#lastReady.clear()\n }\n\n #stabilize(cwd: string, next: RepositoryStatus): RepositoryStatus {\n const previous = this.#lastReady.get(cwd)\n if (next.status !== 'ready') return previous ?? next\n const sameCheckout = previous?.status === 'ready'\n && previous.root === next.root\n && previous.branch === next.branch\n const stable = sameCheckout\n ? {\n ...next,\n ...(next.pullRequest === undefined && previous.pullRequest !== undefined ? { pullRequest: previous.pullRequest } : {}),\n ...(next.pullRequest === undefined && previous.pullRequest !== undefined && previous.diff !== undefined\n ? { diff: previous.diff }\n : next.diff === undefined && previous.diff !== undefined ? { diff: previous.diff } : {}),\n }\n : next\n this.#lastReady.set(cwd, stable)\n return stable\n }\n\n /** Lines [from, to] of a working-tree file, used to expand unmodified context around diff hunks. */\n async fileLines(cwd: string, relativePath: string, from: number, to: number): Promise<RepositoryFileLines> {\n if (relativePath.length === 0 || isAbsolute(relativePath) || relativePath.includes('\\0') || relativePath.split(/[\\\\/]/u).includes('..')) {\n throw new RepositoryFileError('invalid-request', 'The file path must be relative to the repository.')\n }\n if (!Number.isSafeInteger(from) || !Number.isSafeInteger(to) || from < 1 || to < from || to - from >= MAX_FILE_LINES_PER_REQUEST) {\n throw new RepositoryFileError('invalid-request', 'The requested line range is invalid.')\n }\n const git = await this.#git()\n const top = await run(this.#runtime, git, ['rev-parse', '--path-format=absolute', '--show-toplevel'], cwd, GIT_TIMEOUT_MS)\n if (top.exitCode !== 0) throw new RepositoryFileError('not-repository', 'The directory is not inside a git repository.')\n const root = resolve(top.stdout.trim())\n const target = resolve(root, relativePath)\n if (target !== root && !target.startsWith(root + sep)) throw new RepositoryFileError('invalid-request', 'The file path escapes the repository.')\n const content = await readFile(target, 'utf8')\n if (content.length > MAX_FILE_BYTES) throw new RepositoryFileError('too-large', 'The file is too large to expand.')\n const all = content.split(/\\r?\\n/u)\n if (all.at(-1) === '') all.pop()\n return { lines: all.slice(from - 1, to), total: all.length }\n }\n\n async #git(): Promise<string> {\n this.#gitExecutable ??= this.#runtime.resolveExecutable('git')\n return this.#gitExecutable\n }\n\n async #gh(): Promise<string | undefined> {\n this.#ghExecutable ??= this.#runtime.resolveExecutable('gh').catch(() => undefined)\n return this.#ghExecutable\n }\n\n async #inspect(cwd: string, signal?: AbortSignal): Promise<RepositoryStatus> {\n const safeCwd = bounded(cwd)\n let git: string\n try {\n git = await this.#git()\n } catch {\n return { status: 'unavailable', cwd: safeCwd }\n }\n try {\n const paths = await run(this.#runtime, git, [\n 'rev-parse', '--path-format=absolute', '--show-toplevel', '--absolute-git-dir', '--git-common-dir',\n ], cwd, GIT_TIMEOUT_MS)\n if (paths.exitCode !== 0) return { status: 'not-repository', cwd: safeCwd }\n const [rootValue, gitDirValue, commonDirValue] = paths.stdout.split(/\\r?\\n/u)\n const root = bounded(rootValue ?? '')\n const gitDir = bounded(gitDirValue ?? '')\n const commonDir = bounded(commonDirValue ?? '')\n if (root.length === 0 || gitDir.length === 0 || commonDir.length === 0) return { status: 'unavailable', cwd: safeCwd }\n const statusResult = await run(this.#runtime, git, ['status', '--porcelain=v2', '--branch', '--untracked-files=normal'], cwd, GIT_TIMEOUT_MS)\n if (statusResult.exitCode !== 0) return { status: 'unavailable', cwd: safeCwd }\n const status = parseGitStatus(statusResult.stdout)\n const operation = await detectRepositoryOperation(gitDir)\n // A stopped rebase detaches HEAD, which would otherwise drop the branch,\n // its pull request and every control keyed on them for as long as the\n // conflict lasts -- exactly when the user needs them most.\n const branch = operation?.branch ?? status.branch\n const remoteResult = await run(this.#runtime, git, ['remote', 'get-url', 'origin'], cwd, GIT_TIMEOUT_MS)\n const remote = remoteResult.exitCode === 0 ? parseGitHubRemote(remoteResult.stdout) : undefined\n const pullRequest = branch === undefined || remote === undefined\n ? undefined\n : await this.#pullRequest(cwd, remote, branch)\n const diffBase = pullRequest?.baseBranch === undefined\n ? 'HEAD'\n : await this.#mergeBase(cwd, git, pullRequest.baseBranch) ?? 'HEAD'\n const diff = status.dirty || diffBase !== 'HEAD'\n ? await this.#diff(cwd, git, diffBase, signal)\n : { additions: 0, deletions: 0, files: 0, truncated: false }\n const baseBehind = pullRequest?.state === 'open' && pullRequest.baseBranch !== undefined\n ? await this.#baseBehind(cwd, git, pullRequest.baseBranch)\n : undefined\n return {\n status: 'ready',\n cwd: safeCwd,\n root,\n ...status,\n ...(branch === undefined ? {} : { branch }),\n ...(operation === undefined ? {} : { operation: operation.operation }),\n worktree: normalizedPath(gitDir) !== normalizedPath(commonDir),\n ...(remote === undefined ? {} : { remote }),\n ...(pullRequest === undefined ? {} : { pullRequest }),\n ...(diff === undefined ? {} : { diff }),\n ...(baseBehind === undefined ? {} : { baseBehind }),\n }\n } catch {\n return { status: 'unavailable', cwd: safeCwd }\n }\n }\n\n async #baseBehind(cwd: string, git: string, baseBranch: string): Promise<number | undefined> {\n try {\n const result = await run(this.#runtime, git, ['rev-list', '--count', `HEAD..refs/remotes/origin/${baseBranch}`, '--'], cwd, GIT_TIMEOUT_MS)\n if (result.exitCode !== 0 || result.lossy) return undefined\n const count = Number(bounded(result.stdout))\n return Number.isSafeInteger(count) && count >= 0 ? count : undefined\n } catch {\n return undefined\n }\n }\n\n async #mergeBase(cwd: string, git: string, baseBranch: string): Promise<string | undefined> {\n try {\n const result = await run(this.#runtime, git, ['merge-base', 'HEAD', `refs/remotes/origin/${baseBranch}`], cwd, GIT_TIMEOUT_MS)\n if (result.exitCode !== 0 || result.lossy) return undefined\n const oid = bounded(result.stdout)\n return /^[0-9a-f]{40}$/iu.test(oid) ? oid : undefined\n } catch {\n return undefined\n }\n }\n\n async #diff(cwd: string, git: string, base: string, signal?: AbortSignal): Promise<RepositoryDiffStatus | undefined> {\n try {\n const numstat = await run(this.#runtime, git, ['diff', '--no-ext-diff', '--numstat', base, '--'], cwd, GIT_TIMEOUT_MS)\n if (numstat.exitCode !== 0 || numstat.lossy) return undefined\n const summary = parseDiffNumstat(numstat.stdout)\n const patch = await run(this.#runtime, git, [...await diffFuncnameArgs(), 'diff', '--no-ext-diff', '--no-color', '--unified=3', base, '--'], cwd, GIT_TIMEOUT_MS, MAX_DIFF_BYTES)\n if (patch.exitCode !== 0) return { ...summary, truncated: true }\n const untracked = await this.#untrackedDiff(cwd, git, signal)\n const combinedPatch = `${patch.stdout}${untracked.patch}`\n return {\n additions: summary.additions + untracked.additions,\n deletions: summary.deletions,\n files: summary.files + untracked.files,\n ...(patch.lossy ? {} : { patch: combinedPatch.slice(0, MAX_DIFF_BYTES) }),\n truncated: patch.lossy || untracked.truncated || combinedPatch.length > MAX_DIFF_BYTES,\n }\n } catch {\n return undefined\n }\n }\n\n async #untrackedDiff(cwd: string, git: string, signal?: AbortSignal): Promise<{ additions: number; files: number; patch: string; truncated: boolean }> {\n const listed = await run(this.#runtime, git, ['ls-files', '--others', '--exclude-standard', '-z'], cwd, GIT_TIMEOUT_MS)\n if (listed.exitCode !== 0 || listed.lossy) return { additions: 0, files: 0, patch: '', truncated: listed.lossy }\n const paths = listed.stdout.split('\\0').filter(path => path.length > 0)\n let additions = 0\n let patch = ''\n let truncated = paths.length > MAX_UNTRACKED_DIFFS\n for (const path of paths.slice(0, MAX_UNTRACKED_DIFFS)) {\n // The caller is gone or the route budget elapsed: stop spawning.\n if (signal?.aborted === true) return { additions, files: paths.length, patch, truncated: true }\n const result = await run(this.#runtime, git, [\n 'diff', '--no-ext-diff', '--no-color', '--unified=3', '--numstat', '--patch', '--no-index', '--', '/dev/null', path,\n ], cwd, GIT_TIMEOUT_MS, MAX_DIFF_BYTES)\n if (result.exitCode !== 0 && result.exitCode !== 1) {\n truncated = true\n continue\n }\n const start = result.stdout.indexOf('diff --git ')\n additions += parseDiffNumstat(start >= 0 ? result.stdout.slice(0, start) : result.stdout).additions\n if (result.lossy) truncated = true\n else if (start >= 0) patch += result.stdout.slice(start)\n }\n return { additions, files: paths.length, patch, truncated }\n }\n\n async #pullRequest(cwd: string, repository: string, branch: string): Promise<RepositoryPullRequestStatus | undefined> {\n const gh = await this.#gh()\n if (gh === undefined) return undefined\n try {\n const result = await run(this.#runtime, gh, [\n 'pr', 'view', branch,\n '--repo', repository,\n '--json', 'number,title,url,state,isDraft,reviewDecision,mergeStateStatus,mergedAt,statusCheckRollup,author,createdAt,baseRefName',\n ], cwd, GH_TIMEOUT_MS)\n if (result.exitCode !== 0) return undefined\n return parsePullRequest(JSON.parse(result.stdout))\n } catch {\n return undefined\n }\n }\n}\n","/** Name a generated worktree branch after what the user is about to ask for.\n *\n * The composer draft is the only description of the work that exists before\n * the session starts, and it is usually not English and never branch-safe, so\n * a throwaway Haiku turn compresses it into a slug. Naming is a nicety: every\n * failure here returns `undefined` and the caller keeps its timestamped name. */\nimport { query as claudeQuery, type Options as ClaudeOptions, type Query } from '@anthropic-ai/claude-agent-sdk'\n\n/** Cheapest model that can translate and compress a sentence. */\nexport const BRANCH_SUMMARY_MODEL = 'haiku'\n\n/** A branch name is not worth blocking worktree creation on for long. */\nexport const BRANCH_SUMMARY_TIMEOUT_MS = 15_000\n\nconst MAX_INTENT_CHARS = 2_000\n/** A compliant reply is one short fragment; anything longer is prose. */\nconst MAX_REPLY_CHARS = 80\n/** More words than this is a sentence, not the fragment we asked for. */\nconst MAX_SLUG_WORDS = 6\nconst MAX_SLUG_CHARS = 48\n\nexport function branchSummaryPrompt(intent: string): string {\n return [\n 'Summarize this software task as a Git branch name fragment.',\n 'Reply with 2-5 lowercase English words joined by hyphens and nothing else:',\n 'no quotes, no slashes, no prefix, no punctuation, no explanation.',\n 'Translate the task to English if it is written in another language.',\n '',\n 'Task:',\n `\"\"\"\\n${intent.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`,\n ].join('\\n')\n}\n\n/** Branch-safe slug for a model reply, or `undefined` when the reply is not\n * the fragment we asked for. Mangling a refusal or a paragraph into a slug\n * would produce a worse name than the timestamped fallback. */\nexport function branchSlug(reply: string): string | undefined {\n const line = reply.trim()\n if (line.length === 0 || line.length > MAX_REPLY_CHARS || /[\\r\\n]/u.test(line)) return undefined\n const words = line.toLocaleLowerCase('en-US')\n .replace(/[^a-z0-9]+/gu, '-')\n .split('-')\n .filter(word => word.length > 0)\n if (words.length === 0 || words.length > MAX_SLUG_WORDS) return undefined\n // ponytail: a long fragment is cut mid-word; six short words almost never\n // reach 48 characters, and a branch name is allowed to be blunt.\n const slug = words.join('-').slice(0, MAX_SLUG_CHARS).replace(/-+$/u, '')\n return slug.length === 0 ? undefined : slug\n}\n\n/** First free name in `<candidate>`, `<candidate>-2`, `<candidate>-3`, … */\nexport function uniqueBranchName(candidate: string, taken: readonly string[]): string {\n const existing = new Set(taken)\n if (!existing.has(candidate)) return candidate\n for (let index = 2; index < 100; index += 1) {\n const name = `${candidate}-${index}`\n if (!existing.has(name)) return name\n }\n return candidate\n}\n\n/** Compress a composer draft into a branch slug with a throwaway Claude turn.\n *\n * Deliberately NOT routed through the supervisor, for the same reasons as the\n * plan-usage probe: there is no session to borrow yet. The turn is isolated\n * from filesystem settings as well, because a CLAUDE.md instruction (\"always\n * reply in the user's language\") turns the answer into an unusable slug. */\nexport async function summarizeBranchSlug(\n executablePath: string,\n intent: string,\n factory: (params: { prompt: string; options: ClaudeOptions }) => Query = claudeQuery,\n): Promise<string | undefined> {\n const task = intent.trim().slice(0, MAX_INTENT_CHARS)\n if (task.length === 0) return undefined\n const lifetime = new AbortController()\n const timer = setTimeout(() => lifetime.abort(), BRANCH_SUMMARY_TIMEOUT_MS)\n timer.unref?.()\n try {\n const query = factory({\n prompt: branchSummaryPrompt(task),\n options: {\n cwd: process.cwd(),\n abortController: lifetime,\n model: BRANCH_SUMMARY_MODEL,\n allowedTools: [],\n settingSources: [],\n maxTurns: 1,\n ...(executablePath.length === 0 ? {} : { pathToClaudeCodeExecutable: executablePath }),\n },\n })\n for await (const message of query) {\n if (message.type === 'result' && message.subtype === 'success') return branchSlug(message.result)\n }\n return undefined\n } catch {\n return undefined\n } finally {\n clearTimeout(timer)\n lifetime.abort()\n }\n}\n","import { randomUUID } from 'node:crypto'\nimport { mkdir, readdir, readFile, rename, rm, stat, writeFile } from 'node:fs/promises'\nimport { basename, isAbsolute, join, resolve } from 'node:path'\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { uniqueBranchName } from './branch-name.ts'\n\nconst MAX_OUTPUT_BYTES = 128 * 1024\nconst GIT_TIMEOUT_MS = 10_000\nconst GIT_FETCH_TIMEOUT_MS = 60_000\nconst MAX_PATH_CHARS = 4_096\nconst MAX_BRANCH_CHARS = 512\nconst LEASE_SCHEMA_VERSION = 1\n// ponytail: grace only needs to outlive the worktree-create -> workspace-register\n// hop (seconds); two minutes keeps deletion feeling prompt while staying safe.\nconst CLEANUP_GRACE_MS = 2 * 60_000\n\ntype RepositorySetupRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n\ninterface CommandResult {\n readonly exitCode: number | null\n readonly stdout: string\n readonly stderr: string\n readonly lossy: boolean\n}\n\nexport interface RepositoryBranchList {\n readonly root: string\n readonly current?: string\n readonly dirty: boolean\n readonly branches: readonly string[]\n readonly remoteBranches: readonly string[]\n}\n\nexport type RepositorySetupStage = 'inspecting' | 'fetching' | 'summarizing' | 'creating-worktree' | 'saving-worktree' | 'switching-branch'\nexport type RepositorySetupProgress = (stage: RepositorySetupStage) => void\n\nexport interface RepositorySetupResult {\n readonly mode: 'checkout' | 'worktree'\n readonly root: string\n readonly path: string\n readonly branch: string\n readonly leaseId?: string\n}\n\nexport interface RepositoryCleanupResult {\n readonly mode: 'checkout' | 'worktree'\n readonly root: string\n readonly branch: string\n}\n\ninterface WorktreeLease {\n readonly id: string\n readonly root: string\n readonly path: string\n readonly branch: string\n readonly createdAt: string\n readonly pluginGeneratedBranch: boolean\n readonly sessionId?: string\n}\n\ninterface LeaseDocument {\n readonly schemaVersion: typeof LEASE_SCHEMA_VERSION\n readonly leases: readonly WorktreeLease[]\n}\n\nexport interface RepositorySetupServiceOptions {\n readonly leasePath?: string\n readonly worktreeRoot?: string\n readonly branchPrefix?: () => Promise<string>\n readonly cleanupGraceMs?: number\n /** Compress the composer draft into a branch slug; `undefined` result (or an\n * omitted option) falls back to the timestamped name. */\n readonly summarizeBranch?: (intent: string) => Promise<string | undefined>\n}\n\nexport class RepositorySetupError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'RepositorySetupError'\n this.code = code\n }\n}\n\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\n const outcome = await handle.done\n const stdout = handle.collected.stdout?.readFrom(0)\n const stderr = handle.collected.stderr?.readFrom(0)\n return {\n exitCode: outcome.exitCode,\n stdout: stdout?.text ?? '',\n stderr: stderr?.text ?? '',\n lossy: stdout?.lossy === true || stderr?.lossy === true,\n }\n}\n\nfunction safePath(value: string): string {\n if (value.length === 0 || value.length > MAX_PATH_CHARS || !isAbsolute(value) || value.includes('\\0')) {\n throw new RepositorySetupError('invalid-path', 'The workspace path is invalid.')\n }\n return resolve(value)\n}\n\nfunction safeBranch(value: string): string {\n if (value.length === 0 || value.length > MAX_BRANCH_CHARS || value.trim() !== value || /[\\0\\r\\n]/u.test(value)) {\n throw new RepositorySetupError('invalid-branch', 'The branch name is invalid.')\n }\n return value\n}\n\nfunction parseCurrentBranch(value: string): string | undefined {\n const branch = value.trim()\n return branch.length === 0 || branch === 'HEAD' ? undefined : branch\n}\n\nexport function parseWorktreeBranches(value: string): ReadonlyMap<string, string> {\n const occupied = new Map<string, string>()\n let path: string | undefined\n for (const line of `${value}\\n`.split(/\\r?\\n/u)) {\n if (line.startsWith('worktree ')) path = line.slice('worktree '.length)\n else if (line.startsWith('branch refs/heads/') && path !== undefined) {\n occupied.set(line.slice('branch refs/heads/'.length), path)\n } else if (line.length === 0) path = undefined\n }\n return occupied\n}\n\nfunction slug(value: string, fallback: string): string {\n const normalized = value.toLocaleLowerCase('en-US').replace(/[^a-z0-9._-]+/gu, '-').replace(/^-+|-+$/gu, '')\n return normalized.slice(0, 48) || fallback\n}\n\n/** A branch name as one path segment: `/` and anything else unsafe folds to\n * `-`, case is kept so a ticket key stays scannable (`PSOS-5683`, not\n * `psos-5683`). Flattened rather than nested on purpose -- see\n * {@link worktreeDirectoryName}. */\nfunction branchSegment(branch: string): string {\n const flattened = branch.replace(/[^A-Za-z0-9._-]+/gu, '-').replace(/^[-.]+/u, '').replace(/-+$/u, '')\n return flattened.slice(0, 48).replace(/-+$/u, '') || 'branch'\n}\n\n/** Name a worktree directory after the repository and the branch it holds, so\n * the workspace list reads without opening a session.\n *\n * One flat segment, never a `feature/x` subdirectory: the orphan sweep lists\n * this root one level deep, and a prefix directory holds no lease of its own,\n * so it would be removed along with every live worktree inside it. */\nexport function worktreeDirectoryName(root: string, branch: string): string {\n return `${slug(basename(root), 'repository')}-${branchSegment(branch)}`\n}\n\n/** Comparable form for path identity: resolved, forward slashes, case-folded\n * so Windows drive-letter or case spelling differences cannot hide a match. */\nexport function comparablePath(value: string): string {\n return resolve(value).replaceAll('\\\\', '/').toLocaleLowerCase('en-US')\n}\n\nfunction pathExists(value: string): Promise<boolean> {\n return stat(value).then(() => true, () => false)\n}\n\nfunction lease(value: unknown): WorktreeLease | undefined {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined\n const input = value as Record<string, unknown>\n if (typeof input.id !== 'string' || typeof input.root !== 'string' || typeof input.path !== 'string'\n || typeof input.branch !== 'string' || typeof input.createdAt !== 'string'\n || (input.pluginGeneratedBranch !== undefined && typeof input.pluginGeneratedBranch !== 'boolean')\n || (input.sessionId !== undefined && typeof input.sessionId !== 'string')) return undefined\n return {\n id: input.id,\n root: input.root,\n path: input.path,\n branch: input.branch,\n createdAt: input.createdAt,\n pluginGeneratedBranch: input.pluginGeneratedBranch === true,\n ...(input.sessionId === undefined ? {} : { sessionId: input.sessionId }),\n }\n}\n\nexport class RepositorySetupService {\n readonly #runtime: RepositorySetupRuntime\n readonly #leasePath: string\n readonly #worktreeRoot: string\n readonly #branchPrefix: () => Promise<string>\n readonly #summarizeBranch: (intent: string) => Promise<string | undefined>\n readonly #cleanupGraceMs: number\n #gitPath: Promise<string> | undefined\n #pending: Promise<unknown> = Promise.resolve()\n\n constructor(runtime: RepositorySetupRuntime, options: RepositorySetupServiceOptions = {}) {\n this.#runtime = runtime\n this.#leasePath = options.leasePath ?? dshHomePath('plugins', 'dsh-claude', 'worktrees.json')\n this.#worktreeRoot = options.worktreeRoot ?? dshHomePath('plugins', 'dsh-claude', 'worktrees')\n this.#branchPrefix = options.branchPrefix ?? (async () => 'claude')\n this.#summarizeBranch = options.summarizeBranch ?? (async () => undefined)\n this.#cleanupGraceMs = options.cleanupGraceMs ?? CLEANUP_GRACE_MS\n }\n\n async listBranches(cwd: string): Promise<RepositoryBranchList> {\n const git = await this.#git()\n return this.#listBranches(git, await this.#repositoryRoot(git, safePath(cwd)))\n }\n\n /** Refresh remote-tracking refs before listing: a branch pushed after this\n * checkout last fetched has no local ref, so the picker cannot offer it. */\n async refreshBranches(cwd: string): Promise<RepositoryBranchList> {\n const git = await this.#git()\n const root = await this.#repositoryRoot(git, safePath(cwd))\n await this.#fetchRemotes(git, root)\n return this.#listBranches(git, root)\n }\n\n async #listBranches(git: string, root: string): Promise<RepositoryBranchList> {\n const [status, refs, remoteRefs] = await Promise.all([\n this.#run(git, ['status', '--porcelain=v2', '--branch', '--untracked-files=normal'], root),\n this.#run(git, ['for-each-ref', '--format=%(refname:short)', 'refs/heads'], root),\n this.#run(git, ['for-each-ref', '--format=%(refname:short) %(symref)', 'refs/remotes'], root),\n ])\n if (status.exitCode !== 0 || status.lossy || refs.exitCode !== 0 || refs.lossy\n || remoteRefs.exitCode !== 0 || remoteRefs.lossy) {\n throw new RepositorySetupError('repository-unavailable', 'The repository state is unavailable.')\n }\n const current = status.stdout.split(/\\r?\\n/u)\n .find(line => line.startsWith('# branch.head '))\n ?.slice('# branch.head '.length)\n const branches = refs.stdout.split(/\\r?\\n/u).filter(Boolean).sort((left, right) => left.localeCompare(right))\n const remoteBranches = remoteRefs.stdout.split(/\\r?\\n/u)\n .map(line => line.trim().split(/\\s+/u))\n .filter(parts => parts[0] !== undefined && parts[0].length > 0 && parts.length === 1)\n .map(parts => parts[0]!)\n .sort((left, right) => left.localeCompare(right))\n const currentBranch = current === undefined ? undefined : parseCurrentBranch(current)\n return {\n root,\n ...(currentBranch === undefined ? {} : { current: currentBranch }),\n dirty: status.stdout.split(/\\r?\\n/u).some(line => line.length > 0 && !line.startsWith('# ')),\n branches,\n remoteBranches,\n }\n }\n\n async setup(\n cwd: string,\n branchValue: string,\n useWorktree: boolean,\n explicitBranchName?: string,\n progress: RepositorySetupProgress = () => {},\n intent?: string,\n ): Promise<RepositorySetupResult> {\n progress('inspecting')\n const branch = safeBranch(branchValue)\n const info = await this.listBranches(cwd)\n const local = info.branches.includes(branch)\n const remote = info.remoteBranches.includes(branch)\n if (!local && !remote) {\n throw new RepositorySetupError('branch-not-found', 'The selected local or remote-tracking branch does not exist.')\n }\n const requestedBranch = explicitBranchName === undefined ? undefined : safeBranch(explicitBranchName)\n if (useWorktree) {\n return this.#createWorktree(\n info,\n branch,\n local ? `refs/heads/${branch}` : `refs/remotes/${branch}`,\n requestedBranch,\n requestedBranch !== undefined && info.branches.includes(requestedBranch),\n progress,\n intent,\n )\n }\n progress('switching-branch')\n return !local && remote ? this.#checkoutRemote(info, branch) : this.#checkout(info, branch)\n }\n\n /** Tear down a merged branch: remove a plugin worktree (and its lease and\n * branch), or switch a plain checkout back to the base branch and delete\n * the merged branch. Refuses dirty trees. */\n async cleanupMerged(pathValue: string, baseBranch: string): Promise<RepositoryCleanupResult> {\n const path = safePath(pathValue)\n const base = safeBranch(baseBranch)\n const git = await this.#git()\n const status = await this.#run(git, ['status', '--porcelain=v1', '--untracked-files=normal'], path)\n if (status.exitCode !== 0 || status.lossy) throw new RepositorySetupError('repository-unavailable', 'The repository state is unavailable.')\n if (status.stdout.trim().length > 0) throw new RepositorySetupError('dirty-workspace', 'Commit or stash workspace changes before cleaning up.')\n const lease = (await this.#readLeases()).find(item => comparablePath(item.path) === comparablePath(path))\n if (lease !== undefined) {\n return this.#serialize(async () => {\n const removed = await this.#run(git, ['worktree', 'remove', '--', lease.path], lease.root)\n if (removed.exitCode !== 0) throw new RepositorySetupError('worktree-remove-failed', 'Git could not remove the worktree.')\n await this.#run(git, ['branch', '-D', '--', lease.branch], lease.root).catch(() => undefined)\n const current = await this.#readLeases()\n await this.#writeLeases(current.filter(item => item.id !== lease.id))\n return { mode: 'worktree' as const, root: lease.root, branch: lease.branch }\n })\n }\n const root = await this.#repositoryRoot(git, path)\n const head = await this.#run(git, ['symbolic-ref', '--quiet', '--short', 'HEAD'], root)\n const branch = head.exitCode === 0 ? head.stdout.trim() : ''\n if (branch.length === 0 || branch === base) throw new RepositorySetupError('nothing-to-clean', 'The checkout is already on the base branch.')\n const switched = await this.#run(git, ['switch', '--', base], root)\n if (switched.exitCode !== 0) throw new RepositorySetupError('checkout-failed', 'Git could not switch to the base branch.')\n await this.#run(git, ['branch', '-D', '--', branch], root).catch(() => undefined)\n await this.#run(git, ['pull', '--ff-only'], root, GIT_FETCH_TIMEOUT_MS).catch(() => undefined)\n return { mode: 'checkout', root, branch }\n }\n\n bindLease(leaseId: string, sessionId: string): Promise<void> {\n if (leaseId.length === 0 || leaseId.length > 128 || sessionId.length === 0 || sessionId.length > 1_024) {\n return Promise.reject(new RepositorySetupError('invalid-lease', 'The worktree lease is invalid.'))\n }\n return this.#serialize(async () => {\n const leases = await this.#readLeases()\n const index = leases.findIndex(item => item.id === leaseId)\n if (index < 0) throw new RepositorySetupError('lease-not-found', 'The worktree lease no longer exists.')\n const existing = leases[index]\n if (existing === undefined) throw new RepositorySetupError('lease-not-found', 'The worktree lease no longer exists.')\n leases[index] = { ...existing, sessionId }\n await this.#writeLeases(leases)\n })\n }\n\n /** Reconcile leases against the set of directories still referenced by a\n * workspace. Deleting a workspace is the user saying they are done with it,\n * so an unreferenced worktree goes even with uncommitted changes; its\n * sessions are archived first, through `archiveSessions`, or the Host\n * rebuilds the deleted workspace from their headers on the next boot.\n * Fresh leases are retained for a grace period so a worktree created\n * moments ago cannot be swept before its workspace registration lands.\n *\n * Every command runs from the repository root, never from the worktree\n * being removed: spawning in a directory that is already gone throws\n * ENOENT, which used to strand the lease forever. */\n cleanupOrphans(\n activePaths: readonly string[],\n archiveSessions?: (worktreePath: string) => Promise<void>,\n ): Promise<void> {\n const active = new Set(activePaths.map(comparablePath))\n return this.#serialize(async () => {\n const leases = await this.#readLeases()\n const retained: WorktreeLease[] = []\n let changed = false\n const git = await this.#git()\n const now = Date.now()\n for (const item of leases) {\n const age = now - Date.parse(item.createdAt)\n if (active.has(comparablePath(item.path)) || !(age >= this.#cleanupGraceMs)) {\n retained.push(item)\n continue\n }\n try {\n // Best effort: a Host that cannot archive must not strand the lease,\n // and the worktree removal below is what the user asked for.\n await archiveSessions?.(item.path).catch(() => undefined)\n if (await pathExists(item.path)) {\n const removed = await this.#run(git, ['worktree', 'remove', '--force', '--', item.path], item.root)\n if (removed.exitCode !== 0) {\n retained.push(item)\n continue\n }\n } else {\n // The directory is already gone; let Git forget the stale\n // worktree registration before the lease follows it.\n await this.#run(git, ['worktree', 'prune'], item.root).catch(() => undefined)\n }\n if (item.pluginGeneratedBranch) {\n await this.#run(git, ['branch', '-D', '--', item.branch], item.root).catch(() => undefined)\n }\n changed = true\n } catch {\n if (await pathExists(item.root)) retained.push(item)\n else changed = true // the repository itself is gone; the lease is dead weight\n }\n }\n if (changed) await this.#writeLeases(retained)\n await this.#removeUnleasedDirectories(retained, active, now, archiveSessions)\n })\n }\n\n /** Remove directories under the plugin's own worktree root that no lease and\n * no workspace claims. A lease file lost to a crash, or a worktree whose\n * lease write failed, otherwise leaves a directory nothing will ever sweep.\n * The grace period covers the gap between `worktree add` and the lease\n * write, so a worktree being created right now is never taken. */\n async #removeUnleasedDirectories(\n retained: readonly WorktreeLease[],\n active: ReadonlySet<string>,\n now: number,\n archiveSessions?: (worktreePath: string) => Promise<void>,\n ): Promise<void> {\n const leased = new Set(retained.map(item => comparablePath(item.path)))\n let entries: string[]\n try {\n entries = await readdir(this.#worktreeRoot)\n } catch {\n return // no worktree root yet, or it is unreadable; nothing to sweep\n }\n for (const entry of entries) {\n const path = join(this.#worktreeRoot, entry)\n const key = comparablePath(path)\n if (leased.has(key) || active.has(key)) continue\n try {\n const info = await stat(path)\n if (!info.isDirectory()) continue\n const created = info.birthtimeMs > 0 ? info.birthtimeMs : info.mtimeMs\n // Date.now() truncates to whole milliseconds while birthtime carries a\n // fraction, so a directory created moments ago can read as newer than\n // the clock; clamp rather than let that skip a sweep.\n if (Math.max(0, now - created) < this.#cleanupGraceMs) continue\n // A lost lease is still the user's deleted workspace: its sessions\n // have to be archived here too, or the Host rebuilds the workspace\n // from their headers on the next boot.\n await archiveSessions?.(path).catch(() => undefined)\n await rm(path, { recursive: true, force: true })\n } catch {\n // A directory that vanished under us, or one we may not remove; the\n // next pass sees it again.\n }\n }\n }\n\n async #checkoutRemote(info: RepositoryBranchList, remoteBranch: string): Promise<RepositorySetupResult> {\n const separator = remoteBranch.indexOf('/')\n if (separator <= 0 || separator === remoteBranch.length - 1) {\n throw new RepositorySetupError('invalid-branch', 'The remote-tracking branch name is invalid.')\n }\n const localBranch = safeBranch(remoteBranch.slice(separator + 1))\n if (info.branches.includes(localBranch)) {\n const git = await this.#git()\n const upstream = await this.#run(git, ['for-each-ref', '--format=%(upstream:short)', `refs/heads/${localBranch}`], info.root)\n if (upstream.exitCode !== 0 || upstream.lossy) {\n throw new RepositorySetupError('repository-unavailable', 'The local branch tracking state is unavailable.')\n }\n if (upstream.stdout.trim() !== remoteBranch) {\n throw new RepositorySetupError('branch-tracking-conflict', `The local branch ${localBranch} does not track ${remoteBranch}.`)\n }\n return this.#checkout(info, localBranch)\n }\n if (info.dirty) throw new RepositorySetupError('dirty-workspace', 'Commit or stash workspace changes before switching branches.')\n const git = await this.#git()\n const switched = await this.#run(git, ['switch', '--track', '-c', localBranch, `refs/remotes/${remoteBranch}`], info.root)\n if (switched.exitCode !== 0) throw new RepositorySetupError('checkout-failed', 'Git could not create the local tracking branch.')\n return { mode: 'checkout', root: info.root, path: info.root, branch: localBranch }\n }\n\n async #fetchRemotes(git: string, root: string): Promise<void> {\n const fetched = await this.#run(\n git,\n ['-c', 'credential.interactive=never', 'fetch', '--all', '--prune'],\n root,\n GIT_FETCH_TIMEOUT_MS,\n )\n if (fetched.exitCode !== 0 || fetched.lossy) {\n throw new RepositorySetupError('fetch-failed', 'Git could not refresh remote references.')\n }\n }\n\n /** The remote-tracking ref a local base branch follows, when that ref still\n * exists. Falls back to the local branch for a branch with no upstream. */\n async #upstreamRef(git: string, info: RepositoryBranchList, branch: string): Promise<string | undefined> {\n const upstream = await this.#run(git, ['for-each-ref', '--format=%(upstream:short)', `refs/heads/${branch}`], info.root)\n if (upstream.exitCode !== 0 || upstream.lossy) return undefined\n const name = upstream.stdout.trim()\n return name.length > 0 && info.remoteBranches.includes(name) ? `refs/remotes/${name}` : undefined\n }\n\n async #checkout(info: RepositoryBranchList, branch: string): Promise<RepositorySetupResult> {\n if (info.current !== branch) {\n if (info.dirty) throw new RepositorySetupError('dirty-workspace', 'Commit or stash workspace changes before switching branches.')\n const git = await this.#git()\n const worktrees = await this.#run(git, ['worktree', 'list', '--porcelain'], info.root)\n if (worktrees.exitCode !== 0 || worktrees.lossy) throw new RepositorySetupError('repository-unavailable', 'Worktree state is unavailable.')\n const occupiedPath = parseWorktreeBranches(worktrees.stdout).get(branch)\n if (occupiedPath !== undefined && resolve(occupiedPath) !== info.root) {\n throw new RepositorySetupError('branch-occupied', 'The selected branch is already checked out in another worktree.')\n }\n const switched = await this.#run(git, ['switch', '--', branch], info.root)\n if (switched.exitCode !== 0) throw new RepositorySetupError('checkout-failed', 'Git could not switch to the selected branch.')\n }\n return { mode: 'checkout', root: info.root, path: info.root, branch }\n }\n\n async #createWorktree(\n info: RepositoryBranchList,\n baseBranch: string,\n baseRef: string,\n explicitBranchName: string | undefined,\n reuseExistingBranch: boolean,\n progress: RepositorySetupProgress,\n intent: string | undefined,\n ): Promise<RepositorySetupResult> {\n const { root } = info\n const git = await this.#git()\n progress('fetching')\n await this.#fetchRemotes(git, root)\n // A fresh worktree is meant to start from the remote tip the fetch just\n // refreshed, not from whatever the local base branch last pulled.\n const startRef = reuseExistingBranch ? baseRef : (await this.#upstreamRef(git, info, baseBranch)) ?? baseRef\n const suffix = randomUUID().slice(0, 8)\n const stamp = new Date().toISOString().replace(/[-:]/gu, '').replace(/\\.\\d{3}Z$/u, 'Z')\n const branch = explicitBranchName ?? await this.#generatedBranch(info, baseBranch, intent, stamp, suffix, progress)\n const path = join(this.#worktreeRoot, await this.#freeDirectoryName(root, branch))\n progress('creating-worktree')\n await mkdir(this.#worktreeRoot, { recursive: true })\n // A stale registration from a deleted worktree directory would keep the\n // existing branch \"checked out\" and block reusing it.\n if (reuseExistingBranch) await this.#run(git, ['worktree', 'prune'], root).catch(() => undefined)\n const created = await this.#run(\n git,\n reuseExistingBranch ? ['worktree', 'add', '--', path, branch] : ['worktree', 'add', '-b', branch, path, startRef],\n root,\n )\n if (created.exitCode !== 0) {\n const detail = created.stderr.split(/\\r?\\n/u).map(line => line.trim()).filter(line => line.length > 0).at(-1)\n throw new RepositorySetupError('worktree-failed', detail === undefined ? 'Git could not create the worktree.' : `Git could not create the worktree: ${detail}`)\n }\n const item: WorktreeLease = {\n id: randomUUID(),\n root,\n path,\n branch,\n createdAt: new Date().toISOString(),\n pluginGeneratedBranch: explicitBranchName === undefined,\n }\n progress('saving-worktree')\n try {\n await this.#serialize(async () => {\n const leases = await this.#readLeases()\n await this.#writeLeases([...leases, item])\n })\n } catch (error) {\n await this.#run(git, ['worktree', 'remove', '--force', '--', path], root).catch(() => undefined)\n if (!reuseExistingBranch) await this.#run(git, ['branch', '-D', '--', branch], root).catch(() => undefined)\n throw error\n }\n return { mode: 'worktree', root, path, branch, leaseId: item.id }\n }\n\n /** `<prefix>/<what the draft is about>`, falling back to\n * `<prefix>/<base branch>-<stamp>-<random>` whenever the summary is missing\n * or unusable. The prefix and the fallback shape are unchanged. */\n /** The branch-named directory, or the first `-2`, `-3`, ... spelling free of\n * anything already on disk. Names no longer carry a timestamp, so a stale\n * directory a crash left behind -- or two branches that fold to the same\n * segment -- would otherwise fail `worktree add` outright. Compared\n * case-folded, since a case-insensitive filesystem would collide anyway. */\n async #freeDirectoryName(root: string, branch: string): Promise<string> {\n const base = worktreeDirectoryName(root, branch)\n const taken = await readdir(this.#worktreeRoot).then(\n entries => new Set(entries.map(entry => entry.toLocaleLowerCase('en-US'))),\n () => new Set<string>(),\n )\n if (!taken.has(base.toLocaleLowerCase('en-US'))) return base\n for (let index = 2; index < 100; index += 1) {\n const candidate = `${base}-${index}`\n if (!taken.has(candidate.toLocaleLowerCase('en-US'))) return candidate\n }\n return base\n }\n\n async #generatedBranch(\n info: RepositoryBranchList,\n baseBranch: string,\n intent: string | undefined,\n stamp: string,\n suffix: string,\n progress: RepositorySetupProgress,\n ): Promise<string> {\n const prefix = safeBranch(await this.#branchPrefix())\n if (intent !== undefined && intent.trim().length > 0) {\n progress('summarizing')\n // The summary is a convenience, never a reason to fail the worktree.\n const summary = await this.#summarizeBranch(intent).catch(() => undefined)\n if (summary !== undefined) return uniqueBranchName(`${prefix}/${summary}`, info.branches)\n }\n return `${prefix}/${slug(baseBranch, 'branch')}-${stamp}-${suffix}`\n }\n\n async #repositoryRoot(git: string, cwd: string): Promise<string> {\n const result = await this.#run(git, ['rev-parse', '--path-format=absolute', '--show-toplevel'], cwd)\n const root = result.stdout.trim()\n if (result.exitCode !== 0 || result.lossy || root.length === 0 || !isAbsolute(root)) {\n throw new RepositorySetupError('not-repository', 'The workspace is not a Git repository.')\n }\n return resolve(root)\n }\n\n #git(): Promise<string> {\n // A cached pending or rejected lookup would wedge every later request, so\n // bound it and drop the cache on failure.\n this.#gitPath ??= this.#runtime.resolveExecutable('git', undefined, AbortSignal.timeout(GIT_TIMEOUT_MS))\n .catch((error: unknown) => {\n this.#gitPath = undefined\n throw error\n })\n return this.#gitPath\n }\n\n\n async #run(executable: string, args: readonly string[], cwd: string, timeoutMs = GIT_TIMEOUT_MS): Promise<CommandResult> {\n return collect(this.#runtime.spawn({\n argv: [executable, ...args],\n cwd,\n stdio: {\n stdin: 'ignore',\n stdout: { maxBytes: MAX_OUTPUT_BYTES },\n stderr: { maxBytes: MAX_OUTPUT_BYTES },\n },\n graceMs: 1_000,\n signal: AbortSignal.timeout(timeoutMs),\n env: {},\n }))\n }\n\n async #readLeases(): Promise<WorktreeLease[]> {\n try {\n const parsed = JSON.parse(await readFile(this.#leasePath, 'utf8')) as unknown\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return []\n const input = parsed as Record<string, unknown>\n if (input.schemaVersion !== LEASE_SCHEMA_VERSION || !Array.isArray(input.leases)) return []\n return input.leases.map(lease).filter((item): item is WorktreeLease => item !== undefined)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return []\n throw error\n }\n }\n\n async #writeLeases(leases: readonly WorktreeLease[]): Promise<void> {\n await mkdir(resolve(this.#leasePath, '..'), { recursive: true })\n const temporary = `${this.#leasePath}.${process.pid}.${randomUUID()}.tmp`\n const document: LeaseDocument = { schemaVersion: LEASE_SCHEMA_VERSION, leases }\n try {\n await writeFile(temporary, `${JSON.stringify(document, null, 2)}\\n`, { mode: 0o600 })\n await rename(temporary, this.#leasePath)\n } finally {\n await rm(temporary, { force: true }).catch(() => undefined)\n }\n }\n\n #serialize<T>(operation: () => Promise<T>): Promise<T> {\n const result = this.#pending.then(operation, operation)\n this.#pending = result.then(() => undefined, () => undefined)\n return result\n }\n}\n","import { createHash } from 'node:crypto'\nimport { basename } from 'node:path'\nimport type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { diffFuncnameArgs } from './diff-funcname.ts'\nimport { detectRepositoryOperation } from './repository-status.ts'\n\nconst MAX_OUTPUT_BYTES = 256 * 1024\nconst MAX_PATCH_CHARS = 64 * 1024\nconst MAX_MESSAGE_CHARS = 512\nconst MAX_PR_TEXT_CHARS = 8 * 1024\nconst MAX_UNPUSHED_COMMITS = 20\nconst GIT_TIMEOUT_MS = 15_000\nconst REMOTE_TIMEOUT_MS = 60_000\nconst GENERATE_TIMEOUT_MS = 60_000\n/** One cold `claude -p` per generation, so everything the subject line cannot\n * use is cost: MCP servers (which `ask` already skips for the same reason,\n * and which stall for as long as an unreachable one takes to give up) and the\n * user's own hooks and settings. Project settings stay: a repository's commit\n * conventions belong in the message. `--tools ''` keeps `--output-format`\n * between it and the prompt -- both flags are variadic. */\nconst GENERATE_ARGUMENTS: readonly string[] = [\n '-p',\n '--strict-mcp-config', '--mcp-config', '{\"mcpServers\":{}}',\n '--setting-sources', 'project,local',\n '--tools', '', '--output-format', 'text',\n]\n\ntype RepositoryActionRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\nexport type RepositoryActionKind = 'commit' | 'commit-push' | 'push' | 'create-pr' | 'merge-pr' | 'update-branch' | 'resolve-continue' | 'resolve-abort'\nexport type RepositoryMergeMethod = 'merge' | 'squash' | 'rebase'\n\ninterface CommandResult {\n readonly exitCode: number | null\n readonly stdout: string\n readonly stderr: string\n readonly lossy: boolean\n}\n\nexport interface RepositoryActionFile {\n readonly path: string\n readonly staged: boolean\n readonly unstaged: boolean\n readonly untracked: boolean\n}\n\nexport interface RepositoryActionCommit {\n readonly hash: string\n readonly subject: string\n}\n\nexport interface RepositoryActionPreview {\n readonly root: string\n readonly branch: string\n readonly head: string\n readonly fingerprint: string\n readonly files: readonly RepositoryActionFile[]\n readonly patch: string\n readonly truncated: boolean\n readonly hasStaged: boolean\n readonly hasUnstaged: boolean\n readonly hasUntracked: boolean\n readonly upstream?: string\n readonly unpushedCommits: readonly RepositoryActionCommit[]\n readonly unpushedTruncated: boolean\n}\n\nexport interface RepositoryActionRequest {\n readonly action: RepositoryActionKind\n readonly fingerprint: string\n readonly message: string\n readonly includeUnstaged: boolean\n readonly prTitle?: string\n readonly prBody?: string\n readonly baseBranch?: string\n readonly draft?: boolean\n readonly mergeMethod?: RepositoryMergeMethod\n /** Merge as a repository administrator, past branch protection (`gh pr merge --admin`). */\n readonly admin?: boolean\n /** Push once `resolve-continue` finishes the operation it resumed. */\n readonly push?: boolean\n}\n\nexport interface RepositoryActionResult {\n readonly commit: string\n readonly pushed: boolean\n readonly pullRequestUrl?: string\n /** Conflicted paths left in the working tree by an update-branch merge or\n * rebase, or by the commit a resumed one stopped on next. */\n readonly conflicts?: readonly string[]\n}\n\nexport class RepositoryActionError extends Error {\n readonly code: string\n readonly commit?: string\n\n constructor(code: string, message: string, commit?: string) {\n super(message)\n this.name = 'RepositoryActionError'\n this.code = code\n if (commit !== undefined) this.commit = commit\n }\n}\n\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\n const outcome = await handle.done\n const stdout = handle.collected.stdout?.readFrom(0)\n const stderr = handle.collected.stderr?.readFrom(0)\n return {\n exitCode: outcome.exitCode,\n stdout: stdout?.text ?? '',\n stderr: stderr?.text ?? '',\n lossy: stdout?.lossy === true || stderr?.lossy === true,\n }\n}\n\nfunction safeText(value: string, maximum: number, label: string): string {\n const text = value.trim()\n if (text.length === 0 || text.length > maximum || /[\\0\\r]/u.test(text)) {\n throw new RepositoryActionError('invalid-request', `${label} is invalid.`)\n }\n return text\n}\n\nexport function isProtectedWarpPath(path: string): boolean {\n return basename(path.replaceAll('\\\\', '/')).toLocaleLowerCase('en-US') === 'warp.md'\n}\n\nexport function parseRepositoryActionStatus(output: string): readonly RepositoryActionFile[] {\n const files = new Map<string, RepositoryActionFile>()\n const records = output.includes('\\0') ? output.split('\\0') : output.split(/\\r?\\n/u)\n for (let position = 0; position < records.length; position += 1) {\n const line = records[position] ?? ''\n if (line.length < 4) continue\n const index = line[0] ?? ' '\n const worktree = line[1] ?? ' '\n let path = line.slice(3)\n const rename = path.lastIndexOf(' -> ')\n if (rename >= 0) path = path.slice(rename + 4)\n if (output.includes('\\0') && (index === 'R' || index === 'C' || worktree === 'R' || worktree === 'C')) position += 1\n if (path.length === 0 || path.includes('\\0') || isProtectedWarpPath(path)) continue\n files.set(path, {\n path,\n staged: index !== ' ' && index !== '?',\n unstaged: worktree !== ' ' && worktree !== '?',\n untracked: index === '?' && worktree === '?',\n })\n }\n return [...files.values()].sort((left, right) => left.path.localeCompare(right.path))\n}\n\nfunction conflictPaths(result: CommandResult): readonly string[] {\n if (result.exitCode !== 0 || result.lossy) return []\n return result.stdout.split(/\\r?\\n/u).filter(line => line.length > 0).slice(0, 100)\n}\n\nfunction fallbackCommitMessage(files: readonly RepositoryActionFile[]): string {\n if (files.length === 1) return `Update ${files[0]?.path ?? 'repository files'}`\n return `Update ${files.length} repository files`\n}\n\nfunction normalizedGeneratedMessage(value: string, fallback: string): string {\n const first = value.split(/\\r?\\n/u).map(line => line.trim()).find(Boolean)\n if (first === undefined) return fallback\n const message = first.replace(/^['\"`]+|['\"`]+$/gu, '').replace(/[\\0\\r\\n]/gu, ' ').trim()\n return message.length === 0 || message.length > 72 ? fallback : message\n}\n\nfunction validPrUrl(value: string): string | undefined {\n try {\n const url = new URL(value.trim())\n return url.protocol === 'https:' && url.hostname === 'github.com' ? url.href : undefined\n } catch {\n return undefined\n }\n}\n\nexport function validPullRequestBody(value: string): boolean {\n const body = value.trim()\n const match = /^Summary:\\s+([^\\r\\n]+)\\r?\\n\\r?\\nChanges:\\s*\\r?\\n([\\s\\S]+)$/u.exec(body)\n const summary = match?.[1]?.trim()\n const changes = match?.[2]?.trim()\n if (summary === undefined || summary.length === 0 || changes === undefined || changes.length === 0) return false\n return !/^#{1,6}\\s|^[A-Za-z][A-Za-z ]+:\\s*$/mu.test(changes)\n}\n\nexport class RepositoryActionService {\n readonly #runtime: RepositoryActionRuntime\n readonly #claudeExecutable: string\n readonly #invalidate: (cwd: string) => void\n #gitExecutable?: Promise<string>\n #ghExecutable?: Promise<string>\n #pending: Promise<unknown> = Promise.resolve()\n\n constructor(runtime: RepositoryActionRuntime, claudeExecutable: string, invalidate: (cwd: string) => void = () => {}) {\n this.#runtime = runtime\n this.#claudeExecutable = claudeExecutable\n this.#invalidate = invalidate\n }\n\n preview(cwd: string): Promise<RepositoryActionPreview> {\n return this.#preview(cwd)\n }\n\n async generateMessage(cwd: string, fingerprint: string): Promise<string> {\n const preview = await this.#preview(cwd)\n if (preview.fingerprint !== fingerprint) throw new RepositoryActionError('repository-changed', 'Repository changes have changed. Refresh the commit panel.')\n const fallback = fallbackCommitMessage(preview.files)\n const prompt = [\n 'Write one concise English git commit subject (imperative mood, maximum 72 characters).',\n 'Return only the subject without quotes, markdown, body, or explanation.',\n `Files: ${preview.files.map(file => file.path).join(', ')}`,\n `Diff:\\n${preview.patch.slice(0, 24 * 1024)}`,\n ].join('\\n')\n try {\n const result = await this.#run(this.#claudeExecutable, GENERATE_ARGUMENTS.concat(prompt), preview.root, GENERATE_TIMEOUT_MS)\n return result.exitCode === 0 && !result.lossy ? normalizedGeneratedMessage(result.stdout, fallback) : fallback\n } catch {\n return fallback\n }\n }\n\n execute(cwd: string, request: RepositoryActionRequest): Promise<RepositoryActionResult> {\n const operation = this.#pending.then(() => this.#execute(cwd, request))\n this.#pending = operation.then(() => undefined, () => undefined)\n return operation\n }\n\n async #execute(cwd: string, request: RepositoryActionRequest): Promise<RepositoryActionResult> {\n // A stopped rebase leaves a detached HEAD and an unmerged tree, which the\n // preview refuses outright -- so resuming one has to run before it.\n if (request.action === 'resolve-continue' || request.action === 'resolve-abort') return this.#resolve(cwd, request.action, request.push === true)\n const before = await this.#preview(cwd)\n if (before.fingerprint !== request.fingerprint) throw new RepositoryActionError('repository-changed', 'Repository changes have changed. Refresh the commit panel.')\n if (request.action === 'push') {\n const git = await this.#git()\n try {\n await this.#push(git, before.root, before.branch)\n } catch (error) {\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.')\n }\n this.#invalidate(before.root)\n return { commit: before.head, pushed: true }\n }\n if (request.action === 'merge-pr') {\n const method = request.mergeMethod\n if (method !== 'merge' && method !== 'squash' && method !== 'rebase') {\n throw new RepositoryActionError('invalid-request', 'The merge method is invalid.')\n }\n let gh: string\n try {\n gh = await this.#gh()\n } catch (error) {\n throw new RepositoryActionError('gh-unavailable', error instanceof Error ? error.message : 'GitHub CLI is unavailable.')\n }\n const merged = await this.#run(gh, ['pr', 'merge', `--${method}`, ...(request.admin === true ? ['--admin'] : [])], before.root, REMOTE_TIMEOUT_MS)\n if (merged.exitCode !== 0 || merged.lossy) {\n const reason = merged.stderr.split(/\\r?\\n/u).map(line => line.trim()).filter(line => line.length > 0).at(-1)\n throw new RepositoryActionError('merge-failed', reason === undefined || reason.length === 0 ? 'The pull request could not be merged.' : reason)\n }\n this.#invalidate(before.root)\n return { commit: before.head, pushed: true }\n }\n if (request.action === 'update-branch') {\n const base = safeText(request.baseBranch ?? '', 512, 'Base branch')\n if (before.files.length > 0) {\n throw new RepositoryActionError('dirty-workspace', 'Commit or stash workspace changes before updating the branch.')\n }\n const method = request.mergeMethod ?? 'rebase'\n if (method !== 'merge' && method !== 'rebase') throw new RepositoryActionError('invalid-request', 'Update branch supports merge or rebase.')\n const git = await this.#git()\n await this.#mustRun(git, ['fetch', 'origin', '--', base], before.root, REMOTE_TIMEOUT_MS, 'fetch-failed', 'Git could not fetch the base branch.')\n const merged = await this.#run(git, method === 'rebase' ? ['rebase', '--', `origin/${base}`] : ['merge', '--no-edit', '--', `origin/${base}`], before.root, REMOTE_TIMEOUT_MS)\n if (merged.exitCode !== 0 || merged.lossy) {\n const conflicts = conflictPaths(await this.#run(git, ['diff', '--name-only', '--diff-filter=U', '--'], before.root, GIT_TIMEOUT_MS))\n if (conflicts.length === 0) {\n await this.#run(git, [method, '--abort'], before.root, GIT_TIMEOUT_MS).catch(() => undefined)\n throw new RepositoryActionError('merge-failed', `Git could not ${method} the base branch.`)\n }\n // Leave the conflicted tree in place: resolving it is the next step.\n this.#invalidate(before.root)\n return { commit: before.head, pushed: false, conflicts }\n }\n const mergedHead = (await this.#mustRun(git, ['rev-parse', 'HEAD'], before.root, GIT_TIMEOUT_MS, 'merge-failed', 'The updated commit could not be verified.')).stdout.trim()\n try {\n // A rebase rewrites the branch, so the push must replace the remote ref; --force-with-lease still refuses if someone else pushed.\n await this.#push(git, before.root, before.branch, method === 'rebase')\n } catch (error) {\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.', mergedHead)\n }\n this.#invalidate(before.root)\n return { commit: mergedHead, pushed: true }\n }\n const message = safeText(request.message, MAX_MESSAGE_CHARS, 'Commit message')\n if (before.files.length === 0 && request.action !== 'create-pr') {\n throw new RepositoryActionError('nothing-to-commit', 'There are no changes to commit.')\n }\n const git = await this.#git()\n let oid = before.head\n if (before.files.length > 0) {\n await this.#rejectStagedWarp(git, before.root)\n if (request.includeUnstaged) {\n const paths = before.files.filter(file => file.unstaged || file.untracked).map(file => file.path)\n if (paths.length > 0) await this.#mustRun(git, ['add', '--', ...paths], before.root, GIT_TIMEOUT_MS, 'stage-failed', 'Changes could not be staged.')\n }\n await this.#rejectStagedWarp(git, before.root)\n const staged = await this.#run(git, ['diff', '--cached', '--quiet', '--exit-code', '--'], before.root, GIT_TIMEOUT_MS)\n if (staged.exitCode === 0) throw new RepositoryActionError('nothing-to-commit', 'There are no staged changes to commit.')\n if (staged.exitCode !== 1) throw new RepositoryActionError('repository-unavailable', 'The staged changes could not be verified.')\n await this.#mustRun(git, ['commit', '-m', message, '--'], before.root, GIT_TIMEOUT_MS, 'commit-failed', 'Git commit failed.')\n oid = (await this.#mustRun(git, ['rev-parse', 'HEAD'], before.root, GIT_TIMEOUT_MS, 'commit-failed', 'The new commit could not be verified.')).stdout.trim()\n this.#invalidate(before.root)\n if (request.action === 'commit') return { commit: oid, pushed: false }\n }\n try {\n await this.#push(git, before.root, before.branch)\n } catch (error) {\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.', oid)\n }\n this.#invalidate(before.root)\n if (request.action === 'commit-push') return { commit: oid, pushed: true }\n const title = safeText(request.prTitle ?? message, 256, 'Pull request title')\n const body = safeText(request.prBody ?? '', MAX_PR_TEXT_CHARS, 'Pull request description')\n if (!validPullRequestBody(body)) {\n throw new RepositoryActionError('invalid-pr-description', 'Pull request description must contain only Summary and Changes sections.', oid)\n }\n let gh: string\n try {\n gh = await this.#gh()\n } catch (error) {\n throw new RepositoryActionError('gh-unavailable', error instanceof Error ? error.message : 'GitHub CLI is unavailable.', oid)\n }\n const args = ['pr', 'create', '--title', title, '--body', body]\n if (request.draft !== false) args.push('--draft')\n if (request.baseBranch !== undefined) args.push('--base', safeText(request.baseBranch, 512, 'Base branch'))\n const created = await this.#run(gh, args, before.root, REMOTE_TIMEOUT_MS)\n const url = created.exitCode === 0 && !created.lossy ? validPrUrl(created.stdout) : undefined\n if (url === undefined) throw new RepositoryActionError('pr-failed', 'The pull request could not be created.', oid)\n return { commit: oid, pushed: true, pullRequestUrl: url }\n }\n\n /** Finishes or discards the merge, rebase, cherry-pick or revert git is\n * waiting on. The operation is read from the git dir rather than taken from\n * the caller: `--continue` and `--abort` are only safe against the one that\n * is actually in progress. */\n async #resolve(cwd: string, action: 'resolve-continue' | 'resolve-abort', push: boolean): Promise<RepositoryActionResult> {\n const git = await this.#git()\n const paths = await this.#mustRun(git, ['rev-parse', '--path-format=absolute', '--show-toplevel', '--absolute-git-dir'], cwd, GIT_TIMEOUT_MS, 'not-repository', 'The session directory is not a Git repository.')\n const [rootValue, gitDirValue] = paths.stdout.split(/\\r?\\n/u)\n const root = (rootValue ?? '').trim()\n const gitDir = (gitDirValue ?? '').trim()\n if (root.length === 0 || gitDir.length === 0) throw new RepositoryActionError('repository-unavailable', 'Repository state is unavailable.')\n const state = await detectRepositoryOperation(gitDir)\n if (state === undefined) throw new RepositoryActionError('no-operation', 'No merge, rebase, cherry-pick or revert is in progress.')\n const operation = state.operation\n if (action === 'resolve-abort') {\n await this.#mustRun(git, [operation, '--abort'], root, GIT_TIMEOUT_MS, 'abort-failed', `Git could not abort the ${operation}.`)\n this.#invalidate(root)\n return { commit: await this.#head(git, root), pushed: false }\n }\n const unmerged = conflictPaths(await this.#run(git, ['diff', '--name-only', '--diff-filter=U', '--'], root, GIT_TIMEOUT_MS))\n if (unmerged.length > 0) throw new RepositoryActionError('unresolved-conflicts', 'Resolve and stage every conflicted file before continuing.')\n // `core.editor=true` accepts the prepared message: nothing here can host an\n // editor, and a rebase that opens one would hang until the timeout.\n const continued = await this.#run(git, ['-c', 'core.editor=true', operation, '--continue'], root, REMOTE_TIMEOUT_MS)\n this.#invalidate(root)\n if (continued.exitCode !== 0 || continued.lossy) {\n // A rebase replays commit by commit, so the next one can stop on its own\n // conflicts: that is progress, not a failure, and it keeps the panel open.\n const next = conflictPaths(await this.#run(git, ['diff', '--name-only', '--diff-filter=U', '--'], root, GIT_TIMEOUT_MS))\n if (next.length > 0) return { commit: await this.#head(git, root), pushed: false, conflicts: next }\n const reason = continued.stderr.split(/\\r?\\n/u).map(line => line.trim()).filter(line => line.length > 0).at(-1)\n throw new RepositoryActionError('continue-failed', reason === undefined || reason.length === 0 ? `Git could not continue the ${operation}.` : reason)\n }\n const head = await this.#head(git, root)\n if (!push) return { commit: head, pushed: false }\n const branch = await this.#run(git, ['symbolic-ref', '--quiet', '--short', 'HEAD'], root, GIT_TIMEOUT_MS)\n if (branch.exitCode !== 0 || branch.lossy) throw new RepositoryActionError('detached-head', 'The finished operation left a detached HEAD, so nothing was pushed.', head)\n try {\n // A rebase rewrote the branch, so its push has to replace the remote ref.\n await this.#push(git, root, branch.stdout.trim(), operation === 'rebase')\n } catch (error) {\n throw new RepositoryActionError('push-failed', error instanceof Error ? error.message : 'Git push failed.', head)\n }\n this.#invalidate(root)\n return { commit: head, pushed: true }\n }\n\n async #head(git: string, root: string): Promise<string> {\n const head = await this.#run(git, ['rev-parse', 'HEAD'], root, GIT_TIMEOUT_MS)\n return head.exitCode === 0 && !head.lossy ? head.stdout.trim() : ''\n }\n\n async #preview(cwd: string): Promise<RepositoryActionPreview> {\n const git = await this.#git()\n const rootResult = await this.#mustRun(git, ['rev-parse', '--path-format=absolute', '--show-toplevel'], cwd, GIT_TIMEOUT_MS, 'not-repository', 'The session directory is not a Git repository.')\n const root = rootResult.stdout.trim()\n const funcname = await diffFuncnameArgs()\n const [branchResult, headResult, statusResult, stagedPatch, unstagedPatch] = await Promise.all([\n this.#run(git, ['symbolic-ref', '--quiet', '--short', 'HEAD'], root, GIT_TIMEOUT_MS),\n this.#run(git, ['rev-parse', 'HEAD'], root, GIT_TIMEOUT_MS),\n this.#run(git, ['status', '--porcelain=v1', '-z', '--untracked-files=all'], root, GIT_TIMEOUT_MS),\n this.#run(git, [...funcname, 'diff', '--cached', '--no-ext-diff', '--no-color', '--unified=3', '--', ':(exclude)WARP.md', ':(exclude)**/WARP.md'], root, GIT_TIMEOUT_MS, MAX_OUTPUT_BYTES),\n this.#run(git, [...funcname, 'diff', '--no-ext-diff', '--no-color', '--unified=3', '--', ':(exclude)WARP.md', ':(exclude)**/WARP.md'], root, GIT_TIMEOUT_MS, MAX_OUTPUT_BYTES),\n ])\n if (branchResult.exitCode !== 0) throw new RepositoryActionError('detached-head', 'A detached HEAD cannot be committed from this panel.')\n if (headResult.exitCode !== 0 || statusResult.exitCode !== 0 || statusResult.lossy) throw new RepositoryActionError('repository-unavailable', 'Repository state is unavailable.')\n const files = parseRepositoryActionStatus(statusResult.stdout)\n const patch = `${stagedPatch.stdout}${stagedPatch.stdout.length > 0 && unstagedPatch.stdout.length > 0 ? '\\n' : ''}${unstagedPatch.stdout}`.slice(0, MAX_PATCH_CHARS)\n const branch = branchResult.stdout.trim()\n const head = headResult.stdout.trim()\n const fingerprint = createHash('sha256').update([head, branch, statusResult.stdout, stagedPatch.stdout, unstagedPatch.stdout].join('\\0')).digest('hex')\n const upstreamResult = await this.#run(git, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'], root, GIT_TIMEOUT_MS)\n const upstream = upstreamResult.exitCode === 0 && !upstreamResult.lossy ? upstreamResult.stdout.trim() : undefined\n const logResult = await this.#run(git, [\n 'log', '--format=%H%x09%s', `-n`, String(MAX_UNPUSHED_COMMITS + 1), upstream === undefined ? 'HEAD' : '@{upstream}..HEAD', '--',\n ], root, GIT_TIMEOUT_MS)\n const commitLines = logResult.exitCode === 0 && !logResult.lossy\n ? logResult.stdout.split(/\\r?\\n/u).filter(line => line.includes('\\t'))\n : []\n const unpushedCommits = commitLines.slice(0, MAX_UNPUSHED_COMMITS).flatMap(line => {\n const tab = line.indexOf('\\t')\n const hash = line.slice(0, tab)\n return /^[0-9a-f]{40}$/iu.test(hash) ? [{ hash, subject: line.slice(tab + 1).slice(0, 140) }] : []\n })\n return {\n root,\n branch,\n head,\n fingerprint,\n files,\n patch,\n truncated: stagedPatch.lossy || unstagedPatch.lossy || stagedPatch.stdout.length + unstagedPatch.stdout.length > MAX_PATCH_CHARS,\n hasStaged: files.some(file => file.staged),\n hasUnstaged: files.some(file => file.unstaged),\n hasUntracked: files.some(file => file.untracked),\n ...(upstream === undefined ? {} : { upstream }),\n unpushedCommits,\n unpushedTruncated: commitLines.length > MAX_UNPUSHED_COMMITS,\n }\n }\n\n async #rejectStagedWarp(git: string, cwd: string): Promise<void> {\n const staged = await this.#run(git, ['diff', '--cached', '--name-only', '--'], cwd, GIT_TIMEOUT_MS)\n if (staged.exitCode !== 0 || staged.lossy) throw new RepositoryActionError('repository-unavailable', 'Staged files could not be verified.')\n if (staged.stdout.split(/\\r?\\n/u).some(path => path.length > 0 && isProtectedWarpPath(path))) {\n throw new RepositoryActionError('protected-warp-file', 'WARP.md files cannot be committed. Unstage them before continuing.')\n }\n }\n\n async #push(git: string, cwd: string, branch: string, forceWithLease = false): Promise<void> {\n const upstream = await this.#run(git, ['rev-parse', '--abbrev-ref', '--symbolic-full-name', '@{upstream}'], cwd, GIT_TIMEOUT_MS)\n const args = upstream.exitCode === 0 ? ['push', ...(forceWithLease ? ['--force-with-lease'] : [])] : ['push', '--set-upstream', 'origin', branch]\n await this.#mustRun(git, args, cwd, REMOTE_TIMEOUT_MS, 'push-failed', 'Git push failed.')\n }\n\n #git(): Promise<string> {\n this.#gitExecutable ??= this.#runtime.resolveExecutable('git')\n return this.#gitExecutable\n }\n\n #gh(): Promise<string> {\n this.#ghExecutable ??= this.#runtime.resolveExecutable('gh').catch(() => { throw new RepositoryActionError('gh-unavailable', 'GitHub CLI is unavailable.') })\n return this.#ghExecutable\n }\n\n async #mustRun(executable: string, args: readonly string[], cwd: string, timeoutMs: number, code: string, message: string): Promise<CommandResult> {\n const result = await this.#run(executable, args, cwd, timeoutMs)\n if (result.exitCode !== 0 || result.lossy) throw new RepositoryActionError(code, message)\n return result\n }\n\n #run(executable: string, args: readonly string[], cwd: string, timeoutMs: number, maxBytes = MAX_OUTPUT_BYTES): Promise<CommandResult> {\n return collect(this.#runtime.spawn({\n argv: [executable, ...args],\n cwd,\n stdio: { stdin: 'ignore', stdout: { maxBytes }, stderr: { maxBytes: MAX_OUTPUT_BYTES } },\n graceMs: 1_000,\n signal: AbortSignal.timeout(timeoutMs),\n env: {},\n }))\n }\n}\n","import type { ServerResponse } from 'node:http'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REPOSITORY_SETUP_PATH } from './constants.ts'\nimport { json, registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport {\n RepositorySetupError,\n type RepositorySetupResult,\n type RepositorySetupService,\n type RepositorySetupStage,\n} from './repository-setup.ts'\n\nconst MAX_BODY_BYTES = 16 * 1024\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as Record<string, unknown>\n : undefined\n}\n\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\n let parsed: unknown\n try {\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\n } catch (error) {\n if (error instanceof SyntaxError) throw error\n throw new RepositorySetupError('body-too-large', 'The request body is too large.')\n }\n const value = record(parsed)\n if (value === undefined) throw new RepositorySetupError('invalid-request', 'The request body is invalid.')\n return value\n}\n\nfunction string(input: Record<string, unknown>, key: string): string {\n const value = input[key]\n if (typeof value !== 'string') throw new RepositorySetupError('invalid-request', `The ${key} field is required.`)\n return value\n}\n\nfunction optionalString(input: Record<string, unknown>, key: string): string | undefined {\n const value = input[key]\n if (value === undefined) return undefined\n if (typeof value !== 'string') throw new RepositorySetupError('invalid-request', `The ${key} field must be a string.`)\n return value\n}\n\nfunction ndjsonHeaders(res: ServerResponse): void {\n res.writeHead(200, {\n 'content-type': 'application/x-ndjson; charset=utf-8',\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n })\n res.flushHeaders?.()\n}\n\nfunction ndjson(res: ServerResponse, value: unknown): void {\n res.write(`${JSON.stringify(value)}\\n`)\n}\n\n// `RepositorySetupService.setup` takes no signal, so the route's disconnect\n// abort cannot reach the Git work it drives; the stream registration is still\n// what bounds how many of these may be live at once.\nasync function streamSetup(\n res: ServerResponse,\n service: RepositorySetupService,\n input: Record<string, unknown>,\n): Promise<void> {\n ndjsonHeaders(res)\n let ended = false\n try {\n const result: RepositorySetupResult = await service.setup(\n string(input, 'cwd'),\n string(input, 'branch'),\n input.worktree as boolean,\n optionalString(input, 'branchName'),\n (stage: RepositorySetupStage) => { if (!ended) ndjson(res, { type: 'progress', stage }) },\n optionalString(input, 'intent'),\n )\n ndjson(res, { type: 'complete', result })\n } catch (error) {\n const setupError = error instanceof RepositorySetupError ? error : undefined\n ndjson(res, {\n type: 'error',\n code: setupError?.code ?? 'repository-setup-unavailable',\n message: setupError?.message ?? 'Repository setup is unavailable.',\n })\n } finally {\n ended = true\n res.end()\n }\n}\n\n/** Register trusted browser routes for safe pre-session Git setup.\n *\n * The prefix is registered as a stream because the setup POST holds its\n * connection open for the whole worktree build; the short sibling paths ride\n * the same registration and answer with `json` before releasing it. */\nexport function registerRepositorySetupRoute(\n ctx: Context,\n service: RepositorySetupService,\n /** Kick the worktree/workspace reconciliation, when the Host exposes one. */\n sweep?: () => void,\n /** A checkout was cleaned up: status readers caching by path must drop it. */\n cleaned?: (path: string) => void,\n): void {\n registerPluginRoute(ctx, {\n mode: 'stream',\n kind: 'prefix',\n path: CLAUDE_REPOSITORY_SETUP_PATH,\n methods: ['GET', 'POST'],\n maxConcurrent: 2,\n // Only the branch paths name their checkout in the URL; the setup POST\n // carries it in the body, so it keys on its path alone and a reopen\n // supersedes the response it is replacing.\n streamKey: url => `${url.pathname}?${url.searchParams.get('cwd') ?? url.searchParams.get('branch') ?? ''}`,\n handler: async (res, io) => {\n const pathname = io.url.pathname\n try {\n // Not a GET: --prune rewrites this checkout's remote-tracking refs.\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/branches/refresh`) {\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\n const input = await readJson(io)\n return json(res, 200, await service.refreshBranches(string(input, 'cwd')))\n }\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/branches`) {\n if (io.method !== 'GET') return json(res, 405, { error: 'method not allowed' })\n const cwd = io.url.searchParams.get('cwd')\n if (cwd === null) throw new RepositorySetupError('invalid-request', 'The cwd query parameter is required.')\n return json(res, 200, await service.listBranches(cwd))\n }\n if (pathname === CLAUDE_REPOSITORY_SETUP_PATH) {\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\n const input = await readJson(io)\n if (typeof input.worktree !== 'boolean') throw new RepositorySetupError('invalid-request', 'The worktree field is required.')\n await streamSetup(res, service, input)\n return\n }\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/cleanup`) {\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\n const input = await readJson(io)\n const path = string(input, 'path')\n const result = await service.cleanupMerged(path, string(input, 'baseBranch'))\n cleaned?.(path)\n return json(res, 200, result)\n }\n // The Host's own workspace deletion publishes no server-side event, so\n // the Client kicks the sweep the moment a workspace leaves its list.\n // Carries no payload: the sweep re-reads the registry itself.\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/sweep`) {\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\n sweep?.()\n return json(res, 200, { ok: true })\n }\n if (pathname === `${CLAUDE_REPOSITORY_SETUP_PATH}/bind`) {\n if (io.method !== 'POST') return json(res, 405, { error: 'method not allowed' })\n const input = await readJson(io)\n await service.bindLease(string(input, 'leaseId'), string(input, 'sessionId'))\n return json(res, 200, { ok: true })\n }\n return json(res, 404, { error: 'not found' })\n } catch (error) {\n if (error instanceof RepositorySetupError) return json(res, 409, { error: error.code, message: error.message })\n if (error instanceof SyntaxError) return json(res, 400, { error: 'invalid json' })\n return json(res, 500, { error: 'repository setup unavailable' })\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REPOSITORY_ACTION_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport {\n RepositoryActionError,\n type RepositoryActionKind,\n type RepositoryActionRequest,\n type RepositoryMergeMethod,\n type RepositoryActionService,\n} from './repository-actions.ts'\n\nconst MAX_BODY_BYTES = 16 * 1024\nconst MAX_SESSION_ID_CHARS = 1_024\nconst MAX_ROOT_CHARS = 4_096\nconst ACTIONS = new Set<RepositoryActionKind>(['commit', 'commit-push', 'push', 'create-pr', 'merge-pr', 'update-branch', 'resolve-continue', 'resolve-abort'])\n/** Actions that commit nothing of their own, so the panel sends no message. */\nconst MESSAGELESS = new Set<RepositoryActionKind>(['push', 'merge-pr', 'update-branch', 'resolve-continue', 'resolve-abort'])\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\n let parsed: unknown\n try {\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\n } catch (error) {\n // Malformed JSON keeps its own 400; the cap is the only other refusal the\n // transport raises, and the panel already knows that code.\n if (error instanceof SyntaxError) throw error\n throw new RepositoryActionError('body-too-large', 'The request body is too large.')\n }\n const value = record(parsed)\n if (value === undefined) throw new RepositoryActionError('invalid-request', 'The request body is invalid.')\n return value\n}\n\nfunction sessionId(url: URL): string {\n const value = url.searchParams.get('sessionId')\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) {\n throw new RepositoryActionError('invalid-session', 'The session is invalid.')\n }\n return value\n}\n\nfunction requestedRoot(url: URL): string | undefined {\n const value = url.searchParams.get('root')\n return value === null || value.length === 0 || value.length > MAX_ROOT_CHARS ? undefined : value\n}\n\nfunction string(input: Record<string, unknown>, key: string): string {\n const value = input[key]\n if (typeof value !== 'string') throw new RepositoryActionError('invalid-request', `The ${key} field is required.`)\n return value\n}\n\nfunction optionalString(input: Record<string, unknown>, key: string): string | undefined {\n const value = input[key]\n if (value === undefined) return undefined\n if (typeof value !== 'string') throw new RepositoryActionError('invalid-request', `The ${key} field must be a string.`)\n return value\n}\n\nfunction actionRequest(input: Record<string, unknown>): RepositoryActionRequest {\n const action = input.action\n if (typeof action !== 'string' || !ACTIONS.has(action as RepositoryActionKind)\n || typeof input.includeUnstaged !== 'boolean') {\n throw new RepositoryActionError('invalid-request', 'The repository action is invalid.')\n }\n return {\n action: action as RepositoryActionKind,\n fingerprint: string(input, 'fingerprint'),\n message: MESSAGELESS.has(action as RepositoryActionKind) ? optionalString(input, 'message') ?? '' : string(input, 'message'),\n includeUnstaged: input.includeUnstaged,\n ...(optionalString(input, 'prTitle') === undefined ? {} : { prTitle: optionalString(input, 'prTitle')! }),\n ...(optionalString(input, 'prBody') === undefined ? {} : { prBody: optionalString(input, 'prBody')! }),\n ...(optionalString(input, 'baseBranch') === undefined ? {} : { baseBranch: optionalString(input, 'baseBranch')! }),\n ...(input.draft === undefined ? {} : typeof input.draft === 'boolean' ? { draft: input.draft } : (() => { throw new RepositoryActionError('invalid-request', 'The draft field must be a boolean.') })()),\n ...(input.push === undefined ? {} : typeof input.push === 'boolean' ? { push: input.push } : (() => { throw new RepositoryActionError('invalid-request', 'The push field must be a boolean.') })()),\n ...(input.admin === undefined ? {} : typeof input.admin === 'boolean' ? { admin: input.admin } : (() => { throw new RepositoryActionError('invalid-request', 'The admin field must be a boolean.') })()),\n ...(input.mergeMethod === undefined\n ? {}\n : input.mergeMethod === 'merge' || input.mergeMethod === 'squash' || input.mergeMethod === 'rebase'\n ? { mergeMethod: input.mergeMethod as RepositoryMergeMethod }\n : (() => { throw new RepositoryActionError('invalid-request', 'The mergeMethod field is invalid.') })()),\n }\n}\n\n/** One prefix serves the local-Git preview and the POST arms that push, open\n * and merge pull requests, so the registration takes the wider of the two\n * budgets: a `remote` arm cut short at the `git` deadline would abandon work\n * that had already reached GitHub. */\nexport function registerRepositoryActionRoute(\n ctx: Context,\n service: RepositoryActionService,\n /** `root` names one of the other repositories the session wrote into; the\n * resolver vouches for it or answers undefined, exactly as for the session. */\n cwdForSession: (sessionId: string, root?: string) => string | undefined,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'prefix',\n path: CLAUDE_REPOSITORY_ACTION_PATH,\n methods: ['GET', 'POST'],\n budget: 'remote',\n handler: async io => {\n const url = io.url\n try {\n const id = sessionId(url)\n const cwd = cwdForSession(id, requestedRoot(url))\n if (cwd === undefined) throw new RepositoryActionError('session-unavailable', 'The Claude session is unavailable.')\n if (url.pathname === `${CLAUDE_REPOSITORY_ACTION_PATH}/preview`) {\n if (io.method !== 'GET') return { status: 405, value: { error: 'method not allowed' } }\n return { status: 200, value: await service.preview(cwd) }\n }\n if (url.pathname === `${CLAUDE_REPOSITORY_ACTION_PATH}/message`) {\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\n const input = await readJson(io)\n return { status: 200, value: { message: await service.generateMessage(cwd, string(input, 'fingerprint')) } }\n }\n if (url.pathname === CLAUDE_REPOSITORY_ACTION_PATH) {\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\n return { status: 200, value: await service.execute(cwd, actionRequest(await readJson(io))) }\n }\n return { status: 404, value: { error: 'not found' } }\n } catch (error) {\n if (error instanceof RepositoryActionError) {\n return {\n status: 409,\n value: {\n error: error.code,\n message: error.message,\n ...(error.commit === undefined ? {} : { commit: error.commit }),\n },\n }\n }\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 500, value: { error: 'repository-action-unavailable', message: 'Repository action is unavailable.' } }\n }\n },\n })\n}\n","import type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\n\nconst MAX_OUTPUT_BYTES = 8 * 1024\n/** Long enough for a launcher shim to fail loudly, short enough that the\n * request returns while the IDE is still booting. On Windows and Linux the\n * IDE binary IS the launched process, so still running past this is success. */\nconst SETTLE_MS = 1_500\n\nexport type EditorId = 'cursor' | 'idea'\nexport const EDITOR_IDS: ReadonlySet<string> = new Set<EditorId>(['cursor', 'idea'])\n\n/** Launch commands tried in order, first success wins. macOS keeps `open -a`\n * behind the CLI shim because both shims are opt-in installs there, while\n * `open -a` finds the bundle wherever Toolbox or the DMG dropped it. */\nconst LAUNCHERS: Record<EditorId, Partial<Record<NodeJS.Platform, readonly (readonly string[])[]>>> = {\n cursor: {\n darwin: [['cursor'], ['open', '-a', 'Cursor']],\n win32: [['cursor']],\n linux: [['cursor']],\n },\n idea: {\n darwin: [['idea'], ['open', '-a', 'IntelliJ IDEA'], ['open', '-a', 'IntelliJ IDEA CE']],\n win32: [['idea'], ['idea64.exe']],\n linux: [['idea'], ['idea.sh']],\n },\n}\n\n/** cmd.exe re-interprets these, and a mis-parsed path opens the wrong project\n * rather than failing. Refuse instead of guessing. */\nconst WINDOWS_UNSAFE = /[\"&|<>^%]/u\n\nexport class EditorOpenError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'EditorOpenError'\n this.code = code\n }\n}\n\n/** Open a session's working directory in a desktop editor. */\nexport class EditorOpenService {\n readonly #runtime: Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n readonly #platform: NodeJS.Platform\n readonly #settleMs: number\n\n constructor(\n runtime: Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>,\n platform: NodeJS.Platform = process.platform,\n settleMs: number = SETTLE_MS,\n ) {\n this.#runtime = runtime\n this.#platform = platform\n this.#settleMs = settleMs\n }\n\n async open(cwd: string, editor: EditorId): Promise<void> {\n if (this.#platform === 'win32' && WINDOWS_UNSAFE.test(cwd)) {\n throw new EditorOpenError('unsupported-path', 'The project path cannot be opened through the Windows shell.')\n }\n const candidates = LAUNCHERS[editor][this.#platform] ?? LAUNCHERS[editor].linux ?? []\n let found = false\n for (const candidate of candidates) {\n const argv = await this.#argv(candidate, cwd)\n if (argv === undefined) continue\n found = true\n if (await this.#launch(argv, cwd)) return\n }\n throw found\n ? new EditorOpenError('launch-failed', 'The editor refused to open the project.')\n : new EditorOpenError('editor-unavailable', 'The editor was not found on PATH.')\n }\n\n async #argv(candidate: readonly string[], cwd: string): Promise<readonly string[] | undefined> {\n const [program, ...rest] = candidate\n if (program === undefined) return undefined\n // Windows launcher shims are `.cmd` files, which Node refuses to spawn\n // directly; cmd.exe runs those and plain `.exe` entries alike, and does\n // its own PATH/PATHEXT lookup — so no resolution step here.\n if (this.#platform === 'win32') return ['cmd.exe', '/d', '/s', '/c', program, ...rest, cwd]\n try {\n return [await this.#runtime.resolveExecutable(program), ...rest, cwd]\n } catch {\n return undefined\n }\n }\n\n /** True once the editor is launched: either the shim exited cleanly or the\n * process is still alive past the settle window. */\n async #launch(argv: readonly string[], cwd: string): Promise<boolean> {\n let handle: SubprocessHandle\n try {\n // No abort signal on purpose — the editor must outlive this request.\n // ponytail: on platforms whose launcher does not fork (idea64.exe) the\n // IDE stays a child of the host; detach if that ever orphans badly.\n handle = this.#runtime.spawn({\n argv,\n cwd,\n stdio: { stdin: 'ignore', stdout: { maxBytes: MAX_OUTPUT_BYTES }, stderr: { maxBytes: MAX_OUTPUT_BYTES } },\n graceMs: 1_000,\n env: {},\n })\n } catch {\n return false\n }\n return await Promise.race([\n handle.done.then(outcome => outcome.exitCode === 0),\n new Promise<boolean>(resolve => {\n const timer = setTimeout(() => resolve(true), this.#settleMs)\n timer.unref?.()\n }),\n ])\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_EDITOR_OPEN_PATH } from './constants.ts'\nimport { registerPluginRoute } from './http.ts'\nimport { EDITOR_IDS, EditorOpenError, type EditorId, type EditorOpenService } from './editor-open.ts'\n\nconst MAX_SESSION_ID_CHARS = 1_024\n\n/** Open the session's working directory in a desktop editor. Query-only: the\n * request carries two enum-ish values, so there is no body to parse. */\nexport function registerEditorOpenRoute(\n ctx: Context,\n service: Pick<EditorOpenService, 'open'>,\n cwdForSession: (sessionId: string) => string | undefined,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_EDITOR_OPEN_PATH,\n methods: ['POST'],\n budget: 'fast',\n handler: async io => {\n const params = io.url.searchParams\n const id = params.get('sessionId')\n const editor = params.get('editor')\n if (id === null || id.length === 0 || id.length > MAX_SESSION_ID_CHARS) {\n return { status: 400, value: { error: 'invalid-session', message: 'The session is invalid.' } }\n }\n if (editor === null || !EDITOR_IDS.has(editor)) {\n return { status: 400, value: { error: 'invalid-editor', message: 'The editor is invalid.' } }\n }\n const cwd = cwdForSession(id)\n if (cwd === undefined) return { status: 409, value: { error: 'session-unavailable', message: 'The Claude session is unavailable.' } }\n try {\n await service.open(cwd, editor as EditorId)\n return { status: 200, value: { opened: true } }\n } catch (error) {\n if (error instanceof EditorOpenError) return { status: 409, value: { error: error.code, message: error.message } }\n return { status: 500, value: { error: 'editor-open-unavailable', message: 'The editor could not be launched.' } }\n }\n },\n })\n}\n","import { homedir } from 'node:os'\nimport { mkdir, opendir, readFile, writeFile } from 'node:fs/promises'\nimport { extname, join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { CLAUDE_PROMPTS_PATH, CLAUDE_PROMPT_NAME_PATH, CLAUDE_PROMPT_REFINE_PATH } from './constants.ts'\nimport { redactText } from './events.ts'\nimport { registerPluginRoute } from './http.ts'\n\n/** One prompt file as the composer menu sees it: the file name is the menu\n * row, the body is what lands in the composer verbatim. */\nexport interface ClaudePromptView {\n name: string\n description: string\n body: string\n /** Where the file sits, written for a human to read rather than to open:\n * the home directory collapses to `~`, so the confirmation that a prompt\n * was saved can name the file without spilling the whole absolute path. */\n location: string\n}\n\nconst MAX_PROMPT_FILES = 256\nconst MAX_PROMPT_BYTES = 16 * 1024\nconst MAX_DESCRIPTION_CHARS = 120\nconst MAX_REQUEST_BYTES = 32 * 1024\n\n/**\n * The same shape as the output-style name in `global-settings.ts`, plus\n * `\\p{M}` so a macOS-decomposed name survives. Two properties matter and both\n * are load-bearing: no member of the class is a path separator, and the first\n * character can be neither a dot nor a separator — so `join(dir, name + '.md')`\n * cannot address anything outside `dir`. Nothing else validates the path.\n */\nconst PROMPT_NAME = /^[\\p{L}\\p{N}][\\p{L}\\p{M}\\p{N} ._()\\[\\]-]{0,127}$/u\n\n/** Prompt snippets live beside the rest of the user's Claude Code state. */\nexport function claudePromptsDir(): string {\n return join(homedir(), '.claude', 'prompts')\n}\n\n/** `~/.claude/prompts/x.md` rather than the absolute path it expands to.\n * Windows joins with backslashes; the display form is the same on every OS. */\nexport function displayPath(file: string): string {\n const home = homedir()\n const separator = file.charAt(home.length)\n if (!file.startsWith(home) || (separator !== '/' && separator !== '\\\\')) return file\n return `~${file.slice(home.length).replaceAll('\\\\', '/')}`\n}\n\n/** The menu's second row: the first non-empty line, collapsed and bounded. */\nfunction summarize(body: string): string {\n const line = body.split('\\n').map(text => text.trim()).find(text => text.length > 0) ?? ''\n return redactText(line.replace(/\\s+/gu, ' '), MAX_DESCRIPTION_CHARS)\n}\n\n/**\n * Every `.md` file in the prompts directory, sorted by name.\n *\n * A missing directory is the ordinary state before the user saves anything,\n * and one unreadable file must not empty the whole menu — both answer with\n * what is there rather than throwing.\n */\nexport async function readClaudePrompts(directory: string): Promise<readonly ClaudePromptView[]> {\n const prompts: ClaudePromptView[] = []\n let entries\n try {\n entries = await opendir(directory)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return prompts\n throw error\n }\n for await (const entry of entries) {\n if (prompts.length >= MAX_PROMPT_FILES) break\n if (!entry.isFile() || extname(entry.name).toLowerCase() !== '.md') continue\n const name = entry.name.slice(0, -3)\n if (!PROMPT_NAME.test(name)) continue\n try {\n const file = join(directory, entry.name)\n const body = await readFile(file, 'utf8')\n if (body.trim().length === 0 || Buffer.byteLength(body) > MAX_PROMPT_BYTES) continue\n prompts.push({ name, description: summarize(body), body, location: displayPath(file) })\n } catch {\n // Ignore unreadable prompt files.\n }\n }\n return prompts.sort((left, right) => left.name.localeCompare(right.name))\n}\n\nexport type ClaudePromptWriteCode = 'invalid-name' | 'invalid-body' | 'name-taken'\n\nexport class ClaudePromptWriteError extends Error {\n readonly code: ClaudePromptWriteCode\n\n constructor(code: ClaudePromptWriteCode, message: string) {\n super(message)\n this.name = 'ClaudePromptWriteError'\n this.code = code\n }\n}\n\n/**\n * Save one prompt, refusing to clobber an existing file.\n *\n * `wx` is the whole collision policy: a name the user already uses is theirs\n * to resolve, and overwriting a prompt they keep is not something they can\n * undo from inside DSH.\n */\nexport async function writeClaudePrompt(directory: string, name: unknown, body: unknown): Promise<ClaudePromptView> {\n if (typeof name !== 'string' || !PROMPT_NAME.test(name)) {\n throw new ClaudePromptWriteError('invalid-name', 'The prompt name is invalid.')\n }\n if (typeof body !== 'string' || body.trim().length === 0 || Buffer.byteLength(body) > MAX_PROMPT_BYTES) {\n throw new ClaudePromptWriteError('invalid-body', 'The prompt text is empty or too large.')\n }\n const text = body.endsWith('\\n') ? body : `${body}\\n`\n const file = join(directory, `${name}.md`)\n await mkdir(directory, { recursive: true, mode: 0o700 })\n try {\n await writeFile(file, text, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'EEXIST') {\n throw new ClaudePromptWriteError('name-taken', 'A prompt with that name already exists.')\n }\n throw error\n }\n return { name, description: summarize(text), body: text, location: displayPath(file) }\n}\n\n\nconst MAX_NAME_DRAFT_CHARS = 4_000\nconst MAX_NAME_OUTPUT_BYTES = 4 * 1024\nconst MAX_SUGGESTED_NAME_CHARS = 48\nconst MAX_REFINE_DRAFT_CHARS = 16_000\nconst MAX_REFINED_BYTES = 32 * 1024\nconst ASSIST_TIMEOUT_MS = 40_000\n\n/**\n * Ask for a file name and nothing else, with the draft fenced as data.\n *\n * Two things here were measured rather than guessed. The instruction travels\n * in the user turn, not in `--system-prompt`: a saved prompt is itself an\n * instruction and a system prompt does not outrank it, so the model reads the\n * draft as its task and answers it instead of naming it. And the default\n * system prompt is left in place even though it is large, because the CLI\n * sends it as a cache read (~6.5k cached tokens); replacing it with a short\n * one costs a fresh 3.5k-token prefill and measured slower end to end.\n *\n * The naming spec is this specific because a vaguer one (\"describe what the\n * template does, at most 40 characters\") produced names that were both\n * inconsistent in style and stripped of the detail that tells two similar\n * templates apart.\n */\nexport function promptNamePrompt(draft: string): string {\n const text = draft.trim().slice(0, MAX_NAME_DRAFT_CHARS)\n return [\n 'Below is a reusable prompt template a user is saving to a file. Name it.',\n '',\n `\"\"\"\\n${text.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`,\n '',\n 'Answer with the file name alone: no quotes, no explanation, no extension, no leading dot, no slashes.',\n 'Write it in English however the template is written, as lower-case words joined by hyphens.',\n 'Name the task the template performs, keeping whatever detail distinguishes it from a',\n 'similar template. At most 6 words.',\n ].join('\\n')\n}\n\n/**\n * Rewrite the draft into something an agent can act on, with the draft fenced\n * as data for the same reason the naming prompt fences it.\n *\n * The rule about people and places is not politeness. Asked to rewrite\n * \"后端 assign 给我\", the model reached into Claude Code's ambient system\n * prompt and substituted the operator's actual email address — inventing a\n * detail the original never carried, and putting a personal address into a\n * message the user had not written it into. Naming the failure explicitly is\n * what stopped it; stripping the ambient context with `--system-prompt` also\n * stopped it but cost a fresh prefill and produced looser rewrites.\n */\nexport function promptRefinePrompt(draft: string): string {\n const text = draft.trim().slice(0, MAX_REFINE_DRAFT_CHARS)\n return [\n 'Below is a prompt a user is about to send to a coding agent. Rewrite it so the agent can act on it without coming back with questions.',\n '',\n `\"\"\"\\n${text.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`,\n '',\n 'Keep the intent and every concrete detail exactly as given — names, paths, branches, identifiers, numbers.',\n 'Leave every reference to a person or place as the original wrote it (\"me\", \"我\", \"the usual branch\");',\n 'you do not know who or what they resolve to, and guessing puts a wrong name in the user\\'s message.',\n 'Do not invent requirements the original does not imply, do not answer the prompt, do not add a preamble or sign-off.',\n 'Write the rewrite in the same language the original is written in.',\n 'Reply with the rewritten prompt alone.',\n ].join('\\n')\n}\n\n/** One turn, no tools, no MCP: neither of these tasks needs them, and both\n * cost seconds of cold start. Variadic `--tools` stays last. */\nexport function promptAssistArguments(): readonly string[] {\n return [\n '-p', '--output-format', 'text',\n '--model', 'haiku',\n '--strict-mcp-config', '--mcp-config', '{\"mcpServers\":{}}',\n '--tools', '',\n ]\n}\n\n/** The rewrite in a model reply, or undefined when the reply is unusable.\n *\n * A model told to answer with the text alone still sometimes wraps it in a\n * markdown fence, so one is peeled off; anything else is the user's to read\n * and edit, and is passed through untouched. */\nexport function refinedPrompt(output: string): string | undefined {\n const trimmed = output.trim()\n const fenced = /^```[^\\n]*\\n([\\s\\S]*?)\\n?```$/u.exec(trimmed)\n const text = (fenced?.[1] ?? trimmed).trim()\n return text.length === 0 || Buffer.byteLength(text) > MAX_REFINED_BYTES ? undefined : text\n}\n\n/**\n * The usable name in a model reply, or undefined when there is none.\n *\n * A one-line answer is what the prompt asks for and usually what comes back,\n * but \"usually\" is not a contract: the reply is scrubbed to what a file name\n * may hold and then held to the same {@link PROMPT_NAME} guard the write path\n * uses, so a chatty or malformed answer is dropped rather than offered.\n */\nexport function suggestedName(output: string): string | undefined {\n const line = output.split('\\n').map(text => text.trim()).find(text => text.length > 0) ?? ''\n const bare = line.replace(/^[\"'`]+|[\"'`]+$/gu, '').replace(/\\.md$/iu, '')\n const scrubbed = wordBounded(bare\n .replace(/[^\\p{L}\\p{M}\\p{N} ._()\\[\\]-]/gu, ' ')\n .replace(/\\s+/gu, ' ')\n .trim())\n return PROMPT_NAME.test(scrubbed) ? scrubbed : undefined\n}\n\n/** Cut a long name at its last word boundary. A name the user has to repair\n * (\"analyze-frontend-backend-create-jira-tic\") is worse than a shorter one. */\nfunction wordBounded(name: string): string {\n if (name.length <= MAX_SUGGESTED_NAME_CHARS) return name\n const cut = name.slice(0, MAX_SUGGESTED_NAME_CHARS)\n const boundary = cut.search(/[\\s\\-_][^\\s\\-_]*$/u)\n return (boundary > 0 ? cut.slice(0, boundary) : cut).trim()\n}\n\n/** Runs Claude Code's cheapest model over the draft: names it, or rewrites it. */\nexport class PromptAssistService {\n readonly #runtime: Pick<SubprocessRuntime, 'spawn'>\n readonly #executablePath: () => string\n\n constructor(runtime: Pick<SubprocessRuntime, 'spawn'>, executablePath: () => string) {\n this.#runtime = runtime\n this.#executablePath = executablePath\n }\n\n /** One bounded, tool-less turn; undefined whenever it cannot be had. */\n async #ask(prompt: string, maxOutputBytes: number, signal?: AbortSignal): Promise<string | undefined> {\n const executablePath = this.#executablePath()\n if (executablePath.length === 0) return undefined\n const timeout = AbortSignal.timeout(ASSIST_TIMEOUT_MS)\n try {\n const handle = this.#runtime.spawn({\n argv: [executablePath, ...promptAssistArguments()],\n // Nowhere in particular: no tool can reach the file system, and a\n // project directory would only pull that project's CLAUDE.md in.\n cwd: homedir(),\n stdio: {\n stdin: { data: prompt },\n stdout: { maxBytes: maxOutputBytes },\n stderr: { maxBytes: MAX_NAME_OUTPUT_BYTES },\n },\n graceMs: 1_000,\n signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),\n // Extended thinking was 340 of the naming call's 358 output tokens and\n // most of its ten seconds, spent deliberating over a file name.\n // Turning it off takes that call from ~10s to ~3s. A CLI that stops\n // honouring the variable is slow again, never wrong.\n env: { MAX_THINKING_TOKENS: '0' },\n })\n const outcome = await handle.done\n if (outcome.exitCode !== 0) return undefined\n return handle.collected.stdout?.readFrom(0).text ?? ''\n } catch {\n return undefined\n }\n }\n\n /** The suggested file name, or undefined whenever one cannot be had. The\n * caller already has a name derived locally, so every failure here is a\n * non-event: nothing is reported, and nothing is retried. */\n async suggest(draft: string, signal?: AbortSignal): Promise<string | undefined> {\n if (draft.trim().length === 0) return undefined\n const output = await this.#ask(promptNamePrompt(draft), MAX_NAME_OUTPUT_BYTES, signal)\n return output === undefined ? undefined : suggestedName(output)\n }\n\n /** The rewritten draft, or undefined when the rewrite could not be had.\n * Unlike naming, this failure is worth reporting: the user asked for it and\n * is waiting on it. */\n async refine(draft: string, signal?: AbortSignal): Promise<string | undefined> {\n if (draft.trim().length === 0) return undefined\n const output = await this.#ask(promptRefinePrompt(draft), MAX_REFINED_BYTES, signal)\n return output === undefined ? undefined : refinedPrompt(output)\n }\n}\n\n/** List the user's prompt snippets, and save the composer draft as a new one. */\nexport function registerClaudePromptsRoute(ctx: Context, directory: string = claudePromptsDir()): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_PROMPTS_PATH,\n methods: ['GET', 'POST'],\n budget: 'fast',\n handler: async (io) => {\n if (io.method === 'GET') return { status: 200, value: { prompts: await readClaudePrompts(directory) } }\n const payload = await io.body<{ name?: unknown; body?: unknown }>(MAX_REQUEST_BYTES)\n try {\n const prompt = await writeClaudePrompt(directory, payload.name, payload.body)\n return { status: 200, value: { saved: true, prompt } }\n } catch (error) {\n if (error instanceof ClaudePromptWriteError) {\n return { status: error.code === 'name-taken' ? 409 : 400, value: { error: error.code, message: error.message } }\n }\n return { status: 500, value: { error: 'prompt-write-failed', message: 'The prompt could not be saved.' } }\n }\n },\n })\n}\n\n/** Suggest a file name for a draft. Answers `{}` when no name could be had:\n * the caller keeps the name it derived locally, so this is never an error. */\nexport function registerClaudePromptNameRoute(ctx: Context, service: Pick<PromptAssistService, 'suggest'>): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_PROMPT_NAME_PATH,\n methods: ['POST'],\n // Not Git, but the same order of magnitude: one cold Claude Code start.\n budget: 'git',\n handler: async (io) => {\n const payload = await io.body<{ draft?: unknown }>(MAX_REQUEST_BYTES)\n const draft = typeof payload.draft === 'string' ? payload.draft : ''\n const name = await service.suggest(draft, io.signal)\n return { status: 200, value: name === undefined ? {} : { name } }\n },\n })\n}\n\n/** Rewrite a draft into something an agent can act on. */\nexport function registerClaudePromptRefineRoute(ctx: Context, service: Pick<PromptAssistService, 'refine'>): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_PROMPT_REFINE_PATH,\n methods: ['POST'],\n // Not Git, but the same order of magnitude: one cold Claude Code start.\n budget: 'git',\n handler: async (io) => {\n const payload = await io.body<{ draft?: unknown }>(MAX_REQUEST_BYTES)\n const draft = typeof payload.draft === 'string' ? payload.draft : ''\n if (draft.trim().length === 0) {\n return { status: 400, value: { error: 'empty-draft', message: 'There is nothing to rewrite.' } }\n }\n const text = await service.refine(draft, io.signal)\n return text === undefined\n ? { status: 503, value: { error: 'refine-unavailable', message: 'Claude could not rewrite the prompt.' } }\n : { status: 200, value: { text } }\n },\n })\n}\n","/** Only GitHub's own image hosts; the browser loads these directly, so a URL\n * the API did not vouch for must never become an outbound request. */\nexport function githubAvatarUrl(value: unknown): string | undefined {\n if (typeof value !== 'string' || value.length === 0 || value.length > 1_024) return undefined\n try {\n const url = new URL(value)\n const allowed = url.hostname === 'github.com' || url.hostname === 'githubusercontent.com' || url.hostname.endsWith('.githubusercontent.com')\n return url.protocol === 'https:' && allowed ? url.href : undefined\n } catch {\n return undefined\n }\n}\n","import type { SubprocessHandle, SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { githubAvatarUrl } from './github-url.ts'\nimport { parseGitHubRemote } from './repository-status.ts'\n\nexport { githubAvatarUrl } from './github-url.ts'\n\nconst MAX_OUTPUT_BYTES = 512 * 1024\nconst GIT_TIMEOUT_MS = 10_000\nconst GH_TIMEOUT_MS = 60_000\nconst MAX_COMMENTS = 100\nconst MAX_THREADS = 100\nconst MAX_MENTIONABLE_USERS = 20\nconst MAX_REPLY_CHARS = 2_000\nconst MAX_COMMENT_CHARS = 4_096\nconst MAX_FAILING_CHECKS = 3\nconst MAX_LOG_CHARS = 8 * 1024\n\ntype FeedbackRuntime = Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>\n\ninterface CommandResult {\n readonly exitCode: number | null\n readonly stdout: string\n readonly lossy: boolean\n}\n\nexport interface PullRequestReviewComment {\n readonly id: number\n readonly path: string\n readonly line?: number\n readonly side: 'new' | 'old'\n readonly author: string\n /** GitHub-hosted avatar of the comment's author, when the API named one. */\n readonly avatarUrl?: string\n readonly body: string\n readonly url: string\n /** ISO timestamp GitHub reports; the panel shows it the way GitHub does. */\n readonly createdAt?: string\n /** App account. GraphQL reports it as an actor type; REST spells the login\n * `name[bot]`. Either way the panel shows a Bot pill, like GitHub. */\n readonly bot?: boolean\n}\n\n/** One GitHub review conversation: the comments share an anchor, and Resolve\n * acts on the thread rather than on any single comment. */\nexport interface PullRequestReviewThread {\n /** GraphQL node id — the only handle the resolve mutations accept. */\n readonly id: string\n readonly path: string\n readonly line?: number\n readonly side: 'new' | 'old'\n readonly resolved: boolean\n readonly outdated: boolean\n readonly comments: readonly PullRequestReviewComment[]\n}\n\n/** A user GitHub will notify when the reply names them. */\nexport interface MentionableUser {\n readonly login: string\n readonly avatarUrl?: string\n}\n\nexport interface FailingCheck {\n readonly name: string\n readonly link?: string\n readonly description?: string\n readonly log?: string\n}\n\nexport class PullRequestFeedbackError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'PullRequestFeedbackError'\n this.code = code\n }\n}\n\n/** Threads carry the anchor; comments carry the prose. `isOutdated` marks a\n * thread whose lines the branch has since moved past. */\nconst REVIEW_THREADS_QUERY = `query($owner:String!,$name:String!,$number:Int!){\n repository(owner:$owner,name:$name){\n pullRequest(number:$number){\n reviewThreads(first:100){\n nodes{\n id isResolved isOutdated path line originalLine diffSide\n comments(first:50){ nodes{ databaseId body url createdAt author{ __typename login avatarUrl } } }\n }\n }\n }\n }\n}`\n\nconst RESOLVE_MUTATION = `mutation($threadId:ID!){\n resolveReviewThread(input:{threadId:$threadId}){ thread{ isResolved } }\n}`\n\nconst UNRESOLVE_MUTATION = `mutation($threadId:ID!){\n unresolveReviewThread(input:{threadId:$threadId}){ thread{ isResolved } }\n}`\n\nconst MENTIONABLE_USERS_QUERY = `query($owner:String!,$name:String!,$q:String!){\n repository(owner:$owner,name:$name){\n mentionableUsers(first:20,query:$q){ nodes{ login avatarUrl } }\n }\n}`\n\nasync function collect(handle: SubprocessHandle): Promise<CommandResult> {\n const outcome = await handle.done\n const stdout = handle.collected.stdout?.readFrom(0)\n return { exitCode: outcome.exitCode, stdout: stdout?.text ?? '', lossy: stdout?.lossy === true }\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\n/** Read `repository.pullRequest.reviewThreads.nodes` out of a GraphQL response.\n * A payload carrying `errors` instead of data yields nothing rather than\n * throwing: the caller distinguishes \"no threads\" from \"call failed\" by the\n * process exit code. */\nexport function parseReviewThreads(value: unknown): readonly PullRequestReviewThread[] {\n const nodes = record(record(record(record(record(value)?.data)?.repository)?.pullRequest)?.reviewThreads)?.nodes\n if (!Array.isArray(nodes)) return []\n const threads: PullRequestReviewThread[] = []\n let total = 0\n for (const item of nodes) {\n const input = record(item)\n if (input === undefined || typeof input.id !== 'string' || input.id.length === 0) continue\n const path = typeof input.path === 'string' ? input.path : ''\n if (path.length === 0) continue\n const line = Number.isSafeInteger(input.line)\n ? Number(input.line)\n : Number.isSafeInteger(input.originalLine) ? Number(input.originalLine) : undefined\n const side = input.diffSide === 'LEFT' ? 'old' as const : 'new' as const\n const anchor = { path, ...(line === undefined ? {} : { line }), side }\n const comments: PullRequestReviewComment[] = []\n const commentNodes = record(input.comments)?.nodes\n for (const node of Array.isArray(commentNodes) ? commentNodes : []) {\n if (total >= MAX_COMMENTS) break\n const comment = record(node)\n if (comment === undefined || !Number.isSafeInteger(comment.databaseId)) continue\n const body = typeof comment.body === 'string' ? comment.body.trim() : ''\n if (body.length === 0) continue\n const author = record(comment.author)\n const avatarUrl = githubAvatarUrl(author?.avatarUrl)\n const login = typeof author?.login === 'string' ? author.login : 'unknown'\n comments.push({\n id: Number(comment.databaseId),\n ...anchor,\n author: login,\n ...(author?.__typename === 'Bot' || login.endsWith('[bot]') ? { bot: true } : {}),\n ...(avatarUrl === undefined ? {} : { avatarUrl }),\n body: body.slice(0, MAX_COMMENT_CHARS),\n url: typeof comment.url === 'string' ? comment.url : '',\n ...(typeof comment.createdAt === 'string' ? { createdAt: comment.createdAt } : {}),\n })\n total += 1\n }\n // A thread with nothing readable left is not worth an anchor in the diff.\n if (comments.length === 0) continue\n threads.push({\n id: input.id,\n ...anchor,\n resolved: input.isResolved === true,\n outdated: input.isOutdated === true,\n comments,\n })\n if (threads.length >= MAX_THREADS || total >= MAX_COMMENTS) break\n }\n return threads\n}\n\n/** One posted reply, shaped like the thread comments it joins. */\nexport function parseReplyComment(value: unknown, anchor: { path: string; line?: number; side: 'new' | 'old' }): PullRequestReviewComment | undefined {\n const input = record(value)\n if (input === undefined || !Number.isSafeInteger(input.id)) return undefined\n const body = typeof input.body === 'string' ? input.body.trim() : ''\n if (body.length === 0) return undefined\n const user = record(input.user)\n const avatarUrl = githubAvatarUrl(user?.avatar_url)\n const login = typeof user?.login === 'string' ? user.login : 'unknown'\n return {\n id: Number(input.id),\n ...anchor,\n author: login,\n ...(user?.type === 'Bot' || login.endsWith('[bot]') ? { bot: true } : {}),\n ...(avatarUrl === undefined ? {} : { avatarUrl }),\n body: body.slice(0, MAX_COMMENT_CHARS),\n url: typeof input.html_url === 'string' ? input.html_url : '',\n ...(typeof input.created_at === 'string' ? { createdAt: input.created_at } : {}),\n }\n}\n\nexport function parseMentionableUsers(value: unknown): readonly MentionableUser[] {\n const nodes = record(record(record(record(value)?.data)?.repository)?.mentionableUsers)?.nodes\n if (!Array.isArray(nodes)) return []\n const users: MentionableUser[] = []\n for (const item of nodes) {\n const input = record(item)\n if (input === undefined || typeof input.login !== 'string' || input.login.length === 0) continue\n const avatarUrl = githubAvatarUrl(input.avatarUrl)\n users.push({ login: input.login, ...(avatarUrl === undefined ? {} : { avatarUrl }) })\n if (users.length >= MAX_MENTIONABLE_USERS) break\n }\n return users\n}\n\n/** Extract the Actions job id from a check run link, when it is one. */\nexport function actionsJobId(link: string | undefined): string | undefined {\n if (link === undefined) return undefined\n return /\\/actions\\/runs\\/\\d+\\/jobs?\\/(\\d+)/u.exec(link)?.[1]\n}\n\nexport function parseFailingChecks(value: unknown): readonly FailingCheck[] {\n if (!Array.isArray(value)) return []\n const failing: FailingCheck[] = []\n for (const item of value) {\n const input = record(item)\n if (input === undefined || input.bucket !== 'fail' || typeof input.name !== 'string') continue\n failing.push({\n name: input.name,\n ...(typeof input.link === 'string' && input.link.length > 0 ? { link: input.link } : {}),\n ...(typeof input.description === 'string' && input.description.length > 0 ? { description: input.description } : {}),\n })\n }\n return failing\n}\n\n/** Keep the informative end of a failed-job log within the size budget. */\nexport function boundedLogTail(value: string): string {\n const text = value.replaceAll('\\0', '').trimEnd()\n return text.length <= MAX_LOG_CHARS ? text : text.slice(text.length - MAX_LOG_CHARS)\n}\n\nexport class PullRequestFeedbackService {\n readonly #runtime: FeedbackRuntime\n #gitExecutable?: Promise<string>\n #ghExecutable?: Promise<string>\n\n constructor(runtime: FeedbackRuntime) {\n this.#runtime = runtime\n }\n\n async threads(cwd: string, pullNumber: number): Promise<readonly PullRequestReviewThread[]> {\n const { owner, name } = await this.#repositoryParts(cwd)\n const gh = await this.#gh()\n const result = await this.#run(gh, [\n 'api', 'graphql',\n '-f', `owner=${owner}`, '-f', `name=${name}`, '-F', `number=${pullNumber}`,\n '-f', `query=${REVIEW_THREADS_QUERY}`,\n ], cwd, GH_TIMEOUT_MS)\n if (result.exitCode !== 0) throw new PullRequestFeedbackError('comments-unavailable', 'Pull request comments could not be loaded.')\n try {\n return parseReviewThreads(JSON.parse(result.stdout))\n } catch {\n throw new PullRequestFeedbackError('comments-unavailable', 'Pull request comments could not be parsed.')\n }\n }\n\n /** Post a reply into the thread the given comment belongs to. GitHub parses\n * `@login` in the body server-side, so mentions need nothing from us. */\n async reply(cwd: string, pullNumber: number, commentId: number, body: string): Promise<PullRequestReviewComment> {\n const text = body.trim()\n if (text.length === 0 || text.length > MAX_REPLY_CHARS) {\n throw new PullRequestFeedbackError('invalid-request', 'The reply body is invalid.')\n }\n const repository = await this.#repository(cwd)\n const gh = await this.#gh()\n const result = await this.#run(\n gh,\n ['api', '-X', 'POST', `repos/${repository}/pulls/${pullNumber}/comments/${commentId}/replies`, '--input', '-'],\n cwd,\n GH_TIMEOUT_MS,\n JSON.stringify({ body: text }),\n )\n if (result.exitCode !== 0) throw new PullRequestFeedbackError('reply-failed', 'The reply could not be posted.')\n let posted: PullRequestReviewComment | undefined\n try {\n const parsed = JSON.parse(result.stdout) as unknown\n const path = typeof record(parsed)?.path === 'string' ? String(record(parsed)?.path) : ''\n const line = Number.isSafeInteger(record(parsed)?.line) ? Number(record(parsed)?.line) : undefined\n posted = parseReplyComment(parsed, {\n path,\n ...(line === undefined ? {} : { line }),\n side: record(parsed)?.side === 'LEFT' ? 'old' : 'new',\n })\n } catch {\n posted = undefined\n }\n if (posted === undefined) throw new PullRequestFeedbackError('reply-failed', 'The posted reply could not be read back.')\n return posted\n }\n\n /** Resolve or reopen a thread. Returns the state GitHub reports afterwards. */\n async setResolved(cwd: string, threadId: string, resolved: boolean): Promise<boolean> {\n const gh = await this.#gh()\n const result = await this.#run(gh, [\n 'api', 'graphql',\n '-f', `threadId=${threadId}`,\n '-f', `query=${resolved ? RESOLVE_MUTATION : UNRESOLVE_MUTATION}`,\n ], cwd, GH_TIMEOUT_MS)\n if (result.exitCode !== 0) throw new PullRequestFeedbackError('resolve-failed', 'The thread could not be updated.')\n try {\n const data = record(record(JSON.parse(result.stdout) as unknown)?.data)\n const thread = record(record(data?.[resolved ? 'resolveReviewThread' : 'unresolveReviewThread'])?.thread)\n if (typeof thread?.isResolved !== 'boolean') throw new Error('missing state')\n return thread.isResolved\n } catch {\n throw new PullRequestFeedbackError('resolve-failed', 'The thread state could not be read back.')\n }\n }\n\n /** Logins GitHub would notify from this repository, for the reply composer. */\n async mentionables(cwd: string, query: string): Promise<readonly MentionableUser[]> {\n const { owner, name } = await this.#repositoryParts(cwd)\n const gh = await this.#gh()\n const result = await this.#run(gh, [\n 'api', 'graphql',\n '-f', `owner=${owner}`, '-f', `name=${name}`, '-f', `q=${query}`,\n '-f', `query=${MENTIONABLE_USERS_QUERY}`,\n ], cwd, GH_TIMEOUT_MS)\n if (result.exitCode !== 0) return []\n try {\n return parseMentionableUsers(JSON.parse(result.stdout))\n } catch {\n return []\n }\n }\n\n /** `signal` bounds the log fetches below: each is capped on its own, but they\n * run one after another, so the honest worst case is their sum rather than\n * any single ceiling — more than a route is allowed to hold a connection. */\n async failingChecks(cwd: string, pullNumber: number, signal?: AbortSignal): Promise<readonly FailingCheck[]> {\n const gh = await this.#gh()\n const result = await this.#run(gh, [\n 'pr', 'checks', String(pullNumber), '--json', 'name,state,link,description,bucket',\n ], cwd, GH_TIMEOUT_MS)\n // gh pr checks exits non-zero when checks are failing; that IS our case.\n let checks: readonly FailingCheck[]\n try {\n checks = parseFailingChecks(JSON.parse(result.stdout))\n } catch {\n throw new PullRequestFeedbackError('checks-unavailable', 'Pull request checks could not be loaded.')\n }\n const detailed: FailingCheck[] = []\n for (const check of checks) {\n const jobId = detailed.length < MAX_FAILING_CHECKS ? actionsJobId(check.link) : undefined\n if (jobId === undefined) {\n detailed.push(check)\n continue\n }\n if (signal?.aborted === true) {\n detailed.push(check)\n continue\n }\n const log = await this.#run(gh, ['run', 'view', '--job', jobId, '--log-failed'], cwd, GH_TIMEOUT_MS)\n detailed.push(log.exitCode === 0 && log.stdout.trim().length > 0 ? { ...check, log: boundedLogTail(log.stdout) } : check)\n }\n return detailed\n }\n\n async #repository(cwd: string): Promise<string> {\n const git = await this.#git()\n const remote = await this.#run(git, ['remote', 'get-url', 'origin'], cwd, GIT_TIMEOUT_MS)\n const repository = remote.exitCode === 0 ? parseGitHubRemote(remote.stdout) : undefined\n if (repository === undefined) throw new PullRequestFeedbackError('no-github-remote', 'The repository has no GitHub origin remote.')\n return repository\n }\n\n /** GraphQL takes the owner and the name as separate variables, so they never\n * reach the query text itself. */\n async #repositoryParts(cwd: string): Promise<{ owner: string; name: string }> {\n const [owner, name] = (await this.#repository(cwd)).split('/')\n if (owner === undefined || name === undefined || owner.length === 0 || name.length === 0) {\n throw new PullRequestFeedbackError('no-github-remote', 'The repository has no GitHub origin remote.')\n }\n return { owner, name }\n }\n\n #git(): Promise<string> {\n this.#gitExecutable ??= this.#runtime.resolveExecutable('git')\n return this.#gitExecutable\n }\n\n #gh(): Promise<string> {\n this.#ghExecutable ??= this.#runtime.resolveExecutable('gh').catch(() => {\n throw new PullRequestFeedbackError('gh-unavailable', 'GitHub CLI is unavailable.')\n })\n return this.#ghExecutable\n }\n\n #run(executable: string, args: readonly string[], cwd: string, timeoutMs: number, input?: string): Promise<CommandResult> {\n const handle = this.#runtime.spawn({\n argv: [executable, ...args],\n cwd,\n stdio: {\n stdin: input === undefined ? 'ignore' : 'pipe',\n stdout: { maxBytes: MAX_OUTPUT_BYTES },\n stderr: { maxBytes: 64 * 1024 },\n },\n graceMs: 1_000,\n signal: AbortSignal.timeout(timeoutMs),\n env: {},\n })\n if (input !== undefined) handle.stdin?.end(input)\n return collect(handle)\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REPOSITORY_FEEDBACK_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport { PullRequestFeedbackError, type PullRequestFeedbackService } from './pr-feedback.ts'\n\nconst MAX_SESSION_ID_CHARS = 1_024\nconst MAX_BODY_BYTES = 16 * 1024\nconst MAX_REPLY_CHARS = 2_000\nconst MAX_THREAD_ID_CHARS = 512\nconst MAX_MENTION_QUERY_CHARS = 64\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\n let parsed: unknown\n try {\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\n } catch (error) {\n // Malformed JSON keeps its own 400; the cap is the only other refusal the\n // transport raises, and the panel already knows that code.\n if (error instanceof SyntaxError) throw error\n throw new PullRequestFeedbackError('body-too-large', 'The request body is too large.')\n }\n const value = record(parsed)\n if (value === undefined) throw new PullRequestFeedbackError('invalid-request', 'The request body is invalid.')\n return value\n}\n\nfunction replyBody(input: Record<string, unknown>): string {\n const body = typeof input.body === 'string' ? input.body.trim() : ''\n if (body.length === 0 || body.length > MAX_REPLY_CHARS || body.includes('\\0')) {\n throw new PullRequestFeedbackError('invalid-request', 'The reply body is invalid.')\n }\n return body\n}\n\nfunction commentId(input: Record<string, unknown>): number {\n const value = input.commentId\n if (typeof value !== 'number' || !Number.isSafeInteger(value) || value <= 0) {\n throw new PullRequestFeedbackError('invalid-request', 'The comment id is invalid.')\n }\n return value\n}\n\nfunction threadId(input: Record<string, unknown>): string {\n const value = input.threadId\n if (typeof value !== 'string' || value.length === 0 || value.length > MAX_THREAD_ID_CHARS) {\n throw new PullRequestFeedbackError('invalid-request', 'The thread id is invalid.')\n }\n return value\n}\n\nfunction sessionId(url: URL): string {\n const value = url.searchParams.get('sessionId')\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) {\n throw new PullRequestFeedbackError('invalid-session', 'The session is invalid.')\n }\n return value\n}\n\nfunction pullNumber(url: URL): number {\n const value = Number(url.searchParams.get('number'))\n if (!Number.isSafeInteger(value) || value <= 0 || value > 1_000_000_000) {\n throw new PullRequestFeedbackError('invalid-request', 'The pull request number is invalid.')\n }\n return value\n}\n\n/** Every arm shells out to `gh`, so the whole prefix carries the network budget. */\nexport function registerPullRequestFeedbackRoute(\n ctx: Context,\n service: PullRequestFeedbackService,\n cwdForSession: (sessionId: string, root?: string) => string | undefined,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'prefix',\n path: CLAUDE_REPOSITORY_FEEDBACK_PATH,\n methods: ['GET', 'POST'],\n budget: 'remote',\n handler: async io => {\n const url = io.url\n const reads = io.method === 'GET'\n const writes = io.method === 'POST'\n try {\n const cwd = cwdForSession(sessionId(url), url.searchParams.get('root') ?? undefined)\n if (cwd === undefined) throw new PullRequestFeedbackError('session-unavailable', 'The Claude session is unavailable.')\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/comments`) {\n if (!reads) return { status: 405, value: { error: 'method not allowed' } }\n return { status: 200, value: { threads: await service.threads(cwd, pullNumber(url)) } }\n }\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/checks`) {\n if (!reads) return { status: 405, value: { error: 'method not allowed' } }\n return { status: 200, value: { checks: await service.failingChecks(cwd, pullNumber(url), io.signal) } }\n }\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/mentionables`) {\n if (!reads) return { status: 405, value: { error: 'method not allowed' } }\n const query = (url.searchParams.get('q') ?? '').slice(0, MAX_MENTION_QUERY_CHARS)\n return { status: 200, value: { users: await service.mentionables(cwd, query) } }\n }\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/reply`) {\n if (!writes) return { status: 405, value: { error: 'method not allowed' } }\n const input = await readJson(io)\n const comment = await service.reply(cwd, pullNumber(url), commentId(input), replyBody(input))\n return { status: 200, value: { comment } }\n }\n if (url.pathname === `${CLAUDE_REPOSITORY_FEEDBACK_PATH}/resolve`) {\n if (!writes) return { status: 405, value: { error: 'method not allowed' } }\n const input = await readJson(io)\n if (typeof input.resolved !== 'boolean') {\n throw new PullRequestFeedbackError('invalid-request', 'The resolved field is required.')\n }\n return { status: 200, value: { resolved: await service.setResolved(cwd, threadId(input), input.resolved) } }\n }\n return { status: 404, value: { error: 'not found' } }\n } catch (error) {\n if (error instanceof PullRequestFeedbackError) {\n return { status: 409, value: { error: error.code, message: error.message } }\n }\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 500, value: { error: 'pr-feedback-unavailable', message: 'Pull request feedback is unavailable.' } }\n }\n },\n })\n}\n","import { isAbsolute } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REPOSITORY_STATUS_PATH } from './constants.ts'\nimport { registerPluginRoute } from './http.ts'\nimport type { RepositoryStatusService } from './repository-status.ts'\n\nconst MAX_PATH_CHARS = 4_096\n\n/** Read-only repository status for an arbitrary directory (the overview panel\n * aggregates every Claude session's checkout through this).\n *\n * The route signal is threaded into the service because this is the one read\n * the overview polls per distinct checkout every 30 seconds: freeing the\n * socket at the budget while the Host kept scanning would just grow a queue\n * of work nobody is waiting for any more. */\nexport function registerRepositoryStatusRoute(ctx: Context, service: RepositoryStatusService): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_REPOSITORY_STATUS_PATH,\n methods: ['GET'],\n budget: 'git',\n handler: async io => {\n const cwd = io.url.searchParams.get('cwd')\n if (cwd === null || cwd.length === 0 || cwd.length > MAX_PATH_CHARS || !isAbsolute(cwd) || cwd.includes('\\0')) {\n return { status: 400, value: { error: 'invalid-request', message: 'The cwd query parameter is invalid.' } }\n }\n try {\n return { status: 200, value: await service.inspect(cwd, io.signal) }\n } catch {\n return { status: 500, value: { error: 'repository-status-unavailable', message: 'Repository status is unavailable.' } }\n }\n },\n })\n}\n","import { isAbsolute } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REPOSITORY_FILE_PATH } from './constants.ts'\nimport { registerPluginRoute } from './http.ts'\nimport { RepositoryFileError, type RepositoryStatusService } from './repository-status.ts'\n\nconst MAX_PATH_CHARS = 4_096\n\n/** Read-only slice of a working-tree file so the diff panel can expand unmodified lines around hunks. */\nexport function registerRepositoryFileRoute(ctx: Context, service: Pick<RepositoryStatusService, 'fileLines'>): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_REPOSITORY_FILE_PATH,\n methods: ['GET'],\n // One bounded read of a file already on disk.\n budget: 'git',\n handler: async io => {\n const params = io.url.searchParams\n const cwd = params.get('cwd')\n const path = params.get('path')\n const from = Number(params.get('from'))\n const to = Number(params.get('to'))\n if (cwd === null || cwd.length === 0 || cwd.length > MAX_PATH_CHARS || !isAbsolute(cwd) || cwd.includes('\\0')) {\n return { status: 400, value: { error: 'invalid-request', message: 'The cwd query parameter is invalid.' } }\n }\n if (path === null || path.length === 0 || path.length > MAX_PATH_CHARS) {\n return { status: 400, value: { error: 'invalid-request', message: 'The path query parameter is invalid.' } }\n }\n try {\n return { status: 200, value: await service.fileLines(cwd, path, from, to) }\n } catch (error) {\n if (error instanceof RepositoryFileError) {\n return { status: error.code === 'invalid-request' ? 400 : 409, value: { error: error.code, message: error.message } }\n }\n return { status: 500, value: { error: 'repository-file-unavailable', message: 'The file could not be read.' } }\n }\n },\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { chmod, mkdir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\n\nconst REQUEST_TIMEOUT_MS = 15_000\nconst MAX_RESULTS = 20\nconst MAX_QUERY_CHARS = 200\nconst MAX_STORE_BYTES = 64 * 1024\n\nexport interface JiraConnectionInput {\n readonly siteUrl: string\n readonly email: string\n readonly apiToken: string\n}\n\ninterface JiraStore extends JiraConnectionInput {\n readonly displayName?: string\n readonly accountId?: string\n}\n\n/** Connection state exposed to the browser; never carries the token. */\nexport interface JiraStatus {\n readonly connected: boolean\n readonly siteUrl?: string\n readonly email?: string\n readonly displayName?: string\n}\n\nexport interface JiraTicket {\n readonly key: string\n readonly summary: string\n readonly url: string\n readonly status?: string\n readonly type?: string\n}\n\nexport interface JiraServiceOptions {\n readonly storePath?: string\n readonly fetch?: typeof fetch\n}\n\nexport class JiraError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'JiraError'\n this.code = code\n }\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\n/** Jira Cloud sites are origins; Data Center may carry a context path. */\nexport function normalizeSiteUrl(value: string): string {\n let url: URL\n try {\n url = new URL(value.trim())\n } catch {\n throw new JiraError('invalid-site', 'The Jira site URL is invalid.')\n }\n if (url.protocol !== 'https:') throw new JiraError('invalid-site', 'The Jira site URL must use https.')\n return `${url.origin}${url.pathname.replace(/\\/+$/u, '')}`\n}\n\nexport function ticketKeyOf(query: string): string | undefined {\n const match = /^([A-Za-z][A-Za-z0-9_]*)-(\\d+)$/u.exec(query.trim())\n return match === null ? undefined : `${match[1]!.toUpperCase()}-${match[2]!}`\n}\n\n/** Jira's text index carries summary, description and comments -- never the\n * issue key -- so a bare ticket number (\"5697\") can never reach PSOS-5697\n * through `text ~`. The issue picker is the endpoint behind Jira's own quick\n * search and does match keys; its hits become the key filter the normal\n * search then reads the display fields from. */\nexport function pickerKeys(value: unknown, number: string): readonly string[] {\n const sections = record(value)?.sections\n if (!Array.isArray(sections)) return []\n const keys: string[] = []\n for (const section of sections) {\n const issues = record(section)?.issues\n if (!Array.isArray(issues)) continue\n for (const issue of issues) {\n const raw = record(issue)?.key\n const key = ticketKeyOf(typeof raw === 'string' ? raw : '')\n if (key !== undefined && key.endsWith(`-${number}`) && !keys.includes(key)) keys.push(key)\n }\n }\n return keys\n}\n\n/** Keys arrive validated by `ticketKeyOf`, so they cannot break out of the quotes. */\nexport function keyJql(keys: readonly string[]): string {\n return `key in (${keys.map(key => `\"${key}\"`).join(', ')}) ORDER BY updated DESC`\n}\n\nexport function buildJql(query: string): string {\n const trimmed = query.trim().slice(0, MAX_QUERY_CHARS)\n if (trimmed.length === 0) return 'statusCategory != Done ORDER BY updated DESC'\n const key = ticketKeyOf(trimmed)\n if (key !== undefined) return `key = \"${key}\"`\n const escaped = trimmed.replaceAll('\\\\', '\\\\\\\\').replaceAll('\"', '\\\\\"')\n return `text ~ \"${escaped}*\" ORDER BY updated DESC`\n}\n\nexport function parseTickets(value: unknown, siteUrl: string): readonly JiraTicket[] {\n const issues = record(value)?.issues\n if (!Array.isArray(issues)) return []\n const tickets: JiraTicket[] = []\n for (const item of issues) {\n const issue = record(item)\n const fields = record(issue?.fields)\n if (issue === undefined || typeof issue.key !== 'string' || fields === undefined) continue\n const status = record(fields.status)?.name\n const type = record(fields.issuetype)?.name\n tickets.push({\n key: issue.key,\n summary: typeof fields.summary === 'string' ? fields.summary.slice(0, 256) : '',\n url: `${siteUrl}/browse/${issue.key}`,\n ...(typeof status === 'string' ? { status } : {}),\n ...(typeof type === 'string' ? { type } : {}),\n })\n if (tickets.length >= MAX_RESULTS) break\n }\n return tickets\n}\n\nfunction statusOf(store: JiraStore | undefined): JiraStatus {\n if (store === undefined) return { connected: false }\n return {\n connected: true,\n siteUrl: store.siteUrl,\n email: store.email,\n ...(store.displayName === undefined ? {} : { displayName: store.displayName }),\n }\n}\n\n/** Jira Cloud access through the user's API token (Basic auth). */\nexport class JiraService {\n readonly #storePath: string\n readonly #fetch: typeof fetch\n\n constructor(options: JiraServiceOptions = {}) {\n this.#storePath = options.storePath ?? dshHomePath('plugins', 'dsh-claude', 'jira.json')\n this.#fetch = options.fetch ?? globalThis.fetch\n }\n\n async status(): Promise<JiraStatus> {\n return statusOf(await this.#read())\n }\n\n async connect(input: JiraConnectionInput): Promise<JiraStatus> {\n const siteUrl = normalizeSiteUrl(input.siteUrl)\n const email = input.email.trim()\n const apiToken = input.apiToken.trim()\n if (email.length === 0 || email.length > 320 || apiToken.length === 0 || apiToken.length > 4_096) {\n throw new JiraError('invalid-credentials', 'An account email and API token are required.')\n }\n const connection = { siteUrl, email, apiToken }\n const myself = record(await this.#json(connection, '/rest/api/3/myself'))\n const displayName = typeof myself?.displayName === 'string' ? myself.displayName : undefined\n const accountId = typeof myself?.accountId === 'string' ? myself.accountId : undefined\n const store: JiraStore = {\n ...connection,\n ...(displayName === undefined ? {} : { displayName }),\n ...(accountId === undefined ? {} : { accountId }),\n }\n await this.#write(store)\n return statusOf(store)\n }\n\n /** Assign a ticket to the connected account (used once a ticket's worktree exists). */\n async assignToMe(key: string): Promise<void> {\n const store = await this.#read()\n if (store === undefined) throw new JiraError('not-connected', 'Connect Jira in Settings first.')\n const ticket = ticketKeyOf(key)\n if (ticket === undefined) throw new JiraError('invalid-request', 'The ticket key is invalid.')\n let accountId = store.accountId\n if (accountId === undefined) {\n const myself = record(await this.#json(store, '/rest/api/3/myself'))\n if (typeof myself?.accountId !== 'string') throw new JiraError('jira-failed', 'The Jira account id is unavailable.')\n accountId = myself.accountId\n await this.#write({ ...store, accountId })\n }\n await this.#json(store, `/rest/api/3/issue/${ticket}/assignee`, { method: 'PUT', body: { accountId } })\n }\n\n async disconnect(): Promise<void> {\n await rm(this.#storePath, { force: true })\n }\n\n async search(query: string): Promise<readonly JiraTicket[]> {\n const store = await this.#read()\n if (store === undefined) throw new JiraError('not-connected', 'Connect Jira in Settings first.')\n const params = new URLSearchParams({\n jql: await this.#searchJql(store, query.trim().slice(0, MAX_QUERY_CHARS)),\n maxResults: String(MAX_RESULTS),\n fields: 'summary,status,issuetype',\n })\n let body: unknown\n try {\n body = await this.#json(store, `/rest/api/3/search/jql?${params.toString()}`)\n } catch (error) {\n // Older deployments only serve the classic search endpoint.\n if (!(error instanceof JiraError && error.code === 'not-found')) throw error\n body = await this.#json(store, `/rest/api/3/search?${params.toString()}`)\n }\n return parseTickets(body, store.siteUrl)\n }\n\n /** A bare ticket number resolves through the picker; everything else is JQL.\n * A site that cannot serve the picker falls back to the text search rather\n * than failing the whole lookup. */\n async #searchJql(store: JiraStore, query: string): Promise<string> {\n if (!/^\\d+$/u.test(query)) return buildJql(query)\n const keys = await this.#json(store, `/rest/api/3/issue/picker?query=${encodeURIComponent(query)}`)\n .then(body => pickerKeys(body, query), () => [])\n return keys.length === 0 ? buildJql(query) : keyJql(keys)\n }\n\n async #json(connection: JiraConnectionInput, path: string, init: { method?: 'GET' | 'PUT'; body?: unknown } = {}): Promise<unknown> {\n let response: Response\n try {\n response = await this.#fetch(`${connection.siteUrl}${path}`, {\n method: init.method ?? 'GET',\n headers: {\n accept: 'application/json',\n authorization: `Basic ${Buffer.from(`${connection.email}:${connection.apiToken}`).toString('base64')}`,\n ...(init.body === undefined ? {} : { 'content-type': 'application/json' }),\n },\n ...(init.body === undefined ? {} : { body: JSON.stringify(init.body) }),\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n })\n } catch {\n throw new JiraError('unreachable', 'The Jira site could not be reached.')\n }\n if (response.status === 401 || response.status === 403) throw new JiraError('unauthorized', 'Jira rejected the credentials.')\n if (response.status === 404) throw new JiraError('not-found', 'The Jira endpoint was not found.')\n if (!response.ok) throw new JiraError('jira-failed', `Jira responded with HTTP ${response.status}.`)\n if (response.status === 204) return undefined\n try {\n return await response.json() as unknown\n } catch {\n throw new JiraError('jira-failed', 'Jira returned an invalid response.')\n }\n }\n\n async #read(): Promise<JiraStore | undefined> {\n let text: string\n try {\n text = await readFile(this.#storePath, 'utf8')\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n if (Buffer.byteLength(text) > MAX_STORE_BYTES) return undefined\n const input = record(JSON.parse(text))\n if (input === undefined || typeof input.siteUrl !== 'string' || typeof input.email !== 'string' || typeof input.apiToken !== 'string') return undefined\n return {\n siteUrl: input.siteUrl,\n email: input.email,\n apiToken: input.apiToken,\n ...(typeof input.displayName === 'string' ? { displayName: input.displayName } : {}),\n ...(typeof input.accountId === 'string' ? { accountId: input.accountId } : {}),\n }\n }\n\n async #write(store: JiraStore): Promise<void> {\n await mkdir(dirname(this.#storePath), { recursive: true, mode: 0o700 })\n const temporary = `${this.#storePath}.${process.pid}.${randomUUID()}.tmp`\n try {\n await writeFile(temporary, `${JSON.stringify(store, null, 2)}\\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\n await chmod(temporary, 0o600)\n await rename(temporary, this.#storePath)\n } finally {\n await rm(temporary, { force: true }).catch(() => undefined)\n }\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_JIRA_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport { JiraError, type JiraService } from './jira.ts'\n\nconst MAX_BODY_BYTES = 8 * 1024\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\n/** The wrapper enforces the byte cap; its plain rejection is translated back\n * into the JiraError shape the panel already knows how to render. */\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\n let body: unknown\n try {\n body = await io.body(MAX_BODY_BYTES)\n } catch (error) {\n if (error instanceof SyntaxError) throw error\n throw new JiraError('body-too-large', 'The request body is too large.')\n }\n const value = record(body)\n if (value === undefined) throw new JiraError('invalid-request', 'The request body is invalid.')\n return value\n}\n\nfunction string(input: Record<string, unknown>, key: string): string {\n const value = input[key]\n if (typeof value !== 'string') throw new JiraError('invalid-request', `The ${key} field is required.`)\n return value\n}\n\nexport function registerJiraRoute(ctx: Context, service: JiraService): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'prefix',\n path: CLAUDE_JIRA_PATH,\n methods: ['GET', 'POST'],\n budget: 'git',\n handler: async io => {\n const url = io.url\n try {\n if (url.pathname === `${CLAUDE_JIRA_PATH}/status`) {\n if (io.method !== 'GET') return { status: 405, value: { error: 'method not allowed' } }\n return { status: 200, value: await service.status() }\n }\n if (url.pathname === `${CLAUDE_JIRA_PATH}/connect`) {\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\n const input = await readJson(io)\n return {\n status: 200,\n value: await service.connect({\n siteUrl: string(input, 'siteUrl'),\n email: string(input, 'email'),\n apiToken: string(input, 'apiToken'),\n }),\n }\n }\n if (url.pathname === `${CLAUDE_JIRA_PATH}/disconnect`) {\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\n await service.disconnect()\n return { status: 200, value: { connected: false } }\n }\n if (url.pathname === `${CLAUDE_JIRA_PATH}/assign`) {\n if (io.method !== 'POST') return { status: 405, value: { error: 'method not allowed' } }\n const input = await readJson(io)\n await service.assignToMe(string(input, 'key'))\n return { status: 200, value: { assigned: true } }\n }\n if (url.pathname === `${CLAUDE_JIRA_PATH}/search`) {\n if (io.method !== 'GET') return { status: 405, value: { error: 'method not allowed' } }\n return { status: 200, value: { tickets: await service.search(url.searchParams.get('query') ?? '') } }\n }\n return { status: 404, value: { error: 'not found' } }\n } catch (error) {\n if (error instanceof JiraError) return { status: 409, value: { error: error.code, message: error.message } }\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 500, value: { error: 'jira-unavailable', message: 'Jira is unavailable.' } }\n }\n },\n })\n}\n","import { StringDecoder } from 'node:string_decoder'\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\n\nconst MAX_SELECTION_CHARS = 8_000\nconst MAX_CONTEXT_CHARS = 16_000\nconst MAX_QUESTION_CHARS = 2_000\nconst ASK_TIMEOUT_MS = 180_000\nconst MAX_STDERR_BYTES = 64 * 1024\nconst MAX_TOOL_SUMMARY_CHARS = 160\nexport const READ_ONLY_TOOLS = ['Read', 'Grep', 'Glob'] as const\n\ntype AskRuntime = Pick<SubprocessRuntime, 'spawn'>\n\nexport interface AskRequest {\n readonly selection: string\n readonly context?: string\n readonly question: string\n}\n\n/** Model and effort the session last ran with; mirrored onto the side query. */\nexport interface AskPreferences {\n readonly model?: string\n readonly thinkingMode?: string\n}\n\nexport class AskError extends Error {\n readonly code: string\n\n constructor(code: string, message: string) {\n super(message)\n this.name = 'AskError'\n this.code = code\n }\n}\n\nfunction fence(value: string): string {\n return `\"\"\"\\n${value.replaceAll('\"\"\"', '\" \" \"')}\\n\"\"\"`\n}\n\nexport function askPrompt(request: AskRequest): string {\n const selection = request.selection.trim().slice(0, MAX_SELECTION_CHARS)\n const context = (request.context ?? '').trim().slice(0, MAX_CONTEXT_CHARS)\n const question = request.question.trim().slice(0, MAX_QUESTION_CHARS)\n return [\n 'You are answering a follow-up question about part of an earlier assistant reply in this project.',\n '',\n 'Selected passage:',\n fence(selection),\n ...(context.length === 0 || context === selection ? [] : ['', 'Surrounding reply, for context only:', fence(context)]),\n '',\n `Question: ${question}`,\n '',\n 'Answer the question directly and concisely, in the same language as the question. Use Markdown.',\n 'Only the read-only tools Read, Grep, and Glob are available; use them when the answer depends on project code, otherwise answer from the passage.',\n ].join('\\n')\n}\n\n/** CLI effort for a session thinking mode; `off` and unknown modes send nothing. */\nexport function effortFor(thinkingMode: string | undefined): string | undefined {\n if (thinkingMode === undefined || thinkingMode === 'off') return undefined\n if (thinkingMode === 'ultracode') return 'max'\n return ['low', 'medium', 'high', 'max'].includes(thinkingMode) ? thinkingMode : undefined\n}\n\nexport function askArguments(preferences: AskPreferences): readonly string[] {\n const effort = effortFor(preferences.thinkingMode)\n return [\n '-p', '--output-format', 'stream-json', '--verbose', '--include-partial-messages',\n // No MCP servers: a follow-up question never needs them and connecting\n // them roughly doubles cold start.\n '--strict-mcp-config', '--mcp-config', '{\"mcpServers\":{}}',\n ...(preferences.model === undefined || preferences.model === 'default' ? [] : ['--model', preferences.model]),\n ...(effort === undefined ? [] : ['--effort', effort]),\n // Read-only inspection only; both flags are variadic, so they stay last\n // and the prompt travels over stdin.\n '--tools', ...READ_ONLY_TOOLS, '--allowedTools', ...READ_ONLY_TOOLS,\n ]\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\n/** What one stream-json line contributes: streamed answer text, streamed\n * thinking, or the final result (used only when no text streamed). */\nexport type AskToolPhase = 'start' | 'input' | 'done'\n\nexport type AskStreamEvent =\n | { readonly type: 'text'; readonly text: string }\n | { readonly type: 'thinking'; readonly text: string }\n | { readonly type: 'status'; readonly text: string }\n | { readonly type: 'tool'; readonly id: string; readonly phase: AskToolPhase; readonly name?: string; readonly summary?: string; readonly error?: boolean }\n | { readonly type: 'result'; readonly text: string }\n\n/** One-line description of a tool call, mirroring the main window's step titles. */\nexport function toolSummary(input: unknown): string | undefined {\n const fields = record(input)\n if (fields === undefined) return undefined\n const candidate = [fields.command, fields.pattern, fields.file_path, fields.path, fields.query].find(value => typeof value === 'string' && value.length > 0)\n const text = typeof candidate === 'string' ? candidate : JSON.stringify(fields)\n return text.replaceAll(/\\s+/gu, ' ').trim().slice(0, MAX_TOOL_SUMMARY_CHARS)\n}\n\nexport function eventsOfStreamLine(line: string): readonly AskStreamEvent[] {\n let parsed: Record<string, unknown> | undefined\n try {\n parsed = record(JSON.parse(line))\n } catch {\n return []\n }\n if (parsed === undefined) return []\n if (parsed.type === 'system' && parsed.subtype === 'init') return [{ type: 'status', text: 'ready' }]\n if (parsed.type === 'stream_event') {\n const event = record(parsed.event)\n if (event?.type === 'content_block_start') {\n const block = record(event.content_block)\n if (block?.type === 'tool_use' && typeof block.id === 'string' && typeof block.name === 'string') {\n return [{ type: 'tool', id: block.id, phase: 'start', name: block.name }]\n }\n return []\n }\n const delta = record(event?.delta)\n if (event?.type !== 'content_block_delta' || delta === undefined) return []\n if (delta.type === 'text_delta' && typeof delta.text === 'string') return [{ type: 'text', text: delta.text }]\n if (delta.type === 'thinking_delta' && typeof delta.thinking === 'string') return [{ type: 'thinking', text: delta.thinking }]\n return []\n }\n if (parsed.type === 'assistant' || parsed.type === 'user') {\n const content = record(parsed.message)?.content\n if (!Array.isArray(content)) return []\n const events: AskStreamEvent[] = []\n for (const item of content) {\n const block = record(item)\n if (block?.type === 'tool_use' && typeof block.id === 'string' && typeof block.name === 'string') {\n const summary = toolSummary(block.input)\n events.push({ type: 'tool', id: block.id, phase: 'input', name: block.name, ...(summary === undefined ? {} : { summary }) })\n } else if (block?.type === 'tool_result' && typeof block.tool_use_id === 'string') {\n events.push({ type: 'tool', id: block.tool_use_id, phase: 'done', ...(block.is_error === true ? { error: true } : {}) })\n }\n }\n return events\n }\n if (parsed.type === 'result' && typeof parsed.result === 'string') return [{ type: 'result', text: parsed.result }]\n return []\n}\n\nexport type AskProgressEvent = Exclude<AskStreamEvent, { type: 'result' }>\n\n/** One-shot Claude Code query answering a question about selected reply text. */\nexport class AskService {\n readonly #runtime: AskRuntime\n readonly #executablePath: string\n\n constructor(runtime: AskRuntime, executablePath: string) {\n this.#runtime = runtime\n this.#executablePath = executablePath\n }\n\n async ask(cwd: string, request: AskRequest, preferences: AskPreferences, onEvent: (event: AskProgressEvent) => void, signal?: AbortSignal): Promise<void> {\n if (request.question.trim().length === 0 || request.selection.trim().length === 0) {\n throw new AskError('invalid-request', 'A selection and a question are required.')\n }\n if (this.#executablePath.length === 0) throw new AskError('claude-unavailable', 'Claude Code is unavailable.')\n const timeout = AbortSignal.timeout(ASK_TIMEOUT_MS)\n // The prompt rides stdin: `--tools ''` is variadic and would swallow a\n // trailing positional prompt argument.\n const handle = this.#runtime.spawn({\n argv: [this.#executablePath, ...askArguments(preferences)],\n cwd,\n stdio: { stdin: { data: askPrompt(request) }, stdout: 'pipe', stderr: { maxBytes: MAX_STDERR_BYTES } },\n graceMs: 1_000,\n signal: signal === undefined ? timeout : AbortSignal.any([signal, timeout]),\n env: {},\n })\n const stdout = handle.stdout\n if (stdout === undefined) throw new AskError('ask-failed', 'Claude output is unavailable.')\n const decoder = new StringDecoder('utf8')\n let buffer = ''\n let emitted = false\n let result: string | undefined\n const consume = (line: string): void => {\n for (const event of eventsOfStreamLine(line)) {\n if (event.type === 'result') {\n result = event.text\n continue\n }\n if (event.type !== 'tool' && event.text.length === 0) continue\n if (event.type === 'text') emitted = true\n onEvent(event)\n }\n }\n for await (const chunk of stdout) {\n buffer += typeof chunk === 'string' ? chunk : decoder.write(chunk as Buffer)\n const lines = buffer.split('\\n')\n buffer = lines.pop() ?? ''\n for (const line of lines) if (line.trim().length > 0) consume(line)\n }\n buffer += decoder.end()\n if (buffer.trim().length > 0) consume(buffer)\n const outcome = await handle.done\n if (!emitted && result !== undefined && result.length > 0) {\n emitted = true\n onEvent({ type: 'text', text: result })\n }\n if (!emitted) {\n if (signal?.aborted === true) throw new AskError('aborted', 'The question was cancelled.')\n if (timeout.aborted) throw new AskError('timeout', 'Claude took too long to answer.')\n const stderr = handle.collected.stderr?.readFrom(0).text.trim().split(/\\r?\\n/u).filter(line => line.length > 0).at(-1)\n throw new AskError('ask-failed', stderr !== undefined && stderr.length > 0 ? stderr : `Claude exited with code ${String(outcome.exitCode)}.`)\n }\n }\n}\n","import type { ServerResponse } from 'node:http'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { AskError, type AskPreferences, type AskRequest, type AskService } from './ask.ts'\nimport { CLAUDE_ASK_PATH } from './constants.ts'\nimport { json, registerPluginRoute } from './http.ts'\n\nconst MAX_BODY_BYTES = 128 * 1024\nconst MAX_SESSION_ID_CHARS = 1_024\n/** Two sessions may await an answer at once; a third evicts the oldest. */\nconst MAX_CONCURRENT_ASKS = 2\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nfunction askRequest(input: Record<string, unknown>): AskRequest {\n if (typeof input.selection !== 'string' || typeof input.question !== 'string' || (input.context !== undefined && typeof input.context !== 'string')) {\n throw new AskError('invalid-request', 'The selection and question fields are required.')\n }\n return { selection: input.selection, question: input.question, ...(typeof input.context === 'string' ? { context: input.context } : {}) }\n}\n\nfunction ndjson(res: ServerResponse, value: unknown): void {\n res.write(`${JSON.stringify(value)}\\n`)\n}\n\n/** A stream route rather than a unary one: the answer is written as it arrives,\n * so the deadline stays where the work is — `ASK_TIMEOUT_MS` inside the\n * service, fused there with the disconnect signal — instead of a route budget\n * that would cut a legitimate long answer off mid-sentence. */\nexport function registerAskRoute(\n ctx: Context,\n service: AskService,\n cwdForSession: (sessionId: string) => string | undefined,\n preferencesFor: (sessionId: string) => AskPreferences | undefined,\n): void {\n registerPluginRoute(ctx, {\n mode: 'stream',\n kind: 'exact',\n path: CLAUDE_ASK_PATH,\n methods: ['POST'],\n maxConcurrent: MAX_CONCURRENT_ASKS,\n streamKey: url => url.searchParams.get('sessionId') ?? '',\n handler: async (res, io) => {\n let cwd: string\n let request: AskRequest\n let sessionId: string\n try {\n const value = io.url.searchParams.get('sessionId')\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) throw new AskError('invalid-session', 'The session is invalid.')\n sessionId = value\n const resolved = cwdForSession(sessionId)\n if (resolved === undefined) throw new AskError('session-unavailable', 'The Claude session is unavailable.')\n cwd = resolved\n const body = record(await io.body(MAX_BODY_BYTES))\n if (body === undefined) throw new AskError('invalid-request', 'The request body is invalid.')\n request = askRequest(body)\n } catch (error) {\n if (error instanceof AskError) return json(res, 409, { error: error.code, message: error.message })\n if (error instanceof SyntaxError) return json(res, 400, { error: 'invalid-json' })\n return json(res, 500, { error: 'ask-unavailable', message: 'The question could not be sent.' })\n }\n res.writeHead(200, {\n 'content-type': 'application/x-ndjson; charset=utf-8',\n 'cache-control': 'no-store',\n 'x-content-type-options': 'nosniff',\n })\n res.flushHeaders?.()\n try {\n await service.ask(cwd, request, preferencesFor(sessionId) ?? {}, event => { ndjson(res, event.type === 'text' ? { type: 'delta', text: event.text } : event) }, io.signal)\n ndjson(res, { type: 'done' })\n } catch (error) {\n ndjson(res, {\n type: 'error',\n code: error instanceof AskError ? error.code : 'ask-unavailable',\n message: error instanceof AskError ? error.message : 'The question could not be answered.',\n })\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REVIEW_COMMENT_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport { ReviewCommentError, type ReviewCommentStore } from './review-comments.ts'\n\nconst MAX_BODY_BYTES = 16 * 1024\nconst MAX_SESSION_ID_CHARS = 1_024\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\n let parsed: unknown\n try {\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\n } catch (error) {\n if (error instanceof SyntaxError) throw error\n throw new ReviewCommentError('body-too-large', 'The request body is too large.')\n }\n const value = record(parsed)\n if (value === undefined) throw new ReviewCommentError('invalid-request', 'The request body is invalid.')\n return value\n}\n\nfunction sessionIdFromUrl(url: URL): string {\n const value = url.searchParams.get('sessionId')\n if (value === null || value.length === 0 || value.length > MAX_SESSION_ID_CHARS) {\n throw new ReviewCommentError('invalid-session', 'The session is invalid.')\n }\n return value\n}\n\nexport function registerReviewCommentRoute(\n ctx: Context,\n store: ReviewCommentStore,\n ownsSession: (sessionId: string) => boolean,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'prefix',\n path: CLAUDE_REVIEW_COMMENT_PATH,\n methods: ['POST'],\n // The comment store is in memory; only reading the body can wait.\n budget: 'fast',\n handler: async io => {\n try {\n const sessionId = sessionIdFromUrl(io.url)\n if (!ownsSession(sessionId)) throw new ReviewCommentError('session-unavailable', 'The Claude session is unavailable.')\n const pathname = io.url.pathname\n if (pathname === CLAUDE_REVIEW_COMMENT_PATH) {\n const input = await readJson(io)\n const comment = store.add(sessionId, {\n path: input.path,\n line: input.line,\n startLine: input.startLine,\n side: input.side,\n text: input.text,\n })\n return { status: 200, value: { comment } }\n }\n if (pathname === `${CLAUDE_REVIEW_COMMENT_PATH}/clear`) {\n return { status: 200, value: { removed: store.drain(sessionId).length } }\n }\n if (pathname === `${CLAUDE_REVIEW_COMMENT_PATH}/remove`) {\n const input = await readJson(io)\n if (typeof input.id !== 'string' || input.id.length === 0 || input.id.length > 128) {\n throw new ReviewCommentError('invalid-request', 'The comment id is invalid.')\n }\n return { status: 200, value: { removed: store.remove(sessionId, input.id) } }\n }\n return { status: 404, value: { error: 'not found' } }\n } catch (error) {\n if (error instanceof ReviewCommentError) return { status: 409, value: { error: error.code, message: error.message } }\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 500, value: { error: 'review-comment-unavailable', message: 'Review comments are unavailable.' } }\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_PLAN_FEEDBACK_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport { PlanFeedbackError, planNotesOf, type PlanFeedbackGate } from './plan-feedback.ts'\n\nconst MAX_BODY_BYTES = 64 * 1024\nconst MAX_SESSION_ID_CHARS = 1_024\nconst MAX_TOOL_USE_ID_CHARS = 256\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown>> {\n let parsed: unknown\n try {\n parsed = await io.body<unknown>(MAX_BODY_BYTES)\n } catch (error) {\n if (error instanceof SyntaxError) throw error\n throw new PlanFeedbackError('body-too-large', 'The request body is too large.')\n }\n const value = record(parsed)\n if (value === undefined) throw new PlanFeedbackError('invalid-request', 'The request body is invalid.')\n return value\n}\n\n/** Send one plan back for changes.\n *\n * Unary rather than a stream: the panel hands over what the reviewer wrote\n * and the turn carries on in the transcript it was already watching. Answers\n * 409 when nothing is waiting, which is what the panel shows if the approval\n * dialog was answered while the reviewer was still typing. */\nexport function registerPlanFeedbackRoute(\n ctx: Context,\n gate: PlanFeedbackGate,\n ownsSession: (sessionId: string) => boolean,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n budget: 'fast',\n kind: 'exact',\n path: CLAUDE_PLAN_FEEDBACK_PATH,\n methods: ['POST'],\n handler: async io => {\n try {\n const sessionId = io.url.searchParams.get('sessionId')\n if (sessionId === null || sessionId.length === 0 || sessionId.length > MAX_SESSION_ID_CHARS) {\n return { status: 400, value: { error: 'invalid-session' } }\n }\n if (!ownsSession(sessionId)) return { status: 409, value: { error: 'session-unavailable' } }\n const body = await readJson(io)\n const toolUseId = body.toolUseId\n if (typeof toolUseId !== 'string' || toolUseId.length === 0 || toolUseId.length > MAX_TOOL_USE_ID_CHARS) {\n return { status: 400, value: { error: 'invalid-request' } }\n }\n const notes = planNotesOf(body.notes)\n // A plan that is no longer open was decided in the dialog while the\n // reviewer was writing; saying so beats silently dropping their notes.\n if (!gate.submit(toolUseId, notes)) return { status: 409, value: { error: 'plan-settled' } }\n return { status: 200, value: { ok: true } }\n } catch (error) {\n if (error instanceof PlanFeedbackError) return { status: 400, value: { error: error.code, message: error.message } }\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 500, value: { error: 'plan-feedback-unavailable' } }\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_CLIENT_DIAGNOSTICS_PATH } from './constants.ts'\nimport { redactText } from './events.ts'\nimport { registerPluginRoute } from './http.ts'\n\n/** Enough for a message plus a trimmed stack; the client caps its own volume. */\nconst MAX_DIAGNOSTIC_BYTES = 8 * 1024\nconst MAX_DETAIL_CHARS = 2_000\nconst MAX_KIND_CHARS = 60\n\n/** `POST <path>` with `{ kind, detail }`: write one renderer finding to the Host log.\n *\n * The renderer has no other way to speak. A Slot entry that throws is caught\n * by the Host's Slot system and dropped, the shipped Desktop opens no\n * DevTools, and startup still reports `rendererStatus: \"healthy\"` — so a\n * plugin whose UI died silently is indistinguishable from a working one.\n * Every finding here is data written by this package's own client half, but\n * it is still bounded and redacted like any other untrusted input. */\nexport function registerClaudeClientDiagnosticsRoute(ctx: Context): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_CLIENT_DIAGNOSTICS_PATH,\n methods: ['POST'],\n budget: 'fast',\n handler: async io => {\n try {\n const body = await io.body<{ kind?: unknown; detail?: unknown } | null>(MAX_DIAGNOSTIC_BYTES)\n const kind = typeof body?.kind === 'string' ? body.kind.slice(0, MAX_KIND_CHARS) : 'unknown'\n const detail = typeof body?.detail === 'string' ? body.detail : ''\n if (detail === '') return { status: 400, value: { error: 'invalid-request' } }\n ctx.logger.warn(`dsh-claude client [${kind}]: ${redactText(detail, MAX_DETAIL_CHARS)}`)\n return { status: 200, value: { ok: true } }\n } catch (error) {\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 400, value: { error: 'invalid-request' } }\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type { SessionEvent } from '@deepseek-ai/dsh-session'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_REWIND_PATH } from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\nimport { EMPTY_REWIND_STATE, planRewind, rewindRestoreTree, turnAtOrAfter } from './rewind.ts'\nimport type { ClaudeSidecarRepository } from './sidecar.ts'\n\nconst MAX_BODY_BYTES = 4 * 1024\nconst MAX_SESSION_ID_CHARS = 1_024\n\nexport interface ClaudeRewindSessionAccess {\n /** The session log of one plugin-owned session, or undefined for any other. */\n eventsFor: (sessionId: string) => readonly SessionEvent[] | undefined\n /** Whether a turn is in flight; rewinding one would cut it mid-run. */\n busy: (sessionId: string) => boolean\n /** Drop the live Claude process so the next turn resumes at the fork target. */\n reset: (sessionId: string) => Promise<void>\n /** Put the session's checkout back to a captured tree, reporting whether it\n * landed. Absent when the Host offers no way to run git. */\n restoreFiles?: (sessionId: string, tree: string) => Promise<boolean>\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : undefined\n}\n\n/** An oversized body fails the same field checks as a missing one; only\n * malformed JSON is worth reporting separately. */\nasync function readJson(io: PluginRouteIo): Promise<Record<string, unknown> | undefined> {\n try {\n return record(await io.body<unknown>(MAX_BODY_BYTES))\n } catch (error) {\n if (error instanceof SyntaxError) throw error\n return undefined\n }\n}\n\n/** `POST <path>` with `{ sessionId, seq, restoreFiles? }`: hide that surface\n * event and every later one, and arm Claude to resume before the turn it\n * opened. With `restoreFiles`, the checkout is also put back to the tree that\n * turn was admitted against.\n *\n * The conversation rewind is what the user confirmed, so it lands first and\n * stands on its own; a checkout that cannot be restored — no snapshot, a\n * collected tree, no git — reports `filesRestored: false` rather than\n * failing the rewind. */\nexport function registerClaudeRewindRoute(\n ctx: Context,\n sidecar: ClaudeSidecarRepository,\n access: ClaudeRewindSessionAccess,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_REWIND_PATH,\n methods: ['POST'],\n // The session log is already in memory; the sidecar write is local.\n budget: 'git',\n handler: async io => {\n try {\n const input = await readJson(io)\n const sessionId = input?.sessionId\n const seq = input?.seq\n if (typeof sessionId !== 'string' || sessionId.length === 0 || sessionId.length > MAX_SESSION_ID_CHARS\n || typeof seq !== 'number' || !Number.isSafeInteger(seq) || seq < 0) {\n return { status: 400, value: { error: 'invalid-request' } }\n }\n const events = access.eventsFor(sessionId)\n if (events === undefined) return { status: 409, value: { error: 'session-unavailable' } }\n if (access.busy(sessionId)) return { status: 409, value: { error: 'session-busy' } }\n const current = (await sidecar.read(sessionId)).rewind ?? EMPTY_REWIND_STATE\n const planned = planRewind(current, events, seq)\n if (planned === undefined) return { status: 409, value: { error: 'seq-unavailable' } }\n const tree = input?.restoreFiles === true ? rewindRestoreTree(current, events, seq) : undefined\n // The first turn the rewind discards, so the projection drops its\n // activity alongside the hidden seq ranges. Undefined when the cut\n // lands past the last turn, which discards no turn at all.\n await sidecar.writeRewind(sessionId, planned, turnAtOrAfter(events, seq))\n await access.reset(sessionId)\n const filesRestored = tree === undefined || access.restoreFiles === undefined\n ? false\n : await access.restoreFiles(sessionId, tree).catch(() => false)\n return { status: 200, value: { ranges: planned.ranges, filesRestored } }\n } catch (error) {\n if (error instanceof SyntaxError) return { status: 400, value: { error: 'invalid-json' } }\n return { status: 500, value: { error: 'rewind-unavailable' } }\n }\n },\n })\n}\n","/** Which other repositories a session has written into.\n *\n * A session is pinned to one checkout, but Claude writes wherever it is\n * pointed: a monorepo sibling, a dependency checked out next door. Those\n * edits never showed up anywhere -- no diff, no pull request -- because every\n * repository read keyed off the session's own cwd. The file tools' arguments\n * are already on the activity log, so the extra roots are derived from there\n * rather than tracked as new state. */\nimport { dirname, isAbsolute } from 'node:path'\nimport type { ClaudeActivityEvent } from './events.ts'\nimport type { RepositoryStatus } from './repository-status.ts'\n\nconst FILE_TOOLS = new Set(['Edit', 'MultiEdit', 'Write', 'NotebookEdit'])\n/** The activity detail is a redacted JSON string that may be cut short, so\n * this matches the one key rather than parsing the document. */\nconst PATH_KEY = /\"(?:file_path|notebook_path)\"\\s*:\\s*\"((?:[^\"\\\\]|\\\\.)*)\"/u\n\n/** Absolute paths Claude wrote through its file tools, first-seen order. */\nexport function touchedFilePaths(activities: readonly ClaudeActivityEvent[]): readonly string[] {\n const paths = new Set<string>()\n for (const activity of activities) {\n if ((activity.kind !== 'tool-call' && activity.kind !== 'subagent')\n || activity.toolName === undefined || !FILE_TOOLS.has(activity.toolName)\n || activity.detail === undefined) continue\n const escaped = PATH_KEY.exec(activity.detail)?.[1]\n if (escaped === undefined) continue\n try {\n const path = JSON.parse(`\"${escaped}\"`) as string\n if (isAbsolute(path)) paths.add(path)\n } catch {\n // An escape sequence split by the cap; the path is unreadable.\n }\n }\n return [...paths]\n}\n\n/** Repository roots behind the touched paths, minus the session's own, in\n * first-seen order. `rootOf` answers undefined outside any repository. */\nexport async function touchedRepositoryRoots(\n paths: readonly string[],\n sessionRoot: string,\n rootOf: (directory: string) => Promise<string | undefined>,\n max: number,\n): Promise<readonly string[]> {\n const roots: string[] = []\n const directories = new Set(paths.map(path => dirname(path)))\n for (const directory of directories) {\n const root = await rootOf(directory)\n if (root === undefined || root === sessionRoot || roots.includes(root)) continue\n roots.push(root)\n if (roots.length >= max) break\n }\n return roots\n}\n\n/** Whether a linked checkout still has anything to show. A cleaned-up\n * worktree is gone, and a checkout cleaned up in place is back on base with\n * nothing pending -- either way its bar comes down. A clean checkout with an\n * open or merged pull request, or unpushed work, stays. */\nexport function linkedRepositoryShown(status: RepositoryStatus): boolean {\n if (status.status !== 'ready') return false\n return status.dirty === true || status.upstream === false || (status.ahead ?? 0) > 0 || status.pullRequest !== undefined\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport type { SubprocessRuntime } from '@deepseek-ai/dsh-subprocess'\nimport { resolveDshHome } from '@deepseek-ai/dsh-home-paths'\nimport { opendir, readFile, realpath } from 'node:fs/promises'\nimport { dirname, join, resolve } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport { CLAUDE_UPDATE_CHECK_PATH, CLAUDE_UPDATE_PATH } from './constants.ts'\nimport { redactText } from './events.ts'\nimport { registerPluginRoute, type PluginMethod } from './http.ts'\n\nexport const PLUGIN_PACKAGE_NAME = '@norman-else/dsh-claude'\nconst MAX_MANIFEST_BYTES = 256 * 1024\nconst MAX_UPDATE_OUTPUT_BYTES = 32 * 1024\nconst SEMVER = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([0-9A-Za-z.-]+))?(?:\\+[0-9A-Za-z.-]+)?$/\nconst PROFILE_NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$/\n\nexport type InstallSource = 'registry' | 'link' | 'unsupported' | 'unknown'\nexport type UpdateState = 'current' | 'available' | 'linked' | 'unsupported' | 'unavailable' | 'error'\n\nexport interface PluginUpdateStatus {\n currentVersion: string\n latestVersion?: string\n source: InstallSource\n state: UpdateState\n canUpdate: boolean\n restartRequired: boolean\n message?: string\n}\n\ninterface PackageManifest {\n name?: unknown\n version?: unknown\n dependencies?: unknown\n}\n\nexport interface Installation {\n profile: string\n profileDir: string\n source: InstallSource\n spec: string\n}\n\nexport interface UpdateDependencies {\n packageDir?: string\n dshHome?: string\n fetchLatest?: (signal: AbortSignal) => Promise<string>\n resolveExecutable?: (name: string, env?: Readonly<Record<string, string>>, signal?: AbortSignal) => Promise<string>\n spawn?: SubprocessRuntime['spawn']\n requestRestart?: () => void\n}\n\n/** The route owns the deadline now. A direct caller with nothing to cancel\n * against gets a signal that never fires, rather than a second timeout\n * competing with the budget the route already declared. */\nconst NEVER_ABORTS = new AbortController().signal\n\nfunction safeMessage(error: unknown): string {\n return redactText(error instanceof Error ? error.message : String(error), 500)\n}\n\nasync function readManifest(path: string): Promise<PackageManifest> {\n const text = await readFile(path, 'utf8')\n if (Buffer.byteLength(text) > MAX_MANIFEST_BYTES) throw new Error('package manifest is too large')\n const value = JSON.parse(text) as unknown\n if (typeof value !== 'object' || value === null || Array.isArray(value)) throw new Error('package manifest is invalid')\n return value as PackageManifest\n}\n\nfunction dependencySpec(manifest: PackageManifest): string | undefined {\n if (typeof manifest.dependencies !== 'object' || manifest.dependencies === null || Array.isArray(manifest.dependencies)) return undefined\n const value = (manifest.dependencies as Record<string, unknown>)[PLUGIN_PACKAGE_NAME]\n return typeof value === 'string' && value.length <= 2_000 ? value : undefined\n}\n\nexport function classifyInstallSpec(spec: string): InstallSource {\n if (/^(?:link|file|workspace):/i.test(spec)) return 'link'\n if (/^(?:git(?:\\+[^:]+)?:|github:|https?:|npm:)/i.test(spec) || /\\.git(?:#|$)/i.test(spec)) return 'unsupported'\n return /^(?:\\^|~|>=?|<=?|=)?\\s*v?\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?(?:\\s*\\|\\|\\s*(?:\\^|~|>=?|<=?|=)?\\s*v?\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)*$/.test(spec.trim())\n ? 'registry'\n : 'unsupported'\n}\n\nasync function samePath(left: string, right: string): Promise<boolean> {\n try {\n const [a, b] = await Promise.all([realpath(left), realpath(right)])\n return process.platform === 'win32' ? a.toLowerCase() === b.toLowerCase() : a === b\n } catch {\n return false\n }\n}\n\nfunction linkedTarget(profileDir: string, spec: string): string | undefined {\n const match = /^(?:link|file):(.*)$/i.exec(spec)\n return match?.[1] === undefined ? undefined : resolve(profileDir, match[1])\n}\n\nexport async function discoverInstallation(dshHome: string, packageDir: string): Promise<Installation | undefined> {\n const profilesDir = join(dshHome, 'profiles')\n const matches: Installation[] = []\n let profiles\n try {\n profiles = await opendir(profilesDir)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return undefined\n throw error\n }\n for await (const entry of profiles) {\n if (!entry.isDirectory() || !PROFILE_NAME.test(entry.name)) continue\n const profileDir = join(profilesDir, entry.name)\n let manifest: PackageManifest\n try {\n manifest = await readManifest(join(profileDir, 'package.json'))\n } catch {\n continue\n }\n const spec = dependencySpec(manifest)\n if (spec === undefined) continue\n const source = classifyInstallSpec(spec)\n const matchesPackage = source === 'link'\n ? linkedTarget(profileDir, spec) !== undefined && await samePath(linkedTarget(profileDir, spec)!, packageDir)\n : await samePath(join(profileDir, 'node_modules', ...PLUGIN_PACKAGE_NAME.split('/')), packageDir)\n if (matchesPackage) matches.push({ profile: entry.name, profileDir, source, spec })\n }\n return matches.length === 1 ? matches[0] : undefined\n}\n\nfunction parseVersion(version: string): RegExpExecArray {\n const match = SEMVER.exec(version)\n if (match === null) throw new Error('package version is not valid semver')\n return match\n}\n\nexport function compareVersions(left: string, right: string): number {\n const a = parseVersion(left)\n const b = parseVersion(right)\n for (const index of [1, 2, 3]) {\n const difference = Number(a[index]) - Number(b[index])\n if (difference !== 0) return Math.sign(difference)\n }\n const aPre = a[4]\n const bPre = b[4]\n if (aPre === undefined) return bPre === undefined ? 0 : 1\n if (bPre === undefined) return -1\n return aPre.localeCompare(bPre, 'en', { numeric: true })\n}\n\nasync function registryLatest(signal: AbortSignal): Promise<string> {\n const response = await fetch('https://registry.npmjs.org/%40norman-else%2Fdsh-claude', {\n headers: { accept: 'application/vnd.npm.install-v1+json' },\n signal,\n })\n if (!response.ok) throw new Error(`npm registry returned HTTP ${response.status}`)\n const payload = await response.json() as { 'dist-tags'?: { latest?: unknown } }\n const latest = payload['dist-tags']?.latest\n if (typeof latest !== 'string') throw new Error('npm registry response has no latest version')\n parseVersion(latest)\n return latest\n}\n\nasync function resolvePackageContextDir(configured?: string): Promise<{ packageDir: string; manifest: PackageManifest }> {\n const moduleDir = dirname(fileURLToPath(import.meta.url))\n const candidates = configured === undefined ? [moduleDir, dirname(moduleDir)] : [configured]\n for (const packageDir of candidates) {\n try {\n const manifest = await readManifest(join(packageDir, 'package.json'))\n if (manifest.name === PLUGIN_PACKAGE_NAME) return { packageDir, manifest }\n } catch {\n // Continue until the owning package manifest is found.\n }\n }\n throw new Error('plugin package manifest is invalid')\n}\n\nasync function packageContext(deps: UpdateDependencies): Promise<{ version: string; installation?: Installation }> {\n const { packageDir, manifest } = await resolvePackageContextDir(deps.packageDir)\n if (typeof manifest.version !== 'string') throw new Error('plugin package manifest is invalid')\n parseVersion(manifest.version)\n const home = deps.dshHome ?? resolveDshHome()\n const installation = await discoverInstallation(home, packageDir)\n return { version: manifest.version, ...(installation === undefined ? {} : { installation }) }\n}\n\nexport async function checkPluginUpdate(deps: UpdateDependencies = {}, signal: AbortSignal = NEVER_ABORTS): Promise<PluginUpdateStatus> {\n try {\n const { version, installation } = await packageContext(deps)\n if (installation === undefined) return { currentVersion: version, source: 'unknown', state: 'unavailable', canUpdate: false, restartRequired: false, message: 'Active DSH profile could not be identified uniquely' }\n if (installation.source === 'link') return { currentVersion: version, source: 'link', state: 'linked', canUpdate: false, restartRequired: false, message: 'Local development link; updates come from the linked checkout' }\n if (installation.source !== 'registry') return { currentVersion: version, source: installation.source, state: 'unsupported', canUpdate: false, restartRequired: false, message: 'This installation source cannot be updated from the npm registry' }\n const latest = await (deps.fetchLatest ?? registryLatest)(signal)\n const comparison = compareVersions(version, latest)\n return {\n currentVersion: version,\n latestVersion: latest,\n source: 'registry',\n state: comparison < 0 ? 'available' : 'current',\n canUpdate: comparison < 0,\n restartRequired: comparison < 0,\n }\n } catch (error) {\n return { currentVersion: 'unknown', source: 'unknown', state: 'error', canUpdate: false, restartRequired: false, message: safeMessage(error) }\n }\n}\n\nasync function verifyInstalledVersion(installation: Installation, expectedVersion: string): Promise<void> {\n const profileManifest = await readManifest(join(installation.profileDir, 'package.json'))\n if (dependencySpec(profileManifest) !== expectedVersion) {\n throw new Error('DSH plugin update completed without updating the profile dependency')\n }\n const installedManifest = await readManifest(join(\n installation.profileDir,\n 'node_modules',\n ...PLUGIN_PACKAGE_NAME.split('/'),\n 'package.json',\n ))\n if (installedManifest.name !== PLUGIN_PACKAGE_NAME || installedManifest.version !== expectedVersion) {\n throw new Error('DSH plugin update completed without installing the requested version')\n }\n}\n\nexport async function updatePlugin(deps: UpdateDependencies = {}, signal: AbortSignal = NEVER_ABORTS): Promise<PluginUpdateStatus> {\n const { version, installation } = await packageContext(deps)\n if (installation === undefined || installation.source !== 'registry') throw new Error('Plugin update is unavailable for this installation')\n const latest = await (deps.fetchLatest ?? registryLatest)(signal)\n if (compareVersions(version, latest) >= 0) return { currentVersion: version, latestVersion: latest, source: 'registry', state: 'current', canUpdate: false, restartRequired: false }\n const resolveExecutable = deps.resolveExecutable\n const spawn = deps.spawn\n if (resolveExecutable === undefined || spawn === undefined) throw new Error('DSH update runtime is unavailable')\n const executable = await resolveExecutable('dsh', {}, signal)\n const handle = spawn({\n argv: [executable, 'plugin', '--profile', installation.profile, 'add', `${PLUGIN_PACKAGE_NAME}@${latest}`],\n cwd: installation.profileDir,\n env: {},\n stdio: { stdin: 'ignore', stdout: { maxBytes: MAX_UPDATE_OUTPUT_BYTES }, stderr: { maxBytes: MAX_UPDATE_OUTPUT_BYTES } },\n graceMs: 2_000,\n signal,\n })\n const outcome = await handle.done\n if (outcome.exitCode !== 0) {\n const detail = handle.collected.stderr?.readFrom(0).text ?? ''\n throw new Error(`DSH plugin update failed (${outcome.exitCode ?? outcome.signal ?? 'unknown exit'}): ${safeMessage(detail)}`)\n }\n await verifyInstalledVersion(installation, latest)\n if (deps.requestRestart !== undefined) setTimeout(() => deps.requestRestart?.(), 100).unref?.()\n return {\n currentVersion: latest,\n latestVersion: latest,\n source: 'registry',\n state: 'current',\n canUpdate: false,\n restartRequired: deps.requestRestart === undefined,\n message: deps.requestRestart === undefined\n ? 'Update installed; restart DSH Desktop to load it'\n : 'Update installed; DSH Desktop is restarting to load it',\n }\n}\n\nexport function registerClaudeUpdateRoutes(ctx: Context, runtime: Pick<SubprocessRuntime, 'resolveExecutable' | 'spawn'>, deps: UpdateDependencies = {}): void {\n const shared: UpdateDependencies = { ...deps, resolveExecutable: runtime.resolveExecutable.bind(runtime), spawn: runtime.spawn.bind(runtime) }\n const routes: readonly { path: string; method: PluginMethod; run: (signal: AbortSignal) => Promise<PluginUpdateStatus> }[] = [\n { path: CLAUDE_UPDATE_CHECK_PATH, method: 'GET', run: signal => checkPluginUpdate(shared, signal) },\n { path: CLAUDE_UPDATE_PATH, method: 'POST', run: signal => updatePlugin(shared, signal) },\n ]\n for (const route of routes) {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: route.path,\n methods: [route.method],\n // The npm registry, then `dsh plugin add`, then a manifest re-read.\n budget: 'remote',\n handler: async io => {\n try {\n return { status: 200, value: await route.run(io.signal) }\n } catch (error) {\n return { status: 500, value: { error: safeMessage(error) } }\n }\n },\n })\n }\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { CLAUDE_USAGE_PATH } from './constants.ts'\nimport { redactText } from './events.ts'\nimport { registerPluginRoute } from './http.ts'\nimport { latestPlanUsage, recordPlanUsage, type PlanUsageReport } from './plan-usage.ts'\n\nconst EMPTY: PlanUsageReport = { available: false, windows: [], fetchedAt: 0 }\n\nfunction safeMessage(error: unknown): string {\n return redactText(error instanceof Error ? error.message : String(error), 1_000)\n}\n\n/** Plan usage: GET serves the value the metadata bridge last cached (free —\n * it rides an already-running session), POST reads fresh numbers from a\n * throwaway probe process so a refresh never depends on, or disturbs, a live\n * Claude session. */\nexport function registerPlanUsageRoute(\n ctx: Context,\n probe: (fetchedAt: number) => Promise<PlanUsageReport>,\n now: () => number = Date.now,\n): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_USAGE_PATH,\n methods: ['GET', 'POST'],\n // The probe spawns a throwaway CLI; the cached GET answers from memory.\n budget: 'git',\n handler: async io => {\n if (io.method === 'GET') return { status: 200, value: latestPlanUsage() ?? EMPTY }\n try {\n const report = await probe(now())\n recordPlanUsage(report)\n return { status: 200, value: report }\n } catch (error) {\n return { status: 500, value: { error: safeMessage(error) } }\n }\n },\n })\n}\n","import { randomUUID } from 'node:crypto'\nimport { homedir } from 'node:os'\nimport { chmod, mkdir, opendir, readFile, rename, rm, writeFile } from 'node:fs/promises'\nimport { dirname, extname, join } from 'node:path'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport { dshHomePath } from '@deepseek-ai/dsh-home-paths'\nimport {\n CLAUDE_GLOBAL_SETTINGS_PATH,\n CLAUDE_ALERT_MODES,\n CLAUDE_RENDER_MODES,\n CLAUDE_PROSE_MODES,\n DEFAULT_CLAUDE_ALERT_MODE,\n DEFAULT_CLAUDE_PROSE_MODE,\n DEFAULT_CLAUDE_RENDER_MODE,\n isClaudeAlertMode,\n isClaudeProseMode,\n isClaudeRenderMode,\n type ClaudeRenderMode,\n} from './constants.ts'\nimport { registerPluginRoute, type PluginRouteIo } from './http.ts'\n\nconst MAX_SETTINGS_BYTES = 256 * 1024\nconst MAX_REQUEST_BYTES = 8 * 1024\nconst MAX_STYLE_BYTES = 64 * 1024\nconst MAX_STYLE_FILES = 256\nconst BUILTIN_OUTPUT_STYLES = ['Default', 'Proactive', 'Concise', 'Explanatory', 'Learning'] as const\nconst STYLE_NAME = /^[\\p{L}\\p{N}][\\p{L}\\p{N} ._()\\[\\]-]{0,127}$/u\nconst DEFAULT_WORKTREE_BRANCH_PREFIX = 'claude'\nconst MAX_BRANCH_PREFIX_CHARS = 128\nconst MAX_PROCESSES_LIMIT = 16\nconst MAX_IDLE_TIMEOUT_MINUTES = 24 * 60\nconst DEFAULT_LIMITS: SupervisorLimits = { maxProcesses: 4, idleTimeoutMs: 30 * 60_000 }\n\ntype JsonObject = Record<string, unknown>\nexport type GlobalSettingEffect = 'immediate' | 'new-session' | 'next-turn' | 'next-worktree' | 'restart'\n\nexport interface GlobalSettingOption {\n value: string\n label: string\n source: 'built-in' | 'user' | 'configured'\n}\n\nexport type GlobalSettingView = {\n key: string\n kind: 'select'\n value: string\n options: readonly GlobalSettingOption[]\n effect: GlobalSettingEffect\n} | {\n key: string\n kind: 'text'\n value: string\n maxLength: number\n effect: GlobalSettingEffect\n}\n\nexport interface GlobalSettingsView {\n settings: readonly GlobalSettingView[]\n}\n\ninterface GlobalSettingsPaths {\n settingsFile: string\n outputStylesDir: string\n pluginSettingsFile: string\n}\n\n/** Effective supervisor limits: the plugin config values unless overridden in Settings. */\nexport interface SupervisorLimits {\n maxProcesses: number\n idleTimeoutMs: number\n}\n\nexport interface GlobalSettingsDependencies {\n paths?: Partial<GlobalSettingsPaths>\n /** Limits from the plugin config, shown when Settings holds no override. */\n defaultLimits?: SupervisorLimits\n /** Invoked after a successful update so live runtime state can follow. */\n onUpdated?: () => void | Promise<void>\n}\n\ninterface SelectSettingDescriptor {\n key: string\n kind: 'select'\n document: 'claude' | 'plugin'\n effect: GlobalSettingEffect\n options(paths: GlobalSettingsPaths): Promise<readonly GlobalSettingOption[]>\n read(document: JsonObject, options: readonly GlobalSettingOption[]): string\n apply(document: JsonObject, value: unknown, options: readonly GlobalSettingOption[]): void\n}\n\ninterface TextSettingDescriptor {\n key: string\n kind: 'text'\n document: 'claude' | 'plugin'\n effect: GlobalSettingEffect\n maxLength: number\n read(document: JsonObject, defaults?: SupervisorLimits): string\n apply(document: JsonObject, value: unknown): void\n}\n\ntype SettingDescriptor = SelectSettingDescriptor | TextSettingDescriptor\n\nfunction pathsFor(deps: GlobalSettingsDependencies): GlobalSettingsPaths {\n const root = join(homedir(), '.claude')\n return {\n settingsFile: deps.paths?.settingsFile ?? join(root, 'settings.json'),\n outputStylesDir: deps.paths?.outputStylesDir ?? join(root, 'output-styles'),\n pluginSettingsFile: deps.paths?.pluginSettingsFile ?? dshHomePath('plugins', 'dsh-claude', 'settings.json'),\n }\n}\n\nfunction object(value: unknown): JsonObject | undefined {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n ? value as JsonObject\n : undefined\n}\n\nasync function readDocument(path: string): Promise<JsonObject> {\n try {\n const text = await readFile(path, 'utf8')\n if (Buffer.byteLength(text) > MAX_SETTINGS_BYTES) throw new Error('Claude Code settings file is too large')\n const parsed = object(JSON.parse(text))\n if (parsed === undefined) throw new Error('Claude Code settings file must contain a JSON object')\n return parsed\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return {}\n throw error\n }\n}\n\nfunction frontmatterName(text: string): string | undefined {\n if (!text.startsWith('---\\n') && !text.startsWith('---\\r\\n')) return undefined\n const normalized = text.replaceAll('\\r\\n', '\\n')\n const end = normalized.indexOf('\\n---\\n', 4)\n if (end < 0) return undefined\n for (const line of normalized.slice(4, end).split('\\n')) {\n const match = /^name:\\s*(.+?)\\s*$/.exec(line)\n if (match?.[1] === undefined) continue\n const raw = match[1]\n const value = (raw.startsWith('\"') && raw.endsWith('\"')) || (raw.startsWith(\"'\") && raw.endsWith(\"'\"))\n ? raw.slice(1, -1)\n : raw\n return STYLE_NAME.test(value) ? value : undefined\n }\n return undefined\n}\n\nasync function userOutputStyleOptions(directory: string): Promise<GlobalSettingOption[]> {\n const options: GlobalSettingOption[] = []\n let entries\n try {\n entries = await opendir(directory)\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') return options\n throw error\n }\n for await (const entry of entries) {\n if (options.length >= MAX_STYLE_FILES) break\n if (!entry.isFile() || extname(entry.name).toLowerCase() !== '.md') continue\n try {\n const text = await readFile(join(directory, entry.name), 'utf8')\n if (Buffer.byteLength(text) > MAX_STYLE_BYTES) continue\n const name = frontmatterName(text) ?? entry.name.slice(0, -3)\n if (STYLE_NAME.test(name)) options.push({ value: name, label: name, source: 'user' })\n } catch {\n // Ignore unreadable or malformed optional style files.\n }\n }\n return options\n}\n\nconst OUTPUT_STYLE: SettingDescriptor = {\n key: 'outputStyle',\n kind: 'select',\n document: 'claude',\n effect: 'new-session',\n async options(paths) {\n const builtIn = BUILTIN_OUTPUT_STYLES.map(value => ({ value, label: value, source: 'built-in' as const }))\n const user = await userOutputStyleOptions(paths.outputStylesDir)\n const seen = new Set<string>(builtIn.map(option => option.value))\n return [...builtIn, ...user.filter(option => !seen.has(option.value)).sort((a, b) => a.label.localeCompare(b.label))]\n },\n read(document, options) {\n const value = document.outputStyle\n return typeof value === 'string' && STYLE_NAME.test(value) ? value : 'Default'\n },\n apply(document, value, options) {\n if (typeof value !== 'string' || !options.some(option => option.value === value)) {\n throw new Error('Invalid value for global setting outputStyle')\n }\n if (value === 'Default') delete document.outputStyle\n else document.outputStyle = value\n },\n}\n\nexport function isValidWorktreeBranchPrefix(value: string): boolean {\n return value.length > 0\n && value.length <= MAX_BRANCH_PREFIX_CHARS\n && value.trim() === value\n && !value.startsWith('/')\n && !value.endsWith('/')\n && !value.includes('//')\n && !value.includes('..')\n && !value.includes('@{')\n && !/[\\0-\\x20\\x7f~^:?*[\\\\]/u.test(value)\n && value.split('/').every(segment => segment.length > 0 && !segment.startsWith('.') && !segment.endsWith('.lock'))\n}\n\nconst WORKTREE_BRANCH_PREFIX: TextSettingDescriptor = {\n key: 'worktreeBranchPrefix',\n kind: 'text',\n document: 'plugin',\n effect: 'next-worktree',\n maxLength: MAX_BRANCH_PREFIX_CHARS,\n read(document) {\n const value = document.worktreeBranchPrefix\n return typeof value === 'string' && isValidWorktreeBranchPrefix(value) ? value : DEFAULT_WORKTREE_BRANCH_PREFIX\n },\n apply(document, value) {\n if (typeof value !== 'string' || !isValidWorktreeBranchPrefix(value)) {\n throw new Error('Invalid value for global setting worktreeBranchPrefix')\n }\n if (value === DEFAULT_WORKTREE_BRANCH_PREFIX) delete document.worktreeBranchPrefix\n else document.worktreeBranchPrefix = value\n },\n}\n\n/** Which renderer draws Claude's visible output. Plugin settings, not Claude's:\n * the CLI has no opinion about how DSH paints a turn. The option labels stay\n * machine-readable ids; the Client translates the two known values. */\nconst RENDERER: SelectSettingDescriptor = {\n key: 'renderer',\n kind: 'select',\n document: 'plugin',\n // The Host reads this per message and stamps every record it writes with the\n // renderer that produced it, so the switch lands on the next turn and a turn\n // already recorded keeps the renderer it was recorded with.\n effect: 'next-turn',\n async options() {\n return CLAUDE_RENDER_MODES.map(value => ({ value, label: value, source: 'built-in' as const }))\n },\n read(document) {\n const value = document.renderer\n return isClaudeRenderMode(value) ? value : DEFAULT_CLAUDE_RENDER_MODE\n },\n apply(document, value) {\n if (!isClaudeRenderMode(value)) throw new Error('Invalid value for global setting renderer')\n if (value === DEFAULT_CLAUDE_RENDER_MODE) delete document.renderer\n else document.renderer = value\n },\n}\n\n/** Whether Claude's prose gets the highlight palette. Presentation only: no\n * record carries it and nothing on the server reads it back, so unlike\n * {@link RENDERER} the switch lands the moment the Client rewrites its own\n * stylesheet — hence 'immediate' rather than 'next-turn'. */\nconst PROSE: SelectSettingDescriptor = {\n key: 'prose',\n kind: 'select',\n document: 'plugin',\n effect: 'immediate',\n async options() {\n return CLAUDE_PROSE_MODES.map(value => ({ value, label: value, source: 'built-in' as const }))\n },\n read(document) {\n const value = document.prose\n return isClaudeProseMode(value) ? value : DEFAULT_CLAUDE_PROSE_MODE\n },\n apply(document, value) {\n if (!isClaudeProseMode(value)) throw new Error('Invalid value for global setting prose')\n if (value === DEFAULT_CLAUDE_PROSE_MODE) delete document.prose\n else document.prose = value\n },\n}\n\n/** Whether a session that needs the user interrupts them. Presentation only,\n * and read by the Client at delivery time, so like {@link PROSE} the switch\n * lands the moment it is saved. */\nconst ALERTS: SelectSettingDescriptor = {\n key: 'alerts',\n kind: 'select',\n document: 'plugin',\n effect: 'immediate',\n async options() {\n return CLAUDE_ALERT_MODES.map(value => ({ value, label: value, source: 'built-in' as const }))\n },\n read(document) {\n const value = document.alerts\n return isClaudeAlertMode(value) ? value : DEFAULT_CLAUDE_ALERT_MODE\n },\n apply(document, value) {\n if (!isClaudeAlertMode(value)) throw new Error('Invalid value for global setting alerts')\n if (value === DEFAULT_CLAUDE_ALERT_MODE) delete document.alerts\n else document.alerts = value\n },\n}\n\nfunction isBoundedInteger(value: unknown, min: number, max: number): value is number {\n return typeof value === 'number' && Number.isInteger(value) && value >= min && value <= max\n}\n\nfunction integerSetting(\n key: 'maxProcesses' | 'idleTimeoutMinutes',\n min: number,\n max: number,\n defaultFor: (limits: SupervisorLimits) => number,\n effect: GlobalSettingEffect = 'new-session',\n): TextSettingDescriptor {\n return {\n key,\n kind: 'text',\n document: 'plugin',\n effect,\n maxLength: String(max).length,\n read(document, defaults = DEFAULT_LIMITS) {\n const value = document[key]\n return String(isBoundedInteger(value, min, max) ? value : defaultFor(defaults))\n },\n apply(document, value) {\n const parsed = typeof value === 'string' && /^\\d{1,6}$/u.test(value.trim()) ? Number(value.trim()) : value\n if (!isBoundedInteger(parsed, min, max)) throw new Error(`Invalid value for global setting ${key}`)\n document[key] = parsed\n },\n }\n}\n\nconst MAX_PROCESSES = integerSetting('maxProcesses', 1, MAX_PROCESSES_LIMIT, limits => limits.maxProcesses, 'immediate')\nconst IDLE_TIMEOUT_MINUTES = integerSetting('idleTimeoutMinutes', 1, MAX_IDLE_TIMEOUT_MINUTES, limits => Math.max(1, Math.round(limits.idleTimeoutMs / 60_000)))\n\nconst DESCRIPTORS: readonly SettingDescriptor[] = [OUTPUT_STYLE, RENDERER, PROSE, ALERTS, WORKTREE_BRANCH_PREFIX, MAX_PROCESSES, IDLE_TIMEOUT_MINUTES]\nconst DESCRIPTOR_BY_KEY = new Map(DESCRIPTORS.map(descriptor => [descriptor.key, descriptor]))\nlet pendingWrite: Promise<unknown> = Promise.resolve()\n\nfunction documentFor(descriptor: SettingDescriptor, documents: { claude: JsonObject; plugin: JsonObject }): JsonObject {\n return documents[descriptor.document]\n}\n\nasync function views(documents: { claude: JsonObject; plugin: JsonObject }, paths: GlobalSettingsPaths, defaults: SupervisorLimits): Promise<GlobalSettingsView> {\n return {\n settings: await Promise.all(DESCRIPTORS.map(async descriptor => {\n const document = documentFor(descriptor, documents)\n if (descriptor.kind === 'text') {\n return {\n key: descriptor.key,\n kind: descriptor.kind,\n value: descriptor.read(document, defaults),\n maxLength: descriptor.maxLength,\n effect: descriptor.effect,\n }\n }\n const discovered = await descriptor.options(paths)\n const value = descriptor.read(document, discovered)\n const options = discovered.some(option => option.value === value)\n ? discovered\n : [...discovered, { value, label: value, source: 'configured' as const }]\n return {\n key: descriptor.key,\n kind: descriptor.kind,\n value,\n options,\n effect: descriptor.effect,\n }\n })),\n }\n}\n\nasync function readDocuments(paths: GlobalSettingsPaths): Promise<{ claude: JsonObject; plugin: JsonObject }> {\n const [claude, plugin] = await Promise.all([readDocument(paths.settingsFile), readDocument(paths.pluginSettingsFile)])\n return { claude, plugin }\n}\n\nexport async function readGlobalSettings(deps: GlobalSettingsDependencies = {}): Promise<GlobalSettingsView> {\n const paths = pathsFor(deps)\n return views(await readDocuments(paths), paths, deps.defaultLimits ?? DEFAULT_LIMITS)\n}\n\n/** Supervisor limits the user overrode in Settings; absent keys fall back to the plugin config. */\nexport async function readSupervisorLimitOverrides(deps: GlobalSettingsDependencies = {}): Promise<Partial<SupervisorLimits>> {\n let document: JsonObject\n try {\n document = await readDocument(pathsFor(deps).pluginSettingsFile)\n } catch {\n return {}\n }\n const maxProcesses = document.maxProcesses\n const idleTimeoutMinutes = document.idleTimeoutMinutes\n return {\n ...(isBoundedInteger(maxProcesses, 1, MAX_PROCESSES_LIMIT) ? { maxProcesses } : {}),\n ...(isBoundedInteger(idleTimeoutMinutes, 1, MAX_IDLE_TIMEOUT_MINUTES) ? { idleTimeoutMs: idleTimeoutMinutes * 60_000 } : {}),\n }\n}\n\n/** The renderer the Host should produce output for. A missing, unreadable, or\n * malformed plugin settings file keeps today's plugin-owned transcript. */\nexport async function readRenderMode(deps: GlobalSettingsDependencies = {}): Promise<ClaudeRenderMode> {\n let document: JsonObject\n try {\n document = await readDocument(pathsFor(deps).pluginSettingsFile)\n } catch {\n return DEFAULT_CLAUDE_RENDER_MODE\n }\n return isClaudeRenderMode(document.renderer) ? document.renderer : DEFAULT_CLAUDE_RENDER_MODE\n}\n\nexport async function readWorktreeBranchPrefix(deps: GlobalSettingsDependencies = {}): Promise<string> {\n const paths = pathsFor(deps)\n return WORKTREE_BRANCH_PREFIX.read(await readDocument(paths.pluginSettingsFile))\n}\n\nasync function atomicWrite(path: string, document: JsonObject): Promise<void> {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 })\n const temporary = `${path}.${process.pid}.${randomUUID()}.tmp`\n try {\n await writeFile(temporary, `${JSON.stringify(document, null, 2)}\\n`, { encoding: 'utf8', mode: 0o600, flag: 'wx' })\n await chmod(temporary, 0o600)\n await rename(temporary, path)\n await chmod(path, 0o600)\n } finally {\n await rm(temporary, { force: true }).catch(() => undefined)\n }\n}\n\nexport function updateGlobalSettings(changes: unknown, deps: GlobalSettingsDependencies = {}): Promise<GlobalSettingsView> {\n const changeObject = object(changes)\n if (changeObject === undefined || Object.keys(changeObject).length === 0) {\n return Promise.reject(new Error('Global settings changes must be a non-empty object'))\n }\n for (const key of Object.keys(changeObject)) {\n if (!DESCRIPTOR_BY_KEY.has(key)) return Promise.reject(new Error(`Unsupported global setting: ${key}`))\n }\n const paths = pathsFor(deps)\n const operation = pendingWrite.catch(() => undefined).then(async () => {\n const documents = await readDocuments(paths)\n const changedDocuments = new Set<'claude' | 'plugin'>()\n for (const [key, value] of Object.entries(changeObject)) {\n const descriptor = DESCRIPTOR_BY_KEY.get(key)!\n const document = documentFor(descriptor, documents)\n if (descriptor.kind === 'select') descriptor.apply(document, value, await descriptor.options(paths))\n else descriptor.apply(document, value)\n changedDocuments.add(descriptor.document)\n }\n if (changedDocuments.has('claude')) await atomicWrite(paths.settingsFile, documents.claude)\n if (changedDocuments.has('plugin')) await atomicWrite(paths.pluginSettingsFile, documents.plugin)\n return views(documents, paths, deps.defaultLimits ?? DEFAULT_LIMITS)\n })\n pendingWrite = operation\n return operation\n}\n\nasync function requestJson(io: PluginRouteIo): Promise<unknown> {\n const body = object(await io.body(MAX_REQUEST_BYTES))\n if (body === undefined || Object.keys(body).some(key => key !== 'changes')) throw new Error('Invalid global settings request')\n return body.changes\n}\n\nexport function registerClaudeGlobalSettingsRoute(ctx: Context, deps: GlobalSettingsDependencies = {}): void {\n registerPluginRoute(ctx, {\n mode: 'unary',\n kind: 'exact',\n path: CLAUDE_GLOBAL_SETTINGS_PATH,\n methods: ['GET', 'PATCH'],\n // Reads and writes two small JSON files under the home directory.\n budget: 'fast',\n handler: async io => {\n try {\n const result = io.method === 'GET'\n ? await readGlobalSettings(deps)\n : await updateGlobalSettings(await requestJson(io), deps)\n if (io.method === 'PATCH') await deps.onUpdated?.()\n return { status: 200, value: result }\n } catch (error) {\n return { status: 400, value: { error: error instanceof Error ? error.message : 'Invalid global settings request' } }\n }\n },\n })\n}\n","import type { Context } from '@deepseek-ai/cordis'\nimport type {} from '@deepseek-ai/dsh-attachment'\nimport z from '@deepseek-ai/schemastery'\nimport type { Agent } from '@deepseek-ai/dsh-agent'\nimport type {} from '@deepseek-ai/dsh-commands'\nimport type {} from '@deepseek-ai/dsh-agent-presets'\nimport type {} from '@deepseek-ai/dsh-host-webserver'\nimport type {} from '@deepseek-ai/dsh-subprocess'\nimport type {} from '@deepseek-ai/dsh-user-approval'\nimport type {} from '@deepseek-ai/dsh-user-questions'\nimport { CLAUDE_CODE_PRESET_ID, CLAUDE_CODE_PROVIDER_IDS } from './constants.ts'\nimport { CLAUDE_COMMANDS_SERVICE, projectClaudeCommands, type ClaudeAgentCommandService, type ClaudeCommandView } from './command-bridge.ts'\nimport { ClaudeSidecarRepository } from './sidecar.ts'\nimport { resolveClaudeExecutable } from './executable.ts'\nimport { ClaudeSupervisor } from './supervisor.ts'\nimport { createClaudeCodeAdapter } from './adapter.ts'\nimport { ensureManagedPreset, ManagedPresetConflictError } from './preset-installer.ts'\nimport { claudeBridgeDiagnostics, registerClaudeDoctorRoutes, type ClaudeBridgeDiagnostic } from './doctor-routes.ts'\nimport { registerClaudeProjectionRoute } from './projection-routes.ts'\nimport { RepositoryStatusService, type RepositoryStatus } from './repository-status.ts'\nimport type { ClaudeActivityEvent } from './events.ts'\nimport { comparablePath, RepositorySetupService } from './repository-setup.ts'\nimport { summarizeBranchSlug } from './branch-name.ts'\nimport { summarizeSessionTitle } from './session-title.ts'\nimport { RepositoryActionService } from './repository-actions.ts'\nimport { registerRepositorySetupRoute } from './repository-setup-routes.ts'\nimport { registerRepositoryActionRoute } from './repository-action-routes.ts'\nimport { registerEditorOpenRoute } from './editor-open-routes.ts'\nimport { PromptAssistService, registerClaudePromptNameRoute, registerClaudePromptRefineRoute, registerClaudePromptsRoute } from './prompts.ts'\nimport { EditorOpenService } from './editor-open.ts'\nimport { PullRequestFeedbackService } from './pr-feedback.ts'\nimport { registerPullRequestFeedbackRoute } from './pr-feedback-routes.ts'\nimport { registerRepositoryStatusRoute } from './repository-status-routes.ts'\nimport { registerRepositoryFileRoute } from './repository-file-routes.ts'\nimport { JiraService } from './jira.ts'\nimport { registerJiraRoute } from './jira-routes.ts'\nimport { AskService } from './ask.ts'\nimport { registerAskRoute } from './ask-routes.ts'\nimport { registerReviewCommentRoute } from './review-comment-routes.ts'\nimport { registerPlanFeedbackRoute } from './plan-feedback-routes.ts'\nimport { registerClaudeClientDiagnosticsRoute } from './client-diagnostics-routes.ts'\nimport { registerClaudeRewindRoute } from './rewind-routes.ts'\nimport { restoreWorktreeTree } from './worktree-snapshot.ts'\nimport { linkedRepositoryShown, touchedFilePaths, touchedRepositoryRoots } from './touched-repositories.ts'\nimport { ReviewCommentStore } from './review-comments.ts'\nimport { registerClaudeUpdateRoutes } from './update-routes.ts'\nimport { claudeModelValue, probeClaudeModels } from './model-catalog.ts'\nimport { normalizePlanUsage, probePlanUsage, recordPlanUsage } from './plan-usage.ts'\nimport { registerPlanUsageRoute } from './plan-usage-routes.ts'\nimport { readRenderMode, readSupervisorLimitOverrides, readWorktreeBranchPrefix, registerClaudeGlobalSettingsRoute } from './global-settings.ts'\n\nexport const name = 'llm-claude'\nexport const inject = ['llm', 'agents', 'agentPresets', 'commands', 'subprocess', 'approval', 'userQuestions', 'attachments']\n\nexport interface Config {\n executablePath?: string\n model?: string\n idleTimeoutMs?: number\n maxProcesses?: number\n}\n\nexport const Config: z<Config> = z.object({\n executablePath: z.string().default(''),\n model: z.string().default('default'),\n idleTimeoutMs: z.number().min(1_000).max(2_147_483_647).default(30 * 60 * 1_000),\n maxProcesses: z.number().step(1).min(1).default(4),\n})\n\nconst CLAUDE_SCOPE_UNAVAILABLE_MESSAGE = 'agent command scope unavailable (preset route not mounted?)'\nconst CATALOG_RETRY_MS = 5_000\nconst SCOPE_RETRY_MS = 500\nconst MAX_CATALOG_RETRIES = 3\n/** Bounded: each extra checkout costs a git chain and a `gh pr view` per sweep. */\nconst MAX_EXTRA_REPOSITORIES = 8\nconst MAX_SCOPE_RETRIES = 24\n\nexport function mountClaudeMetadata(\n ctx: Context,\n supervisor: ClaudeSupervisor,\n agent: Agent,\n model: string,\n sidecar: ClaudeSidecarRepository,\n publishCommands: (commands: readonly ClaudeCommandView[]) => void = () => {},\n // IMPORTANT: call through the injected agentPresets SERVICE, never an\n // imported serviceForAgent() — a linked plugin resolves peer packages from\n // its own node_modules, which creates a second module instance with empty\n // module-level mount state. The service method runs on the app's instance.\n resolveCommands: () => ClaudeAgentCommandService | undefined =\n () => ctx.agentPresets.serviceFor(agent, CLAUDE_COMMANDS_SERVICE),\n): (() => Promise<void>) | undefined {\n if (ctx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID) return undefined\n\n let stopped = false\n let pending = Promise.resolve()\n let commandScope: ClaudeAgentCommandService | undefined\n\n // The commands service is unreachable from this host view of agent.ctx;\n // the preset route plugin provides it as an isolated per-session service.\n const scopedCommands = () => {\n const scoped = commandScope ?? resolveCommands()\n if (scoped === undefined) throw new Error(CLAUDE_SCOPE_UNAVAILABLE_MESSAGE)\n commandScope = scoped\n return scoped\n }\n\n const commandTarget = {\n list: () => scopedCommands().list(agent),\n }\n\n const warn = (area: string, error: unknown) => {\n ctx.logger.warn(`dsh-claude: ${area} refresh failed for ${String(agent.id)}: ${error instanceof Error ? error.message : String(error)}`)\n }\n\n const isScopeUnavailable = (error: unknown): boolean => {\n if (error instanceof Error) return error.message === CLAUDE_SCOPE_UNAVAILABLE_MESSAGE\n return String(error) === CLAUDE_SCOPE_UNAVAILABLE_MESSAGE\n }\n\n const diagnostic: ClaudeBridgeDiagnostic = claudeBridgeDiagnostics.get(agent) ?? { attempts: 0 }\n claudeBridgeDiagnostics.set(agent, diagnostic)\n\n // A fresh session's first catalog fetch races CLI startup (skills/plugins\n // can make init slow); retry with backoff so the command palette still\n // populates without waiting for the first completed turn.\n let catalogRetries = 0\n let scopeRetries = 0\n let retryTimer: ReturnType<typeof setTimeout> | undefined\n\n const scheduleRetry = (area: 'command catalog' | 'command scope', attempt: number) => {\n if (retryTimer !== undefined) clearTimeout(retryTimer)\n const delay = area === 'command catalog' ? CATALOG_RETRY_MS * attempt : Math.min(SCOPE_RETRY_MS * 2 ** attempt, 5_000)\n retryTimer = setTimeout(() => {\n if (!stopped) refresh()\n }, delay)\n retryTimer.unref?.()\n }\n\n const refresh = () => {\n pending = pending.then(async () => {\n if (stopped) return\n diagnostic.attempts += 1\n\n let catalog: Awaited<ReturnType<ClaudeSupervisor['supportedCommands']>> | undefined\n\n try {\n const result = await supervisor.supportedCommands(agent, model)\n catalog = result\n catalogRetries = 0\n scopeRetries = 0\n diagnostic.lastCatalog = catalog.length\n delete diagnostic.lastError\n } catch (error) {\n diagnostic.lastError = error instanceof Error ? error.message : String(error)\n warn('command catalog', error)\n if (!stopped && catalogRetries < MAX_CATALOG_RETRIES) {\n catalogRetries += 1\n scheduleRetry('command catalog', catalogRetries)\n }\n }\n\n if (stopped || catalog === undefined) return\n\n try {\n const commands = projectClaudeCommands(catalog, commandTarget)\n publishCommands(commands)\n diagnostic.registered = commands.map(view => view.publicName)\n if (!stopped) scopeRetries = 0\n } catch (error) {\n diagnostic.lastError = error instanceof Error ? error.message : String(error)\n warn('command catalog', error)\n if (!stopped && isScopeUnavailable(error) && scopeRetries < MAX_SCOPE_RETRIES) {\n scopeRetries += 1\n scheduleRetry('command scope', scopeRetries)\n }\n }\n\n if (stopped) return\n try {\n const usage = await supervisor.contextUsage(agent, model)\n if (!stopped) await sidecar.writeContextUsage(agent.id as string, usage)\n } catch (error) {\n warn('context usage', error)\n }\n\n if (stopped) return\n // Plan limits belong to the account, not the session, so any idle Claude\n // agent can refresh the cache the (session-less) settings page reads.\n try {\n const plan = await supervisor.planUsage(agent, model)\n if (!stopped) recordPlanUsage(normalizePlanUsage(plan, Date.now()))\n } catch (error) {\n warn('plan usage', error)\n }\n })\n }\n\n return agent.ctx.effect(() => {\n const stopStatus = agent.ctx.on('agent/status', ({ status }) => {\n if (status === 'idle') refresh()\n })\n\n refresh()\n\n return async () => {\n stopped = true\n publishCommands([])\n if (retryTimer !== undefined) clearTimeout(retryTimer)\n stopStatus()\n await pending\n }\n }, 'dsh-claude: agent metadata bridge')\n}\n\nexport async function installManagedPresetCompatibility(\n logger: Pick<Context['logger'], 'warn'>,\n install: typeof ensureManagedPreset = ensureManagedPreset,\n): Promise<'installed' | 'unchanged' | 'conflict'> {\n try {\n return await install()\n } catch (error) {\n if (!(error instanceof ManagedPresetConflictError)) throw error\n logger.warn(`dsh-claude: preserving user-modified preset at ${error.path}`)\n return 'conflict'\n }\n}\n\nexport async function apply(ctx: Context, config: Config): Promise<void> {\n // DSH Desktop 2.0.4 does not retain third-party preset roots from bundle\n // patches, so keep a guarded user-root copy. Its bare route specifier resolves\n // through the profile package factory and does not create a second Loader source.\n await installManagedPresetCompatibility(ctx.logger)\n const defaultLimits = {\n idleTimeoutMs: config.idleTimeoutMs ?? 30 * 60 * 1_000,\n maxProcesses: config.maxProcesses ?? 4,\n }\n const supervisorConfig = {\n executablePath: '',\n defaultModel: config.model ?? 'default',\n ...defaultLimits,\n }\n // Settings overrides win over the plugin config; the supervisor reads the\n // shared config object on every admission and idle schedule, so updates take\n // effect without a restart. The renderer is not kept here: the adapter reads\n // its file at the start of each turn and pins the answer to that turn, so\n // both halves of a turn -- the records the supervisor stamps and the blocks\n // the adapter streams -- agree about who is drawing it, and a settings file\n // edited outside the Settings dialog lands on the next turn all the same.\n const applySettingsOverrides = async (): Promise<void> => {\n const overrides = await readSupervisorLimitOverrides()\n supervisorConfig.idleTimeoutMs = overrides.idleTimeoutMs ?? defaultLimits.idleTimeoutMs\n supervisorConfig.maxProcesses = overrides.maxProcesses ?? defaultLimits.maxProcesses\n }\n await applySettingsOverrides()\n const sidecar = new ClaudeSidecarRepository()\n const repositoryStatus = new RepositoryStatusService(ctx.subprocess)\n const repositorySetup = new RepositorySetupService(ctx.subprocess, {\n branchPrefix: () => readWorktreeBranchPrefix(),\n // Read at call time: the executable is resolved after this service exists.\n summarizeBranch: intent => summarizeBranchSlug(supervisorConfig.executablePath, intent),\n })\n const reviewComments = new ReviewCommentStore()\n const commandCatalogs = new Map<string, readonly ClaudeCommandView[]>()\n const supervisor = new ClaudeSupervisor({\n runtime: ctx.subprocess,\n approval: ctx.approval,\n userQuestions: ctx.userQuestions,\n config: supervisorConfig,\n runDetached: operation => ctx.agents.withoutInitiator(operation),\n sidecar,\n })\n let resolutionError: unknown\n try {\n const resolution = await resolveClaudeExecutable(\n ctx.subprocess,\n config.executablePath === undefined || config.executablePath.length === 0\n ? undefined\n : config.executablePath,\n )\n supervisorConfig.executablePath = resolution.path\n ctx.llm.registerAdapter(\n [...CLAUDE_CODE_PROVIDER_IDS],\n createClaudeCodeAdapter(supervisor, ctx.agents, ctx.attachments, agent => ctx.agentPresets.composedPreset(agent.ctx), sessionId => reviewComments.drain(sessionId), () => readRenderMode(), request => summarizeSessionTitle(supervisorConfig.executablePath, request), () => probeClaudeModels(supervisorConfig.executablePath)),\n )\n ctx.effect(() => {\n const mounted = new Map<Agent, () => Promise<void>>()\n const pending = new Set<Agent>()\n const MOUNT_RETRY_MS = 200\n const MOUNT_RETRY_LIMIT = 50\n const mount = (agent: Agent) => {\n if (mounted.has(agent)) return\n const sessionId = agent.id as string\n const dispose = mountClaudeMetadata(\n ctx,\n supervisor,\n agent,\n supervisorConfig.defaultModel,\n sidecar,\n commands => {\n if (commands.length === 0) commandCatalogs.delete(sessionId)\n else commandCatalogs.set(sessionId, commands)\n },\n )\n if (dispose !== undefined) mounted.set(agent, dispose)\n pending.delete(agent)\n }\n // The standing preset mount lands AFTER agent/created (the PresetTree is\n // applied asynchronously), so composedPreset is still undefined at that\n // point. Poll briefly until the join settles, then decide.\n const mountWhenPresetSettles = (agent: Agent) => {\n if (mounted.has(agent) || pending.has(agent)) return\n if (ctx.agentPresets.composedPreset(agent.ctx) !== undefined) {\n mount(agent)\n return\n }\n pending.add(agent)\n let attempts = 0\n const retry = () => {\n if (mounted.has(agent) || !pending.has(agent)) return\n if (ctx.agentPresets.composedPreset(agent.ctx) !== undefined) {\n mount(agent)\n return\n }\n attempts += 1\n if (attempts >= MOUNT_RETRY_LIMIT) {\n pending.delete(agent)\n return\n }\n const timer = setTimeout(retry, MOUNT_RETRY_MS)\n timer.unref?.()\n }\n const timer = setTimeout(retry, MOUNT_RETRY_MS)\n timer.unref?.()\n }\n const stopCreated = ctx.on('agent/created', ({ agent }) => { mountWhenPresetSettles(agent) })\n // Belt and suspenders: the session records its preset selection as a\n // durable event, which agent-presets republishes as agent-preset/selected.\n // agent-preset/selected is emitted by dsh-agent-presets but is not part\n // of the typed host event map yet; subscribe through a typed escape hatch.\n const onPresetSelected = ctx.on as (event: 'agent-preset/selected', handler: (sessionId: string, preset: string) => void) => () => void\n const stopSelected = onPresetSelected('agent-preset/selected', (sessionId, preset) => {\n if (preset !== CLAUDE_CODE_PRESET_ID) return\n const agent = ctx.agents.get(sessionId as never)\n if (agent !== undefined) mountWhenPresetSettles(agent)\n })\n for (const agent of ctx.agents.list()) mountWhenPresetSettles(agent)\n return async () => {\n stopCreated()\n stopSelected()\n pending.clear()\n await Promise.allSettled([...mounted.values()].map(dispose => dispose()))\n mounted.clear()\n }\n }, 'dsh-claude: metadata bridges')\n } catch (error) {\n resolutionError = error\n }\n ctx.on('agent/disposed', async ({ agent }) => {\n reviewComments.disposeSession(agent.id as string)\n await supervisor.disposeSession(agent.id as string)\n })\n // Set once the reconciliation below is wired; the Client's sweep route kicks\n // it so a deleted workspace does not wait out the interval.\n let sweepWorktrees: (() => void) | undefined\n // Deleting a workspace from the sidebar is a durable-registry mutation with\n // no agent lifecycle edge, so worktree cleanup reconciles leases against\n // the workspace registry instead: unreferenced clean worktrees are removed\n // on boot, on the Client's deletion kick, and on a slow interval.\n // workspaceRegistry is not part of this plugin's typed host surface yet;\n // inject through an untyped escape hatch so older Hosts without the service\n // simply never start the sweep.\n const injectWorkspaceRegistry = ctx.inject as unknown as (\n deps: readonly string[],\n callback: (sweepCtx: Context & {\n workspaceRegistry: {\n list(): readonly { readonly path: string }[]\n archiveSession(sessionId: string): Promise<void>\n }\n }) => void,\n ) => void\n injectWorkspaceRegistry(['workspaceRegistry'], sweepCtx => {\n // Deleting a workspace only drops its registration: the Host keeps every\n // session log, and rebuilds the workspace from those headers on the next\n // boot. Archiving the sessions that lived in the worktree is what makes\n // the deletion stick. Resolved per sweep rather than injected so a Host\n // without the service still gets worktree cleanup.\n const archiveSessions = async (worktreePath: string): Promise<void> => {\n const persistence = sweepCtx.get('sessionPersistence') as {\n list(): Promise<readonly { readonly id?: unknown; readonly cwd?: unknown }[]>\n } | undefined\n if (persistence === undefined) return\n const target = comparablePath(worktreePath)\n for (const header of await persistence.list()) {\n if (typeof header.id !== 'string' || typeof header.cwd !== 'string') continue\n if (comparablePath(header.cwd) !== target) continue\n await sweepCtx.workspaceRegistry.archiveSession(header.id).catch(() => undefined)\n }\n }\n const sweep = (): void => {\n try {\n const paths = sweepCtx.workspaceRegistry.list().map(workspace => workspace.path)\n void repositorySetup.cleanupOrphans(paths, archiveSessions).catch(() => undefined)\n } catch {\n // The registry can be mid-teardown; skip this pass.\n }\n }\n sweepCtx.effect(() => {\n sweep()\n sweepWorktrees = sweep\n // The kick covers the deletion the user is watching; this poll is the\n // backstop for a Client that never sent one. A pass with nothing to\n // reconcile is one small file read.\n const timer = setInterval(sweep, 60_000)\n timer.unref?.()\n return () => {\n sweepWorktrees = undefined\n clearInterval(timer)\n }\n }, 'dsh-claude: worktree reconciliation')\n })\n ctx.effect(() => () => reviewComments.dispose(), 'dsh-claude: review comments store')\n ctx.effect(() => () => supervisor.dispose(), 'dsh-claude: process supervisor')\n ctx.effect(() => () => repositoryStatus.dispose(), 'dsh-claude: repository status cache')\n ctx.inject(['webServer'], webCtx => {\n registerClaudeClientDiagnosticsRoute(webCtx)\n registerClaudeDoctorRoutes(webCtx, webCtx.subprocess, supervisor, supervisorConfig, resolutionError)\n const desktopActions = webCtx.get('desktopActions') as { requestRestart?: () => void } | undefined\n registerClaudeUpdateRoutes(webCtx, webCtx.subprocess, {\n ...(typeof desktopActions?.requestRestart === 'function'\n ? { requestRestart: desktopActions.requestRestart.bind(desktopActions) }\n : {}),\n })\n registerClaudeGlobalSettingsRoute(webCtx, {\n defaultLimits,\n onUpdated: async () => {\n await applySettingsOverrides()\n supervisor.limitsChanged()\n },\n })\n registerRepositorySetupRoute(webCtx, repositorySetup, () => sweepWorktrees?.(), path => repositoryStatus.invalidate(path))\n registerRepositoryStatusRoute(webCtx, repositoryStatus)\n registerRepositoryFileRoute(webCtx, repositoryStatus)\n registerJiraRoute(webCtx, new JiraService())\n const repositoryActions = new RepositoryActionService(webCtx.subprocess, supervisorConfig.executablePath, cwd => repositoryStatus.invalidate(cwd))\n /** Roots the latest projection probe vouched for, per session: the only\n * checkouts a route may act on besides the session's own. */\n const extraRoots = new Map<string, readonly string[]>()\n const cwdForClaudeSession = (sessionId: string, root?: string): string | undefined => {\n const agent = webCtx.agents.get(sessionId as never)\n if (agent === undefined || webCtx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID) return undefined\n if (root === undefined) return agent.session.header.cwd\n return extraRoots.get(sessionId)?.includes(root) === true ? root : undefined\n }\n const extraRepositoriesForClaudeSession = async (sessionId: string, activities: readonly ClaudeActivityEvent[]): Promise<readonly RepositoryStatus[]> => {\n const cwd = cwdForClaudeSession(sessionId)\n if (cwd === undefined) return []\n const own = await repositoryStatus.rootOf(cwd)\n const roots = await touchedRepositoryRoots(touchedFilePaths(activities), own ?? cwd, directory => repositoryStatus.rootOf(directory), MAX_EXTRA_REPOSITORIES)\n const statuses = (await Promise.all(roots.map(root => repositoryStatus.inspect(root)))).filter(linkedRepositoryShown)\n extraRoots.set(sessionId, statuses.map(status => status.root ?? status.cwd))\n return statuses\n }\n registerRepositoryActionRoute(webCtx, repositoryActions, cwdForClaudeSession)\n registerEditorOpenRoute(webCtx, new EditorOpenService(webCtx.subprocess), cwdForClaudeSession)\n registerClaudePromptsRoute(webCtx)\n const promptAssist = new PromptAssistService(webCtx.subprocess, () => supervisorConfig.executablePath)\n registerClaudePromptNameRoute(webCtx, promptAssist)\n registerClaudePromptRefineRoute(webCtx, promptAssist)\n registerPullRequestFeedbackRoute(webCtx, new PullRequestFeedbackService(webCtx.subprocess), cwdForClaudeSession)\n registerAskRoute(webCtx, new AskService(webCtx.subprocess, supervisorConfig.executablePath), cwdForClaudeSession, sessionId => {\n const snapshot = supervisor.snapshots().find(item => item.sessionId === sessionId)\n return snapshot === undefined ? undefined : { model: claudeModelValue(snapshot.model), ...(snapshot.thinkingMode === undefined ? {} : { thinkingMode: snapshot.thinkingMode }) }\n })\n const ownsClaudeSession = (sessionId: string): boolean => {\n const agent = webCtx.agents.get(sessionId as never)\n return agent !== undefined && webCtx.agentPresets.composedPreset(agent.ctx) === CLAUDE_CODE_PRESET_ID\n }\n registerReviewCommentRoute(webCtx, reviewComments, ownsClaudeSession)\n registerPlanFeedbackRoute(webCtx, supervisor.planFeedback, ownsClaudeSession)\n registerClaudeRewindRoute(webCtx, sidecar, {\n eventsFor: sessionId => {\n const agent = webCtx.agents.get(sessionId as never)\n return agent === undefined || webCtx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID\n ? undefined\n : agent.session.snapshotEvents()\n },\n busy: sessionId => supervisor.snapshots().some(item => (\n item.sessionId === sessionId && (item.state === 'running' || item.state === 'interrupting')\n )),\n reset: sessionId => supervisor.disposeSession(sessionId),\n restoreFiles: async (sessionId, tree) => {\n const agent = webCtx.agents.get(sessionId as never)\n const cwd = agent?.session.header.cwd\n return cwd === undefined ? false : restoreWorktreeTree(ctx.subprocess, cwd, tree)\n },\n })\n registerPlanUsageRoute(webCtx, fetchedAt => probePlanUsage(supervisorConfig.executablePath, fetchedAt))\n registerClaudeProjectionRoute(webCtx, sidecar, ownsClaudeSession, sessionId => commandCatalogs.get(sessionId) ?? [], async sessionId => {\n const agent = webCtx.agents.get(sessionId as never)\n if (agent === undefined || webCtx.agentPresets.composedPreset(agent.ctx) !== CLAUDE_CODE_PRESET_ID) return undefined\n const cwd = agent.session.header.cwd\n return cwd === undefined ? undefined : repositoryStatus.inspect(cwd)\n }, sessionId => reviewComments.list(sessionId), extraRepositoriesForClaudeSession)\n })\n}\n"],"mappings":"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"}
|