@carboncode/cli 0.1.0
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/LICENSE +21 -0
- package/LICENSES/DeepSeek-Reasonix-MIT.txt +21 -0
- package/README.md +109 -0
- package/README.zh-CN.md +91 -0
- package/THIRD_PARTY_NOTICES.md +14 -0
- package/dashboard/app.css +3233 -0
- package/dashboard/dist/app.js +30444 -0
- package/dashboard/dist/app.js.map +1 -0
- package/dashboard/dist/vendor-hljs.css +10 -0
- package/dashboard/dist/vendor-uplot.css +1 -0
- package/dashboard/index.html +19 -0
- package/data/deepseek-tokenizer.json.gz +0 -0
- package/dist/cli/acp-35C4ME6Y.js +711 -0
- package/dist/cli/acp-35C4ME6Y.js.map +1 -0
- package/dist/cli/chat-A6UJDPGV.js +51 -0
- package/dist/cli/chat-A6UJDPGV.js.map +1 -0
- package/dist/cli/chunk-2425HK6U.js +54 -0
- package/dist/cli/chunk-2425HK6U.js.map +1 -0
- package/dist/cli/chunk-25T6CVUP.js +172 -0
- package/dist/cli/chunk-25T6CVUP.js.map +1 -0
- package/dist/cli/chunk-2UQP6H6T.js +31 -0
- package/dist/cli/chunk-2UQP6H6T.js.map +1 -0
- package/dist/cli/chunk-3OAR6NVL.js +96 -0
- package/dist/cli/chunk-3OAR6NVL.js.map +1 -0
- package/dist/cli/chunk-3T6VBZCL.js +54 -0
- package/dist/cli/chunk-3T6VBZCL.js.map +1 -0
- package/dist/cli/chunk-4IBIPQVB.js +153 -0
- package/dist/cli/chunk-4IBIPQVB.js.map +1 -0
- package/dist/cli/chunk-4MQ3VURH.js +3106 -0
- package/dist/cli/chunk-4MQ3VURH.js.map +1 -0
- package/dist/cli/chunk-4TVNJWMA.js +11619 -0
- package/dist/cli/chunk-4TVNJWMA.js.map +1 -0
- package/dist/cli/chunk-4VR6XF4P.js +341 -0
- package/dist/cli/chunk-4VR6XF4P.js.map +1 -0
- package/dist/cli/chunk-5QCB62C4.js +25319 -0
- package/dist/cli/chunk-5QCB62C4.js.map +1 -0
- package/dist/cli/chunk-6OWJV3YW.js +390 -0
- package/dist/cli/chunk-6OWJV3YW.js.map +1 -0
- package/dist/cli/chunk-7EO27TB3.js +130 -0
- package/dist/cli/chunk-7EO27TB3.js.map +1 -0
- package/dist/cli/chunk-7L2WTRNU.js +308 -0
- package/dist/cli/chunk-7L2WTRNU.js.map +1 -0
- package/dist/cli/chunk-BHTZFEYE.js +47 -0
- package/dist/cli/chunk-BHTZFEYE.js.map +1 -0
- package/dist/cli/chunk-BSGCXZQN.js +343 -0
- package/dist/cli/chunk-BSGCXZQN.js.map +1 -0
- package/dist/cli/chunk-BSINVTTL.js +464 -0
- package/dist/cli/chunk-BSINVTTL.js.map +1 -0
- package/dist/cli/chunk-CPKCNHRR.js +323 -0
- package/dist/cli/chunk-CPKCNHRR.js.map +1 -0
- package/dist/cli/chunk-CXVWUPA3.js +96 -0
- package/dist/cli/chunk-CXVWUPA3.js.map +1 -0
- package/dist/cli/chunk-D5NFKRGO.js +160 -0
- package/dist/cli/chunk-D5NFKRGO.js.map +1 -0
- package/dist/cli/chunk-ECHSFYOY.js +109 -0
- package/dist/cli/chunk-ECHSFYOY.js.map +1 -0
- package/dist/cli/chunk-FEZK652I.js +3644 -0
- package/dist/cli/chunk-FEZK652I.js.map +1 -0
- package/dist/cli/chunk-GALC45Q2.js +696 -0
- package/dist/cli/chunk-GALC45Q2.js.map +1 -0
- package/dist/cli/chunk-IAUOP25G.js +2984 -0
- package/dist/cli/chunk-IAUOP25G.js.map +1 -0
- package/dist/cli/chunk-ILJOIQ5W.js +163 -0
- package/dist/cli/chunk-ILJOIQ5W.js.map +1 -0
- package/dist/cli/chunk-IX6XI2RG.js +225 -0
- package/dist/cli/chunk-IX6XI2RG.js.map +1 -0
- package/dist/cli/chunk-J5BYPUB5.js +62795 -0
- package/dist/cli/chunk-J5BYPUB5.js.map +1 -0
- package/dist/cli/chunk-J5XJHLWM.js +55 -0
- package/dist/cli/chunk-J5XJHLWM.js.map +1 -0
- package/dist/cli/chunk-JKGYMRX5.js +101 -0
- package/dist/cli/chunk-JKGYMRX5.js.map +1 -0
- package/dist/cli/chunk-JMBMLOBP.js +26 -0
- package/dist/cli/chunk-JMBMLOBP.js.map +1 -0
- package/dist/cli/chunk-LN3B5PMX.js +128 -0
- package/dist/cli/chunk-LN3B5PMX.js.map +1 -0
- package/dist/cli/chunk-M2UFZUX3.js +635 -0
- package/dist/cli/chunk-M2UFZUX3.js.map +1 -0
- package/dist/cli/chunk-PJS34556.js +809 -0
- package/dist/cli/chunk-PJS34556.js.map +1 -0
- package/dist/cli/chunk-QJG7OF27.js +655 -0
- package/dist/cli/chunk-QJG7OF27.js.map +1 -0
- package/dist/cli/chunk-QVC75MR3.js +232 -0
- package/dist/cli/chunk-QVC75MR3.js.map +1 -0
- package/dist/cli/chunk-S2KIUQKQ.js +378 -0
- package/dist/cli/chunk-S2KIUQKQ.js.map +1 -0
- package/dist/cli/chunk-S4XVGLRW.js +499 -0
- package/dist/cli/chunk-S4XVGLRW.js.map +1 -0
- package/dist/cli/chunk-T5TQ4NDT.js +190 -0
- package/dist/cli/chunk-T5TQ4NDT.js.map +1 -0
- package/dist/cli/chunk-TH756VLN.js +1924 -0
- package/dist/cli/chunk-TH756VLN.js.map +1 -0
- package/dist/cli/chunk-TUK7OWJA.js +51 -0
- package/dist/cli/chunk-TUK7OWJA.js.map +1 -0
- package/dist/cli/chunk-U4IJVG32.js +363 -0
- package/dist/cli/chunk-U4IJVG32.js.map +1 -0
- package/dist/cli/chunk-UI66BH6D.js +624 -0
- package/dist/cli/chunk-UI66BH6D.js.map +1 -0
- package/dist/cli/chunk-VPMBGAND.js +53 -0
- package/dist/cli/chunk-VPMBGAND.js.map +1 -0
- package/dist/cli/chunk-WLHH3OSR.js +522 -0
- package/dist/cli/chunk-WLHH3OSR.js.map +1 -0
- package/dist/cli/chunk-WRN65TRD.js +908 -0
- package/dist/cli/chunk-WRN65TRD.js.map +1 -0
- package/dist/cli/chunk-X53B3JIX.js +34320 -0
- package/dist/cli/chunk-X53B3JIX.js.map +1 -0
- package/dist/cli/chunk-XJ5SRLKK.js +50 -0
- package/dist/cli/chunk-XJ5SRLKK.js.map +1 -0
- package/dist/cli/chunk-YZSXRGFH.js +54 -0
- package/dist/cli/chunk-YZSXRGFH.js.map +1 -0
- package/dist/cli/code-4TUTAGO5.js +163 -0
- package/dist/cli/code-4TUTAGO5.js.map +1 -0
- package/dist/cli/commands-KMOZEYCF.js +356 -0
- package/dist/cli/commands-KMOZEYCF.js.map +1 -0
- package/dist/cli/commit-DTFA56VQ.js +292 -0
- package/dist/cli/commit-DTFA56VQ.js.map +1 -0
- package/dist/cli/desktop-7N3MHNBD.js +1274 -0
- package/dist/cli/desktop-7N3MHNBD.js.map +1 -0
- package/dist/cli/devtools-HW3WDT3Q.js +91 -0
- package/dist/cli/devtools-HW3WDT3Q.js.map +1 -0
- package/dist/cli/diff-E5OWTF4C.js +165 -0
- package/dist/cli/diff-E5OWTF4C.js.map +1 -0
- package/dist/cli/doctor-IEJQRJMN.js +27 -0
- package/dist/cli/doctor-IEJQRJMN.js.map +1 -0
- package/dist/cli/events-4625EGXI.js +340 -0
- package/dist/cli/events-4625EGXI.js.map +1 -0
- package/dist/cli/index.js +3536 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/mcp-PDI2PDLG.js +277 -0
- package/dist/cli/mcp-PDI2PDLG.js.map +1 -0
- package/dist/cli/mcp-browse-OSPXOFPZ.js +178 -0
- package/dist/cli/mcp-browse-OSPXOFPZ.js.map +1 -0
- package/dist/cli/mcp-inspect-QRFVTHMF.js +148 -0
- package/dist/cli/mcp-inspect-QRFVTHMF.js.map +1 -0
- package/dist/cli/package.json +3 -0
- package/dist/cli/prompt-3CDII3UO.js +16 -0
- package/dist/cli/prompt-3CDII3UO.js.map +1 -0
- package/dist/cli/prune-sessions-KZX4SXKW.js +44 -0
- package/dist/cli/prune-sessions-KZX4SXKW.js.map +1 -0
- package/dist/cli/replay-HYOSRQIV.js +291 -0
- package/dist/cli/replay-HYOSRQIV.js.map +1 -0
- package/dist/cli/run-2ZHADOUP.js +220 -0
- package/dist/cli/run-2ZHADOUP.js.map +1 -0
- package/dist/cli/server-X75PAZG5.js +3572 -0
- package/dist/cli/server-X75PAZG5.js.map +1 -0
- package/dist/cli/sessions-POOZA5CQ.js +120 -0
- package/dist/cli/sessions-POOZA5CQ.js.map +1 -0
- package/dist/cli/setup-YLPFI3OH.js +618 -0
- package/dist/cli/setup-YLPFI3OH.js.map +1 -0
- package/dist/cli/stats-NXJ3TO2D.js +16 -0
- package/dist/cli/stats-NXJ3TO2D.js.map +1 -0
- package/dist/cli/update-ZUO5MKQ6.js +15 -0
- package/dist/cli/update-ZUO5MKQ6.js.map +1 -0
- package/dist/cli/version-NXXWE3WN.js +33 -0
- package/dist/cli/version-NXXWE3WN.js.map +1 -0
- package/dist/index.d.ts +2523 -0
- package/dist/index.js +15408 -0
- package/dist/index.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/desktop.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport { existsSync, statSync, writeSync } from \"node:fs\";\nimport { readFile } from \"node:fs/promises\";\nimport { isAbsolute, join, resolve } from \"node:path\";\nimport { stdin } from \"node:process\";\nimport { createInterface } from \"node:readline\";\nimport {\n type FileWithStats,\n listDirectory,\n listFilesWithStatsAsync,\n parseAtQuery,\n rankPickerCandidates,\n} from \"../../at-mentions.js\";\nimport { pickPrimaryBalance } from \"../../client.js\";\nimport { codeSystemPrompt } from \"../../code/prompt.js\";\nimport { buildCodeToolset } from \"../../code/setup.js\";\nimport {\n type EditMode,\n isPlausibleKey,\n loadApiKey,\n loadBaseUrl,\n loadDesktopOpenTabs,\n loadEditMode,\n loadEditor,\n loadPreset,\n loadReasoningEffort,\n loadRecentWorkspaces,\n loadResolvedSkillPaths,\n loadWorkspaceDir,\n pushRecentWorkspace,\n readConfig,\n saveApiKey,\n saveBaseUrl,\n saveDesktopOpenTabs,\n saveEditMode,\n saveEditor,\n savePreset,\n saveReasoningEffort,\n saveWorkspaceDir,\n writeConfig,\n} from \"../../config.js\";\nimport { Eventizer } from \"../../core/eventize.js\";\nimport type { Event as KernelEvent } from \"../../core/events.js\";\nimport {\n type CheckpointVerdict,\n type ChoiceVerdict,\n type ConfirmationChoice,\n type PlanVerdict,\n type RevisionVerdict,\n pauseGate,\n} from \"../../core/pause-gate.js\";\nimport { autoResolveVerdict } from \"../../core/pause-policy.js\";\nimport { loadDotenv } from \"../../env.js\";\nimport { CacheFirstLoop, DeepSeekClient, ImmutablePrefix } from \"../../index.js\";\nimport { parseMcpSpec } from \"../../mcp/spec.js\";\nimport {\n deleteSession,\n listSessionsForWorkspace,\n loadSessionMessages,\n loadSessionMeta,\n patchSessionMeta,\n sessionPath,\n timestampSuffix,\n} from \"../../memory/session.js\";\nimport { MemoryStore } from \"../../memory/user.js\";\nimport { SkillStore } from \"../../skills.js\";\nimport { countTokensBounded } from \"../../tokenizer.js\";\nimport type { ChoiceOption } from \"../../tools/choice.js\";\nimport type { ChatMessage } from \"../../types.js\";\nimport { VERSION } from \"../../version.js\";\nimport { canonicalPresetName, resolvePreset } from \"../ui/presets.js\";\nimport { type McpRuntime, createMcpRuntime } from \"./mcp-runtime.js\";\n\nexport interface DesktopOptions {\n model: string;\n budgetUsd?: number;\n /** Root directory the agent's filesystem tools operate inside. Defaults to cwd. */\n dir?: string;\n}\n\ntype InMessage = { tabId?: string } & (\n | { cmd: \"user_input\"; text: string }\n | { cmd: \"abort\" }\n | { cmd: \"confirm_response\"; id: number; response: ConfirmationChoice }\n | { cmd: \"choice_response\"; id: number; response: ChoiceVerdict }\n | { cmd: \"plan_response\"; id: number; response: PlanVerdict }\n | { cmd: \"checkpoint_response\"; id: number; response: CheckpointVerdict }\n | { cmd: \"revision_response\"; id: number; response: RevisionVerdict }\n | { cmd: \"session_list\" }\n | { cmd: \"session_delete\"; name: string }\n | { cmd: \"session_load\"; name: string }\n | { cmd: \"new_chat\" }\n | { cmd: \"setup_save_key\"; key: string }\n | { cmd: \"settings_get\" }\n | {\n cmd: \"settings_save\";\n reasoningEffort?: \"high\" | \"max\";\n editMode?: EditMode;\n budgetUsd?: number | null;\n baseUrl?: string;\n workspaceDir?: string;\n preset?: \"auto\" | \"flash\" | \"pro\";\n editor?: string;\n }\n | { cmd: \"mention_query\"; query: string; nonce: number }\n | { cmd: \"mention_preview\"; path: string; nonce: number }\n | { cmd: \"mention_picked\"; path: string }\n | { cmd: \"tab_open\"; workspaceDir?: string }\n | { cmd: \"tab_close\" }\n | { cmd: \"mcp_specs_get\" }\n | { cmd: \"mcp_specs_add\"; spec: string }\n | { cmd: \"mcp_specs_remove\"; spec: string }\n | { cmd: \"skills_get\" }\n | { cmd: \"skill_run\"; name: string; args?: string }\n | { cmd: \"jobs_list\" }\n | { cmd: \"jobs_stop\"; jobId: number }\n | { cmd: \"jobs_stop_all\" }\n);\n\ninterface NeedsSetupEvent {\n type: \"$needs_setup\";\n reason: \"no_api_key\";\n}\n\ninterface SettingsEvent {\n type: \"$settings\";\n reasoningEffort: \"high\" | \"max\";\n editMode: EditMode;\n budgetUsd: number | null;\n baseUrl?: string;\n apiKeyPrefix?: string;\n workspaceDir: string;\n recentWorkspaces: string[];\n model: string;\n preset: \"auto\" | \"flash\" | \"pro\";\n editor?: string;\n version: string;\n}\n\ninterface BalanceEvent {\n type: \"$balance\";\n currency: string;\n total: number;\n isAvailable: boolean;\n}\n\ninterface PlanRequiredEvent {\n type: \"$plan_required\";\n id: number;\n plan: string;\n steps?: unknown[];\n summary?: string;\n}\n\ninterface SessionsEvent {\n type: \"$sessions\";\n items: { name: string; messageCount: number; mtime: string }[];\n}\n\ninterface MentionResultsEvent {\n type: \"$mention_results\";\n nonce: number;\n query: string;\n results: string[];\n}\n\ninterface MentionPreviewEvent {\n type: \"$mention_preview\";\n nonce: number;\n path: string;\n head: string;\n totalLines: number;\n}\n\ninterface TabOpenedEvent {\n type: \"$tab_opened\";\n workspaceDir: string;\n}\n\ninterface TabClosedEvent {\n type: \"$tab_closed\";\n}\n\ntype LoadedSegment =\n | { kind: \"text\"; text: string }\n | { kind: \"reasoning\"; text: string }\n | {\n kind: \"tool\";\n callId: string;\n name: string;\n args: string;\n result?: string;\n ok?: boolean;\n };\n\ntype LoadedMessage =\n | { kind: \"user\"; text: string }\n | {\n kind: \"assistant\";\n turn: number;\n segments: LoadedSegment[];\n pending: false;\n };\n\ninterface SessionLoadedEvent {\n type: \"$session_loaded\";\n name: string;\n messages: LoadedMessage[];\n carryover: {\n totalCostUsd: number;\n cacheHitTokens: number;\n cacheMissTokens: number;\n };\n}\n\ninterface SessionEmptyEvent {\n type: \"$session_empty\";\n name: string;\n sizeBytes: number;\n}\n\ninterface ConfirmRequiredEvent {\n type: \"$confirm_required\";\n id: number;\n kind: \"run_command\" | \"run_background\";\n command: string;\n}\n\ninterface PathAccessRequiredEvent {\n type: \"$path_access_required\";\n id: number;\n path: string;\n intent: \"read\" | \"write\";\n toolName: string;\n sandboxRoot: string;\n allowPrefix: string;\n}\n\ninterface ChoiceRequiredEvent {\n type: \"$choice_required\";\n id: number;\n question: string;\n options: ChoiceOption[];\n allowCustom: boolean;\n}\n\ninterface PlanStepLite {\n id: string;\n title: string;\n action: string;\n risk?: \"low\" | \"med\" | \"high\";\n}\n\ninterface CheckpointRequiredEvent {\n type: \"$checkpoint_required\";\n id: number;\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n completed: number;\n total: number;\n}\n\ninterface RevisionRequiredEvent {\n type: \"$revision_required\";\n id: number;\n reason: string;\n remainingSteps: PlanStepLite[];\n summary?: string;\n}\n\ninterface StepCompletedEvent {\n type: \"$step_completed\";\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n}\n\ninterface PlanClearedEvent {\n type: \"$plan_cleared\";\n}\n\ntype McpSpecStatus = \"configured\" | \"handshake\" | \"connected\" | \"failed\" | \"disabled\";\n\ninterface McpSpecInfo {\n raw: string;\n name: string | null;\n transport: \"stdio\" | \"sse\" | \"streamable-http\";\n summary: string;\n parseError?: string;\n status: McpSpecStatus;\n statusReason?: string;\n toolCount?: number;\n}\n\ninterface McpSpecsEvent {\n type: \"$mcp_specs\";\n specs: McpSpecInfo[];\n bridged: boolean;\n}\n\ninterface CtxBreakdownEvent {\n type: \"$ctx_breakdown\";\n reservedTokens: number;\n}\n\ninterface MemoryEntryInfo {\n name: string;\n scope: \"project\" | \"global\";\n description: string;\n}\n\ninterface MemoryEvent {\n type: \"$memory\";\n entries: MemoryEntryInfo[];\n}\n\ninterface SkillInfo {\n name: string;\n description: string;\n scope: \"project\" | \"custom\" | \"global\" | \"builtin\";\n path: string;\n runAs: \"inline\" | \"subagent\";\n model?: string;\n}\n\ninterface SkillsEvent {\n type: \"$skills\";\n items: SkillInfo[];\n}\n\ninterface JobInfoPayload {\n id: number;\n tabId: string;\n sessionLabel: string;\n command: string;\n pid: number | null;\n running: boolean;\n exitCode: number | null;\n startedAt: number;\n outputTail: string;\n spawnError?: string;\n}\n\ninterface JobsEvent {\n type: \"$jobs\";\n items: JobInfoPayload[];\n}\n\n/** Direct fd write — bypasses Node's stream layer (and its piped-output\n * block buffering) so every JSON line reaches Rust the moment it's\n * produced, not whenever the next 8 KB flushes. */\ntype EmittableEvent =\n | KernelEvent\n | { type: \"$ready\" }\n | { type: \"$error\"; message: string }\n | { type: \"$turn_complete\" }\n | ConfirmRequiredEvent\n | PathAccessRequiredEvent\n | ChoiceRequiredEvent\n | PlanRequiredEvent\n | CheckpointRequiredEvent\n | RevisionRequiredEvent\n | StepCompletedEvent\n | PlanClearedEvent\n | SessionsEvent\n | SessionLoadedEvent\n | SessionEmptyEvent\n | NeedsSetupEvent\n | SettingsEvent\n | BalanceEvent\n | MentionResultsEvent\n | MentionPreviewEvent\n | TabOpenedEvent\n | TabClosedEvent\n | McpSpecsEvent\n | SkillsEvent\n | CtxBreakdownEvent\n | MemoryEvent\n | JobsEvent;\n\nfunction emit(ev: EmittableEvent, tabId?: string): void {\n const payload = tabId ? { ...ev, tabId } : ev;\n writeSync(1, Buffer.from(`${JSON.stringify(payload)}\\n`, \"utf8\"));\n}\n\nfunction tailLines(s: string, n: number): string {\n if (!s) return \"\";\n const lines = s.split(/\\r?\\n/);\n return lines.slice(-n).join(\"\\n\");\n}\n\nfunction buildLoadedMessages(records: ChatMessage[]): LoadedMessage[] {\n const out: LoadedMessage[] = [];\n let turn = 0;\n let pendingAssistantIdx = -1;\n for (const rec of records) {\n if (rec.role === \"system\") continue;\n if (rec.role === \"user\") {\n out.push({ kind: \"user\", text: rec.content ?? \"\" });\n pendingAssistantIdx = -1;\n continue;\n }\n if (rec.role === \"assistant\") {\n turn++;\n const segments: LoadedSegment[] = [];\n if (rec.reasoning_content) segments.push({ kind: \"reasoning\", text: rec.reasoning_content });\n if (rec.content) segments.push({ kind: \"text\", text: rec.content });\n if (rec.tool_calls) {\n for (let i = 0; i < rec.tool_calls.length; i++) {\n const tc = rec.tool_calls[i];\n if (!tc) continue;\n segments.push({\n kind: \"tool\",\n callId: tc.id ?? `tc-r-${turn}-${i}`,\n name: tc.function?.name ?? \"\",\n args: tc.function?.arguments ?? \"\",\n });\n }\n }\n out.push({ kind: \"assistant\", turn, segments, pending: false });\n pendingAssistantIdx = out.length - 1;\n continue;\n }\n if (rec.role === \"tool\") {\n if (pendingAssistantIdx < 0) continue;\n const host = out[pendingAssistantIdx];\n if (host?.kind !== \"assistant\") continue;\n const callId = rec.tool_call_id;\n if (!callId) continue;\n const seg = host.segments.find((s) => s.kind === \"tool\" && s.callId === callId);\n if (seg && seg.kind === \"tool\") {\n seg.result = rec.content ?? \"\";\n seg.ok = !/error|failed/i.test(seg.result.slice(0, 200));\n }\n }\n }\n return out;\n}\n\nfunction emitSettings(tab: Tab): void {\n const apiKey = loadApiKey();\n const recent = loadRecentWorkspaces().filter((p) => p !== tab.rootDir);\n emit(\n {\n type: \"$settings\",\n reasoningEffort: loadReasoningEffort(),\n editMode: loadEditMode(),\n budgetUsd: tab.runtime?.loop.budgetUsd ?? null,\n baseUrl: loadBaseUrl(),\n apiKeyPrefix: apiKey ? `${apiKey.slice(0, 6)}…${apiKey.slice(-3)}` : undefined,\n workspaceDir: tab.rootDir,\n recentWorkspaces: recent,\n model: tab.currentModel,\n preset: tab.currentPreset,\n editor: loadEditor(),\n version: VERSION,\n },\n tab.id,\n );\n}\n\nasync function emitBalance(tab: Tab): Promise<void> {\n if (!tab.runtime) return;\n const bal = await tab.runtime.loop.client.getBalance().catch(() => null);\n if (!bal) return;\n const primary = pickPrimaryBalance(bal.balance_infos);\n if (!primary) return;\n emit(\n {\n type: \"$balance\",\n currency: primary.currency,\n total: Number(primary.total_balance),\n isAvailable: bal.is_available,\n },\n tab.id,\n );\n}\n\nfunction emitSessions(tab: Tab): void {\n try {\n const items = listSessionsForWorkspace(tab.rootDir).map((s) => ({\n name: s.name,\n messageCount: s.messageCount,\n mtime: s.mtime.toISOString(),\n summary: s.meta.summary,\n }));\n emit({ type: \"$sessions\", items }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `session_list failed: ${(err as Error).message}` }, tab.id);\n }\n}\n\nfunction summarizeMcpSpec(raw: string): McpSpecInfo {\n try {\n const parsed = parseMcpSpec(raw);\n if (parsed.transport === \"stdio\") {\n const argv = [parsed.command, ...parsed.args].join(\" \");\n return {\n raw,\n name: parsed.name,\n transport: \"stdio\",\n summary: `stdio · ${argv}`,\n status: \"configured\",\n };\n }\n return {\n raw,\n name: parsed.name,\n transport: parsed.transport,\n summary: `${parsed.transport} · ${parsed.url}`,\n status: \"configured\",\n };\n } catch (err) {\n return {\n raw,\n name: null,\n transport: \"stdio\",\n summary: raw,\n parseError: (err as Error).message,\n status: \"failed\",\n statusReason: (err as Error).message,\n };\n }\n}\n\nfunction emitMcpSpecs(tab: Tab): void {\n const cfg = readConfig();\n const specs = (cfg.mcp ?? []).map((raw) => {\n const base = summarizeMcpSpec(raw);\n const live = tab.mcpStatuses.get(raw);\n if (!live) return base;\n return { ...base, status: live.kind, statusReason: live.reason, toolCount: live.toolCount };\n });\n const bridged = specs.length > 0 && specs.every((s) => s.status === \"connected\");\n emit({ type: \"$mcp_specs\", specs, bridged }, tab.id);\n}\n\nfunction emitMemory(tab: Tab): void {\n try {\n const store = new MemoryStore({ projectRoot: tab.rootDir });\n const entries: MemoryEntryInfo[] = store.list().map((e) => ({\n name: e.name,\n scope: e.scope,\n description: e.description,\n }));\n emit({ type: \"$memory\", entries }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `memory_get failed: ${(err as Error).message}` }, tab.id);\n }\n}\n\n// reserved = system prompt + tool specs, constant for the tab's lifetime once\n// the loop is built. The growing log portion is already covered by the\n// per-turn cache hit/miss numbers in `model.final`.\nfunction emitCtxBreakdown(tab: Tab): void {\n if (!tab.runtime) return;\n try {\n const sys = countTokensBounded(tab.runtime.loop.prefix.system);\n const tools = countTokensBounded(JSON.stringify(tab.runtime.loop.prefix.toolSpecs));\n emit({ type: \"$ctx_breakdown\", reservedTokens: sys + tools }, tab.id);\n } catch {\n // tokenizer warmup can throw on first call before the data file loads\n }\n}\n\nfunction emitSkills(tab: Tab): void {\n try {\n const store = new SkillStore({\n projectRoot: tab.rootDir,\n customSkillPaths: loadResolvedSkillPaths(tab.rootDir),\n });\n const items = store.list().map((s) => ({\n name: s.name,\n description: s.description,\n scope: s.scope,\n path: s.path,\n runAs: s.runAs,\n model: s.model,\n }));\n emit({ type: \"$skills\", items }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `skills_get failed: ${(err as Error).message}` }, tab.id);\n }\n}\n\ninterface RuntimeState {\n loop: CacheFirstLoop;\n eventizer: Eventizer;\n ctx: { model: string; prefixHash: string; reasoningEffort: \"high\" | \"max\" };\n}\n\ntype SymbolEntry = { name: string; path: string; line: number; kind: string };\n\ninterface Tab {\n readonly id: string;\n rootDir: string;\n currentSession: string;\n currentPreset: \"auto\" | \"flash\" | \"pro\";\n currentModel: string;\n budgetUsd: number | undefined;\n /** null while the tab is bootstrapping — see `initTabToolset`. UI gates input on `$ready`, which only fires once this is set. */\n toolset: Awaited<ReturnType<typeof buildCodeToolset>> | null;\n /** Empty while bootstrapping; populated together with `toolset`. */\n system: string;\n runtime: RuntimeState | null;\n aborter: AbortController | null;\n fileIndex: FileWithStats[] | null;\n fileIndexBuilding: Promise<FileWithStats[]> | null;\n fileIndexBuiltAt: number;\n symbolIndex: SymbolEntry[] | null;\n symbolBuilding: Promise<SymbolEntry[]> | null;\n recentMentions: string[];\n /** Pause-gate ids waiting on this tab — abort uses these to free stranded plan_checkpoint / plan_revision / shell-confirm callers. */\n pendingGateIds: Set<number>;\n /** Step ids already marked complete in the in-flight plan — also tells UI when a plan is \"active\". */\n completedStepIds: Set<string>;\n /** Total steps in the in-flight plan (0 = no active plan / steps not provided). */\n planTotalSteps: number;\n mcpRuntime: McpRuntime | null;\n mcpStatuses: Map<string, { kind: McpSpecStatus; reason?: string; toolCount?: number }>;\n}\n\nlet tabCounter = 0;\nfunction nextTabId(): string {\n tabCounter++;\n return `t${tabCounter}`;\n}\n\nfunction mintSessionFor(rootDir: string): string {\n const name = `desktop-${timestampSuffix()}-${tabCounter}`;\n try {\n patchSessionMeta(name, { workspace: rootDir });\n } catch {\n // session meta is for filtering only — failure shouldn't block chat\n }\n return name;\n}\n\nfunction buildRuntimeFor(tab: Tab): RuntimeState {\n if (!tab.toolset) throw new Error(\"buildRuntimeFor called before initTabToolset finished\");\n const toolset = tab.toolset;\n const client = new DeepSeekClient({ baseUrl: loadBaseUrl() });\n const prefix = new ImmutablePrefix({ system: tab.system, toolSpecs: toolset.tools.specs() });\n const reasoningEffort = loadReasoningEffort();\n const { autoEscalate } = resolvePreset(tab.currentPreset);\n const loop = new CacheFirstLoop({\n client,\n prefix,\n tools: toolset.tools,\n model: tab.currentModel,\n budgetUsd: tab.budgetUsd,\n session: tab.currentSession,\n reasoningEffort,\n autoEscalate,\n });\n const eventizer = new Eventizer();\n const ctx = { model: tab.currentModel, prefixHash: prefix.fingerprint, reasoningEffort };\n return { loop, eventizer, ctx };\n}\n\nconst TS_EXPORT_RE =\n /^export\\s+(?:default\\s+)?(?:async\\s+)?(function|class|const|let|var|interface|type|enum)\\s+\\*?\\s*(\\w+)/;\n\n/** TTL on the in-memory file index — without this, files deleted / renamed since the last @ popup still show up as candidates. 10s balances \"fresh enough for typical edit-then-mention flows\" against \"don't re-scan 5000 files on every keystroke\". */\nconst FILE_INDEX_TTL_MS = 10_000;\n\nasync function getFileIndexFor(tab: Tab): Promise<FileWithStats[]> {\n const fresh = tab.fileIndex && Date.now() - tab.fileIndexBuiltAt < FILE_INDEX_TTL_MS;\n if (fresh) return tab.fileIndex as FileWithStats[];\n if (tab.fileIndexBuilding) return tab.fileIndexBuilding;\n tab.fileIndexBuilding = listFilesWithStatsAsync(tab.rootDir, { maxResults: 5000 })\n .then((res) => {\n tab.fileIndex = res;\n tab.fileIndexBuiltAt = Date.now();\n tab.fileIndexBuilding = null;\n return res;\n })\n .catch((err) => {\n tab.fileIndexBuilding = null;\n throw err;\n });\n return tab.fileIndexBuilding;\n}\n\nasync function getSymbolIndexFor(tab: Tab): Promise<SymbolEntry[]> {\n if (tab.symbolIndex) return tab.symbolIndex;\n if (tab.symbolBuilding) return tab.symbolBuilding;\n tab.symbolBuilding = (async () => {\n const files = await getFileIndexFor(tab);\n const sourceExts = /\\.(?:ts|tsx|js|jsx|mts|cts)$/;\n const candidates = files.filter((f) => sourceExts.test(f.path)).slice(0, 1500);\n const out: SymbolEntry[] = [];\n const PARALLEL = 16;\n for (let i = 0; i < candidates.length; i += PARALLEL) {\n const batch = candidates.slice(i, i + PARALLEL);\n await Promise.all(\n batch.map(async (entry) => {\n const abs = isAbsolute(entry.path) ? entry.path : join(tab.rootDir, entry.path);\n try {\n const text = await readFile(abs, \"utf8\");\n const lines = text.split(/\\r?\\n/);\n for (let li = 0; li < lines.length; li++) {\n const line = lines[li]!;\n if (!line.startsWith(\"export \")) continue;\n const m = TS_EXPORT_RE.exec(line);\n if (m) out.push({ kind: m[1]!, name: m[2]!, path: entry.path, line: li + 1 });\n }\n } catch {\n // unreadable / binary — skip\n }\n }),\n );\n }\n tab.symbolIndex = out;\n tab.symbolBuilding = null;\n return out;\n })().catch((err) => {\n tab.symbolBuilding = null;\n throw err;\n });\n return tab.symbolBuilding;\n}\n\nfunction rankSymbols(syms: readonly SymbolEntry[], q: string, limit: number): string[] {\n const needle = q.toLowerCase();\n const scored: { entry: SymbolEntry; score: number }[] = [];\n for (const s of syms) {\n const lower = s.name.toLowerCase();\n let score: number;\n if (lower === needle) score = 0;\n else if (lower.startsWith(needle)) score = 100;\n else if (lower.includes(needle)) score = 500 + lower.indexOf(needle);\n else continue;\n scored.push({ entry: s, score });\n }\n scored.sort((a, b) => a.score - b.score || a.entry.name.localeCompare(b.entry.name));\n return scored.slice(0, limit).map((s) => `${s.entry.path}:${s.entry.line}`);\n}\n\nfunction pushMentionRecent(tab: Tab, path: string): void {\n const MAX = 20;\n const idx = tab.recentMentions.indexOf(path);\n if (idx >= 0) tab.recentMentions.splice(idx, 1);\n tab.recentMentions.unshift(path);\n if (tab.recentMentions.length > MAX) tab.recentMentions.length = MAX;\n}\n\n/** The desktop sidecar is a long-running daemon — Tauri spawns this Node process once per app launch and pipes JSON over stdin/stdout. Without these handlers, any orphaned promise rejection (e.g. from an aborted turn whose cleanup races a session-switch — #1074) crashes the process with exit code 1, which the Tauri host surfaces as \"carboncode exited (code 1)\" and a full reconnect cycle. Log loudly so we can find the underlying bug, but don't take the daemon down. */\nexport function installDesktopCrashGuards(\n stderr: { write: (s: string) => unknown } = process.stderr,\n): void {\n process.on(\"unhandledRejection\", (reason) => {\n const err = reason instanceof Error ? reason : new Error(String(reason));\n stderr.write(`[desktop] unhandledRejection: ${err.stack ?? err.message}\\n`);\n });\n process.on(\"uncaughtException\", (err) => {\n stderr.write(`[desktop] uncaughtException: ${err.stack ?? err.message}\\n`);\n });\n}\n\nexport async function desktopCommand(opts: DesktopOptions): Promise<void> {\n loadDotenv();\n installDesktopCrashGuards();\n\n const tabs = new Map<string, Tab>();\n const tabContext = new AsyncLocalStorage<string>();\n\n function activeRunningTab(): Tab | undefined {\n const id = tabContext.getStore();\n return id ? tabs.get(id) : undefined;\n }\n\n /** Synchronous tab construction — no I/O. All cheap, disk-only events (`$settings`, `$sessions`, `$memory`, `$skills`, `$mcp_specs`) can fire against this immediately. The heavy bits (`buildCodeToolset`, MCP probes, runtime construction) happen in `initTabToolset` so the UI shell paints without waiting for them. */\n function createTabSkeleton(initialDir?: string): Tab {\n const dir = resolve(initialDir ?? opts.dir ?? loadWorkspaceDir() ?? process.cwd());\n pushRecentWorkspace(dir);\n const preset = canonicalPresetName(loadPreset());\n const resolved = resolvePreset(preset);\n const model = opts.model || resolved.model;\n const tab: Tab = {\n id: nextTabId(),\n rootDir: dir,\n currentSession: \"\",\n currentPreset: preset,\n currentModel: model,\n budgetUsd: opts.budgetUsd,\n toolset: null,\n system: \"\",\n runtime: null,\n aborter: null,\n fileIndex: null,\n fileIndexBuilding: null,\n fileIndexBuiltAt: 0,\n symbolIndex: null,\n symbolBuilding: null,\n recentMentions: [],\n pendingGateIds: new Set<number>(),\n completedStepIds: new Set<string>(),\n planTotalSteps: 0,\n mcpRuntime: null,\n mcpStatuses: new Map(),\n };\n tab.currentSession = mintSessionFor(dir);\n tabs.set(tab.id, tab);\n return tab;\n }\n\n /** Builds the toolset / system prompt / runtime / MCP bridge for a freshly-created skeleton. Reads `tab.currentModel` at call time so preset changes that landed during the wait are honored. */\n async function initTabToolset(tab: Tab): Promise<void> {\n const toolset = await buildCodeToolset({\n rootDir: tab.rootDir,\n onSkillInstalled: () => emitSkills(tab),\n onJobsChanged: () => emitJobs(),\n });\n tab.toolset = toolset;\n tab.system = codeSystemPrompt(tab.rootDir, {\n hasSemanticSearch: toolset.semantic.enabled,\n modelId: tab.currentModel,\n });\n if (loadApiKey()) {\n process.env.DEEPSEEK_API_KEY = loadApiKey();\n tab.runtime = buildRuntimeFor(tab);\n void bridgeTabMcp(tab);\n }\n }\n\n function bridgeTabMcp(tab: Tab): Promise<void> {\n if (!tab.runtime || !tab.toolset) return Promise.resolve();\n if (tab.mcpRuntime) {\n // Already constructed — reload so new/removed specs settle without restart.\n return tab.mcpRuntime\n .reloadFromConfig(tab.runtime.loop)\n .then(() => emitMcpSpecs(tab))\n .catch((err) => {\n emit({ type: \"$error\", message: `mcp reload failed: ${(err as Error).message}` }, tab.id);\n });\n }\n const requested = (readConfig().mcp ?? []).length;\n if (requested === 0) return Promise.resolve();\n const runtime = createMcpRuntime({\n getTools: () => {\n if (!tab.toolset) throw new Error(\"toolset gone\");\n return tab.toolset.tools;\n },\n getMcpPrefix: () => undefined,\n getRequestedCount: () => requested,\n progressSink: { current: null },\n });\n tab.mcpRuntime = runtime;\n runtime.setLifecycleSink((notice) => {\n if (notice.kind === \"slow\") return; // not surfaced in the desktop panel\n const cfg = readConfig().mcp ?? [];\n const target = cfg.find((raw) => {\n try {\n return parseMcpSpec(raw).name === notice.name;\n } catch {\n return false;\n }\n });\n if (!target) return;\n if (notice.kind === \"handshake\") {\n tab.mcpStatuses.set(target, { kind: \"handshake\" });\n } else if (notice.kind === \"connected\") {\n tab.mcpStatuses.set(target, { kind: \"connected\", toolCount: notice.tools });\n } else if (notice.kind === \"failed\") {\n tab.mcpStatuses.set(target, { kind: \"failed\", reason: notice.reason });\n } else if (notice.kind === \"disabled\") {\n tab.mcpStatuses.set(target, { kind: \"disabled\" });\n }\n emitMcpSpecs(tab);\n });\n return runtime\n .reloadFromConfig(tab.runtime.loop)\n .then(() => undefined)\n .catch((err) => {\n emit({ type: \"$error\", message: `mcp bridge failed: ${(err as Error).message}` }, tab.id);\n });\n }\n\n /** Snapshot of every open tab's workspace dir, in tab order. Persisted after open/close so a restart restores the full tab set (issue #933). */\n function persistOpenTabs(): void {\n try {\n saveDesktopOpenTabs(Array.from(tabs.values()).map((t) => t.rootDir));\n } catch {\n // best-effort — disk / perms shouldn't break tab management\n }\n }\n\n async function closeTab(tab: Tab): Promise<void> {\n abortTurn(tab);\n try {\n await tab.toolset?.jobs.shutdown();\n } catch {\n // shutdown errors aren't actionable here\n }\n if (tab.mcpRuntime) {\n try {\n await tab.mcpRuntime.closeAll();\n } catch {\n // MCP shutdown errors aren't actionable here either\n }\n }\n tabs.delete(tab.id);\n if (first && first.id === tab.id) {\n const next = tabs.values().next().value;\n if (next) first = next;\n }\n persistOpenTabs();\n emit({ type: \"$tab_closed\" }, tab.id);\n }\n\n async function runTurn(tab: Tab, text: string): Promise<void> {\n if (!tab.runtime) return;\n const rt = tab.runtime;\n tab.aborter = new AbortController();\n if (tab.currentSession) {\n const existing = loadSessionMeta(tab.currentSession).summary;\n if (!existing || !existing.trim()) {\n const summary = text.replace(/\\s+/g, \" \").trim().slice(0, 60);\n if (summary) {\n try {\n patchSessionMeta(tab.currentSession, { summary });\n } catch {\n // meta is for display only — failure shouldn't block the turn\n }\n }\n }\n }\n await tabContext.run(tab.id, async () => {\n try {\n for await (const ev of rt.loop.step(text)) {\n for (const kev of rt.eventizer.consume(ev, rt.ctx)) emit(kev, tab.id);\n // Memory tools mutate disk state behind the loop's back — the UI\n // panel won't know until we re-emit. Without this the right-hand\n // panel only updates on tab reopen.\n if (ev.role === \"tool\" && (ev.toolName === \"remember\" || ev.toolName === \"forget\")) {\n emitMemory(tab);\n }\n if (tab.aborter?.signal.aborted) break;\n }\n } catch (err) {\n emit({ type: \"$error\", message: (err as Error).message }, tab.id);\n } finally {\n tab.aborter = null;\n emit({ type: \"$turn_complete\" }, tab.id);\n if (tab.planTotalSteps > 0 && tab.completedStepIds.size >= tab.planTotalSteps) {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n emitSessions(tab);\n void emitBalance(tab);\n }\n });\n }\n\n async function switchWorkspace(tab: Tab, nextDir: string): Promise<void> {\n const target = resolve(nextDir);\n if (target === tab.rootDir) {\n emitSettings(tab);\n return;\n }\n if (!existsSync(target) || !statSync(target).isDirectory()) {\n emit({ type: \"$error\", message: `Workspace not found: ${target}` }, tab.id);\n emitSettings(tab);\n return;\n }\n abortTurn(tab);\n try {\n await tab.toolset?.jobs.shutdown();\n } catch {\n // shutdown errors aren't actionable here\n }\n tab.rootDir = target;\n saveWorkspaceDir(target);\n pushRecentWorkspace(target);\n tab.fileIndex = null;\n tab.fileIndexBuilding = null;\n tab.fileIndexBuiltAt = 0;\n tab.symbolIndex = null;\n tab.symbolBuilding = null;\n tab.recentMentions.length = 0;\n tab.currentSession = mintSessionFor(target);\n tab.toolset = await buildCodeToolset({\n rootDir: target,\n onSkillInstalled: () => emitSkills(tab),\n onJobsChanged: () => emitJobs(),\n });\n tab.system = codeSystemPrompt(target, {\n hasSemanticSearch: tab.toolset.semantic.enabled,\n modelId: tab.currentModel,\n });\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n emitSessions(tab);\n emitSettings(tab);\n emitSkills(tab);\n }\n\n function forgetGate(id: number): Tab | undefined {\n for (const t of tabs.values()) {\n if (t.pendingGateIds.delete(id)) return t;\n }\n return undefined;\n }\n\n function abortTurn(tab: Tab): void {\n tab.aborter?.abort();\n tab.runtime?.loop.abort();\n }\n\n function tabSessionLabel(tab: Tab): string {\n if (tab.currentSession) {\n try {\n const summary = loadSessionMeta(tab.currentSession).summary?.trim();\n if (summary) return summary;\n } catch {\n // session file unreadable — fall through to workspace basename\n }\n }\n return tab.rootDir.split(/[\\\\/]/).filter(Boolean).pop() ?? tab.rootDir;\n }\n\n function emitJobs(): void {\n const items: JobInfoPayload[] = [];\n for (const t of tabs.values()) {\n const reg = t.toolset?.jobs;\n if (!reg) continue;\n const label = tabSessionLabel(t);\n for (const j of reg.list()) {\n items.push({\n id: j.id,\n tabId: t.id,\n sessionLabel: label,\n command: j.command,\n pid: j.pid,\n running: j.running,\n exitCode: j.exitCode,\n startedAt: j.startedAt,\n outputTail: tailLines(j.output, 8),\n spawnError: j.spawnError,\n });\n }\n }\n items.sort((a, b) => {\n if (a.running !== b.running) return a.running ? -1 : 1;\n return b.startedAt - a.startedAt;\n });\n emit({ type: \"$jobs\", items });\n }\n\n async function stopJob(jobId: number): Promise<boolean> {\n for (const t of tabs.values()) {\n const reg = t.toolset?.jobs;\n if (!reg) continue;\n const hit = reg.list().find((j) => j.id === jobId);\n if (!hit) continue;\n await reg.stop(jobId);\n return true;\n }\n return false;\n }\n\n async function stopAllJobs(): Promise<void> {\n const ops: Promise<unknown>[] = [];\n for (const t of tabs.values()) {\n const reg = t.toolset?.jobs;\n if (!reg) continue;\n for (const j of reg.list()) {\n if (j.running) ops.push(reg.stop(j.id));\n }\n }\n await Promise.allSettled(ops);\n }\n\n function cancelPendingGates(tab: Tab): void {\n const hadActivePlan = tab.planTotalSteps > 0 || tab.completedStepIds.size > 0;\n const ids = [...tab.pendingGateIds];\n tab.pendingGateIds.clear();\n for (const id of ids) pauseGate.cancel(id);\n if (hadActivePlan) {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n }\n\n // `first` is the fallback tab for legacy tabId-less RPC messages. We\n // assign it lazily below so saved-tabs restore (issue #933) can choose\n // the boot dir before construction, and rotate `first` to the next\n // surviving tab when its source closes.\n let first: Tab;\n\n let shuttingDown = false;\n async function gracefulShutdown(): Promise<void> {\n if (shuttingDown) return;\n shuttingDown = true;\n await Promise.allSettled(\n [...tabs.values()].map((t) => t.toolset?.jobs.shutdown(1500) ?? Promise.resolve()),\n );\n process.exit(0);\n }\n process.on(\"SIGTERM\", () => {\n void gracefulShutdown();\n });\n process.on(\"SIGINT\", () => {\n void gracefulShutdown();\n });\n\n pauseGate.on((req) => {\n const tab = activeRunningTab();\n const tabId = tab?.id;\n if (tab) tab.pendingGateIds.add(req.id);\n // Shared auto-resolve policy (e.g. plan_checkpoint in auto/yolo) — must\n // still run BEFORE we emit any UI event, otherwise the surface flickers\n // a card that we'd immediately tear down.\n const auto = autoResolveVerdict(req, loadEditMode());\n if (auto !== null) {\n // plan_checkpoint specifically needs the step-completed signal to flow\n // through so the rail progress ticks. Emit it before resolving.\n if (req.kind === \"plan_checkpoint\") {\n const payload = req.payload as {\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n };\n if (tab) tab.completedStepIds.add(payload.stepId);\n emit(\n {\n type: \"$step_completed\",\n stepId: payload.stepId,\n title: payload.title,\n result: payload.result,\n notes: payload.notes,\n },\n tabId,\n );\n }\n if (tab) tab.pendingGateIds.delete(req.id);\n pauseGate.resolve(req.id, auto);\n return;\n }\n if (req.kind === \"run_command\" || req.kind === \"run_background\") {\n const payload = req.payload as { command?: string };\n emit(\n { type: \"$confirm_required\", id: req.id, kind: req.kind, command: payload.command ?? \"\" },\n tabId,\n );\n return;\n }\n if (req.kind === \"path_access\") {\n const payload = req.payload as {\n path: string;\n intent: \"read\" | \"write\";\n toolName: string;\n sandboxRoot: string;\n allowPrefix: string;\n };\n emit(\n {\n type: \"$path_access_required\",\n id: req.id,\n path: payload.path,\n intent: payload.intent,\n toolName: payload.toolName,\n sandboxRoot: payload.sandboxRoot,\n allowPrefix: payload.allowPrefix,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"choice\") {\n const payload = req.payload as {\n question: string;\n options: ChoiceOption[];\n allowCustom: boolean;\n };\n emit(\n {\n type: \"$choice_required\",\n id: req.id,\n question: payload.question,\n options: payload.options,\n allowCustom: payload.allowCustom,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"plan_proposed\") {\n const payload = req.payload as { plan: string; steps?: PlanStepLite[]; summary?: string };\n if (tab) {\n tab.completedStepIds.clear();\n tab.planTotalSteps = payload.steps?.length ?? 0;\n }\n emit(\n {\n type: \"$plan_required\",\n id: req.id,\n plan: payload.plan,\n steps: payload.steps,\n summary: payload.summary,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"plan_checkpoint\") {\n const payload = req.payload as {\n stepId: string;\n title?: string;\n result: string;\n notes?: string;\n };\n if (tab) tab.completedStepIds.add(payload.stepId);\n emit(\n {\n type: \"$step_completed\",\n stepId: payload.stepId,\n title: payload.title,\n result: payload.result,\n notes: payload.notes,\n },\n tabId,\n );\n emit(\n {\n type: \"$checkpoint_required\",\n id: req.id,\n stepId: payload.stepId,\n title: payload.title,\n result: payload.result,\n notes: payload.notes,\n completed: tab?.completedStepIds.size ?? 0,\n total: tab?.planTotalSteps ?? 0,\n },\n tabId,\n );\n return;\n }\n if (req.kind === \"plan_revision\") {\n const payload = req.payload as {\n reason: string;\n remainingSteps: PlanStepLite[];\n summary?: string;\n };\n emit(\n {\n type: \"$revision_required\",\n id: req.id,\n reason: payload.reason,\n remainingSteps: payload.remainingSteps,\n summary: payload.summary,\n },\n tabId,\n );\n return;\n }\n // Unknown PauseKind — `never` makes a new kind without a handler a compile\n // error; the runtime cancel is the last-mile defense so the agent loop\n // doesn't hang waiting on a request no one will resolve.\n const exhaustive: never = req.kind;\n process.stderr.write(\n `[desktop] no handler for pause kind \"${String(exhaustive)}\" — auto-cancelling gate id=${req.id}\\n`,\n );\n if (tab) tab.pendingGateIds.delete(req.id);\n pauseGate.cancel(req.id);\n });\n\n // Fast-path: emit disk-only events immediately so the UI shell renders\n // before the toolset finishes building. Heavy work (semantic bootstrap,\n // MCP probes, runtime construction) runs in initTabToolset which fires\n // `$ready` when it completes — until then `state.ready` keeps the\n // composer disabled, so users can't send a message before the runtime\n // exists. emitBalance was already fire-and-forget.\n function bootstrapTab(initialDir?: string): Tab {\n const tab = createTabSkeleton(initialDir);\n emit({ type: \"$tab_opened\", workspaceDir: tab.rootDir }, tab.id);\n emitSessions(tab);\n emitSettings(tab);\n emitMcpSpecs(tab);\n emitSkills(tab);\n emitMemory(tab);\n if (!loadApiKey()) emit({ type: \"$needs_setup\", reason: \"no_api_key\" }, tab.id);\n void emitBalance(tab);\n void initTabToolset(tab)\n .then(() => {\n if (loadApiKey()) emit({ type: \"$ready\" }, tab.id);\n emitCtxBreakdown(tab);\n })\n .catch((err) => {\n emit({ type: \"$error\", message: `init failed: ${(err as Error).message}` }, tab.id);\n });\n return tab;\n }\n\n // Restore the full tab set from the previous session (issue #933).\n // `--dir` overrides saved tabs so a CLI-supplied workspace stays\n // authoritative. Missing dirs are silently skipped — a deleted\n // workspace shouldn't block boot.\n const savedTabDirs = opts.dir\n ? []\n : loadDesktopOpenTabs().filter((d) => {\n try {\n return existsSync(d) && statSync(d).isDirectory();\n } catch {\n return false;\n }\n });\n first = bootstrapTab(savedTabDirs[0]);\n for (const d of savedTabDirs.slice(1)) {\n if (resolve(d) === first.rootDir) continue;\n bootstrapTab(d);\n }\n persistOpenTabs();\n\n const rl = createInterface({ input: stdin });\n rl.on(\"line\", (line) => {\n const trimmed = line.trim();\n if (!trimmed) return;\n let msg: InMessage;\n try {\n msg = JSON.parse(trimmed) as InMessage;\n } catch {\n emit({ type: \"$error\", message: `bad json on stdin: ${trimmed.slice(0, 80)}` });\n return;\n }\n\n if (msg.cmd === \"tab_open\") {\n try {\n bootstrapTab(msg.workspaceDir);\n persistOpenTabs();\n } catch (err) {\n emit({ type: \"$error\", message: `tab_open failed: ${(err as Error).message}` });\n }\n return;\n }\n if (msg.cmd === \"confirm_response\") {\n forgetGate(msg.id);\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"choice_response\") {\n forgetGate(msg.id);\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"plan_response\") {\n const tab = forgetGate(msg.id);\n if (tab && msg.response.type === \"cancel\") {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"checkpoint_response\") {\n const tab = forgetGate(msg.id);\n if (tab && msg.response.type === \"stop\") {\n tab.completedStepIds.clear();\n tab.planTotalSteps = 0;\n emit({ type: \"$plan_cleared\" }, tab.id);\n }\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"revision_response\") {\n forgetGate(msg.id);\n pauseGate.resolve(msg.id, msg.response);\n return;\n }\n if (msg.cmd === \"setup_save_key\") {\n const key = msg.key.trim();\n if (!isPlausibleKey(key)) {\n emit({\n type: \"$error\",\n message: \"Key looks too short — paste the full token (16+ chars, no spaces).\",\n });\n return;\n }\n try {\n saveApiKey(key);\n process.env.DEEPSEEK_API_KEY = key;\n for (const tab of tabs.values()) {\n // Skeleton tabs still mid-bootstrap pick up the new key inside\n // initTabToolset's tail when buildCodeToolset settles — don't\n // try to construct a runtime against a null toolset here.\n if (!tab.toolset) {\n emitSettings(tab);\n void emitBalance(tab);\n continue;\n }\n tab.runtime = buildRuntimeFor(tab);\n emit({ type: \"$ready\" }, tab.id);\n emitSettings(tab);\n void emitBalance(tab);\n }\n } catch (err) {\n emit({ type: \"$error\", message: `saveApiKey failed: ${(err as Error).message}` });\n }\n return;\n }\n\n if (msg.cmd === \"jobs_list\") {\n emitJobs();\n return;\n }\n if (msg.cmd === \"jobs_stop\") {\n void stopJob(msg.jobId).finally(() => emitJobs());\n return;\n }\n if (msg.cmd === \"jobs_stop_all\") {\n void stopAllJobs().finally(() => emitJobs());\n return;\n }\n\n const tab = msg.tabId ? tabs.get(msg.tabId) : first;\n if (!tab) {\n // No tabId on the emit ⇒ the renderer's per-tab router drops it\n // silently. Surface to stderr instead so it's at least visible\n // when the desktop is launched from a terminal.\n process.stderr.write(\n `rpc dispatch: unknown tabId=${msg.tabId} for cmd=${msg.cmd} — dropping\\n`,\n );\n return;\n }\n\n if (msg.cmd === \"abort\") {\n abortTurn(tab);\n cancelPendingGates(tab);\n return;\n }\n if (msg.cmd === \"tab_close\") {\n void closeTab(tab);\n return;\n }\n if (msg.cmd === \"mcp_specs_get\") {\n emitMcpSpecs(tab);\n return;\n }\n if (msg.cmd === \"mcp_specs_add\") {\n const spec = msg.spec.trim();\n if (!spec) {\n emit({ type: \"$error\", message: \"mcp_specs_add: spec is empty\" }, tab.id);\n return;\n }\n try {\n parseMcpSpec(spec);\n } catch (err) {\n emit({ type: \"$error\", message: `mcp_specs_add: ${(err as Error).message}` }, tab.id);\n return;\n }\n try {\n const cfg = readConfig();\n const list = cfg.mcp ?? [];\n if (!list.includes(spec)) {\n cfg.mcp = [...list, spec];\n writeConfig(cfg);\n }\n emitMcpSpecs(tab);\n void bridgeTabMcp(tab);\n } catch (err) {\n emit({ type: \"$error\", message: `mcp_specs_add: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"mcp_specs_remove\") {\n try {\n const cfg = readConfig();\n const list = cfg.mcp ?? [];\n if (list.includes(msg.spec)) {\n cfg.mcp = list.filter((s) => s !== msg.spec);\n writeConfig(cfg);\n }\n tab.mcpStatuses.delete(msg.spec);\n emitMcpSpecs(tab);\n void bridgeTabMcp(tab);\n } catch (err) {\n emit({ type: \"$error\", message: `mcp_specs_remove: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"skills_get\") {\n emitSkills(tab);\n return;\n }\n if (msg.cmd === \"skill_run\") {\n if (!tab.runtime) {\n emit(\n { type: \"$error\", message: \"Not configured yet — paste your DeepSeek API key first.\" },\n tab.id,\n );\n return;\n }\n try {\n const store = new SkillStore({\n projectRoot: tab.rootDir,\n customSkillPaths: loadResolvedSkillPaths(tab.rootDir),\n });\n const found = store.read(msg.name);\n if (!found) {\n emit({ type: \"$error\", message: `skill not found: ${msg.name}` }, tab.id);\n return;\n }\n const extra = msg.args?.trim() ?? \"\";\n const header = `# Skill: ${found.name}${found.description ? `\\n> ${found.description}` : \"\"}`;\n const argsLine = extra ? `\\n\\nArguments: ${extra}` : \"\";\n const payload = `${header}\\n\\n${found.body}${argsLine}`;\n void runTurn(tab, payload);\n } catch (err) {\n emit({ type: \"$error\", message: `skill_run: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"session_list\") {\n emitSessions(tab);\n return;\n }\n if (msg.cmd === \"session_delete\") {\n deleteSession(msg.name);\n emitSessions(tab);\n return;\n }\n if (msg.cmd === \"session_load\") {\n try {\n const records = loadSessionMessages(msg.name);\n const meta = loadSessionMeta(msg.name);\n abortTurn(tab);\n cancelPendingGates(tab);\n tab.currentSession = msg.name;\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n const loadedMessages = buildLoadedMessages(records);\n // Empty load is a known silent-failure path (file 0 bytes, all\n // lines malformed, etc.). Log to stderr so a terminal-launched\n // desktop reports something diagnostic, and emit a $session_empty\n // event so the UI can surface \"loaded but empty\" instead of\n // looking like the click did nothing. Issue #1179.\n if (loadedMessages.length === 0) {\n let sizeBytes = 0;\n try {\n sizeBytes = statSync(sessionPath(msg.name)).size;\n } catch {\n /* file may not exist */\n }\n process.stderr.write(\n `session_load: \"${msg.name}\" returned 0 messages (file size=${sizeBytes}B) — empty or unreadable jsonl\\n`,\n );\n emit({ type: \"$session_empty\", name: msg.name, sizeBytes }, tab.id);\n }\n emit(\n {\n type: \"$session_loaded\",\n name: msg.name,\n messages: loadedMessages,\n carryover: {\n totalCostUsd: meta.totalCostUsd ?? 0,\n cacheHitTokens: meta.cacheHitTokens ?? 0,\n cacheMissTokens: meta.cacheMissTokens ?? 0,\n },\n },\n tab.id,\n );\n } catch (err) {\n process.stderr.write(`session_load: \"${msg.name}\" threw — ${(err as Error).message}\\n`);\n emit({ type: \"$error\", message: `session_load failed: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"new_chat\") {\n abortTurn(tab);\n cancelPendingGates(tab);\n tab.currentSession = mintSessionFor(tab.rootDir);\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n emitSessions(tab);\n return;\n }\n if (msg.cmd === \"settings_get\") {\n emitSettings(tab);\n return;\n }\n if (msg.cmd === \"settings_save\") {\n try {\n if (msg.reasoningEffort !== undefined) {\n saveReasoningEffort(msg.reasoningEffort);\n tab.runtime?.loop.configure({ reasoningEffort: msg.reasoningEffort });\n }\n if (msg.editMode !== undefined) saveEditMode(msg.editMode);\n if (msg.budgetUsd !== undefined) {\n tab.budgetUsd = msg.budgetUsd ?? undefined;\n tab.runtime?.loop.setBudget(msg.budgetUsd);\n }\n if (msg.baseUrl !== undefined) saveBaseUrl(msg.baseUrl);\n if (msg.workspaceDir !== undefined) {\n void switchWorkspace(tab, msg.workspaceDir);\n return;\n }\n if (msg.editor !== undefined) saveEditor(msg.editor);\n if (msg.preset !== undefined) {\n tab.currentPreset = canonicalPresetName(msg.preset);\n const resolved = resolvePreset(tab.currentPreset);\n tab.currentModel = resolved.model;\n savePreset(tab.currentPreset);\n // If the toolset isn't built yet (mid-bootstrap), let initTabToolset\n // see the updated currentModel and compute system + runtime once.\n if (tab.toolset) {\n tab.system = codeSystemPrompt(tab.rootDir, {\n hasSemanticSearch: tab.toolset.semantic.enabled,\n modelId: tab.currentModel,\n });\n if (tab.runtime) tab.runtime = buildRuntimeFor(tab);\n }\n }\n emitSettings(tab);\n } catch (err) {\n emit(\n { type: \"$error\", message: `settings_save failed: ${(err as Error).message}` },\n tab.id,\n );\n }\n return;\n }\n if (msg.cmd === \"mention_query\") {\n const nonce = msg.nonce;\n const query = msg.query;\n const parsed = parseAtQuery(query);\n // Empty query → list workspace root's top-level entries (tree\n // style). Without this, bare `@` floods with all 5000 files; the\n // TUI's @+Tab pattern already shows the tree top.\n const treeWalk = parsed.trailingSlash || query.length === 0;\n if (treeWalk) {\n void listDirectory(tab.rootDir, parsed.dir)\n .then((entries) => {\n const results = entries.map((e) => (e.isDir ? `${e.path}/` : e.path));\n emit({ type: \"$mention_results\", nonce, query, results }, tab.id);\n })\n .catch((err) => {\n emit(\n { type: \"$error\", message: `mention_query (dir) failed: ${(err as Error).message}` },\n tab.id,\n );\n emit({ type: \"$mention_results\", nonce, query, results: [] }, tab.id);\n });\n return;\n }\n const wantSymbols = query.length >= 2 && !query.includes(\"/\");\n void (async () => {\n try {\n const files = await getFileIndexFor(tab);\n const fileResults = rankPickerCandidates(files, query, {\n limit: wantSymbols ? 19 : 25,\n recentlyUsed: tab.recentMentions,\n });\n let symResults: string[] = [];\n if (wantSymbols) {\n const syms = await getSymbolIndexFor(tab);\n symResults = rankSymbols(syms, query, 6);\n }\n emit(\n { type: \"$mention_results\", nonce, query, results: [...symResults, ...fileResults] },\n tab.id,\n );\n } catch (err) {\n emit(\n { type: \"$error\", message: `mention_query failed: ${(err as Error).message}` },\n tab.id,\n );\n emit({ type: \"$mention_results\", nonce, query, results: [] }, tab.id);\n }\n })();\n return;\n }\n if (msg.cmd === \"mention_picked\") {\n pushMentionRecent(tab, msg.path);\n return;\n }\n if (msg.cmd === \"mention_preview\") {\n const nonce = msg.nonce;\n const rel = msg.path;\n const abs = isAbsolute(rel) ? rel : join(tab.rootDir, rel);\n const safeAbs = resolve(abs);\n const safeRoot = resolve(tab.rootDir);\n if (!safeAbs.startsWith(safeRoot)) {\n emit({ type: \"$mention_preview\", nonce, path: rel, head: \"\", totalLines: 0 }, tab.id);\n return;\n }\n void readFile(safeAbs, \"utf8\")\n .then((text) => {\n const lines = text.split(/\\r?\\n/);\n if (lines.length > 0 && lines[lines.length - 1] === \"\") lines.pop();\n const head = lines.slice(0, 12).join(\"\\n\");\n emit(\n { type: \"$mention_preview\", nonce, path: rel, head, totalLines: lines.length },\n tab.id,\n );\n })\n .catch(() => {\n emit({ type: \"$mention_preview\", nonce, path: rel, head: \"\", totalLines: 0 }, tab.id);\n });\n return;\n }\n if (msg.cmd === \"user_input\") {\n if (!tab.runtime) {\n emit(\n { type: \"$error\", message: \"Not configured yet — paste your DeepSeek API key first.\" },\n tab.id,\n );\n return;\n }\n void runTurn(tab, msg.text);\n }\n });\n\n await new Promise<void>((resolve) => {\n rl.on(\"close\", () => {\n void gracefulShutdown();\n resolve();\n });\n });\n}\n"],"mappings":"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","names":["tab","resolve"]}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
|
+
import {
|
|
4
|
+
wrapper_default
|
|
5
|
+
} from "./chunk-FEZK652I.js";
|
|
6
|
+
import "./chunk-TUK7OWJA.js";
|
|
7
|
+
|
|
8
|
+
// node_modules/ink/build/devtools-window-polyfill.js
|
|
9
|
+
var customGlobal = globalThis;
|
|
10
|
+
customGlobal.WebSocket ||= wrapper_default;
|
|
11
|
+
customGlobal.window ||= globalThis;
|
|
12
|
+
customGlobal.self ||= globalThis;
|
|
13
|
+
customGlobal.window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = [
|
|
14
|
+
{
|
|
15
|
+
// ComponentFilterElementType
|
|
16
|
+
type: 1,
|
|
17
|
+
// ElementTypeHostComponent
|
|
18
|
+
value: 7,
|
|
19
|
+
isEnabled: true
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
// ComponentFilterDisplayName
|
|
23
|
+
type: 2,
|
|
24
|
+
value: "InternalApp",
|
|
25
|
+
isEnabled: true,
|
|
26
|
+
isValid: true
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
// ComponentFilterDisplayName
|
|
30
|
+
type: 2,
|
|
31
|
+
value: "InternalAppContext",
|
|
32
|
+
isEnabled: true,
|
|
33
|
+
isValid: true
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
// ComponentFilterDisplayName
|
|
37
|
+
type: 2,
|
|
38
|
+
value: "InternalStdoutContext",
|
|
39
|
+
isEnabled: true,
|
|
40
|
+
isValid: true
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
// ComponentFilterDisplayName
|
|
44
|
+
type: 2,
|
|
45
|
+
value: "InternalStderrContext",
|
|
46
|
+
isEnabled: true,
|
|
47
|
+
isValid: true
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
// ComponentFilterDisplayName
|
|
51
|
+
type: 2,
|
|
52
|
+
value: "InternalStdinContext",
|
|
53
|
+
isEnabled: true,
|
|
54
|
+
isValid: true
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
// ComponentFilterDisplayName
|
|
58
|
+
type: 2,
|
|
59
|
+
value: "InternalFocusContext",
|
|
60
|
+
isEnabled: true,
|
|
61
|
+
isValid: true
|
|
62
|
+
}
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
// node_modules/ink/build/devtools.js
|
|
66
|
+
import devtools from "react-devtools-core";
|
|
67
|
+
var isDevToolsReachable = async () => new Promise((resolve) => {
|
|
68
|
+
const socket = new wrapper_default("ws://localhost:8097");
|
|
69
|
+
const timeout = setTimeout(() => {
|
|
70
|
+
socket.terminate();
|
|
71
|
+
resolve(false);
|
|
72
|
+
}, 2e3);
|
|
73
|
+
timeout.unref();
|
|
74
|
+
socket.on("open", () => {
|
|
75
|
+
clearTimeout(timeout);
|
|
76
|
+
socket.terminate();
|
|
77
|
+
resolve(true);
|
|
78
|
+
});
|
|
79
|
+
socket.on("error", () => {
|
|
80
|
+
clearTimeout(timeout);
|
|
81
|
+
socket.terminate();
|
|
82
|
+
resolve(false);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
if (await isDevToolsReachable()) {
|
|
86
|
+
devtools.initialize();
|
|
87
|
+
devtools.connectToDevTools();
|
|
88
|
+
} else {
|
|
89
|
+
console.warn("DEV is set to true, but the React DevTools server is not running. Start it with:\n\n$ npx react-devtools\n");
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=devtools-HW3WDT3Q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../node_modules/ink/src/devtools-window-polyfill.ts","../../node_modules/ink/src/devtools.ts"],"sourcesContent":[null,null],"mappings":";;;;;;;;AAIA,IAAM,eAAe;AAMrB,aAAa,cAAc;AAG3B,aAAa,WAAW;AAGxB,aAAa,SAAS;AAMtB,aAAa,OAAO,uCAAuC;EAC1D;;IAEC,MAAM;;IAEN,OAAO;IACP,WAAW;;EAEZ;;IAEC,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;;EAEV;;IAEC,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;;EAEV;;IAEC,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;;EAEV;;IAEC,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;;EAEV;;IAEC,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;;EAEV;;IAEC,MAAM;IACN,OAAO;IACP,WAAW;IACX,SAAS;;;;;AC7DX,OAAO,cAAc;AAErB,IAAM,sBAAsB,YAC3B,IAAI,QAAQ,aAAU;AACrB,QAAM,SAAS,IAAI,gBAAU,qBAAqB;AAElD,QAAM,UAAU,WAAW,MAAK;AAC/B,WAAO,UAAS;AAChB,YAAQ,KAAK;EACd,GAAG,GAAI;AAEP,UAAQ,MAAK;AAEb,SAAO,GAAG,QAAQ,MAAK;AACtB,iBAAa,OAAO;AACpB,WAAO,UAAS;AAChB,YAAQ,IAAI;EACb,CAAC;AAED,SAAO,GAAG,SAAS,MAAK;AACvB,iBAAa,OAAO;AACpB,WAAO,UAAS;AAChB,YAAQ,KAAK;EACd,CAAC;AACF,CAAC;AAEF,IAAI,MAAM,oBAAmB,GAAI;AAE/B,WAAiB,WAAU;AAE3B,WAAiB,kBAAiB;AACpC,OAAO;AACN,UAAQ,KACP,4GAA4G;AAE9G;","names":[]}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
|
+
import {
|
|
4
|
+
RecordView
|
|
5
|
+
} from "./chunk-3T6VBZCL.js";
|
|
6
|
+
import {
|
|
7
|
+
diffTranscripts,
|
|
8
|
+
findNextDivergence,
|
|
9
|
+
findPrevDivergence,
|
|
10
|
+
renderMarkdown,
|
|
11
|
+
renderSummaryTable
|
|
12
|
+
} from "./chunk-7L2WTRNU.js";
|
|
13
|
+
import {
|
|
14
|
+
readTranscript
|
|
15
|
+
} from "./chunk-T5TQ4NDT.js";
|
|
16
|
+
import {
|
|
17
|
+
Box_default,
|
|
18
|
+
Static,
|
|
19
|
+
Text,
|
|
20
|
+
render_default,
|
|
21
|
+
require_react,
|
|
22
|
+
use_app_default,
|
|
23
|
+
use_input_default
|
|
24
|
+
} from "./chunk-X53B3JIX.js";
|
|
25
|
+
import "./chunk-BSGCXZQN.js";
|
|
26
|
+
import "./chunk-25T6CVUP.js";
|
|
27
|
+
import "./chunk-ILJOIQ5W.js";
|
|
28
|
+
import {
|
|
29
|
+
t
|
|
30
|
+
} from "./chunk-IAUOP25G.js";
|
|
31
|
+
import "./chunk-4MQ3VURH.js";
|
|
32
|
+
import {
|
|
33
|
+
__toESM
|
|
34
|
+
} from "./chunk-TUK7OWJA.js";
|
|
35
|
+
|
|
36
|
+
// src/cli/commands/diff.ts
|
|
37
|
+
import { writeFileSync } from "fs";
|
|
38
|
+
import { basename } from "path";
|
|
39
|
+
var import_react2 = __toESM(require_react(), 1);
|
|
40
|
+
|
|
41
|
+
// src/cli/ui/DiffApp.tsx
|
|
42
|
+
var import_react = __toESM(require_react(), 1);
|
|
43
|
+
function DiffApp({ report }) {
|
|
44
|
+
const { exit } = use_app_default();
|
|
45
|
+
const maxIdx = Math.max(0, report.pairs.length - 1);
|
|
46
|
+
const initialIdx = report.firstDivergenceTurn ? report.pairs.findIndex((p) => p.turn === report.firstDivergenceTurn) : 0;
|
|
47
|
+
const [idx, setIdx] = (0, import_react.useState)(Math.max(0, initialIdx));
|
|
48
|
+
use_input_default((input, key) => {
|
|
49
|
+
if (input === "q" || key.ctrl && input === "c") {
|
|
50
|
+
exit();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (input === "j" || key.downArrow || input === " " || key.return) {
|
|
54
|
+
setIdx((i) => Math.min(maxIdx, i + 1));
|
|
55
|
+
} else if (input === "k" || key.upArrow) {
|
|
56
|
+
setIdx((i) => Math.max(0, i - 1));
|
|
57
|
+
} else if (input === "g") {
|
|
58
|
+
setIdx(0);
|
|
59
|
+
} else if (input === "G") {
|
|
60
|
+
setIdx(maxIdx);
|
|
61
|
+
} else if (input === "n") {
|
|
62
|
+
const next = findNextDivergence(report.pairs, idx);
|
|
63
|
+
if (next !== -1) setIdx(next);
|
|
64
|
+
} else if (input === "N" || input === "p") {
|
|
65
|
+
const prev = findPrevDivergence(report.pairs, idx);
|
|
66
|
+
if (prev !== -1) setIdx(prev);
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
const pair = report.pairs[idx];
|
|
70
|
+
return /* @__PURE__ */ import_react.default.createElement(Box_default, { flexDirection: "column" }, /* @__PURE__ */ import_react.default.createElement(DiffHeader, { report }), /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1, paddingX: 1, justifyContent: "space-between" }, /* @__PURE__ */ import_react.default.createElement(Text, { color: "cyan", bold: true }, t("diffApp.turnLabel", {
|
|
71
|
+
turn: pair?.turn ?? "?",
|
|
72
|
+
current: idx + 1,
|
|
73
|
+
total: report.pairs.length
|
|
74
|
+
})), /* @__PURE__ */ import_react.default.createElement(Text, null, pair ? /* @__PURE__ */ import_react.default.createElement(KindBadge, { kind: pair.kind }) : null)), /* @__PURE__ */ import_react.default.createElement(Box_default, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ import_react.default.createElement(Pane, { label: report.a.label, headerColor: "blue", records: paneRecords(pair, "a") }), /* @__PURE__ */ import_react.default.createElement(Pane, { label: report.b.label, headerColor: "magenta", records: paneRecords(pair, "b") })), pair?.divergenceNote ? /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1, paddingX: 1 }, /* @__PURE__ */ import_react.default.createElement(Text, { color: "yellow" }, "\u2605 "), /* @__PURE__ */ import_react.default.createElement(Text, null, pair.divergenceNote)) : null, /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1, paddingX: 1, borderStyle: "single", borderColor: "gray" }, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "j"), "/", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "\\u2193"), " next \\u00b7 ", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "k"), "/", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "\\u2191"), " prev \\u00b7 ", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "n"), " next-diverge \\u00b7", " ", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "N"), "/", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "p"), " prev-diverge \\u00b7 ", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "g"), "/", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "G"), " first/last \\u00b7 ", /* @__PURE__ */ import_react.default.createElement(Text, { bold: true }, "q"), " quit")));
|
|
75
|
+
}
|
|
76
|
+
function DiffHeader({ report }) {
|
|
77
|
+
const a = report.a;
|
|
78
|
+
const b = report.b;
|
|
79
|
+
const cacheDelta = b.stats.cacheHitRatio - a.stats.cacheHitRatio;
|
|
80
|
+
const costDelta = a.stats.totalCostUsd > 0 ? (b.stats.totalCostUsd - a.stats.totalCostUsd) / a.stats.totalCostUsd * 100 : 0;
|
|
81
|
+
const aStable = a.stats.prefixHashes.length <= 1;
|
|
82
|
+
const bStable = b.stats.prefixHashes.length <= 1;
|
|
83
|
+
let prefixLine = null;
|
|
84
|
+
if (aStable !== bStable) {
|
|
85
|
+
const stableLabel = aStable ? report.a.label : report.b.label;
|
|
86
|
+
const churnLabel = aStable ? report.b.label : report.a.label;
|
|
87
|
+
const churnCount = aStable ? b.stats.prefixHashes.length : a.stats.prefixHashes.length;
|
|
88
|
+
prefixLine = `${stableLabel} stayed byte-stable; ${churnLabel} churned ${churnCount} distinct prefixes.`;
|
|
89
|
+
} else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {
|
|
90
|
+
prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}\u2026 \u2014 cache delta attributable to log stability, not prompt change.`;
|
|
91
|
+
}
|
|
92
|
+
return /* @__PURE__ */ import_react.default.createElement(Box_default, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 }, /* @__PURE__ */ import_react.default.createElement(Box_default, { justifyContent: "space-between" }, /* @__PURE__ */ import_react.default.createElement(Text, null, /* @__PURE__ */ import_react.default.createElement(Text, { color: "cyan", bold: true }, t("diffApp.title")), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, " \\u00b7 A="), /* @__PURE__ */ import_react.default.createElement(Text, { color: "blue" }, a.label), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, " vs B="), /* @__PURE__ */ import_react.default.createElement(Text, { color: "magenta" }, b.label)), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, t("diffApp.turnsAligned", { count: report.pairs.length }))), /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1, gap: 3 }, /* @__PURE__ */ import_react.default.createElement(Text, null, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, "cache "), /* @__PURE__ */ import_react.default.createElement(Text, null, (a.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, " \u2192 "), /* @__PURE__ */ import_react.default.createElement(Text, null, (b.stats.cacheHitRatio * 100).toFixed(1), "%"), /* @__PURE__ */ import_react.default.createElement(Text, { color: cacheDelta >= 0 ? "green" : "red", bold: true }, " ", cacheDelta >= 0 ? "+" : "", (cacheDelta * 100).toFixed(1), "pp")), /* @__PURE__ */ import_react.default.createElement(Text, null, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, "cost "), /* @__PURE__ */ import_react.default.createElement(Text, null, "$", a.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, " \u2192 "), /* @__PURE__ */ import_react.default.createElement(Text, null, "$", b.stats.totalCostUsd.toFixed(6)), /* @__PURE__ */ import_react.default.createElement(Text, { color: costDelta <= 0 ? "green" : "red", bold: true }, " ", costDelta >= 0 ? "+" : "", costDelta.toFixed(1), "%")), /* @__PURE__ */ import_react.default.createElement(Text, null, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true }, "model calls "), /* @__PURE__ */ import_react.default.createElement(Text, null, a.stats.turns, " \u2192 ", b.stats.turns))), prefixLine ? /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true, italic: true }, prefixLine)) : null);
|
|
93
|
+
}
|
|
94
|
+
function Pane({
|
|
95
|
+
label,
|
|
96
|
+
headerColor,
|
|
97
|
+
records
|
|
98
|
+
}) {
|
|
99
|
+
return /* @__PURE__ */ import_react.default.createElement(
|
|
100
|
+
Box_default,
|
|
101
|
+
{
|
|
102
|
+
flexDirection: "column",
|
|
103
|
+
flexGrow: 1,
|
|
104
|
+
paddingX: 1,
|
|
105
|
+
borderStyle: "single",
|
|
106
|
+
borderColor: headerColor
|
|
107
|
+
},
|
|
108
|
+
/* @__PURE__ */ import_react.default.createElement(Text, { color: headerColor, bold: true }, label),
|
|
109
|
+
records.length === 0 ? /* @__PURE__ */ import_react.default.createElement(Box_default, { marginTop: 1 }, /* @__PURE__ */ import_react.default.createElement(Text, { dimColor: true, italic: true }, t("diffApp.paneEmpty"))) : /* @__PURE__ */ import_react.default.createElement(Static, { items: records.map((rec, i) => ({ key: `${label}-${i}`, rec })) }, ({ key, rec }) => /* @__PURE__ */ import_react.default.createElement(RecordView, { key, rec, compact: true }))
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
function KindBadge({ kind }) {
|
|
113
|
+
if (kind === "match") {
|
|
114
|
+
return /* @__PURE__ */ import_react.default.createElement(Text, { color: "green" }, t("diffApp.kindMatch"));
|
|
115
|
+
}
|
|
116
|
+
if (kind === "diverge") {
|
|
117
|
+
return /* @__PURE__ */ import_react.default.createElement(Text, { color: "yellow" }, t("diffApp.kindDiverge"));
|
|
118
|
+
}
|
|
119
|
+
if (kind === "only_in_a") {
|
|
120
|
+
return /* @__PURE__ */ import_react.default.createElement(Text, { color: "blue" }, t("diffApp.kindOnlyInA"));
|
|
121
|
+
}
|
|
122
|
+
return /* @__PURE__ */ import_react.default.createElement(Text, { color: "magenta" }, t("diffApp.kindOnlyInB"));
|
|
123
|
+
}
|
|
124
|
+
function paneRecords(pair, side) {
|
|
125
|
+
if (!pair) return [];
|
|
126
|
+
const tools = side === "a" ? pair.aTools : pair.bTools;
|
|
127
|
+
const assistant = side === "a" ? pair.aAssistant : pair.bAssistant;
|
|
128
|
+
const out = [...tools];
|
|
129
|
+
if (assistant) out.push(assistant);
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// src/cli/commands/diff.ts
|
|
134
|
+
async function diffCommand(opts) {
|
|
135
|
+
const aParsed = readTranscript(opts.a);
|
|
136
|
+
const bParsed = readTranscript(opts.b);
|
|
137
|
+
const report = diffTranscripts(
|
|
138
|
+
{ label: opts.labelA ?? basename(opts.a), parsed: aParsed },
|
|
139
|
+
{ label: opts.labelB ?? basename(opts.b), parsed: bParsed }
|
|
140
|
+
);
|
|
141
|
+
const wantMarkdown = !!opts.mdPath;
|
|
142
|
+
const wantPrint = opts.print || !process.stdout.isTTY;
|
|
143
|
+
const wantTui = opts.tui || !wantPrint && !wantMarkdown;
|
|
144
|
+
if (wantMarkdown) {
|
|
145
|
+
console.log(renderSummaryTable(report));
|
|
146
|
+
const md = renderMarkdown(report);
|
|
147
|
+
writeFileSync(opts.mdPath, md, "utf8");
|
|
148
|
+
console.log(`
|
|
149
|
+
markdown report written to ${opts.mdPath}`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (wantTui) {
|
|
153
|
+
const { waitUntilExit } = render_default(import_react2.default.createElement(DiffApp, { report }), {
|
|
154
|
+
exitOnCtrlC: true,
|
|
155
|
+
patchConsole: false
|
|
156
|
+
});
|
|
157
|
+
await waitUntilExit();
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
console.log(renderSummaryTable(report));
|
|
161
|
+
}
|
|
162
|
+
export {
|
|
163
|
+
diffCommand
|
|
164
|
+
};
|
|
165
|
+
//# sourceMappingURL=diff-E5OWTF4C.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/cli/commands/diff.ts","../../src/cli/ui/DiffApp.tsx"],"sourcesContent":["import { writeFileSync } from \"node:fs\";\nimport { basename } from \"node:path\";\nimport { render } from \"ink\";\nimport React from \"react\";\nimport { diffTranscripts, renderMarkdown, renderSummaryTable } from \"../../transcript/diff.js\";\nimport { readTranscript } from \"../../transcript/log.js\";\nimport { DiffApp } from \"../ui/DiffApp.js\";\n\nexport interface DiffOptions {\n a: string;\n b: string;\n mdPath?: string;\n labelA?: string;\n labelB?: string;\n /** Force stdout summary table (no Ink TUI). Auto when stdout isn't a TTY. */\n print?: boolean;\n /** Force the TUI even when stdout isn't a TTY (rare). */\n tui?: boolean;\n}\n\nexport async function diffCommand(opts: DiffOptions): Promise<void> {\n const aParsed = readTranscript(opts.a);\n const bParsed = readTranscript(opts.b);\n\n const report = diffTranscripts(\n { label: opts.labelA ?? basename(opts.a), parsed: aParsed },\n { label: opts.labelB ?? basename(opts.b), parsed: bParsed },\n );\n\n const wantMarkdown = !!opts.mdPath;\n const wantPrint = opts.print || !process.stdout.isTTY;\n const wantTui = opts.tui || (!wantPrint && !wantMarkdown);\n\n if (wantMarkdown) {\n // Markdown export implies the user wants an artifact, not a TUI.\n // Still echo the stdout summary to confirm the action.\n console.log(renderSummaryTable(report));\n const md = renderMarkdown(report);\n writeFileSync(opts.mdPath!, md, \"utf8\");\n console.log(`\\nmarkdown report written to ${opts.mdPath}`);\n return;\n }\n\n if (wantTui) {\n const { waitUntilExit } = render(React.createElement(DiffApp, { report }), {\n exitOnCtrlC: true,\n patchConsole: false,\n });\n await waitUntilExit();\n return;\n }\n\n // stdout fallback (piped, --print, or non-TTY)\n console.log(renderSummaryTable(report));\n}\n","/**\n * Ink TUI for `carboncode diff`. Split-pane: A on the left, B on the right,\n * shared cursor. Header shows aggregate deltas; footer shows the current\n * pair's divergence note (if any) + key cheat sheet.\n *\n * j/k moves the cursor by one turn; n/N jumps to the next/prev divergent\n * turn — which is the whole point of a diff tool. Quit with q.\n *\n * Pure navigation lives in src/diff.ts (findNextDivergence / findPrevDivergence).\n */\n\nimport { Box, Static, Text, useApp, useInput } from \"ink\";\nimport React, { useState } from \"react\";\nimport { t } from \"../../i18n/index.js\";\nimport {\n type DiffReport,\n type TurnPair,\n findNextDivergence,\n findPrevDivergence,\n} from \"../../transcript/diff.js\";\nimport { RecordView } from \"./RecordView.js\";\n\nexport interface DiffAppProps {\n report: DiffReport;\n}\n\nexport function DiffApp({ report }: DiffAppProps) {\n const { exit } = useApp();\n const maxIdx = Math.max(0, report.pairs.length - 1);\n // Start at the first divergence when one exists — that's the user's most\n // likely destination. Falls back to idx 0 for fully-matching diffs.\n const initialIdx = report.firstDivergenceTurn\n ? report.pairs.findIndex((p) => p.turn === report.firstDivergenceTurn)\n : 0;\n const [idx, setIdx] = useState(Math.max(0, initialIdx));\n\n useInput((input, key) => {\n if (input === \"q\" || (key.ctrl && input === \"c\")) {\n exit();\n return;\n }\n if (input === \"j\" || key.downArrow || input === \" \" || key.return) {\n setIdx((i) => Math.min(maxIdx, i + 1));\n } else if (input === \"k\" || key.upArrow) {\n setIdx((i) => Math.max(0, i - 1));\n } else if (input === \"g\") {\n setIdx(0);\n } else if (input === \"G\") {\n setIdx(maxIdx);\n } else if (input === \"n\") {\n const next = findNextDivergence(report.pairs, idx);\n if (next !== -1) setIdx(next);\n } else if (input === \"N\" || input === \"p\") {\n const prev = findPrevDivergence(report.pairs, idx);\n if (prev !== -1) setIdx(prev);\n }\n });\n\n const pair = report.pairs[idx];\n\n return (\n <Box flexDirection=\"column\">\n <DiffHeader report={report} />\n\n <Box marginTop={1} paddingX={1} justifyContent=\"space-between\">\n <Text color=\"cyan\" bold>\n {t(\"diffApp.turnLabel\", {\n turn: pair?.turn ?? \"?\",\n current: idx + 1,\n total: report.pairs.length,\n })}\n </Text>\n <Text>{pair ? <KindBadge kind={pair.kind} /> : null}</Text>\n </Box>\n\n <Box flexDirection=\"row\" marginTop={1}>\n <Pane label={report.a.label} headerColor=\"blue\" records={paneRecords(pair, \"a\")} />\n <Pane label={report.b.label} headerColor=\"magenta\" records={paneRecords(pair, \"b\")} />\n </Box>\n\n {pair?.divergenceNote ? (\n <Box marginTop={1} paddingX={1}>\n <Text color=\"yellow\">★ </Text>\n <Text>{pair.divergenceNote}</Text>\n </Box>\n ) : null}\n\n <Box marginTop={1} paddingX={1} borderStyle=\"single\" borderColor=\"gray\">\n <Text dimColor>\n <Text bold>j</Text>/<Text bold>\\u2193</Text> next \\u00b7 <Text bold>k</Text>/\n <Text bold>\\u2191</Text> prev \\u00b7 <Text bold>n</Text> next-diverge \\u00b7{\" \"}\n <Text bold>N</Text>/<Text bold>p</Text> prev-diverge \\u00b7 <Text bold>g</Text>/\n <Text bold>G</Text> first/last \\u00b7 <Text bold>q</Text> quit\n </Text>\n </Box>\n </Box>\n );\n}\n\n// ----------------------------------------------------------------------------\n\nfunction DiffHeader({ report }: { report: DiffReport }) {\n const a = report.a;\n const b = report.b;\n\n const cacheDelta = b.stats.cacheHitRatio - a.stats.cacheHitRatio;\n const costDelta =\n a.stats.totalCostUsd > 0\n ? ((b.stats.totalCostUsd - a.stats.totalCostUsd) / a.stats.totalCostUsd) * 100\n : 0;\n\n // Prefix stability one-liner (same logic as the stdout summary).\n const aStable = a.stats.prefixHashes.length <= 1;\n const bStable = b.stats.prefixHashes.length <= 1;\n let prefixLine: string | null = null;\n if (aStable !== bStable) {\n const stableLabel = aStable ? report.a.label : report.b.label;\n const churnLabel = aStable ? report.b.label : report.a.label;\n const churnCount = aStable ? b.stats.prefixHashes.length : a.stats.prefixHashes.length;\n prefixLine = `${stableLabel} stayed byte-stable; ${churnLabel} churned ${churnCount} distinct prefixes.`;\n } else if (a.stats.prefixHashes[0] && a.stats.prefixHashes[0] === b.stats.prefixHashes[0]) {\n prefixLine = `shared prefix hash ${a.stats.prefixHashes[0].slice(0, 12)}… — cache delta attributable to log stability, not prompt change.`;\n }\n\n return (\n <Box flexDirection=\"column\" borderStyle=\"round\" borderColor=\"cyan\" paddingX={1}>\n <Box justifyContent=\"space-between\">\n <Text>\n <Text color=\"cyan\" bold>\n {t(\"diffApp.title\")}\n </Text>\n <Text dimColor> \\u00b7 A=</Text>\n <Text color=\"blue\">{a.label}</Text>\n <Text dimColor> vs B=</Text>\n <Text color=\"magenta\">{b.label}</Text>\n </Text>\n <Text dimColor>{t(\"diffApp.turnsAligned\", { count: report.pairs.length })}</Text>\n </Box>\n\n <Box marginTop={1} gap={3}>\n <Text>\n <Text dimColor>cache </Text>\n <Text>{(a.stats.cacheHitRatio * 100).toFixed(1)}%</Text>\n <Text dimColor> → </Text>\n <Text>{(b.stats.cacheHitRatio * 100).toFixed(1)}%</Text>\n <Text color={cacheDelta >= 0 ? \"green\" : \"red\"} bold>\n {\" \"}\n {cacheDelta >= 0 ? \"+\" : \"\"}\n {(cacheDelta * 100).toFixed(1)}pp\n </Text>\n </Text>\n <Text>\n <Text dimColor>cost </Text>\n <Text>${a.stats.totalCostUsd.toFixed(6)}</Text>\n <Text dimColor> → </Text>\n <Text>${b.stats.totalCostUsd.toFixed(6)}</Text>\n <Text color={costDelta <= 0 ? \"green\" : \"red\"} bold>\n {\" \"}\n {costDelta >= 0 ? \"+\" : \"\"}\n {costDelta.toFixed(1)}%\n </Text>\n </Text>\n <Text>\n <Text dimColor>model calls </Text>\n <Text>\n {a.stats.turns} → {b.stats.turns}\n </Text>\n </Text>\n </Box>\n\n {prefixLine ? (\n <Box marginTop={1}>\n <Text dimColor italic>\n {prefixLine}\n </Text>\n </Box>\n ) : null}\n </Box>\n );\n}\n\nfunction Pane({\n label,\n headerColor,\n records,\n}: {\n label: string;\n headerColor: \"blue\" | \"magenta\";\n records: TurnPair[\"aTools\"];\n}) {\n return (\n <Box\n flexDirection=\"column\"\n flexGrow={1}\n paddingX={1}\n borderStyle=\"single\"\n borderColor={headerColor}\n >\n <Text color={headerColor} bold>\n {label}\n </Text>\n {records.length === 0 ? (\n <Box marginTop={1}>\n <Text dimColor italic>\n {t(\"diffApp.paneEmpty\")}\n </Text>\n </Box>\n ) : (\n <Static items={records.map((rec, i) => ({ key: `${label}-${i}`, rec }))}>\n {({ key, rec }) => <RecordView key={key} rec={rec} compact />}\n </Static>\n )}\n </Box>\n );\n}\n\nfunction KindBadge({ kind }: { kind: TurnPair[\"kind\"] }) {\n if (kind === \"match\") {\n return <Text color=\"green\">{t(\"diffApp.kindMatch\")}</Text>;\n }\n if (kind === \"diverge\") {\n return <Text color=\"yellow\">{t(\"diffApp.kindDiverge\")}</Text>;\n }\n if (kind === \"only_in_a\") {\n return <Text color=\"blue\">{t(\"diffApp.kindOnlyInA\")}</Text>;\n }\n return <Text color=\"magenta\">{t(\"diffApp.kindOnlyInB\")}</Text>;\n}\n\n// ----------------------------------------------------------------------------\n\nfunction paneRecords(pair: TurnPair | undefined, side: \"a\" | \"b\"): TurnPair[\"aTools\"] {\n if (!pair) return [];\n const tools = side === \"a\" ? pair.aTools : pair.bTools;\n const assistant = side === \"a\" ? pair.aAssistant : pair.bAssistant;\n const out: TurnPair[\"aTools\"] = [...tools];\n if (assistant) out.push(assistant);\n return out;\n}\n"],"mappings":"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","names":["import_react","React","React"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
|
|
3
|
+
import {
|
|
4
|
+
doctorCommand,
|
|
5
|
+
formatDoctorJson,
|
|
6
|
+
runDoctorChecks
|
|
7
|
+
} from "./chunk-BSINVTTL.js";
|
|
8
|
+
import "./chunk-5QCB62C4.js";
|
|
9
|
+
import "./chunk-6OWJV3YW.js";
|
|
10
|
+
import "./chunk-BSGCXZQN.js";
|
|
11
|
+
import "./chunk-25T6CVUP.js";
|
|
12
|
+
import "./chunk-2UQP6H6T.js";
|
|
13
|
+
import "./chunk-JKGYMRX5.js";
|
|
14
|
+
import "./chunk-WRN65TRD.js";
|
|
15
|
+
import "./chunk-IX6XI2RG.js";
|
|
16
|
+
import "./chunk-S4XVGLRW.js";
|
|
17
|
+
import "./chunk-U4IJVG32.js";
|
|
18
|
+
import "./chunk-IAUOP25G.js";
|
|
19
|
+
import "./chunk-4MQ3VURH.js";
|
|
20
|
+
import "./chunk-LN3B5PMX.js";
|
|
21
|
+
import "./chunk-TUK7OWJA.js";
|
|
22
|
+
export {
|
|
23
|
+
doctorCommand,
|
|
24
|
+
formatDoctorJson,
|
|
25
|
+
runDoctorChecks
|
|
26
|
+
};
|
|
27
|
+
//# sourceMappingURL=doctor-IEJQRJMN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|