reasonix 0.50.0 → 0.51.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.
Files changed (147) hide show
  1. package/dashboard/dist/app.css +1 -1
  2. package/dashboard/dist/app.js +24 -22
  3. package/dashboard/dist/app.js.map +1 -1
  4. package/dist/cli/{acp-6B25WIFF.js → acp-XEUHGG7X.js} +34 -31
  5. package/dist/cli/acp-XEUHGG7X.js.map +1 -0
  6. package/dist/cli/chat-NJ2Q5KHG.js +50 -0
  7. package/dist/cli/{chunk-OPGWCKKU.js → chunk-2HVTBFCI.js} +3 -3
  8. package/dist/cli/{chunk-AJIZ5KFK.js → chunk-2WUEAI2I.js} +3 -3
  9. package/dist/cli/{chunk-I4Q3QT4W.js → chunk-36BM7INR.js} +2 -2
  10. package/dist/cli/{chunk-3RNFYDDM.js → chunk-3BTK5BHI.js} +11 -7
  11. package/dist/cli/chunk-3BTK5BHI.js.map +1 -0
  12. package/dist/cli/{chunk-GMSAB2TC.js → chunk-3YRTIWFX.js} +2 -2
  13. package/dist/cli/{chunk-NLRC3DWQ.js → chunk-544J4PXD.js} +5 -5
  14. package/dist/cli/{chunk-7WITYWKN.js → chunk-5AIDYVH2.js} +2 -2
  15. package/dist/cli/{chunk-ALCOQP6R.js → chunk-5BBC6YMV.js} +5 -5
  16. package/dist/cli/{chunk-S4XVGLRW.js → chunk-6UNHNVJR.js} +72 -5
  17. package/dist/cli/chunk-6UNHNVJR.js.map +1 -0
  18. package/dist/cli/{chunk-IK6WWRIX.js → chunk-6XWXIVQ3.js} +38 -22
  19. package/dist/cli/chunk-6XWXIVQ3.js.map +1 -0
  20. package/dist/cli/{chunk-AAHB2PFX.js → chunk-7YB26OQO.js} +4 -4
  21. package/dist/cli/chunk-7YB26OQO.js.map +1 -0
  22. package/dist/cli/{chunk-MXWPAPZW.js → chunk-A5PBEIJ7.js} +53 -10
  23. package/dist/cli/chunk-A5PBEIJ7.js.map +1 -0
  24. package/dist/cli/{chunk-FQSQFCBI.js → chunk-BA5R6BAE.js} +2 -2
  25. package/dist/cli/{chunk-XWPZHWC2.js → chunk-BM6BBFAV.js} +2 -2
  26. package/dist/cli/{chunk-CAGKEGNE.js → chunk-BOWSNGQC.js} +52 -140
  27. package/dist/cli/chunk-BOWSNGQC.js.map +1 -0
  28. package/dist/cli/{chunk-EZ57UEZQ.js → chunk-C2MRSJTV.js} +2 -2
  29. package/dist/cli/{chunk-PYIZZAVQ.js → chunk-DVD67FXQ.js} +1716 -4
  30. package/dist/cli/chunk-DVD67FXQ.js.map +1 -0
  31. package/dist/cli/{chunk-ZAXMJANP.js → chunk-EAMXOWUW.js} +3 -3
  32. package/dist/cli/{chunk-TX652NBA.js → chunk-EWVFGYT6.js} +2 -2
  33. package/dist/cli/{chunk-IBRTU5WO.js → chunk-FP7IOWBQ.js} +18 -1182
  34. package/dist/cli/chunk-FP7IOWBQ.js.map +1 -0
  35. package/dist/cli/{chunk-I6FBSTTR.js → chunk-HGK57NBN.js} +9 -353
  36. package/dist/cli/chunk-HGK57NBN.js.map +1 -0
  37. package/dist/cli/chunk-JHWQDJZA.js +80 -0
  38. package/dist/cli/chunk-JHWQDJZA.js.map +1 -0
  39. package/dist/cli/{chunk-X2BQZQEE.js → chunk-K3QJ3GKI.js} +3 -3
  40. package/dist/cli/{chunk-GPUH2BNM.js → chunk-K4YQFULP.js} +612 -254
  41. package/dist/cli/chunk-K4YQFULP.js.map +1 -0
  42. package/dist/cli/chunk-L3VPEESB.js +31 -0
  43. package/dist/cli/chunk-L3VPEESB.js.map +1 -0
  44. package/dist/cli/{chunk-ENFBF6HI.js → chunk-N4SEBLU4.js} +383 -5
  45. package/dist/cli/chunk-N4SEBLU4.js.map +1 -0
  46. package/dist/cli/chunk-NRROJXXT.js +879 -0
  47. package/dist/cli/chunk-NRROJXXT.js.map +1 -0
  48. package/dist/cli/{chunk-3KRRTLC5.js → chunk-R6KIHEF3.js} +1619 -1036
  49. package/dist/cli/chunk-R6KIHEF3.js.map +1 -0
  50. package/dist/cli/{chunk-VVMY4M7J.js → chunk-SBHF5NWD.js} +27 -4
  51. package/dist/cli/chunk-SBHF5NWD.js.map +1 -0
  52. package/dist/cli/{chunk-OWA42BKS.js → chunk-SXSAWOB7.js} +14 -14
  53. package/dist/cli/{chunk-6IUMTRFP.js → chunk-UMZ6KHTS.js} +2 -2
  54. package/dist/cli/{chunk-7X4JJOO7.js → chunk-UO6E7FN3.js} +69 -5
  55. package/dist/cli/{chunk-7X4JJOO7.js.map → chunk-UO6E7FN3.js.map} +1 -1
  56. package/dist/cli/{chunk-3ZZXQ3CZ.js → chunk-UPW544V3.js} +2 -2
  57. package/dist/cli/{chunk-XJZWMU5P.js → chunk-WPOKBW5E.js} +2 -2
  58. package/dist/cli/{chunk-WSBFVOCO.js → chunk-Z3MKG7MQ.js} +2 -2
  59. package/dist/cli/{code-TBK2TASK.js → code-BMXLBC7D.js} +37 -36
  60. package/dist/cli/{code-TBK2TASK.js.map → code-BMXLBC7D.js.map} +1 -1
  61. package/dist/cli/{commands-NXTKSQTN.js → commands-E4RZXMF6.js} +5 -5
  62. package/dist/cli/{commit-IR5SPP7A.js → commit-KSRQ64IL.js} +3 -3
  63. package/dist/cli/{config-XK5WQGTS.js → config-QNDONOTU.js} +4 -2
  64. package/dist/cli/{desktop-5NTQBADL.js → desktop-H3ZHIMDA.js} +83 -37
  65. package/dist/cli/desktop-H3ZHIMDA.js.map +1 -0
  66. package/dist/cli/{diff-JNYX5BSZ.js → diff-I4PYI43W.js} +9 -9
  67. package/dist/cli/{doctor-IKYLUFXX.js → doctor-Y2E4MY2F.js} +12 -12
  68. package/dist/cli/{events-HSC57ONU.js → events-47HOT7ZA.js} +5 -5
  69. package/dist/cli/find-in-code-YLEIK5FK.js +145 -0
  70. package/dist/cli/find-in-code-YLEIK5FK.js.map +1 -0
  71. package/dist/cli/index.js +95 -44
  72. package/dist/cli/index.js.map +1 -1
  73. package/dist/cli/{mcp-BDJJWOCD.js → mcp-76DK63ZB.js} +3 -3
  74. package/dist/cli/{mcp-browse-NJRZDI6V.js → mcp-browse-SDNUGO74.js} +3 -3
  75. package/dist/cli/{mcp-inspect-Y62NWZQL.js → mcp-inspect-BL5DEO5M.js} +3 -3
  76. package/dist/cli/{prompt-UTOIFUQC.js → prompt-JLATI3P7.js} +5 -5
  77. package/dist/cli/{prune-sessions-UCUD4XAP.js → prune-sessions-WHZDFUKD.js} +4 -4
  78. package/dist/cli/{replay-VVIN64MN.js → replay-MHXS7C7Z.js} +10 -10
  79. package/dist/cli/{run-76OBDZFB.js → run-SXNCPRJE.js} +22 -22
  80. package/dist/cli/{server-SZZDKTH2.js → server-GEHOE6CO.js} +61 -35
  81. package/dist/cli/server-GEHOE6CO.js.map +1 -0
  82. package/dist/cli/{sessions-FZTGRCM5.js → sessions-EPBFYISL.js} +18 -18
  83. package/dist/cli/{setup-4UNENGOE.js → setup-IW2XR5XI.js} +8 -7
  84. package/dist/cli/setup-IW2XR5XI.js.map +1 -0
  85. package/dist/cli/{stats-F4NDOD7D.js → stats-4WB4XHBP.js} +6 -6
  86. package/dist/cli/symbols-UQ274IOB.js +167 -0
  87. package/dist/cli/symbols-UQ274IOB.js.map +1 -0
  88. package/dist/cli/version-4SP3DLLH.js +33 -0
  89. package/dist/index.d.ts +25 -6
  90. package/dist/index.js +2700 -578
  91. package/dist/index.js.map +1 -1
  92. package/package.json +6 -3
  93. package/scripts/postinstall.mjs +10 -0
  94. package/dist/cli/acp-6B25WIFF.js.map +0 -1
  95. package/dist/cli/chat-7WASPB4O.js +0 -50
  96. package/dist/cli/chunk-3KRRTLC5.js.map +0 -1
  97. package/dist/cli/chunk-3RNFYDDM.js.map +0 -1
  98. package/dist/cli/chunk-AAHB2PFX.js.map +0 -1
  99. package/dist/cli/chunk-CAGKEGNE.js.map +0 -1
  100. package/dist/cli/chunk-ENFBF6HI.js.map +0 -1
  101. package/dist/cli/chunk-GPUH2BNM.js.map +0 -1
  102. package/dist/cli/chunk-I6FBSTTR.js.map +0 -1
  103. package/dist/cli/chunk-IBRTU5WO.js.map +0 -1
  104. package/dist/cli/chunk-IK6WWRIX.js.map +0 -1
  105. package/dist/cli/chunk-MXWPAPZW.js.map +0 -1
  106. package/dist/cli/chunk-PYIZZAVQ.js.map +0 -1
  107. package/dist/cli/chunk-S4XVGLRW.js.map +0 -1
  108. package/dist/cli/chunk-VVMY4M7J.js.map +0 -1
  109. package/dist/cli/desktop-5NTQBADL.js.map +0 -1
  110. package/dist/cli/server-SZZDKTH2.js.map +0 -1
  111. package/dist/cli/setup-4UNENGOE.js.map +0 -1
  112. package/dist/cli/version-LUVTWHLL.js +0 -33
  113. /package/dist/cli/{chat-7WASPB4O.js.map → chat-NJ2Q5KHG.js.map} +0 -0
  114. /package/dist/cli/{chunk-OPGWCKKU.js.map → chunk-2HVTBFCI.js.map} +0 -0
  115. /package/dist/cli/{chunk-AJIZ5KFK.js.map → chunk-2WUEAI2I.js.map} +0 -0
  116. /package/dist/cli/{chunk-I4Q3QT4W.js.map → chunk-36BM7INR.js.map} +0 -0
  117. /package/dist/cli/{chunk-GMSAB2TC.js.map → chunk-3YRTIWFX.js.map} +0 -0
  118. /package/dist/cli/{chunk-NLRC3DWQ.js.map → chunk-544J4PXD.js.map} +0 -0
  119. /package/dist/cli/{chunk-7WITYWKN.js.map → chunk-5AIDYVH2.js.map} +0 -0
  120. /package/dist/cli/{chunk-ALCOQP6R.js.map → chunk-5BBC6YMV.js.map} +0 -0
  121. /package/dist/cli/{chunk-FQSQFCBI.js.map → chunk-BA5R6BAE.js.map} +0 -0
  122. /package/dist/cli/{chunk-XWPZHWC2.js.map → chunk-BM6BBFAV.js.map} +0 -0
  123. /package/dist/cli/{chunk-EZ57UEZQ.js.map → chunk-C2MRSJTV.js.map} +0 -0
  124. /package/dist/cli/{chunk-ZAXMJANP.js.map → chunk-EAMXOWUW.js.map} +0 -0
  125. /package/dist/cli/{chunk-TX652NBA.js.map → chunk-EWVFGYT6.js.map} +0 -0
  126. /package/dist/cli/{chunk-X2BQZQEE.js.map → chunk-K3QJ3GKI.js.map} +0 -0
  127. /package/dist/cli/{chunk-OWA42BKS.js.map → chunk-SXSAWOB7.js.map} +0 -0
  128. /package/dist/cli/{chunk-6IUMTRFP.js.map → chunk-UMZ6KHTS.js.map} +0 -0
  129. /package/dist/cli/{chunk-3ZZXQ3CZ.js.map → chunk-UPW544V3.js.map} +0 -0
  130. /package/dist/cli/{chunk-XJZWMU5P.js.map → chunk-WPOKBW5E.js.map} +0 -0
  131. /package/dist/cli/{chunk-WSBFVOCO.js.map → chunk-Z3MKG7MQ.js.map} +0 -0
  132. /package/dist/cli/{commands-NXTKSQTN.js.map → commands-E4RZXMF6.js.map} +0 -0
  133. /package/dist/cli/{commit-IR5SPP7A.js.map → commit-KSRQ64IL.js.map} +0 -0
  134. /package/dist/cli/{config-XK5WQGTS.js.map → config-QNDONOTU.js.map} +0 -0
  135. /package/dist/cli/{diff-JNYX5BSZ.js.map → diff-I4PYI43W.js.map} +0 -0
  136. /package/dist/cli/{doctor-IKYLUFXX.js.map → doctor-Y2E4MY2F.js.map} +0 -0
  137. /package/dist/cli/{events-HSC57ONU.js.map → events-47HOT7ZA.js.map} +0 -0
  138. /package/dist/cli/{mcp-BDJJWOCD.js.map → mcp-76DK63ZB.js.map} +0 -0
  139. /package/dist/cli/{mcp-browse-NJRZDI6V.js.map → mcp-browse-SDNUGO74.js.map} +0 -0
  140. /package/dist/cli/{mcp-inspect-Y62NWZQL.js.map → mcp-inspect-BL5DEO5M.js.map} +0 -0
  141. /package/dist/cli/{prompt-UTOIFUQC.js.map → prompt-JLATI3P7.js.map} +0 -0
  142. /package/dist/cli/{prune-sessions-UCUD4XAP.js.map → prune-sessions-WHZDFUKD.js.map} +0 -0
  143. /package/dist/cli/{replay-VVIN64MN.js.map → replay-MHXS7C7Z.js.map} +0 -0
  144. /package/dist/cli/{run-76OBDZFB.js.map → run-SXNCPRJE.js.map} +0 -0
  145. /package/dist/cli/{sessions-FZTGRCM5.js.map → sessions-EPBFYISL.js.map} +0 -0
  146. /package/dist/cli/{stats-F4NDOD7D.js.map → stats-4WB4XHBP.js.map} +0 -0
  147. /package/dist/cli/{version-LUVTWHLL.js.map → version-4SP3DLLH.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/cli/commands/desktop.ts","../../src/desktop/login-shell-path.ts","../../src/desktop/qq-settings.ts","../../src/desktop/qq-turn-routing.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 { toApprovalPrompt } from \"@reasonix/core-utils\";\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 { applyPlanMode, buildCodeToolset } from \"../../code/setup.js\";\nimport {\n DEFAULT_MODEL,\n type DesktopOpenTab,\n type EditMode,\n bridgeEndpointEnv,\n isPlausibleKey,\n isReasoningEffort,\n loadApiKey,\n loadDesktopOpenTabs,\n loadEditMode,\n loadEditor,\n loadEndpoint,\n loadModel,\n loadQQConfig,\n loadReasoningEffort,\n loadRecentWorkspaces,\n loadResolvedSkillPaths,\n loadShowSystemEvents,\n loadSubagentModels,\n loadWorkspaceDir,\n pushRecentWorkspace,\n readConfig,\n webSearchEngine as readWebSearchEngine,\n saveApiKey,\n saveBaseUrl,\n saveDesktopOpenTabs,\n saveEditMode,\n saveEditor,\n saveModel,\n saveReasoningEffort,\n saveShowSystemEvents,\n saveSubagentModels,\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 { augmentProcessPath } from \"../../desktop/login-shell-path.js\";\nimport {\n type MemoryEntryDetail,\n type MemoryEntryInfo,\n collectMemoryEntriesForWorkspace,\n readMemoryEntryDetail,\n} from \"../../desktop/memory-browser.js\";\nimport {\n loadDesktopQQState,\n saveDesktopQQSettings,\n setDesktopQQEnabled,\n} from \"../../desktop/qq-settings.js\";\nimport {\n clearQQTurnRouting,\n createQQTurnRoutingState,\n markQQTurnFinished,\n markQQTurnStarted,\n setQQPendingInteraction,\n shouldRouteQQForTab,\n takeQQPendingInteraction,\n} from \"../../desktop/qq-turn-routing.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 patchSessionWorkspaceIfMissing,\n sessionPath,\n timestampSuffix,\n} from \"../../memory/session.js\";\nimport { QQChannel } from \"../../qq/channel.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 { 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: \"session_rename\"; name: string; title: string }\n | { cmd: \"memory_read\"; path: string }\n | { cmd: \"new_chat\" }\n | { cmd: \"setup_save_key\"; key: string }\n | { cmd: \"settings_get\" }\n | {\n cmd: \"settings_save\";\n reasoningEffort?: import(\"../../config.js\").ReasoningEffort;\n editMode?: EditMode;\n budgetUsd?: number | null;\n baseUrl?: string;\n workspaceDir?: string;\n model?: string;\n editor?: string;\n webSearchEngine?: \"bing\" | \"searxng\" | \"metaso\" | \"tavily\" | \"perplexity\" | \"exa\";\n subagentModels?: Record<string, \"flash\" | \"pro\">;\n showSystemEvents?: boolean;\n }\n | { cmd: \"qq_status_get\" }\n | { cmd: \"qq_connect\" }\n | { cmd: \"qq_disconnect\" }\n | {\n cmd: \"qq_config_save\";\n appId?: string;\n appSecret?: string;\n sandbox: boolean;\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: \"tab_activate\"; tabId: string }\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 | { cmd: \"compact_history\" }\n | { cmd: \"retry\" }\n | { cmd: \"btw\"; text: string }\n | { cmd: \"desktop_resync\" }\n);\n\ninterface NeedsSetupEvent {\n type: \"$needs_setup\";\n reason: \"no_api_key\";\n}\n\ninterface SettingsEvent {\n type: \"$settings\";\n reasoningEffort: import(\"../../config.js\").ReasoningEffort;\n editMode: EditMode;\n budgetUsd: number | null;\n baseUrl?: string;\n apiKeyPrefix?: string;\n workspaceDir: string;\n recentWorkspaces: string[];\n model: string;\n editor?: string;\n webSearchEngine?: \"bing\" | \"searxng\" | \"metaso\" | \"tavily\" | \"perplexity\" | \"exa\";\n subagentModels?: Record<string, \"flash\" | \"pro\">;\n showSystemEvents?: boolean;\n version: string;\n}\n\ninterface QQSettingsEvent {\n type: \"$qq_settings\";\n appId?: string;\n appSecret?: string;\n sandbox: boolean;\n enabled: boolean;\n configured: boolean;\n runtimeState: \"disconnected\" | \"connecting\" | \"connected\" | \"failed\";\n lastError?: string;\n appIdPreview?: string;\n access: 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: {\n name: string;\n messageCount: number;\n mtime: string;\n summary?: string;\n workspaceStatus?: \"matched\" | \"legacy_missing_meta\";\n }[];\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 /** True when the frontend should focus this tab (user-opened, or the restored focused tab). */\n active?: boolean;\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 totalCompletionTokens: 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 prompt?: import(\"@reasonix/core-utils\").ApprovalPrompt;\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 prompt?: import(\"@reasonix/core-utils\").ApprovalPrompt;\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 /** Current log token count (real-time) — sent after /compact to refresh the meter. */\n logTokens?: number;\n}\n\ninterface MemoryEvent {\n type: \"$memory\";\n entries: MemoryEntryInfo[];\n}\n\ninterface MemoryDetailEvent {\n type: \"$memory_detail\";\n detail: MemoryEntryDetail;\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\nconst desktopQqRuntimeSnapshot: {\n runtimeState: \"disconnected\" | \"connecting\" | \"connected\" | \"failed\";\n lastError?: string;\n} = {\n runtimeState: \"disconnected\",\n};\n\ninterface RetryResultEvent {\n type: \"$retry_result\";\n text: string;\n}\n\ninterface BtwResultEvent {\n type: \"$btw_result\";\n question: string;\n answer: string;\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 | QQSettingsEvent\n | BalanceEvent\n | MentionResultsEvent\n | MentionPreviewEvent\n | RetryResultEvent\n | BtwResultEvent\n | TabOpenedEvent\n | TabClosedEvent\n | McpSpecsEvent\n | SkillsEvent\n | CtxBreakdownEvent\n | MemoryEvent\n | MemoryDetailEvent\n | JobsEvent;\n\nconst STDOUT_BACKPRESSURE_WAIT = new Int32Array(new SharedArrayBuffer(4));\n\ntype SyncWriter = (fd: number, buffer: Buffer, offset: number, length: number) => number;\n\nconst SESSION_TITLE_MAX_CHARS = 200;\n\n/** Trim + cap a user-provided session title; empty string means \"clear summary\". Exported for tests. */\nexport function normalizeSessionTitle(raw: string): string {\n return raw.replace(/\\s+/g, \" \").trim().slice(0, SESSION_TITLE_MAX_CHARS);\n}\n\n/** Drain `buffer` to `fd` across partial writes; retry EAGAIN after a 5 ms park. Exported for tests. */\nexport function writeAllSync(\n fd: number,\n buffer: Buffer,\n opts: {\n write?: SyncWriter;\n wait?: () => void;\n } = {},\n): void {\n const write = opts.write ?? writeSync;\n const wait = opts.wait ?? (() => Atomics.wait(STDOUT_BACKPRESSURE_WAIT, 0, 0, 5));\n let offset = 0;\n while (offset < buffer.length) {\n let written: number;\n try {\n written = write(fd, buffer, offset, buffer.length - offset);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === \"EAGAIN\") {\n wait();\n continue;\n }\n throw err;\n }\n if (written <= 0) throw new Error(\"stdout write returned 0 bytes\");\n offset += written;\n }\n}\n\nfunction emit(ev: EmittableEvent, tabId?: string): void {\n const payload = tabId ? { ...ev, tabId } : ev;\n writeAllSync(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\nconst LOADED_RECENT_MESSAGE_WINDOW = 200;\nconst LOADED_MIN_ELIDE_CHARS = 4096;\nconst LOADED_ELIDED_PREFIX = \"[elided — older than the last \";\n\nfunction elideLoadedField(value: string): string {\n if (value.length <= LOADED_MIN_ELIDE_CHARS) return value;\n if (value.startsWith(LOADED_ELIDED_PREFIX)) return value;\n return `${LOADED_ELIDED_PREFIX}${LOADED_RECENT_MESSAGE_WINDOW} messages; ${value.length.toLocaleString()} chars dropped to save memory. Full content is on disk in the session log.]`;\n}\n\nfunction elideLoadedMessages(messages: LoadedMessage[]): LoadedMessage[] {\n if (messages.length < LOADED_RECENT_MESSAGE_WINDOW) return messages;\n const cutoff = messages.length - LOADED_RECENT_MESSAGE_WINDOW;\n return messages.map((msg, i) => {\n if (i >= cutoff || msg.kind !== \"assistant\") return msg;\n return {\n ...msg,\n segments: msg.segments.map((segment) => {\n switch (segment.kind) {\n case \"reasoning\":\n case \"text\":\n return { ...segment, text: elideLoadedField(segment.text) };\n case \"tool\":\n return {\n ...segment,\n args: elideLoadedField(segment.args),\n ...(segment.result !== undefined ? { result: elideLoadedField(segment.result) } : {}),\n };\n default:\n return segment;\n }\n }),\n };\n });\n}\n\nexport function 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 elideLoadedMessages(out);\n}\n\nfunction emitSettings(tab: Tab): void {\n const ep = loadEndpoint();\n const editMode = loadEditMode();\n if (tab.toolset) applyPlanMode(tab.toolset.tools, editMode);\n const recent = loadRecentWorkspaces().filter((p) => p !== tab.rootDir);\n emit(\n {\n type: \"$settings\",\n reasoningEffort: loadReasoningEffort(),\n editMode,\n budgetUsd: tab.runtime?.loop.budgetUsd ?? null,\n baseUrl: ep.baseUrl,\n apiKeyPrefix: ep.apiKey ? `${ep.apiKey.slice(0, 6)}…${ep.apiKey.slice(-3)}` : undefined,\n workspaceDir: tab.rootDir,\n recentWorkspaces: recent,\n model: tab.currentModel,\n editor: loadEditor(),\n webSearchEngine: readWebSearchEngine(),\n subagentModels: loadSubagentModels(),\n showSystemEvents: loadShowSystemEvents(),\n version: VERSION,\n },\n tab.id,\n );\n}\n\nfunction emitQQSettings(tab: Tab): void {\n const base = loadDesktopQQState();\n emit(\n {\n type: \"$qq_settings\",\n ...base,\n runtimeState: desktopQqRuntimeSnapshot.runtimeState,\n lastError: desktopQqRuntimeSnapshot.lastError,\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 workspaceStatus: s.workspaceStatus,\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 entries = collectMemoryEntriesForWorkspace(tab.rootDir);\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 const logTokens = tab.runtime.loop.getCurrentLogTokens();\n emit({ type: \"$ctx_breakdown\", reservedTokens: sys + tools, logTokens }, 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 subagentModels: loadSubagentModels(),\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: {\n model: string;\n prefixHash: string;\n reasoningEffort: import(\"../../config.js\").ReasoningEffort;\n };\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 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 /** True while a session switch is in progress — prevents stale events from the old turn. */\n switching: boolean;\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 applyPlanMode(toolset.tools, loadEditMode());\n const ep = loadEndpoint();\n const client = new DeepSeekClient({ apiKey: ep.apiKey, baseUrl: ep.baseUrl });\n const prefix = new ImmutablePrefix({ system: tab.system, toolSpecs: toolset.tools.specs() });\n const reasoningEffort = loadReasoningEffort();\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 });\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 \"reasonix 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 // Tauri spawns the bundled Node from the GUI process, which never runs the\n // user's shell init (`.bashrc` / `.zshrc` / profile). Probe the login shell\n // once so nvm / asdf / fnm / volta / mise PATH entries reach `run_command`\n // children too (#1252). No-op on Windows — system PATH already covers GUI apps.\n const augmented = augmentProcessPath();\n if (augmented.added.length > 0) {\n process.stderr.write(\n `[desktop] augmented PATH with ${augmented.added.length} login-shell entries\\n`,\n );\n }\n installDesktopCrashGuards();\n\n const tabs = new Map<string, Tab>();\n const tabContext = new AsyncLocalStorage<string>();\n // Frontend-reported focused tab — persisted so a restart reopens on it (#1244).\n let lastActiveTabId = \"\";\n\n function activeRunningTab(): Tab | undefined {\n const id = tabContext.getStore();\n return id ? tabs.get(id) : undefined;\n }\n\n let first: Tab;\n\n const qqRuntime = {\n channel: null as QQChannel | null,\n runtimeState: \"disconnected\" as \"disconnected\" | \"connecting\" | \"connected\" | \"failed\",\n lastError: undefined as string | undefined,\n routing: createQQTurnRoutingState(),\n };\n\n function currentQqSettings(): QQSettingsEvent {\n const base = loadDesktopQQState();\n return {\n type: \"$qq_settings\",\n ...base,\n runtimeState: qqRuntime.runtimeState,\n lastError: qqRuntime.lastError,\n };\n }\n\n function activeDesktopTab(): Tab | undefined {\n return (lastActiveTabId ? tabs.get(lastActiveTabId) : undefined) ?? first;\n }\n\n function broadcastQQSettings(): void {\n for (const tab of tabs.values()) emit(currentQqSettings(), tab.id);\n }\n\n function setQQRuntimeState(\n runtimeState: \"disconnected\" | \"connecting\" | \"connected\" | \"failed\",\n lastError?: string,\n ): void {\n qqRuntime.runtimeState = runtimeState;\n qqRuntime.lastError = lastError;\n desktopQqRuntimeSnapshot.runtimeState = runtimeState;\n desktopQqRuntimeSnapshot.lastError = lastError;\n broadcastQQSettings();\n }\n\n function sendQQInfo(message: string): void {\n const tab = activeDesktopTab();\n if (tab) {\n emit(\n {\n type: \"status\",\n id: Date.now(),\n ts: new Date().toISOString(),\n turn: 0,\n text: message,\n },\n tab.id,\n );\n }\n void qqRuntime.channel?.sendResponse(message).catch((err) => {\n const active = activeDesktopTab();\n if (active) {\n emit({ type: \"$error\", message: `qq send failed: ${(err as Error).message}` }, active.id);\n }\n });\n }\n\n function parseIndexedChoice(text: string): number {\n const rawIndex = text.match(/^(\\d+)/)?.[1];\n return rawIndex ? Number.parseInt(rawIndex, 10) - 1 : -1;\n }\n\n function parseRunPermissionChoice(text: string): \"run_once\" | \"always_allow\" | \"deny\" {\n const lower = text.toLowerCase();\n if (lower.includes(\"1\") || lower.includes(\"run\")) return \"run_once\";\n if (lower.includes(\"2\") || lower.includes(\"always\")) return \"always_allow\";\n return \"deny\";\n }\n\n function parsePlanChoice(text: string): \"approve\" | \"refine\" | \"cancel\" {\n const lower = text.toLowerCase();\n if (lower.includes(\"1\") || lower.includes(\"approve\")) return \"approve\";\n if (lower.includes(\"2\") || lower.includes(\"refine\")) return \"refine\";\n return \"cancel\";\n }\n\n function parseCheckpointChoice(text: string): \"continue\" | \"revise\" | \"stop\" {\n const lower = text.toLowerCase();\n if (lower.includes(\"1\") || lower.includes(\"continue\")) return \"continue\";\n if (lower.includes(\"2\") || lower.includes(\"revise\")) return \"revise\";\n return \"stop\";\n }\n\n function parseRevisionChoice(text: string): \"accept\" | \"reject\" | \"cancel\" {\n const lower = text.toLowerCase();\n if (lower.includes(\"1\") || lower.includes(\"accept\")) return \"accept\";\n if (lower.includes(\"2\") || lower.includes(\"reject\")) return \"reject\";\n return \"cancel\";\n }\n\n function stripFollowupPrefix(text: string): string {\n return text\n .replace(\n /^(?:\\d+\\s*|approve\\s*|refine\\s*|cancel\\s*|continue\\s*|revise\\s*|stop\\s*|accept\\s*|reject\\s*|run\\s*|always\\s*|deny\\s*)/iu,\n \"\",\n )\n .trim();\n }\n\n function handleQQPauseReply(tab: Tab, text: string): boolean {\n const pending = takeQQPendingInteraction(qqRuntime.routing, tab.id);\n if (!pending) return false;\n const followup = stripFollowupPrefix(text);\n const interaction = pending;\n const gateId = pending.gateId;\n\n switch (interaction.kind) {\n case \"run_command\":\n case \"run_background\":\n case \"path_access\":\n pauseGate.resolve(gateId, parseRunPermissionChoice(text));\n return true;\n case \"plan_proposed\": {\n const payload = (interaction.payload as { plan?: string }) ?? {};\n const choice = parsePlanChoice(text);\n if (choice === \"cancel\") {\n pauseGate.cancel(gateId);\n } else {\n pauseGate.resolve(gateId, {\n type: choice === \"approve\" ? \"approve\" : \"refine\",\n feedback: followup,\n override: {\n plan: payload.plan ?? \"\",\n mode: choice === \"approve\" ? \"approve\" : \"refine\",\n },\n });\n }\n return true;\n }\n case \"plan_checkpoint\": {\n const payload = (interaction.payload as { stepId?: string; title?: string }) ?? {};\n const choice = parseCheckpointChoice(text);\n if (choice === \"revise\") {\n pauseGate.resolve(gateId, {\n type: \"revise\",\n feedback: followup,\n checkpoint: { stepId: payload.stepId ?? \"\", title: payload.title },\n });\n } else {\n pauseGate.resolve(gateId, { type: choice });\n }\n return true;\n }\n case \"plan_revision\":\n pauseGate.resolve(gateId, parseRevisionChoice(text));\n return true;\n case \"choice\": {\n const payload =\n (interaction.payload as { options?: ChoiceOption[]; allowCustom?: boolean }) ?? {};\n const options = payload.options ?? [];\n const pickedIndex = parseIndexedChoice(text);\n if (pickedIndex >= 0 && pickedIndex < options.length) {\n const selected = options[pickedIndex];\n if (selected) pauseGate.resolve(gateId, { type: \"pick\", optionId: selected.id });\n return true;\n }\n for (const option of options) {\n if (text.toLowerCase().includes(option.title.toLowerCase())) {\n pauseGate.resolve(gateId, { type: \"pick\", optionId: option.id });\n return true;\n }\n }\n pauseGate.resolve(\n gateId,\n payload.allowCustom ? { type: \"text\", text } : { type: \"cancel\" },\n );\n return true;\n }\n default:\n return false;\n }\n }\n\n function handleQQPauseRequest(tab: Tab, kind: string, payload: Record<string, unknown>): void {\n if (!qqRuntime.channel || !shouldRouteQQForTab(qqRuntime.routing, tab.id)) return;\n let qqMessage = \"\";\n switch (kind) {\n case \"run_command\":\n case \"run_background\": {\n const p = payload as { command: string };\n qqMessage = `Need confirmation\\n\\nCommand: \\`${p.command}\\`\\n\\nReply with:\\n1. Run once\\n2. Always allow\\n3. Deny`;\n break;\n }\n case \"path_access\": {\n const p = payload as { path: string; intent: \"read\" | \"write\"; toolName: string };\n const intentText = p.intent === \"read\" ? \"Read\" : \"Write\";\n qqMessage = `Need file access confirmation\\n\\nAction: ${intentText}\\nPath: ${p.path}\\nTool: ${p.toolName}\\n\\nReply with:\\n1. Run once\\n2. Always allow\\n3. Deny`;\n break;\n }\n case \"plan_proposed\": {\n const p = payload as { plan: string };\n qqMessage = `Plan confirmation\\n\\n${p.plan}\\n\\nReply with:\\n1. Approve\\n2. Refine\\n3. Cancel`;\n break;\n }\n case \"plan_checkpoint\": {\n const p = payload as { title?: string; result: string };\n qqMessage = `Step complete (${tab.completedStepIds.size}/${tab.planTotalSteps})\\n\\n${\n p.title ? `Step: ${p.title}\\n` : \"\"\n }Result: ${p.result}\\n\\nReply with:\\n1. Continue\\n2. Revise\\n3. Stop`;\n break;\n }\n case \"plan_revision\": {\n const p = payload as { reason: string };\n qqMessage = `Plan revision proposed\\n\\n${p.reason}\\n\\nReply with:\\n1. Accept\\n2. Reject\\n3. Cancel`;\n break;\n }\n case \"choice\": {\n const p = payload as { question: string; options: ChoiceOption[]; allowCustom: boolean };\n const optionsList = p.options.map((opt, idx) => `${idx + 1}. ${opt.title}`).join(\"\\n\");\n qqMessage = `Please choose\\n\\n${p.question}\\n\\nOptions:\\n${optionsList}${\n p.allowCustom ? \"\\n\\n(You can also reply with custom text.)\" : \"\"\n }`;\n break;\n }\n }\n if (qqMessage) {\n void qqRuntime.channel.sendResponse(qqMessage).catch((err) => {\n emit({ type: \"$error\", message: `qq send failed: ${(err as Error).message}` }, tab.id);\n });\n }\n }\n\n async function startDesktopQQ(shouldPersistEnabled = true): Promise<void> {\n const current = loadQQConfig();\n if (!(current.appId && current.appSecret)) {\n throw new Error(\"QQ App ID and App Secret are required.\");\n }\n if (qqRuntime.channel) {\n qqRuntime.channel.refreshAccessConfig();\n setQQRuntimeState(\"connected\");\n return;\n }\n setQQRuntimeState(\"connecting\");\n const channel = new QQChannel({\n onSubmitMessage: (text) => {\n const tab = activeDesktopTab();\n if (!tab) return;\n const trimmed = text.trim();\n if (!trimmed) return;\n emit(\n {\n type: \"user.message\",\n id: Date.now(),\n ts: new Date().toISOString(),\n turn: 0,\n text: trimmed,\n },\n tab.id,\n );\n if (handleQQPauseReply(tab, trimmed)) return;\n if (tab.aborter) {\n void channel\n .sendResponse(\n \"Session is busy. Wait for the current turn or reply to the pending prompt.\",\n )\n .catch(() => undefined);\n return;\n }\n void runTurn(tab, trimmed, true);\n },\n onError: (message) => {\n const tab = activeDesktopTab();\n setQQRuntimeState(\"failed\", message);\n if (tab) emit({ type: \"$error\", message: `QQ: ${message}` }, tab.id);\n },\n });\n try {\n await channel.start();\n qqRuntime.channel = channel;\n if (shouldPersistEnabled) setDesktopQQEnabled(true);\n setQQRuntimeState(\"connected\");\n } catch (err) {\n await channel.stop().catch(() => undefined);\n qqRuntime.channel = null;\n if (shouldPersistEnabled) setDesktopQQEnabled(false);\n setQQRuntimeState(\"failed\", (err as Error).message);\n throw err;\n }\n }\n\n async function stopDesktopQQ(shouldDisable = true): Promise<void> {\n const channel = qqRuntime.channel;\n qqRuntime.channel = null;\n clearQQTurnRouting(qqRuntime.routing);\n if (channel) await channel.stop();\n if (shouldDisable) setDesktopQQEnabled(false);\n setQQRuntimeState(\"disconnected\");\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 model = opts.model || loadModel() || DEFAULT_MODEL;\n const tab: Tab = {\n id: nextTabId(),\n rootDir: dir,\n currentSession: \"\",\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 switching: false,\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 model changes 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 bridgeEndpointEnv();\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 getWorkspaceDir: () => tab.rootDir,\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 — workspace dir, loaded session and focus, in tab order. Persisted after open/close/switch so a restart restores the full tab set and each conversation (issues #933, #1244). */\n function persistOpenTabs(): void {\n try {\n saveDesktopOpenTabs(\n Array.from(tabs.values()).map((t) => ({\n dir: t.rootDir,\n session: t.currentSession || undefined,\n active: t.id === lastActiveTabId,\n })),\n );\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, fromQQ = false): Promise<void> {\n if (!tab.runtime) return;\n const rt = tab.runtime;\n tab.aborter = new AbortController();\n if (fromQQ) markQQTurnStarted(qqRuntime.routing, tab.id);\n let lastAssistantText = \"\";\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 if (ev.role === \"assistant_final\" && ev.content) {\n lastAssistantText = ev.content;\n }\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 // If a session switch happened while this turn was running,\n // suppress stale events to avoid UI state corruption (#1217).\n if (!tab.switching) {\n if (\n fromQQ &&\n lastAssistantText &&\n qqRuntime.channel &&\n shouldRouteQQForTab(qqRuntime.routing, tab.id)\n ) {\n await qqRuntime.channel.sendResponse(lastAssistantText).catch((err) => {\n emit(\n { type: \"$error\", message: `qq send failed: ${(err as Error).message}` },\n tab.id,\n );\n });\n }\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 if (fromQQ) markQQTurnFinished(qqRuntime.routing, tab.id);\n tab.switching = false;\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 persistOpenTabs();\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, opts: { discardCurrentTurn?: boolean } = {}): void {\n tab.aborter?.abort();\n tab.runtime?.loop.abort(opts.discardCurrentTurn ? { discardCurrentTurn: true } : undefined);\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 shuttingDown = false;\n async function gracefulShutdown(): Promise<void> {\n if (shuttingDown) return;\n shuttingDown = true;\n await stopDesktopQQ(false).catch(() => undefined);\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 {\n command?: string;\n cwd?: string;\n timeoutSec?: number;\n waitSec?: number;\n };\n if (tab) setQQPendingInteraction(qqRuntime.routing, tab.id, req.id, req.kind, payload);\n emit(\n {\n type: \"$confirm_required\",\n id: req.id,\n kind: req.kind,\n command: payload.command ?? \"\",\n prompt: toApprovalPrompt({\n id: req.id,\n kind: req.kind,\n payload,\n }),\n },\n tabId,\n );\n if (tab) handleQQPauseRequest(tab, req.kind, payload as Record<string, unknown>);\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 if (tab) setQQPendingInteraction(qqRuntime.routing, tab.id, req.id, req.kind, payload);\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 prompt: toApprovalPrompt({\n id: req.id,\n kind: req.kind,\n payload,\n }),\n },\n tabId,\n );\n if (tab) handleQQPauseRequest(tab, req.kind, payload as Record<string, unknown>);\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 if (tab) setQQPendingInteraction(qqRuntime.routing, tab.id, req.id, req.kind, payload);\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 if (tab) handleQQPauseRequest(tab, req.kind, payload as Record<string, unknown>);\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 setQQPendingInteraction(qqRuntime.routing, tab.id, req.id, req.kind, payload);\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 if (tab) handleQQPauseRequest(tab, req.kind, payload as Record<string, unknown>);\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) {\n tab.completedStepIds.add(payload.stepId);\n setQQPendingInteraction(qqRuntime.routing, tab.id, req.id, req.kind, payload);\n }\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 if (tab) handleQQPauseRequest(tab, req.kind, payload as Record<string, unknown>);\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 if (tab) setQQPendingInteraction(qqRuntime.routing, tab.id, req.id, req.kind, payload);\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 if (tab) handleQQPauseRequest(tab, req.kind, payload as Record<string, unknown>);\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(\n initialDir?: string,\n restore?: { session?: string; active?: boolean },\n ): Tab {\n const tab = createTabSkeleton(initialDir);\n // Reopen the conversation the tab had, if its jsonl is still readable.\n let restoredMessages: LoadedMessage[] | undefined;\n if (restore?.session) {\n try {\n if (existsSync(sessionPath(restore.session))) {\n const msgs = buildLoadedMessages(loadSessionMessages(restore.session));\n if (msgs.length > 0) {\n tab.currentSession = restore.session;\n restoredMessages = msgs;\n }\n }\n } catch {\n // unreadable jsonl — fall back to the freshly minted session\n }\n }\n emit({ type: \"$tab_opened\", workspaceDir: tab.rootDir, active: restore?.active }, tab.id);\n emitSessions(tab);\n emitSettings(tab);\n emitMcpSpecs(tab);\n emitSkills(tab);\n emitMemory(tab);\n emitQQSettings(tab);\n if (restoredMessages) {\n const meta = loadSessionMeta(tab.currentSession);\n emit(\n {\n type: \"$session_loaded\",\n name: tab.currentSession,\n messages: restoredMessages,\n carryover: {\n totalCostUsd: meta.totalCostUsd ?? 0,\n cacheHitTokens: meta.cacheHitTokens ?? 0,\n cacheMissTokens: meta.cacheMissTokens ?? 0,\n totalCompletionTokens: meta.totalCompletionTokens ?? 0,\n },\n },\n tab.id,\n );\n }\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 — workspace dir,\n // loaded session and focused tab (issues #933, #1244). Missing dirs\n // are silently skipped — a deleted workspace shouldn't break boot.\n const savedTabs = loadDesktopOpenTabs().filter((t) => {\n try {\n return existsSync(t.dir) && statSync(t.dir).isDirectory();\n } catch {\n return false;\n }\n });\n // When launched with --dir, find the matching saved tab so the user's\n // previous session is restored automatically.\n const startupDir = opts.dir;\n const startupTab = startupDir\n ? savedTabs.find((t) => resolve(t.dir) === resolve(startupDir))\n : savedTabs[0];\n first = bootstrapTab(opts.dir ?? savedTabs[0]?.dir, startupTab);\n const restored: Tab[] = [first];\n for (const t of savedTabs.slice(1)) restored.push(bootstrapTab(t.dir, t));\n // Mirror the persisted focus so the next persist round-trips it.\n const activeIdx = savedTabs.findIndex((t) => t.active);\n lastActiveTabId = ((activeIdx >= 0 ? restored[activeIdx] : first) ?? first).id;\n persistOpenTabs();\n const qqConfig = loadQQConfig();\n if (qqConfig.enabled && qqConfig.appId && qqConfig.appSecret) {\n void startDesktopQQ(false).catch(() => undefined);\n } else {\n broadcastQQSettings();\n }\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 // A user-opened tab takes focus.\n const opened = bootstrapTab(msg.workspaceDir, { active: true });\n lastActiveTabId = opened.id;\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 === \"tab_activate\") {\n if (tabs.has(msg.tabId)) {\n lastActiveTabId = msg.tabId;\n persistOpenTabs();\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 bridgeEndpointEnv();\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 === \"desktop_resync\") {\n // WebView reloads (DevTools F5, host-side respawn) leave the Node child\n // alive but the React app starts blank. Re-fire the bootstrap events\n // so it can rehydrate without restarting the agent.\n const hasKey = !!loadApiKey();\n for (const t of tabs.values()) {\n emit(\n { type: \"$tab_opened\", workspaceDir: t.rootDir, active: t.id === lastActiveTabId },\n t.id,\n );\n emitSessions(t);\n emitSettings(t);\n emitMcpSpecs(t);\n emitSkills(t);\n emitMemory(t);\n emitQQSettings(t);\n if (!hasKey) emit({ type: \"$needs_setup\", reason: \"no_api_key\" }, t.id);\n else if (t.toolset) emit({ type: \"$ready\" }, t.id);\n void emitBalance(t);\n // Re-emit session_loaded so the resumed session's messages and\n // usage stats (cost, tokens, cache%) are restored on the frontend.\n if (t.currentSession) {\n try {\n const msgs = buildLoadedMessages(loadSessionMessages(t.currentSession));\n const meta = loadSessionMeta(t.currentSession);\n emit(\n {\n type: \"$session_loaded\",\n name: t.currentSession,\n messages: msgs,\n carryover: {\n totalCostUsd: meta.totalCostUsd ?? 0,\n cacheHitTokens: meta.cacheHitTokens ?? 0,\n cacheMissTokens: meta.cacheMissTokens ?? 0,\n totalCompletionTokens: meta.totalCompletionTokens ?? 0,\n },\n },\n t.id,\n );\n } catch {\n // unreadable jsonl — skip re-emit\n }\n }\n }\n return;\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, { discardCurrentTurn: true });\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_rename\") {\n try {\n const trimmed = normalizeSessionTitle(msg.title);\n patchSessionMeta(msg.name, { summary: trimmed || undefined });\n emitSessions(tab);\n } catch (err) {\n emit(\n { type: \"$error\", message: `session_rename failed: ${(err as Error).message}` },\n tab.id,\n );\n }\n return;\n }\n if (msg.cmd === \"session_load\") {\n try {\n const records = loadSessionMessages(msg.name);\n const backfilledWorkspace = patchSessionWorkspaceIfMissing(msg.name, tab.rootDir);\n const meta = loadSessionMeta(msg.name);\n // Only set switching flag when there's a live turn to abort —\n // otherwise the flag stays true and suppresses the first turn's events (#1217).\n if (tab.aborter) tab.switching = true;\n abortTurn(tab);\n cancelPendingGates(tab);\n tab.currentSession = msg.name;\n persistOpenTabs();\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 totalCompletionTokens: meta.totalCompletionTokens ?? 0,\n },\n },\n tab.id,\n );\n if (backfilledWorkspace) emitSessions(tab);\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 === \"memory_read\") {\n try {\n const detail = readMemoryEntryDetail({ path: msg.path }, tab.rootDir);\n emit({ type: \"$memory_detail\", detail }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `memory_read failed: ${(err as Error).message}` }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"new_chat\") {\n // Only set switching flag when there's a live turn to abort —\n // otherwise the flag stays true and suppresses the first turn's events (#1217).\n if (tab.aborter) tab.switching = true;\n abortTurn(tab);\n cancelPendingGates(tab);\n tab.currentSession = mintSessionFor(tab.rootDir);\n persistOpenTabs();\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 === \"qq_status_get\") {\n emitQQSettings(tab);\n return;\n }\n if (msg.cmd === \"settings_save\") {\n try {\n if (msg.reasoningEffort !== undefined && isReasoningEffort(msg.reasoningEffort)) {\n saveReasoningEffort(msg.reasoningEffort);\n tab.runtime?.loop.configure({ reasoningEffort: msg.reasoningEffort });\n }\n if (msg.editMode !== undefined) {\n saveEditMode(msg.editMode);\n if (tab.toolset) applyPlanMode(tab.toolset.tools, msg.editMode);\n }\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.showSystemEvents !== undefined) saveShowSystemEvents(msg.showSystemEvents);\n if (msg.webSearchEngine !== undefined) {\n const cfg = readConfig();\n cfg.webSearchEngine = msg.webSearchEngine;\n writeConfig(cfg);\n }\n if (msg.subagentModels !== undefined) {\n saveSubagentModels(msg.subagentModels);\n emitSkills(tab);\n }\n if (msg.model !== undefined) {\n const next = msg.model.trim();\n if (next) {\n tab.currentModel = next;\n saveModel(next);\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 }\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 === \"qq_config_save\") {\n try {\n saveDesktopQQSettings(\n {\n appId: msg.appId,\n appSecret: msg.appSecret,\n sandbox: msg.sandbox,\n },\n undefined,\n );\n emitQQSettings(tab);\n } catch (err) {\n emit(\n { type: \"$error\", message: `qq_config_save failed: ${(err as Error).message}` },\n tab.id,\n );\n }\n return;\n }\n if (msg.cmd === \"qq_connect\") {\n try {\n const current = loadQQConfig();\n emit(\n {\n type: \"status\",\n id: Date.now(),\n ts: new Date().toISOString(),\n turn: 0,\n text: `QQ connecting (${current.sandbox ? \"sandbox\" : \"production\"})`,\n },\n tab.id,\n );\n void startDesktopQQ(true).then(\n () => {\n emit(\n {\n type: \"status\",\n id: Date.now(),\n ts: new Date().toISOString(),\n turn: 0,\n text: `QQ connected (${current.sandbox ? \"sandbox\" : \"production\"})`,\n },\n tab.id,\n );\n emitQQSettings(tab);\n },\n (err) => {\n emit(\n { type: \"$error\", message: `qq_connect failed: ${(err as Error).message}` },\n tab.id,\n );\n emitQQSettings(tab);\n },\n );\n } catch (err) {\n emit({ type: \"$error\", message: `qq_connect failed: ${(err as Error).message}` }, tab.id);\n emitQQSettings(tab);\n }\n return;\n }\n if (msg.cmd === \"qq_disconnect\") {\n try {\n void stopDesktopQQ(true).then(\n () => {\n emit(\n {\n type: \"status\",\n id: Date.now(),\n ts: new Date().toISOString(),\n turn: 0,\n text: \"QQ disabled\",\n },\n tab.id,\n );\n emitQQSettings(tab);\n },\n (err) => {\n emit(\n { type: \"$error\", message: `qq_disconnect failed: ${(err as Error).message}` },\n tab.id,\n );\n },\n );\n } catch (err) {\n emit(\n { type: \"$error\", message: `qq_disconnect 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 === \"compact_history\") {\n if (!tab.runtime) return;\n void tab.runtime.loop\n .compactHistory()\n .then(() => emitCtxBreakdown(tab))\n .catch((err: Error) => {\n emit({ type: \"$error\", message: `/compact failed: ${err.message}` }, tab.id);\n });\n return;\n }\n if (msg.cmd === \"retry\") {\n if (!tab.runtime) return;\n const prev = tab.runtime.loop.retryLastUser();\n if (prev) {\n emit({ type: \"$retry_result\", text: prev }, tab.id);\n }\n return;\n }\n if (msg.cmd === \"btw\") {\n if (!tab.runtime) return;\n const question = msg.text.trim();\n if (!question) return;\n void (async () => {\n try {\n const reply = await tab.runtime!.loop.client.chat({\n model: tab.currentModel,\n messages: [\n {\n role: \"system\",\n content:\n \"You are answering a side question that is unrelated to the current coding conversation. Answer concisely (1-3 sentences) in plain prose. Do not call tools, do not ask clarifying questions, and do not reference any prior turns.\",\n },\n { role: \"user\", content: question },\n ],\n });\n const answer =\n (typeof reply.content === \"string\" ? reply.content.trim() : \"\") || \"(no answer)\";\n emit({ type: \"$btw_result\", question, answer }, tab.id);\n } catch (err) {\n emit({ type: \"$error\", message: `/btw failed: ${(err as Error).message}` }, tab.id);\n }\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","/** GUI launches inherit OS-level env, not the user's interactive-shell env (#1252).\n * Probe `$SHELL -ilc` once at startup so nvm/asdf/fnm/volta/mise injected PATH entries survive. */\n\nimport { spawnSync } from \"node:child_process\";\n\nlet cached: { value: string | null } | undefined;\n\n/** Returns the user's interactive-shell PATH on macOS/Linux, null on Windows or on error. Cached. */\nexport function resolveLoginShellPath(opts: { timeoutMs?: number } = {}): string | null {\n if (cached !== undefined) return cached.value;\n cached = { value: null };\n if (process.platform === \"win32\") return null;\n\n const shell = process.env.SHELL || \"/bin/bash\";\n // -i forces zsh/bash to source rc files; -l also sources profile. The literal\n // `printf '__REASONIX_PATH__=%s\\\\n'` framing protects us from rc files that\n // print banners / completion notices on every interactive shell.\n const marker = \"__REASONIX_PATH__=\";\n try {\n const result = spawnSync(shell, [\"-ilc\", `printf '${marker}%s\\\\n' \"$PATH\"`], {\n encoding: \"utf8\",\n timeout: opts.timeoutMs ?? 2000,\n stdio: [\"ignore\", \"pipe\", \"ignore\"],\n });\n if (result.status !== 0 && result.signal === null) return null;\n const stdout = result.stdout ?? \"\";\n const idx = stdout.lastIndexOf(marker);\n if (idx < 0) return null;\n const tail = stdout.slice(idx + marker.length);\n const newline = tail.indexOf(\"\\n\");\n const path = (newline >= 0 ? tail.slice(0, newline) : tail).trim();\n if (!path || !path.includes(\"/\")) return null;\n cached.value = path;\n return path;\n } catch {\n return null;\n }\n}\n\n/** Prepend missing login-shell PATH entries onto `process.env.PATH`. Idempotent. */\nexport function augmentProcessPath(): { added: string[] } {\n const loginPath = resolveLoginShellPath();\n if (!loginPath) return { added: [] };\n const current = process.env.PATH ?? \"\";\n const seen = new Set(\n current\n .split(\":\")\n .map((s) => s.trim())\n .filter(Boolean),\n );\n const additions: string[] = [];\n for (const entry of loginPath.split(\":\")) {\n const t = entry.trim();\n if (!t || seen.has(t)) continue;\n seen.add(t);\n additions.push(t);\n }\n if (additions.length === 0) return { added: [] };\n process.env.PATH = additions.concat(current ? [current] : []).join(\":\");\n return { added: additions };\n}\n\n/** Test-only — clear the resolved-PATH cache so a fresh `resolveLoginShellPath()` re-probes. */\nexport function resetLoginShellPathCache(): void {\n cached = undefined;\n}\n","import { type LoadedQQConfig, type QQBotConfig, loadQQConfig, saveQQConfig } from \"../config.js\";\nimport { describeQQAccess } from \"../qq/access.js\";\n\nexport interface DesktopQQSettingsState extends Omit<LoadedQQConfig, \"sandbox\" | \"enabled\"> {\n sandbox: boolean;\n enabled: boolean;\n configured: boolean;\n runtimeState: \"disconnected\" | \"connecting\" | \"connected\" | \"failed\";\n lastError?: string;\n appIdPreview?: string;\n access: string;\n}\n\nexport interface DesktopQQSettingsPatch {\n appId?: string;\n appSecret?: string;\n sandbox: boolean;\n}\n\nfunction trimOptional(value: string | undefined): string | undefined {\n const trimmed = value?.trim();\n return trimmed ? trimmed : undefined;\n}\n\nfunction toPreview(appId: string | undefined): string | undefined {\n if (!appId) return undefined;\n return appId.length > 6 ? `${appId.slice(0, 6)}...` : appId;\n}\n\nfunction toAccess(config: QQBotConfig | LoadedQQConfig): string {\n return describeQQAccess({\n ownerOpenId: config.ownerOpenId,\n allowlist: config.allowlist,\n });\n}\n\nexport function loadDesktopQQState(path?: string): DesktopQQSettingsState {\n const config = loadQQConfig(path);\n const configured = Boolean(config.appId && config.appSecret);\n return {\n ...config,\n sandbox: config.sandbox ?? false,\n enabled: config.enabled === true,\n configured,\n runtimeState: \"disconnected\",\n appIdPreview: toPreview(config.appId),\n access: toAccess(config),\n };\n}\n\nexport function saveDesktopQQSettings(\n patch: DesktopQQSettingsPatch,\n path?: string,\n): DesktopQQSettingsState {\n const existing = loadQQConfig(path);\n saveQQConfig(\n {\n ...existing,\n appId: trimOptional(patch.appId),\n appSecret: trimOptional(patch.appSecret),\n sandbox: patch.sandbox,\n },\n path,\n );\n return loadDesktopQQState(path);\n}\n\nexport function setDesktopQQEnabled(enabled: boolean, path?: string): DesktopQQSettingsState {\n const existing = loadQQConfig(path);\n if (enabled && !(existing.appId && existing.appSecret)) {\n throw new Error(\"QQ App ID and App Secret are required.\");\n }\n saveQQConfig({ ...existing, enabled }, path);\n return loadDesktopQQState(path);\n}\n","export type QQPendingInteraction = {\n gateId: number;\n kind: string;\n payload: unknown;\n};\n\nexport type QQTurnRoutingState = {\n replyTabs: Set<string>;\n pendingByTab: Map<string, QQPendingInteraction>;\n};\n\nexport function createQQTurnRoutingState(): QQTurnRoutingState {\n return {\n replyTabs: new Set<string>(),\n pendingByTab: new Map<string, QQPendingInteraction>(),\n };\n}\n\nexport function markQQTurnStarted(state: QQTurnRoutingState, tabId: string): void {\n state.replyTabs.add(tabId);\n}\n\nexport function markQQTurnFinished(state: QQTurnRoutingState, tabId: string): void {\n state.replyTabs.delete(tabId);\n state.pendingByTab.delete(tabId);\n}\n\nexport function shouldRouteQQForTab(state: QQTurnRoutingState, tabId: string): boolean {\n return state.replyTabs.has(tabId);\n}\n\nexport function setQQPendingInteraction(\n state: QQTurnRoutingState,\n tabId: string,\n gateId: number,\n kind: string,\n payload: unknown,\n): void {\n if (!shouldRouteQQForTab(state, tabId)) return;\n state.pendingByTab.set(tabId, { gateId, kind, payload });\n}\n\nexport function takeQQPendingInteraction(\n state: QQTurnRoutingState,\n tabId: string,\n): QQPendingInteraction | null {\n const hit = state.pendingByTab.get(tabId);\n if (!hit) return null;\n state.pendingByTab.delete(tabId);\n return hit;\n}\n\nexport function clearQQTurnRouting(state: QQTurnRoutingState): void {\n state.replyTabs.clear();\n state.pendingByTab.clear();\n}\n"],"mappings":"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","names":["opts","tab","trimmed","resolve"]}
@@ -2,17 +2,18 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  RecordView
5
- } from "./chunk-ZAXMJANP.js";
5
+ } from "./chunk-EAMXOWUW.js";
6
6
  import {
7
7
  diffTranscripts,
8
8
  findNextDivergence,
9
9
  findPrevDivergence,
10
10
  renderMarkdown,
11
11
  renderSummaryTable
12
- } from "./chunk-I4Q3QT4W.js";
12
+ } from "./chunk-36BM7INR.js";
13
13
  import {
14
14
  readTranscript
15
- } from "./chunk-NLRC3DWQ.js";
15
+ } from "./chunk-544J4PXD.js";
16
+ import "./chunk-BA5R6BAE.js";
16
17
  import {
17
18
  Box_default,
18
19
  Static,
@@ -21,14 +22,13 @@ import {
21
22
  require_react,
22
23
  use_app_default,
23
24
  use_input_default
24
- } from "./chunk-7X4JJOO7.js";
25
- import "./chunk-EZ57UEZQ.js";
25
+ } from "./chunk-UO6E7FN3.js";
26
+ import "./chunk-C2MRSJTV.js";
26
27
  import "./chunk-25T6CVUP.js";
27
- import "./chunk-FQSQFCBI.js";
28
28
  import {
29
29
  t
30
- } from "./chunk-PYIZZAVQ.js";
31
- import "./chunk-MXWPAPZW.js";
30
+ } from "./chunk-DVD67FXQ.js";
31
+ import "./chunk-A5PBEIJ7.js";
32
32
  import {
33
33
  __toESM
34
34
  } from "./chunk-TUK7OWJA.js";
@@ -162,4 +162,4 @@ markdown report written to ${opts.mdPath}`);
162
162
  export {
163
163
  diffCommand
164
164
  };
165
- //# sourceMappingURL=diff-JNYX5BSZ.js.map
165
+ //# sourceMappingURL=diff-I4PYI43W.js.map
@@ -4,24 +4,24 @@ import {
4
4
  doctorCommand,
5
5
  formatDoctorJson,
6
6
  runDoctorChecks
7
- } from "./chunk-OWA42BKS.js";
8
- import "./chunk-TX652NBA.js";
9
- import "./chunk-AAHB2PFX.js";
7
+ } from "./chunk-SXSAWOB7.js";
8
+ import "./chunk-EWVFGYT6.js";
9
+ import "./chunk-7YB26OQO.js";
10
10
  import "./chunk-Q46B3Z7H.js";
11
- import "./chunk-CAGKEGNE.js";
12
- import "./chunk-AJIZ5KFK.js";
13
- import "./chunk-S4XVGLRW.js";
14
- import "./chunk-IK6WWRIX.js";
15
- import "./chunk-EZ57UEZQ.js";
11
+ import "./chunk-BOWSNGQC.js";
12
+ import "./chunk-C2MRSJTV.js";
16
13
  import "./chunk-25T6CVUP.js";
17
- import "./chunk-2UQP6H6T.js";
18
- import "./chunk-PYIZZAVQ.js";
19
- import "./chunk-MXWPAPZW.js";
14
+ import "./chunk-2WUEAI2I.js";
15
+ import "./chunk-6UNHNVJR.js";
16
+ import "./chunk-6XWXIVQ3.js";
20
17
  import "./chunk-XXC2BYTV.js";
18
+ import "./chunk-2UQP6H6T.js";
19
+ import "./chunk-DVD67FXQ.js";
20
+ import "./chunk-A5PBEIJ7.js";
21
21
  import "./chunk-TUK7OWJA.js";
22
22
  export {
23
23
  doctorCommand,
24
24
  formatDoctorJson,
25
25
  runDoctorChecks
26
26
  };
27
- //# sourceMappingURL=doctor-IKYLUFXX.js.map
27
+ //# sourceMappingURL=doctor-Y2E4MY2F.js.map
@@ -5,12 +5,12 @@ import {
5
5
  } from "./chunk-J5XJHLWM.js";
6
6
  import {
7
7
  eventLogPath
8
- } from "./chunk-XJZWMU5P.js";
9
- import "./chunk-IK6WWRIX.js";
8
+ } from "./chunk-WPOKBW5E.js";
9
+ import "./chunk-6XWXIVQ3.js";
10
10
  import {
11
11
  t
12
- } from "./chunk-PYIZZAVQ.js";
13
- import "./chunk-MXWPAPZW.js";
12
+ } from "./chunk-DVD67FXQ.js";
13
+ import "./chunk-A5PBEIJ7.js";
14
14
  import "./chunk-TUK7OWJA.js";
15
15
 
16
16
  // src/core/reducers.ts
@@ -341,4 +341,4 @@ function mapReplacer(_key, value) {
341
341
  export {
342
342
  eventsCommand
343
343
  };
344
- //# sourceMappingURL=events-HSC57ONU.js.map
344
+ //# sourceMappingURL=events-47HOT7ZA.js.map
@@ -0,0 +1,145 @@
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
+ getParser
5
+ } from "./chunk-FP7IOWBQ.js";
6
+ import {
7
+ grammarForPath
8
+ } from "./chunk-L3VPEESB.js";
9
+ import "./chunk-TUK7OWJA.js";
10
+
11
+ // src/code-query/find-in-code.ts
12
+ var IDENTIFIER_TYPES = /* @__PURE__ */ new Set([
13
+ "identifier",
14
+ "property_identifier",
15
+ "type_identifier",
16
+ "shorthand_property_identifier",
17
+ "shorthand_property_identifier_pattern",
18
+ "field_identifier",
19
+ "package_identifier"
20
+ ]);
21
+ var DECLARATION_NAME_PARENTS = /* @__PURE__ */ new Set([
22
+ "function_declaration",
23
+ "function_signature",
24
+ "class_declaration",
25
+ "interface_declaration",
26
+ "type_alias_declaration",
27
+ "enum_declaration",
28
+ "method_definition",
29
+ "method_signature",
30
+ "abstract_method_signature",
31
+ "public_field_definition",
32
+ "field_definition",
33
+ "property_signature",
34
+ "internal_module",
35
+ "variable_declarator",
36
+ "function_definition",
37
+ "class_definition",
38
+ "method_declaration",
39
+ "type_spec",
40
+ "function_item",
41
+ "struct_item",
42
+ "enum_item",
43
+ "trait_item",
44
+ "type_item",
45
+ "mod_item",
46
+ "const_item",
47
+ "static_item",
48
+ "constructor_declaration"
49
+ ]);
50
+ var CALL_PARENT_TYPES = /* @__PURE__ */ new Set([
51
+ "call_expression",
52
+ "new_expression",
53
+ "call",
54
+ "method_invocation",
55
+ "object_creation_expression"
56
+ ]);
57
+ var MEMBER_PARENT_TYPES = /* @__PURE__ */ new Set([
58
+ "member_expression",
59
+ "attribute",
60
+ "selector_expression",
61
+ "field_expression"
62
+ ]);
63
+ var CALLEE_FIELDS = ["function", "constructor", "name"];
64
+ var MEMBER_NAME_FIELDS = ["property", "field", "attribute", "name"];
65
+ async function findInCode(filePath, source, name, opts = {}) {
66
+ if (!name) return [];
67
+ const grammar = grammarForPath(filePath);
68
+ if (!grammar) return [];
69
+ const parser = await getParser(grammar);
70
+ try {
71
+ const tree = parser.parse(source);
72
+ if (!tree) return [];
73
+ try {
74
+ const sourceLines = source.split(/\r?\n/);
75
+ const matches = [];
76
+ walk(tree.rootNode, (node) => {
77
+ if (!IDENTIFIER_TYPES.has(node.type)) return;
78
+ if (node.text !== name) return;
79
+ const kind = classify(node);
80
+ const filter = opts.kind ?? "any";
81
+ if (filter !== "any" && filter !== kind) return;
82
+ const line = node.startPosition.row + 1;
83
+ const column = node.startPosition.column + 1;
84
+ matches.push({
85
+ line,
86
+ column,
87
+ kind,
88
+ snippet: sourceLines[node.startPosition.row] ?? ""
89
+ });
90
+ });
91
+ return matches;
92
+ } finally {
93
+ tree.delete();
94
+ }
95
+ } finally {
96
+ parser.delete();
97
+ }
98
+ }
99
+ function classify(node) {
100
+ const parent = node.parent;
101
+ if (!parent) return "reference";
102
+ if (DECLARATION_NAME_PARENTS.has(parent.type)) {
103
+ const nameField = parent.childForFieldName("name");
104
+ if (nameField && nameField.id === node.id) return "definition";
105
+ }
106
+ if (CALL_PARENT_TYPES.has(parent.type) && fieldMatches(parent, node, CALLEE_FIELDS)) {
107
+ return "call";
108
+ }
109
+ if (MEMBER_PARENT_TYPES.has(parent.type) && fieldMatches(parent, node, MEMBER_NAME_FIELDS)) {
110
+ const grandparent = parent.parent;
111
+ if (grandparent && CALL_PARENT_TYPES.has(grandparent.type) && fieldMatches(grandparent, parent, CALLEE_FIELDS)) {
112
+ return "call";
113
+ }
114
+ }
115
+ return "reference";
116
+ }
117
+ function fieldMatches(parent, child, fields) {
118
+ for (const field of fields) {
119
+ const f = parent.childForFieldName(field);
120
+ if (f && f.id === child.id) return true;
121
+ }
122
+ return false;
123
+ }
124
+ function walk(root, visit) {
125
+ const cursor = root.walk();
126
+ try {
127
+ let visitedChildren = false;
128
+ while (true) {
129
+ if (!visitedChildren) visit(cursor.currentNode);
130
+ if (!visitedChildren && cursor.gotoFirstChild()) continue;
131
+ if (cursor.gotoNextSibling()) {
132
+ visitedChildren = false;
133
+ continue;
134
+ }
135
+ if (!cursor.gotoParent()) return;
136
+ visitedChildren = true;
137
+ }
138
+ } finally {
139
+ cursor.delete();
140
+ }
141
+ }
142
+ export {
143
+ findInCode
144
+ };
145
+ //# sourceMappingURL=find-in-code-YLEIK5FK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/code-query/find-in-code.ts"],"sourcesContent":["import type { Node } from \"web-tree-sitter\";\nimport { getParser, grammarForPath } from \"./parser.js\";\n\nexport type CodeMatchKind = \"call\" | \"definition\" | \"reference\";\n\nexport interface CodeMatch {\n line: number;\n column: number;\n kind: CodeMatchKind;\n snippet: string;\n}\n\nexport interface FindInCodeOptions {\n kind?: CodeMatchKind | \"any\";\n}\n\nconst IDENTIFIER_TYPES = new Set([\n \"identifier\",\n \"property_identifier\",\n \"type_identifier\",\n \"shorthand_property_identifier\",\n \"shorthand_property_identifier_pattern\",\n \"field_identifier\",\n \"package_identifier\",\n]);\n\nconst DECLARATION_NAME_PARENTS = new Set([\n \"function_declaration\",\n \"function_signature\",\n \"class_declaration\",\n \"interface_declaration\",\n \"type_alias_declaration\",\n \"enum_declaration\",\n \"method_definition\",\n \"method_signature\",\n \"abstract_method_signature\",\n \"public_field_definition\",\n \"field_definition\",\n \"property_signature\",\n \"internal_module\",\n \"variable_declarator\",\n \"function_definition\",\n \"class_definition\",\n \"method_declaration\",\n \"type_spec\",\n \"function_item\",\n \"struct_item\",\n \"enum_item\",\n \"trait_item\",\n \"type_item\",\n \"mod_item\",\n \"const_item\",\n \"static_item\",\n \"constructor_declaration\",\n]);\n\nconst CALL_PARENT_TYPES = new Set([\n \"call_expression\",\n \"new_expression\",\n \"call\",\n \"method_invocation\",\n \"object_creation_expression\",\n]);\n\nconst MEMBER_PARENT_TYPES = new Set([\n \"member_expression\",\n \"attribute\",\n \"selector_expression\",\n \"field_expression\",\n]);\n\nconst CALLEE_FIELDS = [\"function\", \"constructor\", \"name\"] as const;\nconst MEMBER_NAME_FIELDS = [\"property\", \"field\", \"attribute\", \"name\"] as const;\n\nexport async function findInCode(\n filePath: string,\n source: string,\n name: string,\n opts: FindInCodeOptions = {},\n): Promise<CodeMatch[]> {\n if (!name) return [];\n const grammar = grammarForPath(filePath);\n if (!grammar) return [];\n const parser = await getParser(grammar);\n try {\n const tree = parser.parse(source);\n if (!tree) return [];\n try {\n const sourceLines = source.split(/\\r?\\n/);\n const matches: CodeMatch[] = [];\n walk(tree.rootNode, (node) => {\n if (!IDENTIFIER_TYPES.has(node.type)) return;\n if (node.text !== name) return;\n const kind = classify(node);\n const filter = opts.kind ?? \"any\";\n if (filter !== \"any\" && filter !== kind) return;\n const line = node.startPosition.row + 1;\n const column = node.startPosition.column + 1;\n matches.push({\n line,\n column,\n kind,\n snippet: sourceLines[node.startPosition.row] ?? \"\",\n });\n });\n return matches;\n } finally {\n tree.delete();\n }\n } finally {\n parser.delete();\n }\n}\n\nfunction classify(node: Node): CodeMatchKind {\n const parent = node.parent;\n if (!parent) return \"reference\";\n if (DECLARATION_NAME_PARENTS.has(parent.type)) {\n const nameField = parent.childForFieldName(\"name\");\n if (nameField && nameField.id === node.id) return \"definition\";\n }\n if (CALL_PARENT_TYPES.has(parent.type) && fieldMatches(parent, node, CALLEE_FIELDS)) {\n return \"call\";\n }\n if (MEMBER_PARENT_TYPES.has(parent.type) && fieldMatches(parent, node, MEMBER_NAME_FIELDS)) {\n const grandparent = parent.parent;\n if (\n grandparent &&\n CALL_PARENT_TYPES.has(grandparent.type) &&\n fieldMatches(grandparent, parent, CALLEE_FIELDS)\n ) {\n return \"call\";\n }\n }\n return \"reference\";\n}\n\nfunction fieldMatches(parent: Node, child: Node, fields: readonly string[]): boolean {\n for (const field of fields) {\n const f = parent.childForFieldName(field);\n if (f && f.id === child.id) return true;\n }\n return false;\n}\n\nfunction walk(root: Node, visit: (node: Node) => void): void {\n const cursor = root.walk();\n try {\n let visitedChildren = false;\n while (true) {\n if (!visitedChildren) visit(cursor.currentNode);\n if (!visitedChildren && cursor.gotoFirstChild()) continue;\n if (cursor.gotoNextSibling()) {\n visitedChildren = false;\n continue;\n }\n if (!cursor.gotoParent()) return;\n visitedChildren = true;\n }\n } finally {\n cursor.delete();\n }\n}\n"],"mappings":"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","names":[]}