pi-agent-zh 17.1.8

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 (1519) hide show
  1. package/CHANGELOG.md +14459 -0
  2. package/README.md +35 -0
  3. package/dist/CHANGELOG-vt8ene9g.md +14459 -0
  4. package/dist/cli.js +22079 -0
  5. package/dist/template-dys3vk5b.js +1671 -0
  6. package/dist/template-f8wx9vfn.css +1355 -0
  7. package/dist/template-qat058wr.html +55 -0
  8. package/dist/tool-views.generated-jdfmzwmn.js +35 -0
  9. package/examples/README.md +21 -0
  10. package/examples/custom-tools/README.md +104 -0
  11. package/examples/custom-tools/hello/index.ts +20 -0
  12. package/examples/extensions/README.md +142 -0
  13. package/examples/extensions/api-demo.ts +79 -0
  14. package/examples/extensions/chalk-logger.ts +25 -0
  15. package/examples/extensions/hello.ts +31 -0
  16. package/examples/extensions/pirate.ts +43 -0
  17. package/examples/extensions/plan-mode.ts +549 -0
  18. package/examples/extensions/reload-runtime.ts +38 -0
  19. package/examples/extensions/thinking-note.ts +13 -0
  20. package/examples/extensions/tools.ts +145 -0
  21. package/examples/extensions/with-deps/index.ts +36 -0
  22. package/examples/extensions/with-deps/package-lock.json +31 -0
  23. package/examples/extensions/with-deps/package.json +17 -0
  24. package/examples/hooks/README.md +56 -0
  25. package/examples/hooks/auto-commit-on-exit.ts +48 -0
  26. package/examples/hooks/confirm-destructive.ts +58 -0
  27. package/examples/hooks/custom-compaction.ts +115 -0
  28. package/examples/hooks/dirty-repo-guard.ts +51 -0
  29. package/examples/hooks/file-trigger.ts +40 -0
  30. package/examples/hooks/git-checkpoint.ts +52 -0
  31. package/examples/hooks/handoff.ts +149 -0
  32. package/examples/hooks/permission-gate.ts +33 -0
  33. package/examples/hooks/protected-paths.ts +29 -0
  34. package/examples/hooks/qna.ts +118 -0
  35. package/examples/hooks/status-line.ts +39 -0
  36. package/examples/sdk/01-minimal.ts +21 -0
  37. package/examples/sdk/02-custom-model.ts +49 -0
  38. package/examples/sdk/03-custom-prompt.ts +46 -0
  39. package/examples/sdk/04-skills.ts +43 -0
  40. package/examples/sdk/06-extensions.ts +82 -0
  41. package/examples/sdk/06-hooks.ts +61 -0
  42. package/examples/sdk/07-context-files.ts +35 -0
  43. package/examples/sdk/08-prompt-templates.ts +41 -0
  44. package/examples/sdk/08-slash-commands.ts +46 -0
  45. package/examples/sdk/09-api-keys-and-oauth.ts +54 -0
  46. package/examples/sdk/11-sessions.ts +47 -0
  47. package/examples/sdk/12-redis-sessions.ts +54 -0
  48. package/examples/sdk/13-sql-sessions.ts +61 -0
  49. package/examples/sdk/README.md +169 -0
  50. package/package.json +606 -0
  51. package/scripts/bench-guard.ts +71 -0
  52. package/scripts/bench-title-models.ts +332 -0
  53. package/scripts/build-binary.ts +117 -0
  54. package/scripts/bundle-dist.ts +133 -0
  55. package/scripts/compile-binary.ts +69 -0
  56. package/scripts/embed-mupdf-wasm.ts +67 -0
  57. package/scripts/format-prompts.ts +68 -0
  58. package/scripts/generate-aria-snapshot.ts +134 -0
  59. package/scripts/generate-docs-index.ts +58 -0
  60. package/scripts/generate-share-viewer.ts +34 -0
  61. package/scripts/legacy-pi-virtual-module.ts +195 -0
  62. package/scripts/measure-prompt-tokens.ts +63 -0
  63. package/scripts/omp +42 -0
  64. package/scripts/omp.ts +19 -0
  65. package/src/advisor/advise-tool.ts +216 -0
  66. package/src/advisor/config.ts +341 -0
  67. package/src/advisor/emission-guard.ts +172 -0
  68. package/src/advisor/index.ts +6 -0
  69. package/src/advisor/runtime.ts +1232 -0
  70. package/src/advisor/transcript-recorder.ts +159 -0
  71. package/src/advisor/watchdog.ts +135 -0
  72. package/src/async/index.ts +1 -0
  73. package/src/async/job-manager.ts +821 -0
  74. package/src/auto-thinking/classifier.ts +182 -0
  75. package/src/autolearn/controller.ts +152 -0
  76. package/src/autolearn/managed-skills.ts +255 -0
  77. package/src/autoresearch/command-resume.md +14 -0
  78. package/src/autoresearch/dashboard.ts +436 -0
  79. package/src/autoresearch/git.ts +331 -0
  80. package/src/autoresearch/helpers.ts +218 -0
  81. package/src/autoresearch/index.ts +541 -0
  82. package/src/autoresearch/prompt-setup.md +43 -0
  83. package/src/autoresearch/prompt.md +103 -0
  84. package/src/autoresearch/resume-message.md +10 -0
  85. package/src/autoresearch/state.ts +273 -0
  86. package/src/autoresearch/storage.ts +700 -0
  87. package/src/autoresearch/tools/init-experiment.ts +269 -0
  88. package/src/autoresearch/tools/log-experiment.ts +521 -0
  89. package/src/autoresearch/tools/run-experiment.ts +407 -0
  90. package/src/autoresearch/tools/update-notes.ts +109 -0
  91. package/src/autoresearch/types.ts +168 -0
  92. package/src/capability/context-file.ts +44 -0
  93. package/src/capability/extension-module.ts +34 -0
  94. package/src/capability/extension.ts +47 -0
  95. package/src/capability/fs.ts +117 -0
  96. package/src/capability/hook.ts +40 -0
  97. package/src/capability/index.ts +467 -0
  98. package/src/capability/instruction.ts +37 -0
  99. package/src/capability/mcp.ts +97 -0
  100. package/src/capability/prompt.ts +35 -0
  101. package/src/capability/rule-buckets.ts +66 -0
  102. package/src/capability/rule.ts +298 -0
  103. package/src/capability/settings.ts +34 -0
  104. package/src/capability/skill.ts +63 -0
  105. package/src/capability/slash-command.ts +40 -0
  106. package/src/capability/ssh.ts +41 -0
  107. package/src/capability/system-prompt.ts +34 -0
  108. package/src/capability/tool.ts +38 -0
  109. package/src/capability/types.ts +187 -0
  110. package/src/cleanse/agent.ts +226 -0
  111. package/src/cleanse/balance.ts +79 -0
  112. package/src/cleanse/checkers.ts +996 -0
  113. package/src/cleanse/index.ts +190 -0
  114. package/src/cleanse/loop.ts +51 -0
  115. package/src/cleanse/parsers.ts +726 -0
  116. package/src/cleanse/progress.ts +50 -0
  117. package/src/cleanse/prompts/assignment.md +47 -0
  118. package/src/cleanse/types.ts +72 -0
  119. package/src/cli/agents-cli.ts +138 -0
  120. package/src/cli/args.ts +420 -0
  121. package/src/cli/auth-broker-cli.ts +940 -0
  122. package/src/cli/auth-gateway-cli.ts +674 -0
  123. package/src/cli/bench-cli.ts +990 -0
  124. package/src/cli/classify-install-target.ts +76 -0
  125. package/src/cli/claude-trace-cli.ts +795 -0
  126. package/src/cli/commands/init-xdg.ts +27 -0
  127. package/src/cli/completion-gen.ts +550 -0
  128. package/src/cli/config-cli.ts +459 -0
  129. package/src/cli/dry-balance-cli.ts +864 -0
  130. package/src/cli/extension-flags.ts +48 -0
  131. package/src/cli/file-processor.ts +132 -0
  132. package/src/cli/flag-tables.ts +352 -0
  133. package/src/cli/gallery-cli.ts +272 -0
  134. package/src/cli/gallery-fixtures/agentic.ts +420 -0
  135. package/src/cli/gallery-fixtures/codeintel.ts +187 -0
  136. package/src/cli/gallery-fixtures/edit.ts +254 -0
  137. package/src/cli/gallery-fixtures/fs.ts +220 -0
  138. package/src/cli/gallery-fixtures/index.ts +40 -0
  139. package/src/cli/gallery-fixtures/interaction.ts +46 -0
  140. package/src/cli/gallery-fixtures/memory.ts +81 -0
  141. package/src/cli/gallery-fixtures/misc.ts +177 -0
  142. package/src/cli/gallery-fixtures/search.ts +135 -0
  143. package/src/cli/gallery-fixtures/shell.ts +241 -0
  144. package/src/cli/gallery-fixtures/types.ts +57 -0
  145. package/src/cli/gallery-fixtures/web.ts +158 -0
  146. package/src/cli/gallery-screenshot.ts +279 -0
  147. package/src/cli/gc-cli.ts +946 -0
  148. package/src/cli/grep-cli.ts +161 -0
  149. package/src/cli/grievances-cli.ts +256 -0
  150. package/src/cli/initial-message.ts +58 -0
  151. package/src/cli/models-cli.ts +388 -0
  152. package/src/cli/plugin-cli.ts +996 -0
  153. package/src/cli/profile-alias.ts +369 -0
  154. package/src/cli/profile-bootstrap.ts +233 -0
  155. package/src/cli/read-cli.ts +99 -0
  156. package/src/cli/session-picker.ts +93 -0
  157. package/src/cli/setup-cli.ts +320 -0
  158. package/src/cli/setup-model-picker.ts +43 -0
  159. package/src/cli/shell-cli.ts +176 -0
  160. package/src/cli/ssh-cli.ts +179 -0
  161. package/src/cli/startup-cwd.ts +58 -0
  162. package/src/cli/stats-cli.ts +229 -0
  163. package/src/cli/tiny-models-cli.ts +153 -0
  164. package/src/cli/ttsr-cli.ts +995 -0
  165. package/src/cli/update-cli.ts +1219 -0
  166. package/src/cli/usage-cli.ts +1084 -0
  167. package/src/cli/usage-error.ts +7 -0
  168. package/src/cli/web-search-cli.ts +144 -0
  169. package/src/cli/worktree-cli.ts +311 -0
  170. package/src/cli-commands.ts +166 -0
  171. package/src/cli.ts +407 -0
  172. package/src/collab/crypto.ts +63 -0
  173. package/src/collab/display-name.ts +13 -0
  174. package/src/collab/guest.ts +731 -0
  175. package/src/collab/host.ts +691 -0
  176. package/src/collab/protocol.ts +296 -0
  177. package/src/collab/relay-client.ts +282 -0
  178. package/src/collab/replication-shrink.ts +111 -0
  179. package/src/commands/acp.ts +33 -0
  180. package/src/commands/agents.ts +57 -0
  181. package/src/commands/auth-broker.ts +99 -0
  182. package/src/commands/auth-gateway.ts +69 -0
  183. package/src/commands/bench.ts +65 -0
  184. package/src/commands/cleanse.ts +45 -0
  185. package/src/commands/commit.ts +46 -0
  186. package/src/commands/complete.ts +66 -0
  187. package/src/commands/completions.ts +60 -0
  188. package/src/commands/config.ts +51 -0
  189. package/src/commands/dry-balance.ts +43 -0
  190. package/src/commands/gallery.ts +60 -0
  191. package/src/commands/gc.ts +46 -0
  192. package/src/commands/grep.ts +48 -0
  193. package/src/commands/grievances.ts +51 -0
  194. package/src/commands/install.ts +107 -0
  195. package/src/commands/join.ts +39 -0
  196. package/src/commands/launch.ts +212 -0
  197. package/src/commands/models.ts +60 -0
  198. package/src/commands/plugin.ts +78 -0
  199. package/src/commands/read.ts +38 -0
  200. package/src/commands/say.ts +145 -0
  201. package/src/commands/setup.ts +67 -0
  202. package/src/commands/shell.ts +29 -0
  203. package/src/commands/ssh.ts +60 -0
  204. package/src/commands/stats.ts +29 -0
  205. package/src/commands/tiny-models.ts +36 -0
  206. package/src/commands/token.ts +164 -0
  207. package/src/commands/ttsr.ts +125 -0
  208. package/src/commands/update.ts +33 -0
  209. package/src/commands/usage.ts +54 -0
  210. package/src/commands/web-search.ts +42 -0
  211. package/src/commands/worktree.ts +62 -0
  212. package/src/commit/agentic/agent.ts +322 -0
  213. package/src/commit/agentic/fallback.ts +96 -0
  214. package/src/commit/agentic/index.ts +382 -0
  215. package/src/commit/agentic/lock-files.ts +107 -0
  216. package/src/commit/agentic/prompts/analyze-file.md +22 -0
  217. package/src/commit/agentic/prompts/session-user.md +25 -0
  218. package/src/commit/agentic/prompts/split-confirm.md +1 -0
  219. package/src/commit/agentic/prompts/system.md +38 -0
  220. package/src/commit/agentic/state.ts +60 -0
  221. package/src/commit/agentic/tools/analyze-file.ts +148 -0
  222. package/src/commit/agentic/tools/git-file-diff.ts +191 -0
  223. package/src/commit/agentic/tools/git-hunk.ts +52 -0
  224. package/src/commit/agentic/tools/git-overview.ts +62 -0
  225. package/src/commit/agentic/tools/index.ts +54 -0
  226. package/src/commit/agentic/tools/propose-changelog.ts +147 -0
  227. package/src/commit/agentic/tools/propose-commit.ts +109 -0
  228. package/src/commit/agentic/tools/recent-commits.ts +81 -0
  229. package/src/commit/agentic/tools/schemas.ts +11 -0
  230. package/src/commit/agentic/tools/split-commit.ts +241 -0
  231. package/src/commit/agentic/topo-sort.ts +44 -0
  232. package/src/commit/agentic/trivial.ts +51 -0
  233. package/src/commit/agentic/validation.ts +183 -0
  234. package/src/commit/analysis/conventional.ts +64 -0
  235. package/src/commit/analysis/index.ts +4 -0
  236. package/src/commit/analysis/scope.ts +242 -0
  237. package/src/commit/analysis/summary.ts +107 -0
  238. package/src/commit/analysis/validation.ts +66 -0
  239. package/src/commit/changelog/detect.ts +40 -0
  240. package/src/commit/changelog/generate.ts +101 -0
  241. package/src/commit/changelog/index.ts +234 -0
  242. package/src/commit/changelog/parse.ts +44 -0
  243. package/src/commit/cli.ts +85 -0
  244. package/src/commit/git/diff.ts +148 -0
  245. package/src/commit/index.ts +5 -0
  246. package/src/commit/map-reduce/index.ts +69 -0
  247. package/src/commit/map-reduce/map-phase.ts +193 -0
  248. package/src/commit/map-reduce/reduce-phase.ts +49 -0
  249. package/src/commit/map-reduce/utils.ts +9 -0
  250. package/src/commit/message.ts +11 -0
  251. package/src/commit/model-selection.ts +95 -0
  252. package/src/commit/pipeline.ts +243 -0
  253. package/src/commit/prompts/analysis-system.md +148 -0
  254. package/src/commit/prompts/analysis-user.md +38 -0
  255. package/src/commit/prompts/changelog-system.md +50 -0
  256. package/src/commit/prompts/changelog-user.md +18 -0
  257. package/src/commit/prompts/file-observer-system.md +24 -0
  258. package/src/commit/prompts/file-observer-user.md +8 -0
  259. package/src/commit/prompts/reduce-system.md +50 -0
  260. package/src/commit/prompts/reduce-user.md +17 -0
  261. package/src/commit/prompts/summary-retry.md +3 -0
  262. package/src/commit/prompts/summary-system.md +38 -0
  263. package/src/commit/prompts/summary-user.md +13 -0
  264. package/src/commit/prompts/types-description.md +2 -0
  265. package/src/commit/shared-llm.ts +70 -0
  266. package/src/commit/types.ts +118 -0
  267. package/src/commit/utils/exclusions.ts +42 -0
  268. package/src/commit/utils.ts +58 -0
  269. package/src/config/api-key-resolver.ts +81 -0
  270. package/src/config/append-only-context-mode.ts +76 -0
  271. package/src/config/config-file.ts +347 -0
  272. package/src/config/file-lock.ts +164 -0
  273. package/src/config/inline-tool-descriptors-mode.ts +26 -0
  274. package/src/config/keybindings.ts +688 -0
  275. package/src/config/mcp-schema.json +247 -0
  276. package/src/config/model-discovery.ts +999 -0
  277. package/src/config/model-registry.ts +2725 -0
  278. package/src/config/model-resolver.ts +2068 -0
  279. package/src/config/model-roles.ts +113 -0
  280. package/src/config/models-config-schema-bundle.ts +313 -0
  281. package/src/config/models-config-schema.ts +14 -0
  282. package/src/config/models-config.ts +130 -0
  283. package/src/config/prompt-templates.ts +205 -0
  284. package/src/config/provider-globals.ts +25 -0
  285. package/src/config/resolve-config-value.ts +94 -0
  286. package/src/config/service-tier.ts +141 -0
  287. package/src/config/settings-schema.ts +5751 -0
  288. package/src/config/settings.ts +2369 -0
  289. package/src/config.ts +242 -0
  290. package/src/cursor.ts +513 -0
  291. package/src/dap/client.ts +1043 -0
  292. package/src/dap/config.ts +480 -0
  293. package/src/dap/defaults.json +212 -0
  294. package/src/dap/index.ts +4 -0
  295. package/src/dap/session.ts +1841 -0
  296. package/src/dap/types.ts +611 -0
  297. package/src/debug/index.ts +584 -0
  298. package/src/debug/log-formatting.ts +58 -0
  299. package/src/debug/log-viewer.ts +966 -0
  300. package/src/debug/profiler.ts +168 -0
  301. package/src/debug/protocol-probe.ts +267 -0
  302. package/src/debug/raw-sse-buffer.ts +421 -0
  303. package/src/debug/raw-sse.ts +312 -0
  304. package/src/debug/remote-debugger.ts +151 -0
  305. package/src/debug/report-bundle.ts +411 -0
  306. package/src/debug/system-info.ts +111 -0
  307. package/src/debug/terminal-info.ts +124 -0
  308. package/src/discovery/agents-md.ts +67 -0
  309. package/src/discovery/agents.ts +230 -0
  310. package/src/discovery/at-imports.ts +273 -0
  311. package/src/discovery/builtin-defaults.ts +39 -0
  312. package/src/discovery/builtin-rules/go-add-cleanup.md +33 -0
  313. package/src/discovery/builtin-rules/go-bench-loop.md +36 -0
  314. package/src/discovery/builtin-rules/go-exp-promoted.md +40 -0
  315. package/src/discovery/builtin-rules/go-ioutil.md +37 -0
  316. package/src/discovery/builtin-rules/go-join-hostport.md +30 -0
  317. package/src/discovery/builtin-rules/go-new-expr.md +44 -0
  318. package/src/discovery/builtin-rules/go-rand-v2.md +41 -0
  319. package/src/discovery/builtin-rules/go-range-int.md +45 -0
  320. package/src/discovery/builtin-rules/index.ts +74 -0
  321. package/src/discovery/builtin-rules/rs-box-leak.md +49 -0
  322. package/src/discovery/builtin-rules/rs-future-prelude.md +24 -0
  323. package/src/discovery/builtin-rules/rs-lazylock.md +52 -0
  324. package/src/discovery/builtin-rules/rs-match-ergonomics.md +68 -0
  325. package/src/discovery/builtin-rules/rs-parking-lot.md +45 -0
  326. package/src/discovery/builtin-rules/rs-result-type.md +20 -0
  327. package/src/discovery/builtin-rules/ts-bare-catch.md +39 -0
  328. package/src/discovery/builtin-rules/ts-import-type.md +43 -0
  329. package/src/discovery/builtin-rules/ts-no-any.md +66 -0
  330. package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +45 -0
  331. package/src/discovery/builtin-rules/ts-no-dynamic-import.md +40 -0
  332. package/src/discovery/builtin-rules/ts-no-inline-cast-access.md +55 -0
  333. package/src/discovery/builtin-rules/ts-no-local-is-record.md +48 -0
  334. package/src/discovery/builtin-rules/ts-no-return-type.md +45 -0
  335. package/src/discovery/builtin-rules/ts-no-test-timers.md +55 -0
  336. package/src/discovery/builtin-rules/ts-no-tiny-functions.md +51 -0
  337. package/src/discovery/builtin-rules/ts-promise-with-resolvers.md +66 -0
  338. package/src/discovery/builtin-rules/ts-redundant-clear-guard.md +75 -0
  339. package/src/discovery/builtin-rules/ts-set-map.md +28 -0
  340. package/src/discovery/builtin.ts +935 -0
  341. package/src/discovery/claude-plugins.ts +624 -0
  342. package/src/discovery/claude.ts +588 -0
  343. package/src/discovery/cline.ts +83 -0
  344. package/src/discovery/codex.ts +540 -0
  345. package/src/discovery/cursor.ts +220 -0
  346. package/src/discovery/gemini.ts +383 -0
  347. package/src/discovery/github.ts +337 -0
  348. package/src/discovery/helpers.ts +1159 -0
  349. package/src/discovery/index.ts +81 -0
  350. package/src/discovery/mcp-json.ts +172 -0
  351. package/src/discovery/omp-extension-roots.ts +213 -0
  352. package/src/discovery/omp-plugins.ts +387 -0
  353. package/src/discovery/opencode.ts +441 -0
  354. package/src/discovery/plugin-dir-roots.ts +28 -0
  355. package/src/discovery/ssh.ts +153 -0
  356. package/src/discovery/substitute-plugin-root.ts +77 -0
  357. package/src/discovery/vscode.ts +105 -0
  358. package/src/discovery/windsurf.ts +147 -0
  359. package/src/edit/apply-patch/index.ts +87 -0
  360. package/src/edit/apply-patch/parser.ts +174 -0
  361. package/src/edit/diff.ts +999 -0
  362. package/src/edit/file-snapshot-store.ts +148 -0
  363. package/src/edit/hashline/block-resolver.ts +33 -0
  364. package/src/edit/hashline/diff.ts +356 -0
  365. package/src/edit/hashline/execute.ts +280 -0
  366. package/src/edit/hashline/filesystem.ts +223 -0
  367. package/src/edit/hashline/index.ts +5 -0
  368. package/src/edit/hashline/noop-loop-guard.ts +99 -0
  369. package/src/edit/hashline/params.ts +12 -0
  370. package/src/edit/index.ts +676 -0
  371. package/src/edit/modes/apply-patch.lark +19 -0
  372. package/src/edit/modes/apply-patch.ts +53 -0
  373. package/src/edit/modes/patch.ts +1958 -0
  374. package/src/edit/modes/replace.ts +1137 -0
  375. package/src/edit/normalize.ts +345 -0
  376. package/src/edit/notebook.ts +242 -0
  377. package/src/edit/read-file.ts +25 -0
  378. package/src/edit/renderer.ts +998 -0
  379. package/src/edit/snapshot-details.ts +77 -0
  380. package/src/edit/streaming.ts +698 -0
  381. package/src/eval/agent-bridge.ts +224 -0
  382. package/src/eval/backend-helpers.ts +48 -0
  383. package/src/eval/backend.ts +71 -0
  384. package/src/eval/bridge-timeout.ts +62 -0
  385. package/src/eval/budget-bridge.ts +48 -0
  386. package/src/eval/completion-bridge.ts +211 -0
  387. package/src/eval/concurrency-bridge.ts +34 -0
  388. package/src/eval/executor-base.ts +504 -0
  389. package/src/eval/idle-timeout.ts +91 -0
  390. package/src/eval/index.ts +6 -0
  391. package/src/eval/jl/executor.ts +540 -0
  392. package/src/eval/jl/index.ts +54 -0
  393. package/src/eval/jl/kernel.ts +236 -0
  394. package/src/eval/jl/prelude.jl +736 -0
  395. package/src/eval/jl/prelude.ts +3 -0
  396. package/src/eval/jl/runner.jl +666 -0
  397. package/src/eval/jl/runtime.ts +118 -0
  398. package/src/eval/js/context-manager.ts +701 -0
  399. package/src/eval/js/executor.ts +175 -0
  400. package/src/eval/js/index.ts +40 -0
  401. package/src/eval/js/process-entry.ts +31 -0
  402. package/src/eval/js/shared/helpers.ts +170 -0
  403. package/src/eval/js/shared/indirect-eval.ts +30 -0
  404. package/src/eval/js/shared/local-module-loader.ts +364 -0
  405. package/src/eval/js/shared/prelude.ts +2 -0
  406. package/src/eval/js/shared/prelude.txt +294 -0
  407. package/src/eval/js/shared/rewrite-imports.ts +550 -0
  408. package/src/eval/js/shared/runtime.ts +590 -0
  409. package/src/eval/js/shared/types.ts +18 -0
  410. package/src/eval/js/tool-bridge.ts +163 -0
  411. package/src/eval/js/worker-core.ts +380 -0
  412. package/src/eval/js/worker-entry.ts +37 -0
  413. package/src/eval/js/worker-protocol.ts +47 -0
  414. package/src/eval/kernel-base.ts +569 -0
  415. package/src/eval/py/display.ts +71 -0
  416. package/src/eval/py/executor.ts +603 -0
  417. package/src/eval/py/index.ts +57 -0
  418. package/src/eval/py/kernel.ts +234 -0
  419. package/src/eval/py/prelude.py +672 -0
  420. package/src/eval/py/prelude.ts +3 -0
  421. package/src/eval/py/runner.py +1388 -0
  422. package/src/eval/py/runtime.ts +276 -0
  423. package/src/eval/py/spawn-options.ts +139 -0
  424. package/src/eval/py/tool-bridge.ts +181 -0
  425. package/src/eval/rb/executor.ts +504 -0
  426. package/src/eval/rb/index.ts +54 -0
  427. package/src/eval/rb/kernel.ts +231 -0
  428. package/src/eval/rb/prelude.rb +552 -0
  429. package/src/eval/rb/prelude.ts +3 -0
  430. package/src/eval/rb/runner.rb +581 -0
  431. package/src/eval/rb/runtime.ts +132 -0
  432. package/src/eval/runtime-env.ts +104 -0
  433. package/src/eval/session-id.ts +8 -0
  434. package/src/eval/types.ts +48 -0
  435. package/src/exa/index.ts +2 -0
  436. package/src/exa/mcp-client.ts +370 -0
  437. package/src/exa/types.ts +69 -0
  438. package/src/exec/bash-executor.ts +627 -0
  439. package/src/exec/direnv.ts +145 -0
  440. package/src/exec/exec.ts +53 -0
  441. package/src/exec/non-interactive-env.ts +118 -0
  442. package/src/export/custom-share.ts +65 -0
  443. package/src/export/html/args.ts +20 -0
  444. package/src/export/html/index.ts +313 -0
  445. package/src/export/html/share-loader.js +102 -0
  446. package/src/export/html/template.css +1355 -0
  447. package/src/export/html/template.html +55 -0
  448. package/src/export/html/template.js +1671 -0
  449. package/src/export/html/tool-views.generated.js +35 -0
  450. package/src/export/html/vendor/highlight.min.js +1213 -0
  451. package/src/export/html/vendor/marked.min.js +6 -0
  452. package/src/export/html/web-palette.ts +126 -0
  453. package/src/export/share.ts +682 -0
  454. package/src/export/ttsr.ts +590 -0
  455. package/src/extensibility/custom-commands/bundled/ci-green/index.ts +54 -0
  456. package/src/extensibility/custom-commands/bundled/review/index.ts +698 -0
  457. package/src/extensibility/custom-commands/index.ts +2 -0
  458. package/src/extensibility/custom-commands/loader.ts +242 -0
  459. package/src/extensibility/custom-commands/types.ts +119 -0
  460. package/src/extensibility/custom-tools/index.ts +7 -0
  461. package/src/extensibility/custom-tools/loader.ts +301 -0
  462. package/src/extensibility/custom-tools/types.ts +286 -0
  463. package/src/extensibility/custom-tools/wrapper.ts +50 -0
  464. package/src/extensibility/extensions/compact-handler.ts +40 -0
  465. package/src/extensibility/extensions/get-commands-handler.ts +78 -0
  466. package/src/extensibility/extensions/index.ts +16 -0
  467. package/src/extensibility/extensions/load-errors.ts +13 -0
  468. package/src/extensibility/extensions/loader.ts +624 -0
  469. package/src/extensibility/extensions/managed-timers.ts +83 -0
  470. package/src/extensibility/extensions/model-api.ts +39 -0
  471. package/src/extensibility/extensions/runner.ts +1209 -0
  472. package/src/extensibility/extensions/types.ts +1526 -0
  473. package/src/extensibility/extensions/wrapper.ts +377 -0
  474. package/src/extensibility/hooks/index.ts +6 -0
  475. package/src/extensibility/hooks/loader.ts +244 -0
  476. package/src/extensibility/hooks/runner.ts +425 -0
  477. package/src/extensibility/hooks/tool-wrapper.ts +124 -0
  478. package/src/extensibility/hooks/types.ts +612 -0
  479. package/src/extensibility/legacy-pi-ai-shim.ts +140 -0
  480. package/src/extensibility/legacy-pi-coding-agent-shim.ts +1384 -0
  481. package/src/extensibility/legacy-pi-tui-shim.ts +43 -0
  482. package/src/extensibility/plugins/bun-git-cache.ts +91 -0
  483. package/src/extensibility/plugins/doctor.ts +65 -0
  484. package/src/extensibility/plugins/git-url.ts +367 -0
  485. package/src/extensibility/plugins/index.ts +9 -0
  486. package/src/extensibility/plugins/installer.ts +201 -0
  487. package/src/extensibility/plugins/legacy-pi-compat.ts +2532 -0
  488. package/src/extensibility/plugins/legacy-pi-virtual-modules.d.ts +4 -0
  489. package/src/extensibility/plugins/loader.ts +535 -0
  490. package/src/extensibility/plugins/manager.ts +1142 -0
  491. package/src/extensibility/plugins/marketplace/cache.ts +136 -0
  492. package/src/extensibility/plugins/marketplace/fetcher.ts +316 -0
  493. package/src/extensibility/plugins/marketplace/index.ts +6 -0
  494. package/src/extensibility/plugins/marketplace/manager.ts +926 -0
  495. package/src/extensibility/plugins/marketplace/registry.ts +196 -0
  496. package/src/extensibility/plugins/marketplace/source-resolver.ts +147 -0
  497. package/src/extensibility/plugins/marketplace/types.ts +192 -0
  498. package/src/extensibility/plugins/marketplace-auto-update.ts +49 -0
  499. package/src/extensibility/plugins/parser.ts +107 -0
  500. package/src/extensibility/plugins/runtime-config.ts +9 -0
  501. package/src/extensibility/plugins/types.ts +194 -0
  502. package/src/extensibility/session-handler-types.ts +21 -0
  503. package/src/extensibility/shared-events.ts +401 -0
  504. package/src/extensibility/skills.ts +511 -0
  505. package/src/extensibility/slash-commands.ts +131 -0
  506. package/src/extensibility/tool-event-input.ts +80 -0
  507. package/src/extensibility/tool-proxy.ts +28 -0
  508. package/src/extensibility/typebox.ts +958 -0
  509. package/src/extensibility/utils.ts +184 -0
  510. package/src/goals/index.ts +3 -0
  511. package/src/goals/runtime.ts +521 -0
  512. package/src/goals/state.ts +37 -0
  513. package/src/goals/tools/goal-tool.ts +251 -0
  514. package/src/hindsight/backend.ts +354 -0
  515. package/src/hindsight/bank.ts +156 -0
  516. package/src/hindsight/client.ts +680 -0
  517. package/src/hindsight/config.ts +193 -0
  518. package/src/hindsight/content.ts +266 -0
  519. package/src/hindsight/index.ts +8 -0
  520. package/src/hindsight/mental-models.ts +429 -0
  521. package/src/hindsight/seeds.json +32 -0
  522. package/src/hindsight/state.ts +550 -0
  523. package/src/hindsight/transcript.ts +71 -0
  524. package/src/index.ts +66 -0
  525. package/src/internal-urls/agent-protocol.ts +180 -0
  526. package/src/internal-urls/artifact-protocol.ts +151 -0
  527. package/src/internal-urls/docs-index.ts +102 -0
  528. package/src/internal-urls/filesystem-resource.ts +34 -0
  529. package/src/internal-urls/history-protocol.ts +198 -0
  530. package/src/internal-urls/index.ts +27 -0
  531. package/src/internal-urls/issue-pr-protocol.ts +594 -0
  532. package/src/internal-urls/json-query.ts +126 -0
  533. package/src/internal-urls/local-protocol.ts +470 -0
  534. package/src/internal-urls/mcp-protocol.ts +165 -0
  535. package/src/internal-urls/memory-protocol.ts +347 -0
  536. package/src/internal-urls/omp-protocol.ts +94 -0
  537. package/src/internal-urls/parse.ts +103 -0
  538. package/src/internal-urls/registry-helpers.ts +132 -0
  539. package/src/internal-urls/router.ts +150 -0
  540. package/src/internal-urls/rule-protocol.ts +45 -0
  541. package/src/internal-urls/skill-protocol.ts +117 -0
  542. package/src/internal-urls/ssh-protocol.ts +368 -0
  543. package/src/internal-urls/types.ts +196 -0
  544. package/src/internal-urls/vault-protocol.ts +940 -0
  545. package/src/internal-urls/xd-protocol.ts +46 -0
  546. package/src/irc/bus.ts +380 -0
  547. package/src/jsonrpc/message-framing.ts +142 -0
  548. package/src/launch/broker.ts +1134 -0
  549. package/src/launch/client.ts +350 -0
  550. package/src/launch/paths.ts +17 -0
  551. package/src/launch/presence.ts +82 -0
  552. package/src/launch/protocol.ts +396 -0
  553. package/src/launch/spawn-options.ts +17 -0
  554. package/src/launch/terminal-output.ts +46 -0
  555. package/src/lib/xai-http.ts +150 -0
  556. package/src/live/attestation.ts +91 -0
  557. package/src/live/controller.ts +517 -0
  558. package/src/live/prompts/agent-final-message.md +3 -0
  559. package/src/live/prompts/live-instructions.md +23 -0
  560. package/src/live/protocol.ts +233 -0
  561. package/src/live/transport.ts +422 -0
  562. package/src/live/visualizer.ts +214 -0
  563. package/src/live/voices.ts +18 -0
  564. package/src/lsp/client.ts +1429 -0
  565. package/src/lsp/clients/biome-client.ts +263 -0
  566. package/src/lsp/clients/index.ts +50 -0
  567. package/src/lsp/clients/lsp-linter-client.ts +85 -0
  568. package/src/lsp/clients/swiftlint-client.ts +120 -0
  569. package/src/lsp/config.ts +549 -0
  570. package/src/lsp/defaults.json +499 -0
  571. package/src/lsp/deferred-diagnostics.ts +66 -0
  572. package/src/lsp/diagnostics-ledger.ts +51 -0
  573. package/src/lsp/edits.ts +288 -0
  574. package/src/lsp/format-options.ts +119 -0
  575. package/src/lsp/index.ts +2766 -0
  576. package/src/lsp/lspmux.ts +233 -0
  577. package/src/lsp/render.ts +668 -0
  578. package/src/lsp/startup-events.ts +13 -0
  579. package/src/lsp/types.ts +453 -0
  580. package/src/lsp/utils.ts +718 -0
  581. package/src/main.ts +1647 -0
  582. package/src/markit/NOTICE +32 -0
  583. package/src/markit/converters/docx.ts +56 -0
  584. package/src/markit/converters/epub.ts +136 -0
  585. package/src/markit/converters/mammoth.d.ts +24 -0
  586. package/src/markit/converters/pdf/columns.ts +103 -0
  587. package/src/markit/converters/pdf/extract.ts +598 -0
  588. package/src/markit/converters/pdf/grid.ts +780 -0
  589. package/src/markit/converters/pdf/headers.ts +106 -0
  590. package/src/markit/converters/pdf/index.ts +146 -0
  591. package/src/markit/converters/pdf/render.ts +501 -0
  592. package/src/markit/converters/pdf/types.ts +84 -0
  593. package/src/markit/converters/pptx.ts +325 -0
  594. package/src/markit/converters/xlsx.ts +173 -0
  595. package/src/markit/index.ts +2 -0
  596. package/src/markit/registry.ts +59 -0
  597. package/src/markit/types.ts +35 -0
  598. package/src/mcp/client.ts +511 -0
  599. package/src/mcp/config-writer.ts +377 -0
  600. package/src/mcp/config.ts +381 -0
  601. package/src/mcp/index.ts +29 -0
  602. package/src/mcp/json-rpc.ts +122 -0
  603. package/src/mcp/loader.ts +125 -0
  604. package/src/mcp/manager.ts +1419 -0
  605. package/src/mcp/oauth-credentials.ts +104 -0
  606. package/src/mcp/oauth-discovery.ts +587 -0
  607. package/src/mcp/oauth-flow.ts +820 -0
  608. package/src/mcp/render.ts +214 -0
  609. package/src/mcp/smithery-auth.ts +108 -0
  610. package/src/mcp/smithery-connect.ts +154 -0
  611. package/src/mcp/smithery-registry.ts +500 -0
  612. package/src/mcp/startup-events.ts +116 -0
  613. package/src/mcp/timeout.ts +59 -0
  614. package/src/mcp/tool-bridge.ts +691 -0
  615. package/src/mcp/tool-cache.ts +117 -0
  616. package/src/mcp/transports/http.ts +523 -0
  617. package/src/mcp/transports/index.ts +7 -0
  618. package/src/mcp/transports/sse.ts +377 -0
  619. package/src/mcp/transports/stdio.ts +903 -0
  620. package/src/mcp/types.ts +437 -0
  621. package/src/memories/index.ts +1434 -0
  622. package/src/memories/storage.ts +578 -0
  623. package/src/memory-backend/index.ts +18 -0
  624. package/src/memory-backend/local-backend.ts +47 -0
  625. package/src/memory-backend/off-backend.ts +25 -0
  626. package/src/memory-backend/resolve.ts +25 -0
  627. package/src/memory-backend/runtime.ts +66 -0
  628. package/src/memory-backend/tool-names.ts +2 -0
  629. package/src/memory-backend/types.ts +166 -0
  630. package/src/mnemopi/backend.ts +629 -0
  631. package/src/mnemopi/config.ts +267 -0
  632. package/src/mnemopi/embed-client.ts +246 -0
  633. package/src/mnemopi/embed-protocol.ts +35 -0
  634. package/src/mnemopi/embed-worker.ts +114 -0
  635. package/src/mnemopi/index.ts +3 -0
  636. package/src/mnemopi/state.ts +906 -0
  637. package/src/modes/acp/acp-agent.ts +2577 -0
  638. package/src/modes/acp/acp-client-bridge.ts +154 -0
  639. package/src/modes/acp/acp-event-mapper.ts +1084 -0
  640. package/src/modes/acp/acp-mode.ts +48 -0
  641. package/src/modes/acp/index.ts +2 -0
  642. package/src/modes/acp/terminal-auth.ts +37 -0
  643. package/src/modes/components/advisor-config.ts +635 -0
  644. package/src/modes/components/advisor-message.ts +109 -0
  645. package/src/modes/components/agent-dashboard.ts +1252 -0
  646. package/src/modes/components/agent-hub.ts +648 -0
  647. package/src/modes/components/agent-transcript-viewer.ts +649 -0
  648. package/src/modes/components/ask-dialog.ts +975 -0
  649. package/src/modes/components/assistant-message.ts +972 -0
  650. package/src/modes/components/background-tan-message.ts +36 -0
  651. package/src/modes/components/bash-execution.ts +233 -0
  652. package/src/modes/components/bordered-loader.ts +41 -0
  653. package/src/modes/components/btw-panel.ts +124 -0
  654. package/src/modes/components/cache-invalidation-marker.ts +110 -0
  655. package/src/modes/components/chat-block.ts +111 -0
  656. package/src/modes/components/chat-transcript-builder.ts +495 -0
  657. package/src/modes/components/collab-prompt-message.ts +32 -0
  658. package/src/modes/components/compaction-summary-message.ts +221 -0
  659. package/src/modes/components/copy-selector.ts +218 -0
  660. package/src/modes/components/countdown-timer.ts +75 -0
  661. package/src/modes/components/custom-editor.ts +1027 -0
  662. package/src/modes/components/custom-message.ts +70 -0
  663. package/src/modes/components/diff.ts +254 -0
  664. package/src/modes/components/dynamic-border.ts +37 -0
  665. package/src/modes/components/error-banner.ts +33 -0
  666. package/src/modes/components/eval-execution.ts +169 -0
  667. package/src/modes/components/execution-shared.ts +101 -0
  668. package/src/modes/components/extensions/extension-dashboard.ts +492 -0
  669. package/src/modes/components/extensions/extension-list.ts +507 -0
  670. package/src/modes/components/extensions/index.ts +9 -0
  671. package/src/modes/components/extensions/inspector-panel.ts +321 -0
  672. package/src/modes/components/extensions/state-manager.ts +648 -0
  673. package/src/modes/components/extensions/types.ts +186 -0
  674. package/src/modes/components/footer.ts +276 -0
  675. package/src/modes/components/history-search.ts +268 -0
  676. package/src/modes/components/hook-editor.ts +213 -0
  677. package/src/modes/components/hook-input.ts +87 -0
  678. package/src/modes/components/hook-message.ts +67 -0
  679. package/src/modes/components/hook-selector.ts +691 -0
  680. package/src/modes/components/index.ts +42 -0
  681. package/src/modes/components/keybinding-hints.ts +65 -0
  682. package/src/modes/components/late-diagnostics-message.ts +60 -0
  683. package/src/modes/components/login-dialog.ts +197 -0
  684. package/src/modes/components/logout-account-selector.ts +130 -0
  685. package/src/modes/components/mcp-add-wizard.ts +1413 -0
  686. package/src/modes/components/message-frame.ts +98 -0
  687. package/src/modes/components/model-browser.ts +872 -0
  688. package/src/modes/components/model-hub.ts +2011 -0
  689. package/src/modes/components/model-picker.ts +233 -0
  690. package/src/modes/components/move-overlay.ts +293 -0
  691. package/src/modes/components/oauth-selector.ts +474 -0
  692. package/src/modes/components/omfg-panel.ts +141 -0
  693. package/src/modes/components/overlay-box.ts +109 -0
  694. package/src/modes/components/pause-screen.ts +208 -0
  695. package/src/modes/components/plan-review-overlay.ts +1226 -0
  696. package/src/modes/components/plan-toc.ts +138 -0
  697. package/src/modes/components/plugin-selector.ts +100 -0
  698. package/src/modes/components/plugin-settings.ts +745 -0
  699. package/src/modes/components/queue-mode-selector.ts +61 -0
  700. package/src/modes/components/read-tool-group.ts +678 -0
  701. package/src/modes/components/reset-usage-selector.ts +161 -0
  702. package/src/modes/components/segment-track.ts +89 -0
  703. package/src/modes/components/select-list-mouse-routing.ts +35 -0
  704. package/src/modes/components/selector-helpers.ts +129 -0
  705. package/src/modes/components/session-account-selector.ts +62 -0
  706. package/src/modes/components/session-selector.ts +1019 -0
  707. package/src/modes/components/settings-defs.ts +267 -0
  708. package/src/modes/components/settings-selector.ts +1445 -0
  709. package/src/modes/components/show-images-selector.ts +50 -0
  710. package/src/modes/components/skill-message.ts +110 -0
  711. package/src/modes/components/snapcompact-shape-preview-doc.md +14 -0
  712. package/src/modes/components/snapcompact-shape-preview.ts +192 -0
  713. package/src/modes/components/status-line/component.ts +1516 -0
  714. package/src/modes/components/status-line/context-thresholds.ts +86 -0
  715. package/src/modes/components/status-line/git-utils.ts +42 -0
  716. package/src/modes/components/status-line/index.ts +5 -0
  717. package/src/modes/components/status-line/presets.ts +106 -0
  718. package/src/modes/components/status-line/segments.ts +710 -0
  719. package/src/modes/components/status-line/separators.ts +55 -0
  720. package/src/modes/components/status-line/types.ts +159 -0
  721. package/src/modes/components/theme-selector.ts +68 -0
  722. package/src/modes/components/thinking-selector.ts +57 -0
  723. package/src/modes/components/tiny-title-download-progress.ts +90 -0
  724. package/src/modes/components/tips.txt +26 -0
  725. package/src/modes/components/todo-reminder.ts +43 -0
  726. package/src/modes/components/tool-execution.ts +1356 -0
  727. package/src/modes/components/transcript-container.ts +527 -0
  728. package/src/modes/components/tree-selector.ts +1008 -0
  729. package/src/modes/components/ttsr-notification.ts +123 -0
  730. package/src/modes/components/usage-row.ts +47 -0
  731. package/src/modes/components/user-message-selector.ts +227 -0
  732. package/src/modes/components/user-message.ts +167 -0
  733. package/src/modes/components/visual-truncate.ts +63 -0
  734. package/src/modes/components/welcome.ts +578 -0
  735. package/src/modes/controllers/btw-controller.ts +198 -0
  736. package/src/modes/controllers/command-controller-shared.ts +109 -0
  737. package/src/modes/controllers/command-controller.ts +1993 -0
  738. package/src/modes/controllers/event-controller.ts +1781 -0
  739. package/src/modes/controllers/extension-ui-controller.ts +1242 -0
  740. package/src/modes/controllers/input-controller.ts +2004 -0
  741. package/src/modes/controllers/live-command-controller.ts +260 -0
  742. package/src/modes/controllers/mcp-command-controller.ts +2403 -0
  743. package/src/modes/controllers/omfg-controller.ts +287 -0
  744. package/src/modes/controllers/omfg-rule.ts +647 -0
  745. package/src/modes/controllers/selector-controller.ts +1968 -0
  746. package/src/modes/controllers/session-focus-controller.ts +117 -0
  747. package/src/modes/controllers/ssh-command-controller.ts +385 -0
  748. package/src/modes/controllers/streaming-reveal.ts +399 -0
  749. package/src/modes/controllers/tan-command-controller.ts +229 -0
  750. package/src/modes/controllers/todo-command-controller.ts +487 -0
  751. package/src/modes/controllers/tool-args-reveal.ts +591 -0
  752. package/src/modes/data/emojis.json +1 -0
  753. package/src/modes/emoji-autocomplete.ts +285 -0
  754. package/src/modes/github-ref-autocomplete.ts +75 -0
  755. package/src/modes/gradient-highlight.ts +99 -0
  756. package/src/modes/image-references.ts +137 -0
  757. package/src/modes/index.ts +10 -0
  758. package/src/modes/interactive-mode.ts +4957 -0
  759. package/src/modes/internal-url-autocomplete.ts +158 -0
  760. package/src/modes/loop-limit.ts +192 -0
  761. package/src/modes/magic-keyword-boundary.ts +23 -0
  762. package/src/modes/magic-keywords.ts +42 -0
  763. package/src/modes/markdown-prose.ts +247 -0
  764. package/src/modes/oauth-manual-input.ts +69 -0
  765. package/src/modes/orchestrate.ts +43 -0
  766. package/src/modes/print-mode.ts +265 -0
  767. package/src/modes/prompt-action-autocomplete.ts +322 -0
  768. package/src/modes/queue-input.ts +132 -0
  769. package/src/modes/rpc/host-tools.ts +204 -0
  770. package/src/modes/rpc/host-uris.ts +235 -0
  771. package/src/modes/rpc/rpc-client.ts +1195 -0
  772. package/src/modes/rpc/rpc-frame.ts +316 -0
  773. package/src/modes/rpc/rpc-input.ts +38 -0
  774. package/src/modes/rpc/rpc-messages.ts +127 -0
  775. package/src/modes/rpc/rpc-mode.ts +1504 -0
  776. package/src/modes/rpc/rpc-subagents.ts +265 -0
  777. package/src/modes/rpc/rpc-types.ts +533 -0
  778. package/src/modes/running-subagent-badge.ts +13 -0
  779. package/src/modes/runtime-init.ts +144 -0
  780. package/src/modes/session-observer-registry.ts +218 -0
  781. package/src/modes/session-teardown.ts +82 -0
  782. package/src/modes/setup-version.ts +11 -0
  783. package/src/modes/setup-wizard/index.ts +103 -0
  784. package/src/modes/setup-wizard/lazy.ts +16 -0
  785. package/src/modes/setup-wizard/scenes/glyph.ts +103 -0
  786. package/src/modes/setup-wizard/scenes/model.ts +132 -0
  787. package/src/modes/setup-wizard/scenes/outro.ts +35 -0
  788. package/src/modes/setup-wizard/scenes/providers.ts +105 -0
  789. package/src/modes/setup-wizard/scenes/sign-in.ts +312 -0
  790. package/src/modes/setup-wizard/scenes/splash.ts +201 -0
  791. package/src/modes/setup-wizard/scenes/theme.ts +330 -0
  792. package/src/modes/setup-wizard/scenes/types.ts +65 -0
  793. package/src/modes/setup-wizard/scenes/web-search.ts +153 -0
  794. package/src/modes/setup-wizard/startup-splash.ts +107 -0
  795. package/src/modes/setup-wizard/wizard-overlay.ts +335 -0
  796. package/src/modes/shared.ts +49 -0
  797. package/src/modes/skill-command.ts +91 -0
  798. package/src/modes/theme/dark.json +95 -0
  799. package/src/modes/theme/defaults/alabaster.json +93 -0
  800. package/src/modes/theme/defaults/amethyst.json +96 -0
  801. package/src/modes/theme/defaults/anthracite.json +93 -0
  802. package/src/modes/theme/defaults/basalt.json +91 -0
  803. package/src/modes/theme/defaults/birch.json +95 -0
  804. package/src/modes/theme/defaults/dark-abyss.json +91 -0
  805. package/src/modes/theme/defaults/dark-arctic.json +104 -0
  806. package/src/modes/theme/defaults/dark-aurora.json +95 -0
  807. package/src/modes/theme/defaults/dark-catppuccin.json +107 -0
  808. package/src/modes/theme/defaults/dark-cavern.json +91 -0
  809. package/src/modes/theme/defaults/dark-copper.json +95 -0
  810. package/src/modes/theme/defaults/dark-cosmos.json +90 -0
  811. package/src/modes/theme/defaults/dark-cyberpunk.json +102 -0
  812. package/src/modes/theme/defaults/dark-dracula.json +98 -0
  813. package/src/modes/theme/defaults/dark-eclipse.json +91 -0
  814. package/src/modes/theme/defaults/dark-ember.json +95 -0
  815. package/src/modes/theme/defaults/dark-equinox.json +90 -0
  816. package/src/modes/theme/defaults/dark-forest.json +96 -0
  817. package/src/modes/theme/defaults/dark-github.json +105 -0
  818. package/src/modes/theme/defaults/dark-gruvbox.json +112 -0
  819. package/src/modes/theme/defaults/dark-lavender.json +95 -0
  820. package/src/modes/theme/defaults/dark-lunar.json +89 -0
  821. package/src/modes/theme/defaults/dark-midnight.json +95 -0
  822. package/src/modes/theme/defaults/dark-monochrome.json +94 -0
  823. package/src/modes/theme/defaults/dark-monokai.json +98 -0
  824. package/src/modes/theme/defaults/dark-nebula.json +90 -0
  825. package/src/modes/theme/defaults/dark-nord.json +97 -0
  826. package/src/modes/theme/defaults/dark-ocean.json +101 -0
  827. package/src/modes/theme/defaults/dark-one.json +100 -0
  828. package/src/modes/theme/defaults/dark-poimandres.json +143 -0
  829. package/src/modes/theme/defaults/dark-rainforest.json +91 -0
  830. package/src/modes/theme/defaults/dark-reef.json +91 -0
  831. package/src/modes/theme/defaults/dark-retro.json +92 -0
  832. package/src/modes/theme/defaults/dark-rose-pine.json +96 -0
  833. package/src/modes/theme/defaults/dark-sakura.json +95 -0
  834. package/src/modes/theme/defaults/dark-slate.json +95 -0
  835. package/src/modes/theme/defaults/dark-solarized.json +97 -0
  836. package/src/modes/theme/defaults/dark-solstice.json +90 -0
  837. package/src/modes/theme/defaults/dark-starfall.json +91 -0
  838. package/src/modes/theme/defaults/dark-sunset.json +99 -0
  839. package/src/modes/theme/defaults/dark-swamp.json +90 -0
  840. package/src/modes/theme/defaults/dark-synthwave.json +103 -0
  841. package/src/modes/theme/defaults/dark-taiga.json +91 -0
  842. package/src/modes/theme/defaults/dark-terminal.json +95 -0
  843. package/src/modes/theme/defaults/dark-tokyo-night.json +101 -0
  844. package/src/modes/theme/defaults/dark-tundra.json +91 -0
  845. package/src/modes/theme/defaults/dark-twilight.json +91 -0
  846. package/src/modes/theme/defaults/dark-volcanic.json +91 -0
  847. package/src/modes/theme/defaults/graphite.json +92 -0
  848. package/src/modes/theme/defaults/index.ts +199 -0
  849. package/src/modes/theme/defaults/light-arctic.json +107 -0
  850. package/src/modes/theme/defaults/light-aurora-day.json +91 -0
  851. package/src/modes/theme/defaults/light-canyon.json +91 -0
  852. package/src/modes/theme/defaults/light-catppuccin.json +106 -0
  853. package/src/modes/theme/defaults/light-cirrus.json +90 -0
  854. package/src/modes/theme/defaults/light-coral.json +95 -0
  855. package/src/modes/theme/defaults/light-cyberpunk.json +96 -0
  856. package/src/modes/theme/defaults/light-dawn.json +90 -0
  857. package/src/modes/theme/defaults/light-dunes.json +91 -0
  858. package/src/modes/theme/defaults/light-eucalyptus.json +95 -0
  859. package/src/modes/theme/defaults/light-forest.json +100 -0
  860. package/src/modes/theme/defaults/light-frost.json +95 -0
  861. package/src/modes/theme/defaults/light-github.json +115 -0
  862. package/src/modes/theme/defaults/light-glacier.json +91 -0
  863. package/src/modes/theme/defaults/light-gruvbox.json +108 -0
  864. package/src/modes/theme/defaults/light-haze.json +90 -0
  865. package/src/modes/theme/defaults/light-honeycomb.json +95 -0
  866. package/src/modes/theme/defaults/light-lagoon.json +91 -0
  867. package/src/modes/theme/defaults/light-lavender.json +95 -0
  868. package/src/modes/theme/defaults/light-meadow.json +91 -0
  869. package/src/modes/theme/defaults/light-mint.json +95 -0
  870. package/src/modes/theme/defaults/light-monochrome.json +101 -0
  871. package/src/modes/theme/defaults/light-ocean.json +99 -0
  872. package/src/modes/theme/defaults/light-one.json +99 -0
  873. package/src/modes/theme/defaults/light-opal.json +91 -0
  874. package/src/modes/theme/defaults/light-orchard.json +91 -0
  875. package/src/modes/theme/defaults/light-paper.json +95 -0
  876. package/src/modes/theme/defaults/light-poimandres.json +143 -0
  877. package/src/modes/theme/defaults/light-prism.json +90 -0
  878. package/src/modes/theme/defaults/light-retro.json +98 -0
  879. package/src/modes/theme/defaults/light-sand.json +95 -0
  880. package/src/modes/theme/defaults/light-savanna.json +91 -0
  881. package/src/modes/theme/defaults/light-solarized.json +102 -0
  882. package/src/modes/theme/defaults/light-soleil.json +90 -0
  883. package/src/modes/theme/defaults/light-sunset.json +99 -0
  884. package/src/modes/theme/defaults/light-synthwave.json +98 -0
  885. package/src/modes/theme/defaults/light-tokyo-night.json +111 -0
  886. package/src/modes/theme/defaults/light-wetland.json +91 -0
  887. package/src/modes/theme/defaults/light-zenith.json +89 -0
  888. package/src/modes/theme/defaults/limestone.json +94 -0
  889. package/src/modes/theme/defaults/mahogany.json +97 -0
  890. package/src/modes/theme/defaults/marble.json +93 -0
  891. package/src/modes/theme/defaults/obsidian.json +91 -0
  892. package/src/modes/theme/defaults/onyx.json +91 -0
  893. package/src/modes/theme/defaults/pearl.json +93 -0
  894. package/src/modes/theme/defaults/porcelain.json +91 -0
  895. package/src/modes/theme/defaults/quartz.json +96 -0
  896. package/src/modes/theme/defaults/sandstone.json +95 -0
  897. package/src/modes/theme/defaults/titanium.json +90 -0
  898. package/src/modes/theme/light.json +93 -0
  899. package/src/modes/theme/mermaid-cache.ts +92 -0
  900. package/src/modes/theme/shimmer.ts +305 -0
  901. package/src/modes/theme/theme-schema.json +463 -0
  902. package/src/modes/theme/theme.ts +3019 -0
  903. package/src/modes/turn-budget.ts +31 -0
  904. package/src/modes/types.ts +479 -0
  905. package/src/modes/ultrathink.ts +42 -0
  906. package/src/modes/utils/context-usage.ts +518 -0
  907. package/src/modes/utils/copy-targets.ts +378 -0
  908. package/src/modes/utils/hotkeys-markdown.ts +63 -0
  909. package/src/modes/utils/interactive-context-helpers.ts +30 -0
  910. package/src/modes/utils/keybinding-matchers.ts +86 -0
  911. package/src/modes/utils/tools-markdown.ts +31 -0
  912. package/src/modes/utils/transcript-render-helpers.ts +253 -0
  913. package/src/modes/utils/ui-helpers.ts +963 -0
  914. package/src/modes/warp-events.ts +232 -0
  915. package/src/modes/workflow.ts +49 -0
  916. package/src/plan-mode/approved-plan.ts +194 -0
  917. package/src/plan-mode/model-transition.ts +51 -0
  918. package/src/plan-mode/plan-files.ts +40 -0
  919. package/src/plan-mode/plan-handoff.ts +37 -0
  920. package/src/plan-mode/plan-protection.ts +31 -0
  921. package/src/plan-mode/state.ts +6 -0
  922. package/src/priority.json +60 -0
  923. package/src/prompts/advisor/active-repo-watchdog.md +6 -0
  924. package/src/prompts/advisor/advise-tool.md +3 -0
  925. package/src/prompts/advisor/context-files.md +8 -0
  926. package/src/prompts/advisor/system.md +98 -0
  927. package/src/prompts/agents/designer.md +74 -0
  928. package/src/prompts/agents/frontmatter.md +12 -0
  929. package/src/prompts/agents/init.md +33 -0
  930. package/src/prompts/agents/librarian.md +119 -0
  931. package/src/prompts/agents/reviewer.md +139 -0
  932. package/src/prompts/agents/scout.md +58 -0
  933. package/src/prompts/agents/task.md +17 -0
  934. package/src/prompts/bench/cache-prefix-chunk.md +1 -0
  935. package/src/prompts/bench/cache-prefix.md +3 -0
  936. package/src/prompts/bench/cache-suffix.md +1 -0
  937. package/src/prompts/bench.md +6 -0
  938. package/src/prompts/ci-green-request.md +36 -0
  939. package/src/prompts/dry-balance-bench.md +8 -0
  940. package/src/prompts/goals/goal-budget-limit.md +16 -0
  941. package/src/prompts/goals/goal-continuation.md +28 -0
  942. package/src/prompts/goals/goal-mode-active.md +23 -0
  943. package/src/prompts/goals/goal-mode-context.md +4 -0
  944. package/src/prompts/goals/goal-todo-context.md +12 -0
  945. package/src/prompts/goals/guided-goal-interview.md +43 -0
  946. package/src/prompts/memories/consolidation.md +30 -0
  947. package/src/prompts/memories/consolidation_system.md +4 -0
  948. package/src/prompts/memories/read-path.md +17 -0
  949. package/src/prompts/memories/stage_one_input.md +6 -0
  950. package/src/prompts/memories/stage_one_system.md +21 -0
  951. package/src/prompts/review-custom-request.md +21 -0
  952. package/src/prompts/review-headless-request.md +16 -0
  953. package/src/prompts/review-request.md +68 -0
  954. package/src/prompts/skills/autoload.md +8 -0
  955. package/src/prompts/skills/user-invocation.md +11 -0
  956. package/src/prompts/steering/parent-irc.md +5 -0
  957. package/src/prompts/steering/user-interjection.md +6 -0
  958. package/src/prompts/system/active-repo-context.md +4 -0
  959. package/src/prompts/system/agent-creation-architect.md +50 -0
  960. package/src/prompts/system/agent-creation-user.md +6 -0
  961. package/src/prompts/system/auto-continue.md +1 -0
  962. package/src/prompts/system/auto-thinking-difficulty-local.md +14 -0
  963. package/src/prompts/system/auto-thinking-difficulty.md +12 -0
  964. package/src/prompts/system/autolearn-guidance-learn.md +1 -0
  965. package/src/prompts/system/autolearn-guidance.md +7 -0
  966. package/src/prompts/system/autolearn-nudge-autocontinue.md +5 -0
  967. package/src/prompts/system/background-tan-dispatch.md +8 -0
  968. package/src/prompts/system/btw-user.md +8 -0
  969. package/src/prompts/system/commit-message-system.md +14 -0
  970. package/src/prompts/system/computer-safety.md +14 -0
  971. package/src/prompts/system/custom-system-prompt.md +64 -0
  972. package/src/prompts/system/eager-task.md +7 -0
  973. package/src/prompts/system/eager-todo.md +18 -0
  974. package/src/prompts/system/empty-stop-retry.md +4 -0
  975. package/src/prompts/system/gemini-tool-call-reminder.md +9 -0
  976. package/src/prompts/system/interrupted-thinking.md +7 -0
  977. package/src/prompts/system/irc-autoreply.md +6 -0
  978. package/src/prompts/system/irc-incoming.md +9 -0
  979. package/src/prompts/system/manual-continue.md +7 -0
  980. package/src/prompts/system/mcp-xdev-guidance.md +11 -0
  981. package/src/prompts/system/memory-consolidation-system.md +8 -0
  982. package/src/prompts/system/memory-extraction-system.md +26 -0
  983. package/src/prompts/system/mid-run-todo-nudge.md +3 -0
  984. package/src/prompts/system/omfg-user.md +50 -0
  985. package/src/prompts/system/orchestrate-notice.md +40 -0
  986. package/src/prompts/system/personalities/default.md +18 -0
  987. package/src/prompts/system/personalities/friendly.md +17 -0
  988. package/src/prompts/system/personalities/pragmatic.md +15 -0
  989. package/src/prompts/system/plan-mode-active.md +125 -0
  990. package/src/prompts/system/plan-mode-approved.md +22 -0
  991. package/src/prompts/system/plan-mode-compact-instructions.md +17 -0
  992. package/src/prompts/system/plan-mode-reference.md +10 -0
  993. package/src/prompts/system/plan-mode-subagent.md +33 -0
  994. package/src/prompts/system/plan-mode-tool-decision-reminder.md +9 -0
  995. package/src/prompts/system/plan-yolo-handoff.md +5 -0
  996. package/src/prompts/system/prewalk-checklist.md +7 -0
  997. package/src/prompts/system/prewalk-continue.md +1 -0
  998. package/src/prompts/system/prewalk-plan.md +13 -0
  999. package/src/prompts/system/project-prompt.md +61 -0
  1000. package/src/prompts/system/recap-user.md +9 -0
  1001. package/src/prompts/system/resolve-device-reminder.md +3 -0
  1002. package/src/prompts/system/rewind-report.md +6 -0
  1003. package/src/prompts/system/side-channel-no-tools.md +3 -0
  1004. package/src/prompts/system/snapcompact-context-frames-note.md +1 -0
  1005. package/src/prompts/system/snapcompact-context-stub.md +1 -0
  1006. package/src/prompts/system/snapcompact-system-frames-note.md +1 -0
  1007. package/src/prompts/system/snapcompact-system-stub.md +1 -0
  1008. package/src/prompts/system/snapcompact-toolresult-note.md +1 -0
  1009. package/src/prompts/system/speech-rewrite.md +15 -0
  1010. package/src/prompts/system/subagent-async-pending.md +6 -0
  1011. package/src/prompts/system/subagent-system-prompt.md +73 -0
  1012. package/src/prompts/system/subagent-user-prompt.md +3 -0
  1013. package/src/prompts/system/subagent-yield-reminder.md +23 -0
  1014. package/src/prompts/system/system-prompt.md +283 -0
  1015. package/src/prompts/system/tan-context-switch.md +17 -0
  1016. package/src/prompts/system/task-label.md +23 -0
  1017. package/src/prompts/system/thinking-loop-redirect.md +10 -0
  1018. package/src/prompts/system/title-marker-instruction.md +1 -0
  1019. package/src/prompts/system/title-system.md +16 -0
  1020. package/src/prompts/system/tool-call-loop-redirect.md +8 -0
  1021. package/src/prompts/system/ttsr-interrupt.md +7 -0
  1022. package/src/prompts/system/ttsr-tool-reminder.md +5 -0
  1023. package/src/prompts/system/ultrathink-notice.md +3 -0
  1024. package/src/prompts/system/unexpected-stop-classifier.md +17 -0
  1025. package/src/prompts/system/unexpected-stop-retry.md +4 -0
  1026. package/src/prompts/system/vibe-mode-active.md +26 -0
  1027. package/src/prompts/system/web-search.md +25 -0
  1028. package/src/prompts/system/workflow-notice.md +112 -0
  1029. package/src/prompts/system/xdev-mount-notice.md +20 -0
  1030. package/src/prompts/tools/apply-patch.md +65 -0
  1031. package/src/prompts/tools/ask.md +22 -0
  1032. package/src/prompts/tools/ast-edit.md +11 -0
  1033. package/src/prompts/tools/ast-grep.md +19 -0
  1034. package/src/prompts/tools/async-result.md +8 -0
  1035. package/src/prompts/tools/bash.md +25 -0
  1036. package/src/prompts/tools/browser.md +28 -0
  1037. package/src/prompts/tools/checkpoint.md +15 -0
  1038. package/src/prompts/tools/computer.md +26 -0
  1039. package/src/prompts/tools/debug.md +3 -0
  1040. package/src/prompts/tools/eval.md +45 -0
  1041. package/src/prompts/tools/github.md +22 -0
  1042. package/src/prompts/tools/glob.md +15 -0
  1043. package/src/prompts/tools/goal.md +11 -0
  1044. package/src/prompts/tools/grep.md +12 -0
  1045. package/src/prompts/tools/hub.md +34 -0
  1046. package/src/prompts/tools/image-attachment-describe-system.md +8 -0
  1047. package/src/prompts/tools/image-attachment-describe.md +10 -0
  1048. package/src/prompts/tools/image-gen.md +7 -0
  1049. package/src/prompts/tools/inspect-image-system.md +20 -0
  1050. package/src/prompts/tools/inspect-image.md +22 -0
  1051. package/src/prompts/tools/learn.md +7 -0
  1052. package/src/prompts/tools/lsp-late-diagnostic.md +8 -0
  1053. package/src/prompts/tools/lsp.md +19 -0
  1054. package/src/prompts/tools/manage-skill.md +9 -0
  1055. package/src/prompts/tools/memory-edit.md +12 -0
  1056. package/src/prompts/tools/patch.md +57 -0
  1057. package/src/prompts/tools/read.md +27 -0
  1058. package/src/prompts/tools/recall.md +7 -0
  1059. package/src/prompts/tools/reflect.md +5 -0
  1060. package/src/prompts/tools/replace.md +29 -0
  1061. package/src/prompts/tools/retain.md +6 -0
  1062. package/src/prompts/tools/rewind.md +14 -0
  1063. package/src/prompts/tools/task-async-contract.md +1 -0
  1064. package/src/prompts/tools/task-summary.md +20 -0
  1065. package/src/prompts/tools/task.md +83 -0
  1066. package/src/prompts/tools/todo.md +42 -0
  1067. package/src/prompts/tools/vibe-kill.md +3 -0
  1068. package/src/prompts/tools/vibe-list.md +3 -0
  1069. package/src/prompts/tools/vibe-send.md +9 -0
  1070. package/src/prompts/tools/vibe-spawn.md +10 -0
  1071. package/src/prompts/tools/vibe-turn-result.md +19 -0
  1072. package/src/prompts/tools/vibe-wait.md +8 -0
  1073. package/src/prompts/tools/web-search.md +8 -0
  1074. package/src/prompts/tools/write.md +14 -0
  1075. package/src/registry/agent-lifecycle.ts +455 -0
  1076. package/src/registry/agent-registry.ts +217 -0
  1077. package/src/registry/persisted-agents.ts +98 -0
  1078. package/src/sdk.ts +3553 -0
  1079. package/src/secrets/index.ts +246 -0
  1080. package/src/secrets/obfuscator.ts +2574 -0
  1081. package/src/secrets/regex.ts +21 -0
  1082. package/src/session/acp-permission-gate.ts +165 -0
  1083. package/src/session/agent-session-events.ts +66 -0
  1084. package/src/session/agent-session-types.ts +346 -0
  1085. package/src/session/agent-session.ts +8406 -0
  1086. package/src/session/agent-storage.ts +805 -0
  1087. package/src/session/artifacts.ts +154 -0
  1088. package/src/session/async-job-delivery.ts +82 -0
  1089. package/src/session/auth-broker-config.ts +92 -0
  1090. package/src/session/auth-storage.ts +25 -0
  1091. package/src/session/bash-runner.ts +326 -0
  1092. package/src/session/blob-store.ts +295 -0
  1093. package/src/session/checkpoint-entries.ts +81 -0
  1094. package/src/session/client-bridge.ts +85 -0
  1095. package/src/session/codex-auto-reset.ts +202 -0
  1096. package/src/session/compact-modes.ts +105 -0
  1097. package/src/session/eval-runner.ts +217 -0
  1098. package/src/session/exit-diagnostics.ts +310 -0
  1099. package/src/session/history-storage.ts +327 -0
  1100. package/src/session/indexed-session-storage.ts +544 -0
  1101. package/src/session/irc-bridge.ts +203 -0
  1102. package/src/session/messages.ts +1280 -0
  1103. package/src/session/model-controls.ts +750 -0
  1104. package/src/session/prewalk.ts +257 -0
  1105. package/src/session/provider-image-budget.ts +86 -0
  1106. package/src/session/queued-messages.ts +99 -0
  1107. package/src/session/redis-session-storage.ts +257 -0
  1108. package/src/session/retry-fallback-chains.ts +455 -0
  1109. package/src/session/role-models.ts +85 -0
  1110. package/src/session/session-advisors.ts +1754 -0
  1111. package/src/session/session-context.ts +554 -0
  1112. package/src/session/session-dump-format.ts +216 -0
  1113. package/src/session/session-entries.ts +260 -0
  1114. package/src/session/session-handoff.ts +308 -0
  1115. package/src/session/session-history-format.ts +459 -0
  1116. package/src/session/session-listing.ts +715 -0
  1117. package/src/session/session-loader.ts +280 -0
  1118. package/src/session/session-maintenance.ts +2983 -0
  1119. package/src/session/session-manager.ts +2557 -0
  1120. package/src/session/session-memory.ts +222 -0
  1121. package/src/session/session-metadata.ts +53 -0
  1122. package/src/session/session-migrations.ts +78 -0
  1123. package/src/session/session-paths.ts +222 -0
  1124. package/src/session/session-persistence.ts +293 -0
  1125. package/src/session/session-provider-boundary.ts +306 -0
  1126. package/src/session/session-stats.ts +293 -0
  1127. package/src/session/session-storage.ts +734 -0
  1128. package/src/session/session-title-slot.ts +141 -0
  1129. package/src/session/session-tools.ts +1226 -0
  1130. package/src/session/session-workspace.ts +53 -0
  1131. package/src/session/settings-stream-fn.ts +74 -0
  1132. package/src/session/shake-types.ts +43 -0
  1133. package/src/session/snapcompact-inline.ts +545 -0
  1134. package/src/session/snapcompact-savings-journal.ts +113 -0
  1135. package/src/session/sql-session-storage.ts +374 -0
  1136. package/src/session/stream-guards.ts +417 -0
  1137. package/src/session/streaming-output.ts +1459 -0
  1138. package/src/session/todo-tracker.ts +380 -0
  1139. package/src/session/tool-choice-queue.ts +305 -0
  1140. package/src/session/ttsr-coordinator.ts +496 -0
  1141. package/src/session/turn-persistence.ts +142 -0
  1142. package/src/session/turn-recovery.ts +1728 -0
  1143. package/src/session/unexpected-stop-classifier.ts +132 -0
  1144. package/src/session/yield-queue.ts +183 -0
  1145. package/src/slash-commands/acp-builtins.ts +70 -0
  1146. package/src/slash-commands/available-commands.ts +105 -0
  1147. package/src/slash-commands/builtin-registry.ts +2982 -0
  1148. package/src/slash-commands/helpers/active-oauth-account.ts +80 -0
  1149. package/src/slash-commands/helpers/collab-qrcode.ts +28 -0
  1150. package/src/slash-commands/helpers/context-report.ts +66 -0
  1151. package/src/slash-commands/helpers/format.ts +46 -0
  1152. package/src/slash-commands/helpers/logout.ts +108 -0
  1153. package/src/slash-commands/helpers/marketplace-manager.ts +25 -0
  1154. package/src/slash-commands/helpers/mcp.ts +533 -0
  1155. package/src/slash-commands/helpers/parse.ts +85 -0
  1156. package/src/slash-commands/helpers/reset-usage.ts +66 -0
  1157. package/src/slash-commands/helpers/session-pin.ts +44 -0
  1158. package/src/slash-commands/helpers/ssh.ts +196 -0
  1159. package/src/slash-commands/helpers/stats-dashboard.ts +85 -0
  1160. package/src/slash-commands/helpers/todo.ts +285 -0
  1161. package/src/slash-commands/helpers/usage-report.ts +198 -0
  1162. package/src/slash-commands/marketplace-install-parser.ts +99 -0
  1163. package/src/slash-commands/types.ts +139 -0
  1164. package/src/ssh/config-writer.ts +183 -0
  1165. package/src/ssh/connection-manager.ts +667 -0
  1166. package/src/ssh/file-transfer.ts +214 -0
  1167. package/src/ssh/sshfs-mount.ts +163 -0
  1168. package/src/ssh/utils.ts +51 -0
  1169. package/src/startup-splash.ts +19 -0
  1170. package/src/stt/asr-client.ts +401 -0
  1171. package/src/stt/asr-protocol.ts +65 -0
  1172. package/src/stt/asr-worker.ts +603 -0
  1173. package/src/stt/downloader.ts +142 -0
  1174. package/src/stt/endpointer.ts +259 -0
  1175. package/src/stt/index.ts +6 -0
  1176. package/src/stt/models.ts +150 -0
  1177. package/src/stt/sherpa-runtime.ts +71 -0
  1178. package/src/stt/stt-controller.ts +320 -0
  1179. package/src/stt/submit-trigger.ts +74 -0
  1180. package/src/subprocess/worker-client.ts +463 -0
  1181. package/src/subprocess/worker-runtime.ts +494 -0
  1182. package/src/system-prompt.ts +894 -0
  1183. package/src/task/agents.ts +168 -0
  1184. package/src/task/commands.ts +132 -0
  1185. package/src/task/discovery.ts +145 -0
  1186. package/src/task/executor.ts +3129 -0
  1187. package/src/task/index.ts +1519 -0
  1188. package/src/task/isolation-ownership.ts +106 -0
  1189. package/src/task/isolation-runner.ts +413 -0
  1190. package/src/task/label.ts +40 -0
  1191. package/src/task/name-generator.ts +1577 -0
  1192. package/src/task/omp-command.ts +26 -0
  1193. package/src/task/output-manager.ts +115 -0
  1194. package/src/task/parallel.ts +221 -0
  1195. package/src/task/persisted-revive.ts +141 -0
  1196. package/src/task/prewalk.ts +6 -0
  1197. package/src/task/prompt-policy.ts +8 -0
  1198. package/src/task/provider-concurrency.ts +100 -0
  1199. package/src/task/render.ts +1814 -0
  1200. package/src/task/renderer.ts +14 -0
  1201. package/src/task/repair-args.ts +118 -0
  1202. package/src/task/spawn-policy.ts +58 -0
  1203. package/src/task/structured-subagent.ts +649 -0
  1204. package/src/task/subprocess-tool-registry.ts +88 -0
  1205. package/src/task/types.ts +551 -0
  1206. package/src/task/worktree.ts +967 -0
  1207. package/src/task/yield-assembly.ts +198 -0
  1208. package/src/telemetry-export.ts +500 -0
  1209. package/src/thinking.ts +364 -0
  1210. package/src/tiny/device.ts +111 -0
  1211. package/src/tiny/dtype.ts +101 -0
  1212. package/src/tiny/message-preproc.ts +155 -0
  1213. package/src/tiny/models.ts +268 -0
  1214. package/src/tiny/text.ts +278 -0
  1215. package/src/tiny/title-client.ts +460 -0
  1216. package/src/tiny/title-protocol.ts +56 -0
  1217. package/src/tiny/worker.ts +354 -0
  1218. package/src/tools/acp-bridge.ts +81 -0
  1219. package/src/tools/approval.ts +245 -0
  1220. package/src/tools/ask.ts +1459 -0
  1221. package/src/tools/ast-edit.ts +718 -0
  1222. package/src/tools/ast-grep.ts +520 -0
  1223. package/src/tools/auto-generated-guard.ts +335 -0
  1224. package/src/tools/bash-interactive.ts +435 -0
  1225. package/src/tools/bash-interceptor.ts +67 -0
  1226. package/src/tools/bash-pty-selection.ts +14 -0
  1227. package/src/tools/bash-skill-urls.ts +335 -0
  1228. package/src/tools/bash.ts +1762 -0
  1229. package/src/tools/browser/aria/aria-snapshot.bundle.txt +7 -0
  1230. package/src/tools/browser/aria/aria-snapshot.ts +131 -0
  1231. package/src/tools/browser/attach.ts +194 -0
  1232. package/src/tools/browser/cmux/cmux-tab.ts +1400 -0
  1233. package/src/tools/browser/cmux/rpc.ts +206 -0
  1234. package/src/tools/browser/cmux/socket-client.ts +445 -0
  1235. package/src/tools/browser/launch.ts +788 -0
  1236. package/src/tools/browser/readable.ts +112 -0
  1237. package/src/tools/browser/registry.ts +287 -0
  1238. package/src/tools/browser/render.ts +226 -0
  1239. package/src/tools/browser/run-cancellation.ts +131 -0
  1240. package/src/tools/browser/run-output.ts +76 -0
  1241. package/src/tools/browser/tab-protocol.ts +115 -0
  1242. package/src/tools/browser/tab-supervisor.ts +1040 -0
  1243. package/src/tools/browser/tab-worker-entry.ts +29 -0
  1244. package/src/tools/browser/tab-worker.ts +1842 -0
  1245. package/src/tools/browser.ts +457 -0
  1246. package/src/tools/builtin-names.ts +66 -0
  1247. package/src/tools/checkpoint.ts +150 -0
  1248. package/src/tools/computer/exposure.ts +38 -0
  1249. package/src/tools/computer/protocol.ts +28 -0
  1250. package/src/tools/computer/supervisor.ts +306 -0
  1251. package/src/tools/computer/worker-entry.ts +34 -0
  1252. package/src/tools/computer/worker.ts +131 -0
  1253. package/src/tools/computer-renderer.ts +108 -0
  1254. package/src/tools/computer.ts +516 -0
  1255. package/src/tools/conflict-detect.ts +815 -0
  1256. package/src/tools/context.ts +46 -0
  1257. package/src/tools/debug.ts +1121 -0
  1258. package/src/tools/default-renderer.ts +139 -0
  1259. package/src/tools/essential-tools.ts +46 -0
  1260. package/src/tools/eval-backends.ts +34 -0
  1261. package/src/tools/eval-format/index.ts +24 -0
  1262. package/src/tools/eval-format/javascript.ts +952 -0
  1263. package/src/tools/eval-format/julia.ts +446 -0
  1264. package/src/tools/eval-format/python.ts +544 -0
  1265. package/src/tools/eval-format/ruby.ts +380 -0
  1266. package/src/tools/eval-render.ts +784 -0
  1267. package/src/tools/eval.ts +774 -0
  1268. package/src/tools/fetch.ts +1889 -0
  1269. package/src/tools/file-recorder.ts +35 -0
  1270. package/src/tools/fs-cache-invalidation.ts +28 -0
  1271. package/src/tools/gh-cache-invalidation.ts +175 -0
  1272. package/src/tools/gh-format.ts +12 -0
  1273. package/src/tools/gh-renderer.ts +484 -0
  1274. package/src/tools/gh.ts +3959 -0
  1275. package/src/tools/github-cache.ts +663 -0
  1276. package/src/tools/glob.ts +682 -0
  1277. package/src/tools/grep.ts +1858 -0
  1278. package/src/tools/grouped-file-output.ts +210 -0
  1279. package/src/tools/hub/index.ts +579 -0
  1280. package/src/tools/hub/jobs.ts +714 -0
  1281. package/src/tools/hub/launch.ts +579 -0
  1282. package/src/tools/hub/messaging.ts +735 -0
  1283. package/src/tools/hub/types.ts +117 -0
  1284. package/src/tools/image-gen.ts +1689 -0
  1285. package/src/tools/image-providers.ts +50 -0
  1286. package/src/tools/index.ts +691 -0
  1287. package/src/tools/inspect-image-renderer.ts +133 -0
  1288. package/src/tools/inspect-image.ts +290 -0
  1289. package/src/tools/json-tree.ts +260 -0
  1290. package/src/tools/jtd-to-json-schema.ts +219 -0
  1291. package/src/tools/jtd-to-typescript.ts +136 -0
  1292. package/src/tools/jtd-utils.ts +102 -0
  1293. package/src/tools/learn.ts +141 -0
  1294. package/src/tools/list-limit.ts +40 -0
  1295. package/src/tools/manage-skill.ts +102 -0
  1296. package/src/tools/match-line-format.ts +20 -0
  1297. package/src/tools/memory-edit.ts +61 -0
  1298. package/src/tools/memory-recall.ts +102 -0
  1299. package/src/tools/memory-reflect.ts +88 -0
  1300. package/src/tools/memory-render.ts +211 -0
  1301. package/src/tools/memory-retain.ts +89 -0
  1302. package/src/tools/output-meta.ts +845 -0
  1303. package/src/tools/output-schema-validator.ts +307 -0
  1304. package/src/tools/path-utils.ts +1381 -0
  1305. package/src/tools/plan-mode-guard.ts +155 -0
  1306. package/src/tools/puppeteer/00_stealth_tampering.txt +44 -0
  1307. package/src/tools/puppeteer/01_stealth_activity.txt +80 -0
  1308. package/src/tools/puppeteer/02_stealth_hairline.txt +57 -0
  1309. package/src/tools/puppeteer/03_stealth_botd.txt +380 -0
  1310. package/src/tools/puppeteer/04_stealth_iframe.txt +174 -0
  1311. package/src/tools/puppeteer/05_stealth_webgl.txt +233 -0
  1312. package/src/tools/puppeteer/06_stealth_screen.txt +260 -0
  1313. package/src/tools/puppeteer/07_stealth_fonts.txt +99 -0
  1314. package/src/tools/puppeteer/08_stealth_audio.txt +63 -0
  1315. package/src/tools/puppeteer/09_stealth_locale.txt +51 -0
  1316. package/src/tools/puppeteer/10_stealth_plugins.txt +212 -0
  1317. package/src/tools/puppeteer/11_stealth_hardware.txt +59 -0
  1318. package/src/tools/puppeteer/12_stealth_codecs.txt +42 -0
  1319. package/src/tools/puppeteer/13_stealth_worker.txt +235 -0
  1320. package/src/tools/read.ts +3742 -0
  1321. package/src/tools/render-utils.ts +924 -0
  1322. package/src/tools/renderers.ts +133 -0
  1323. package/src/tools/report-tool-issue.ts +568 -0
  1324. package/src/tools/resolve.ts +423 -0
  1325. package/src/tools/review.ts +103 -0
  1326. package/src/tools/shell-tokenize.ts +83 -0
  1327. package/src/tools/sqlite-reader.ts +884 -0
  1328. package/src/tools/terminal-output.ts +141 -0
  1329. package/src/tools/todo.ts +1226 -0
  1330. package/src/tools/tool-errors.ts +62 -0
  1331. package/src/tools/tool-result.ts +102 -0
  1332. package/src/tools/tool-timeouts.ts +37 -0
  1333. package/src/tools/tts.ts +266 -0
  1334. package/src/tools/vibe.ts +607 -0
  1335. package/src/tools/write.ts +1640 -0
  1336. package/src/tools/xdev.ts +508 -0
  1337. package/src/tools/yield.ts +486 -0
  1338. package/src/tts/downloader.ts +64 -0
  1339. package/src/tts/index.ts +10 -0
  1340. package/src/tts/models.ts +137 -0
  1341. package/src/tts/runtime.ts +21 -0
  1342. package/src/tts/speakable.ts +392 -0
  1343. package/src/tts/speech-enhancer.ts +206 -0
  1344. package/src/tts/streaming-player.ts +120 -0
  1345. package/src/tts/tts-client.ts +475 -0
  1346. package/src/tts/tts-protocol.ts +69 -0
  1347. package/src/tts/tts-worker.ts +434 -0
  1348. package/src/tts/vocalizer.ts +419 -0
  1349. package/src/tts/wav.ts +58 -0
  1350. package/src/tui/code-cell.ts +268 -0
  1351. package/src/tui/file-list.ts +55 -0
  1352. package/src/tui/hyperlink.ts +178 -0
  1353. package/src/tui/index.ts +13 -0
  1354. package/src/tui/output-block.ts +268 -0
  1355. package/src/tui/status-line.ts +54 -0
  1356. package/src/tui/tree-list.ts +172 -0
  1357. package/src/tui/types.ts +15 -0
  1358. package/src/tui/utils.ts +103 -0
  1359. package/src/tui/width-aware-text.ts +58 -0
  1360. package/src/utils/active-repo-context.ts +143 -0
  1361. package/src/utils/block-context.ts +312 -0
  1362. package/src/utils/changelog.ts +232 -0
  1363. package/src/utils/clipboard.ts +327 -0
  1364. package/src/utils/command-args.ts +76 -0
  1365. package/src/utils/commit-message-generator.ts +148 -0
  1366. package/src/utils/cpuprofile.ts +235 -0
  1367. package/src/utils/edit-mode.ts +61 -0
  1368. package/src/utils/enhanced-paste.ts +230 -0
  1369. package/src/utils/event-bus.ts +33 -0
  1370. package/src/utils/external-editor.ts +78 -0
  1371. package/src/utils/fetch-timeout.ts +10 -0
  1372. package/src/utils/file-display-mode.ts +44 -0
  1373. package/src/utils/file-mentions.ts +293 -0
  1374. package/src/utils/git.ts +2425 -0
  1375. package/src/utils/image-loading.ts +231 -0
  1376. package/src/utils/image-resize.ts +420 -0
  1377. package/src/utils/image-vision-fallback.ts +196 -0
  1378. package/src/utils/inspect-image-mode.ts +39 -0
  1379. package/src/utils/ipc.ts +38 -0
  1380. package/src/utils/jj.ts +416 -0
  1381. package/src/utils/lang-from-path.ts +251 -0
  1382. package/src/utils/local-date.ts +7 -0
  1383. package/src/utils/mac-file-urls.applescript +37 -0
  1384. package/src/utils/markit-cache.ts +166 -0
  1385. package/src/utils/markit.ts +223 -0
  1386. package/src/utils/mupdf-wasm-embed.ts +12 -0
  1387. package/src/utils/open.ts +126 -0
  1388. package/src/utils/profile-tree.ts +111 -0
  1389. package/src/utils/prompt-path.ts +3 -0
  1390. package/src/utils/qrcode.ts +535 -0
  1391. package/src/utils/sample-profile.ts +437 -0
  1392. package/src/utils/session-color.ts +142 -0
  1393. package/src/utils/shell-snapshot-fn-env.sh +63 -0
  1394. package/src/utils/shell-snapshot.ts +316 -0
  1395. package/src/utils/sixel.ts +69 -0
  1396. package/src/utils/thinking-display.ts +163 -0
  1397. package/src/utils/title-generator.ts +597 -0
  1398. package/src/utils/token-rate.ts +72 -0
  1399. package/src/utils/tool-choice.ts +63 -0
  1400. package/src/utils/tools-manager.ts +411 -0
  1401. package/src/utils/turndown.ts +83 -0
  1402. package/src/utils/zip.ts +1106 -0
  1403. package/src/vibe/runtime.ts +1540 -0
  1404. package/src/vibe/state.ts +4 -0
  1405. package/src/web/kagi.ts +304 -0
  1406. package/src/web/parallel.ts +354 -0
  1407. package/src/web/scrapers/artifacthub.ts +207 -0
  1408. package/src/web/scrapers/arxiv.ts +83 -0
  1409. package/src/web/scrapers/aur.ts +162 -0
  1410. package/src/web/scrapers/biorxiv.ts +133 -0
  1411. package/src/web/scrapers/bluesky.ts +262 -0
  1412. package/src/web/scrapers/brew.ts +172 -0
  1413. package/src/web/scrapers/cheatsh.ts +68 -0
  1414. package/src/web/scrapers/chocolatey.ts +196 -0
  1415. package/src/web/scrapers/choosealicense.ts +95 -0
  1416. package/src/web/scrapers/cisa-kev.ts +87 -0
  1417. package/src/web/scrapers/clojars.ts +154 -0
  1418. package/src/web/scrapers/coingecko.ts +177 -0
  1419. package/src/web/scrapers/crates-io.ts +97 -0
  1420. package/src/web/scrapers/crossref.ts +136 -0
  1421. package/src/web/scrapers/devto.ts +147 -0
  1422. package/src/web/scrapers/discogs.ts +306 -0
  1423. package/src/web/scrapers/discourse.ts +197 -0
  1424. package/src/web/scrapers/dockerhub.ts +138 -0
  1425. package/src/web/scrapers/docs-rs.ts +663 -0
  1426. package/src/web/scrapers/fdroid.ts +134 -0
  1427. package/src/web/scrapers/firefox-addons.ts +191 -0
  1428. package/src/web/scrapers/flathub.ts +223 -0
  1429. package/src/web/scrapers/github-gist.ts +58 -0
  1430. package/src/web/scrapers/github.ts +800 -0
  1431. package/src/web/scrapers/gitlab.ts +401 -0
  1432. package/src/web/scrapers/go-pkg.ts +266 -0
  1433. package/src/web/scrapers/hackage.ts +140 -0
  1434. package/src/web/scrapers/hackernews.ts +189 -0
  1435. package/src/web/scrapers/hex.ts +105 -0
  1436. package/src/web/scrapers/huggingface.ts +321 -0
  1437. package/src/web/scrapers/iacr.ts +89 -0
  1438. package/src/web/scrapers/index.ts +252 -0
  1439. package/src/web/scrapers/jetbrains-marketplace.ts +159 -0
  1440. package/src/web/scrapers/lemmy.ts +203 -0
  1441. package/src/web/scrapers/lobsters.ts +175 -0
  1442. package/src/web/scrapers/mastodon.ts +292 -0
  1443. package/src/web/scrapers/maven.ts +138 -0
  1444. package/src/web/scrapers/mdn.ts +173 -0
  1445. package/src/web/scrapers/metacpan.ts +222 -0
  1446. package/src/web/scrapers/musicbrainz.ts +250 -0
  1447. package/src/web/scrapers/npm.ts +98 -0
  1448. package/src/web/scrapers/nuget.ts +183 -0
  1449. package/src/web/scrapers/nvd.ts +222 -0
  1450. package/src/web/scrapers/ollama.ts +239 -0
  1451. package/src/web/scrapers/open-vsx.ts +106 -0
  1452. package/src/web/scrapers/opencorporates.ts +292 -0
  1453. package/src/web/scrapers/openlibrary.ts +336 -0
  1454. package/src/web/scrapers/orcid.ts +286 -0
  1455. package/src/web/scrapers/osv.ts +176 -0
  1456. package/src/web/scrapers/packagist.ts +160 -0
  1457. package/src/web/scrapers/pub-dev.ts +143 -0
  1458. package/src/web/scrapers/pubmed.ts +211 -0
  1459. package/src/web/scrapers/pypi.ts +112 -0
  1460. package/src/web/scrapers/rawg.ts +110 -0
  1461. package/src/web/scrapers/readthedocs.ts +120 -0
  1462. package/src/web/scrapers/reddit.ts +95 -0
  1463. package/src/web/scrapers/repology.ts +251 -0
  1464. package/src/web/scrapers/rfc.ts +201 -0
  1465. package/src/web/scrapers/rubygems.ts +103 -0
  1466. package/src/web/scrapers/searchcode.ts +189 -0
  1467. package/src/web/scrapers/sec-edgar.ts +261 -0
  1468. package/src/web/scrapers/semantic-scholar.ts +171 -0
  1469. package/src/web/scrapers/snapcraft.ts +187 -0
  1470. package/src/web/scrapers/sourcegraph.ts +336 -0
  1471. package/src/web/scrapers/spdx.ts +108 -0
  1472. package/src/web/scrapers/spotify.ts +198 -0
  1473. package/src/web/scrapers/stackoverflow.ts +120 -0
  1474. package/src/web/scrapers/terraform.ts +277 -0
  1475. package/src/web/scrapers/tldr.ts +47 -0
  1476. package/src/web/scrapers/twitter.ts +94 -0
  1477. package/src/web/scrapers/types.ts +354 -0
  1478. package/src/web/scrapers/utils.ts +109 -0
  1479. package/src/web/scrapers/vimeo.ts +133 -0
  1480. package/src/web/scrapers/vscode-marketplace.ts +187 -0
  1481. package/src/web/scrapers/w3c.ts +156 -0
  1482. package/src/web/scrapers/wikidata.ts +344 -0
  1483. package/src/web/scrapers/wikipedia.ts +84 -0
  1484. package/src/web/scrapers/youtube.ts +325 -0
  1485. package/src/web/search/index.ts +376 -0
  1486. package/src/web/search/provider.ts +272 -0
  1487. package/src/web/search/providers/anthropic.ts +401 -0
  1488. package/src/web/search/providers/base.ts +110 -0
  1489. package/src/web/search/providers/brave.ts +179 -0
  1490. package/src/web/search/providers/browser-headers.ts +109 -0
  1491. package/src/web/search/providers/browser-page.ts +123 -0
  1492. package/src/web/search/providers/codex.ts +749 -0
  1493. package/src/web/search/providers/duckduckgo.ts +213 -0
  1494. package/src/web/search/providers/ecosia.ts +182 -0
  1495. package/src/web/search/providers/exa.ts +511 -0
  1496. package/src/web/search/providers/firecrawl.ts +211 -0
  1497. package/src/web/search/providers/gemini.ts +628 -0
  1498. package/src/web/search/providers/google.ts +194 -0
  1499. package/src/web/search/providers/jina.ts +134 -0
  1500. package/src/web/search/providers/kagi.ts +95 -0
  1501. package/src/web/search/providers/kimi.ts +217 -0
  1502. package/src/web/search/providers/mojeek.ts +219 -0
  1503. package/src/web/search/providers/parallel.ts +182 -0
  1504. package/src/web/search/providers/perplexity-auth.ts +142 -0
  1505. package/src/web/search/providers/perplexity.ts +994 -0
  1506. package/src/web/search/providers/public.ts +199 -0
  1507. package/src/web/search/providers/searxng.ts +461 -0
  1508. package/src/web/search/providers/startpage.ts +219 -0
  1509. package/src/web/search/providers/synthetic.ts +120 -0
  1510. package/src/web/search/providers/tavily.ts +242 -0
  1511. package/src/web/search/providers/tinyfish.ts +164 -0
  1512. package/src/web/search/providers/utils.ts +128 -0
  1513. package/src/web/search/providers/xai.ts +372 -0
  1514. package/src/web/search/providers/zai.ts +437 -0
  1515. package/src/web/search/query.ts +850 -0
  1516. package/src/web/search/render.ts +262 -0
  1517. package/src/web/search/types.ts +507 -0
  1518. package/src/web/search/utils.ts +17 -0
  1519. package/src/workspace-tree.ts +326 -0
@@ -0,0 +1,1540 @@
1
+ /**
2
+ * Vibe mode worker-session runtime.
3
+ *
4
+ * Owns the persistent, addressable worker sessions ("CLIs") the vibe director
5
+ * drives. Each worker is a real task-executor subagent with full tool access:
6
+ * spawned once through {@link runSubprocess} (keep-alive), continued
7
+ * turn-by-turn through {@link runSubagentFollowUpTurn}. Between turns the
8
+ * worker lives in the AgentRegistry / AgentLifecycleManager as an adopted idle
9
+ * agent (TTL park + JSONL revive), so its conversation context survives across
10
+ * turns and even across parking.
11
+ *
12
+ * Every turn runs as an AsyncJobManager job, so a completed turn self-delivers
13
+ * into the director's conversation exactly like an async `task` result, and
14
+ * `vibe_wait` can block on the first settling turn with `hub`-wait semantics.
15
+ */
16
+ import * as fs from "node:fs/promises";
17
+ import * as os from "node:os";
18
+ import * as path from "node:path";
19
+ import { logger, prompt, Snowflake } from "@oh-my-pi/pi-utils";
20
+ import type { AsyncJob, AsyncJobManager } from "../async/job-manager";
21
+ import { resolveAgentModelPatterns } from "../config/model-resolver";
22
+ import type { LocalProtocolOptions } from "../internal-urls";
23
+ import { registerArtifactsDir } from "../internal-urls/registry-helpers";
24
+ import { MCPManager } from "../mcp/manager";
25
+ import vibeTurnResultTemplate from "../prompts/tools/vibe-turn-result.md" with { type: "text" };
26
+ import { AgentLifecycleManager } from "../registry/agent-lifecycle";
27
+ import { type AgentRef, AgentRegistry, MAIN_AGENT_ID } from "../registry/agent-registry";
28
+ import type { SessionEntry } from "../session/session-entries";
29
+ import { SessionManager, SessionPersistenceIndeterminateError } from "../session/session-manager";
30
+ import { getBundledAgent } from "../task/agents";
31
+ import { type ExecutorOptions, runSubagentFollowUpTurn, runSubprocess } from "../task/executor";
32
+ import { generateTaskName } from "../task/name-generator";
33
+ import { AgentOutputManager } from "../task/output-manager";
34
+ import { type AgentDefinition, type AgentProgress, oneLineLabel, type SingleResult } from "../task/types";
35
+ import type { ToolSession } from "../tools";
36
+ import { formatDuration } from "../tools/render-utils";
37
+ import { ToolError } from "../tools/tool-errors";
38
+ import { calculateTokensPerSecond } from "../utils/token-rate";
39
+
40
+ /** The two worker CLI flavors the director drives. */
41
+ export type VibeCli = "fast" | "good";
42
+
43
+ /**
44
+ * CLI flavor → bundled agent type. This IS the model-tier mapping: `sonic`
45
+ * carries `model: "@smol"` (the configured fast/low-latency role) and `task`
46
+ * carries `model: "@task"` (inherits the session's strong model).
47
+ * Resolution goes through {@link resolveAgentModelPatterns} exactly like a
48
+ * `task` spawn, so `task.agentModelOverrides` and model-role settings apply.
49
+ */
50
+ export const VIBE_CLI_AGENT: Record<VibeCli, string> = {
51
+ fast: "sonic",
52
+ good: "task",
53
+ };
54
+
55
+ /** Worker session lifecycle as shown to the director. */
56
+ export type VibeSessionState = "starting" | "running" | "idle" | "dead";
57
+
58
+ /** One completed tool call in the per-turn activity trace. */
59
+ interface VibeTraceEntry {
60
+ tool: string;
61
+ args: string;
62
+ endMs: number;
63
+ }
64
+
65
+ /** Cap on trace entries retained per turn (the run monitor keeps 5; we widen the window). */
66
+ const TURN_TRACE_CAP = 40;
67
+ /** Cap on a single rendered trace line. */
68
+ const TRACE_LINE_MAX = 120;
69
+ /** Default `vibe_wait` window when no timeout was given (ms). */
70
+ const DEFAULT_WAIT_TIMEOUT_MS = 30_000;
71
+ /** Response text cap inside a delivered turn result; full output stays at agent://<id>. */
72
+ const RESPONSE_PREVIEW_MAX = 6000;
73
+ /** Grace period for abort-aware turns before teardown detaches a stuck provider/tool call. */
74
+ const CANCELLED_TURN_SETTLE_GRACE_MS = 250;
75
+
76
+ const VIBE_LIFECYCLE_CUSTOM_TYPE = "vibe-session-lifecycle";
77
+ const VIBE_LIFECYCLE_VERSION = 1;
78
+
79
+ export interface VibeOwnerScope {
80
+ ownerId: string;
81
+ parentSessionId: string;
82
+ parentSessionFile: string | null;
83
+ }
84
+
85
+ export interface VibeParentSession {
86
+ getAgentId?: () => string | null;
87
+ getSessionId?: () => string | null;
88
+ getSessionFile: () => string | null;
89
+ sessionManager?: ToolSession["sessionManager"] &
90
+ Partial<
91
+ Pick<SessionManager, "appendModeChange" | "appendEntriesAtomically" | "recoverPersistenceFromCurrentState">
92
+ >;
93
+ asyncJobManager?: AsyncJobManager;
94
+ settings: ToolSession["settings"];
95
+ getActiveModelString?: () => string | undefined;
96
+ getModelString?: () => string | undefined;
97
+ }
98
+
99
+ type VibeTombstoneReason = "explicit-kill" | "mode-exit" | "spawn-failed" | "unrecoverable";
100
+
101
+ interface VibeLifecycleBase {
102
+ version: typeof VIBE_LIFECYCLE_VERSION;
103
+ id: string;
104
+ ownerId: string;
105
+ parentSessionId: string;
106
+ }
107
+
108
+ interface VibeSpawnLifecycleEvent extends VibeLifecycleBase {
109
+ action: "spawn";
110
+ cli: VibeCli;
111
+ agent: string;
112
+ childSessionFile: string;
113
+ createdAt: number;
114
+ }
115
+
116
+ interface VibeTurnLifecycleEvent extends VibeLifecycleBase {
117
+ action: "turn-started" | "turn-settled";
118
+ turn: number;
119
+ }
120
+
121
+ interface VibeTombstoneLifecycleEvent extends VibeLifecycleBase {
122
+ action: "tombstone";
123
+ reason: VibeTombstoneReason;
124
+ }
125
+
126
+ interface VibeTombstoneRevocationEvent extends VibeLifecycleBase {
127
+ action: "tombstone-revoked";
128
+ reason: "mode-exit";
129
+ }
130
+
131
+ type VibeLifecycleEvent =
132
+ | VibeSpawnLifecycleEvent
133
+ | VibeTurnLifecycleEvent
134
+ | VibeTombstoneLifecycleEvent
135
+ | VibeTombstoneRevocationEvent;
136
+
137
+ interface VibeRestoreCandidate {
138
+ spawn: VibeSpawnLifecycleEvent;
139
+ turnCount: number;
140
+ lastActivityAt: number;
141
+ inFlight: boolean;
142
+ tombstoneReason?: VibeTombstoneReason;
143
+ }
144
+
145
+ interface ResolvedVibeWorker {
146
+ agent: AgentDefinition;
147
+ modelOverride?: string | string[];
148
+ }
149
+
150
+ interface VibeTurn {
151
+ jobId: string;
152
+ message: string;
153
+ startedAt: number;
154
+ /** Trace of tool calls completed during this turn, oldest first. */
155
+ trace: VibeTraceEntry[];
156
+ /** Total completed tool calls (trace may be narrower than this). */
157
+ toolCount: number;
158
+ }
159
+
160
+ interface VibeRecord {
161
+ id: string;
162
+ cli: VibeCli;
163
+ ownerId: string;
164
+ parentSessionId: string;
165
+ parentSessionFile: string | null;
166
+ childSessionFile?: string;
167
+ agent: AgentDefinition;
168
+ modelOverride?: string | string[];
169
+ state: VibeSessionState;
170
+ createdAt: number;
171
+ lastActivityAt: number;
172
+ /** One-line gist of the latest activity (intent, tool, or result preview). */
173
+ lastActivity?: string;
174
+ /** Resolved model display string once known. */
175
+ resolvedModel?: string;
176
+ turn?: VibeTurn;
177
+ /** Live view of the in-flight turn (current tool, intent, streamed text tail). */
178
+ live?: {
179
+ currentTool?: string;
180
+ currentToolArgs?: string;
181
+ lastIntent?: string;
182
+ /** Latest streamed assistant text lines, oldest first. */
183
+ outputTail: string[];
184
+ };
185
+ /** Job id of the most recently settled turn (wait snapshots after settle). */
186
+ lastJobId?: string;
187
+ /** Messages queued while a turn was in flight; drained into the next turn. */
188
+ queue: string[];
189
+ turnCount: number;
190
+ killed: boolean;
191
+ /** True while a parent switch is detaching this process-local record without terminating it. */
192
+ suspended: boolean;
193
+ /** True only after a terminal lifecycle event has durably flushed. */
194
+ terminalPersisted: boolean;
195
+ }
196
+
197
+ /**
198
+ * Live per-session "screen" for rich rendering: what the worker is doing right
199
+ * now (tool trace, current tool, streamed text tail) plus roster metadata.
200
+ * Every string is already one-line sanitized.
201
+ */
202
+ export interface VibeScreenSnapshot {
203
+ id: string;
204
+ cli: VibeCli;
205
+ state: VibeSessionState;
206
+ model?: string;
207
+ turns: number;
208
+ queued: number;
209
+ /** Start of the in-flight turn, when running. */
210
+ turnStartedAt?: number;
211
+ /** Gist of the message that started the in-flight turn. */
212
+ turnMessage?: string;
213
+ currentTool?: string;
214
+ currentToolArgs?: string;
215
+ lastIntent?: string;
216
+ /** Completed tool calls of the in-flight turn, oldest first (tail). */
217
+ trace: string[];
218
+ /** Latest streamed worker text lines, oldest first. */
219
+ outputTail: string[];
220
+ lastActivity?: string;
221
+ lastActivityAt: number;
222
+ }
223
+
224
+ export interface VibeSpawnOutcome {
225
+ id: string;
226
+ jobId: string;
227
+ }
228
+
229
+ export interface VibeSendOutcome {
230
+ id: string;
231
+ /**
232
+ * - `turn`: a new background turn was started (`jobId` set).
233
+ * - `steered`: worker was mid-turn and streaming; delivered as steering.
234
+ * - `queued`: worker was mid-turn but not steerable; drained into the next turn.
235
+ */
236
+ mode: "turn" | "steered" | "queued";
237
+ jobId?: string;
238
+ }
239
+
240
+ export interface VibeKillOutcome {
241
+ id: string;
242
+ /** True when an in-flight turn job was cancelled along the way. */
243
+ cancelledTurn: boolean;
244
+ }
245
+
246
+ export interface VibeWaitOutcome {
247
+ /** Watched sessions whose snapshotted turn settled during (or before) the wait.
248
+ * May overlap `stillRunning` when a queued follow-up turn already started. */
249
+ settled: Array<{ id: string; jobId: string; status: "completed" | "failed" | "cancelled"; resultText: string }>;
250
+ /** Watched sessions with a turn in flight when the wait returned. */
251
+ stillRunning: string[];
252
+ timedOut: boolean;
253
+ }
254
+
255
+ /** Normalize a text fragment to one bounded roster/trace line. */
256
+ function firstLine(text: string, max = 100): string {
257
+ return oneLineLabel(text, max);
258
+ }
259
+
260
+ function scopeKey(scope: VibeOwnerScope, id: string): string {
261
+ return `${scope.parentSessionId}\0${scope.parentSessionFile ?? ""}\0${scope.ownerId}\0${id}`;
262
+ }
263
+
264
+ function matchesScope(record: VibeRecord, scope: VibeOwnerScope): boolean {
265
+ return (
266
+ record.ownerId === scope.ownerId &&
267
+ record.parentSessionId === scope.parentSessionId &&
268
+ record.parentSessionFile === scope.parentSessionFile
269
+ );
270
+ }
271
+
272
+ function objectRecord(value: unknown): Record<string, unknown> | undefined {
273
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return undefined;
274
+ return value as Record<string, unknown>;
275
+ }
276
+
277
+ function parseLifecycleEvent(value: unknown): VibeLifecycleEvent | undefined {
278
+ const data = objectRecord(value);
279
+ if (!data || data.version !== VIBE_LIFECYCLE_VERSION) return undefined;
280
+ if (typeof data.id !== "string" || !data.id) return undefined;
281
+ if (typeof data.ownerId !== "string" || !data.ownerId) return undefined;
282
+ if (typeof data.parentSessionId !== "string" || !data.parentSessionId) return undefined;
283
+ const base: VibeLifecycleBase = {
284
+ version: VIBE_LIFECYCLE_VERSION,
285
+ id: data.id,
286
+ ownerId: data.ownerId,
287
+ parentSessionId: data.parentSessionId,
288
+ };
289
+ if (data.action === "spawn") {
290
+ const cli = data.cli === "fast" || data.cli === "good" ? data.cli : undefined;
291
+ if (!cli || typeof data.agent !== "string" || typeof data.childSessionFile !== "string") return undefined;
292
+ if (typeof data.createdAt !== "number" || !Number.isFinite(data.createdAt)) return undefined;
293
+ return {
294
+ ...base,
295
+ action: "spawn",
296
+ cli,
297
+ agent: data.agent,
298
+ childSessionFile: data.childSessionFile,
299
+ createdAt: data.createdAt,
300
+ };
301
+ }
302
+ if (data.action === "turn-started" || data.action === "turn-settled") {
303
+ if (typeof data.turn !== "number" || !Number.isInteger(data.turn) || data.turn < 1) return undefined;
304
+ return { ...base, action: data.action, turn: data.turn };
305
+ }
306
+ if (data.action === "tombstone") {
307
+ const reason = data.reason;
308
+ if (
309
+ reason !== "explicit-kill" &&
310
+ reason !== "mode-exit" &&
311
+ reason !== "spawn-failed" &&
312
+ reason !== "unrecoverable"
313
+ ) {
314
+ return undefined;
315
+ }
316
+ return { ...base, action: "tombstone", reason };
317
+ }
318
+ if (data.action === "tombstone-revoked" && data.reason === "mode-exit") {
319
+ return { ...base, action: "tombstone-revoked", reason: "mode-exit" };
320
+ }
321
+ return undefined;
322
+ }
323
+
324
+ /** Child ids claimed by any valid Vibe spawn event, independent of current parent scope. */
325
+ export function persistedVibeChildIds(entries: Iterable<SessionEntry>): Set<string> {
326
+ const ids = new Set<string>();
327
+ for (const entry of entries) {
328
+ if (entry.type !== "custom" || entry.customType !== VIBE_LIFECYCLE_CUSTOM_TYPE) continue;
329
+ const event = parseLifecycleEvent(entry.data);
330
+ if (
331
+ event?.action === "spawn" &&
332
+ /^[A-Za-z0-9_-]+$/.test(event.id) &&
333
+ event.childSessionFile === `${event.id}.jsonl`
334
+ ) {
335
+ ids.add(event.id);
336
+ }
337
+ }
338
+ return ids;
339
+ }
340
+
341
+ /** Merge the monitor's rolling `recentTools` window (newest first) into the per-turn trace (oldest first). */
342
+ function mergeTrace(turn: VibeTurn, progress: AgentProgress): void {
343
+ turn.toolCount = progress.toolCount;
344
+ for (let i = progress.recentTools.length - 1; i >= 0; i--) {
345
+ const entry = progress.recentTools[i];
346
+ if (turn.trace.some(seen => seen.endMs === entry.endMs && seen.tool === entry.tool && seen.args === entry.args)) {
347
+ continue;
348
+ }
349
+ turn.trace.push({ tool: entry.tool, args: entry.args, endMs: entry.endMs });
350
+ if (turn.trace.length > TURN_TRACE_CAP) turn.trace.shift();
351
+ }
352
+ }
353
+
354
+ /** Thrown from a turn job body so the job manager marks the job failed while carrying the formatted result. */
355
+ export class VibeTurnError extends Error {}
356
+
357
+ async function awaitCancelledTurnJobs(jobs: ReadonlySet<AsyncJob>): Promise<void> {
358
+ if (jobs.size === 0) return;
359
+ const settled = Promise.allSettled([...jobs].map(job => job.promise)).then(() => true);
360
+ const timeout = Promise.withResolvers<false>();
361
+ const timer = setTimeout(() => timeout.resolve(false), CANCELLED_TURN_SETTLE_GRACE_MS);
362
+ timer.unref();
363
+ try {
364
+ if (!(await Promise.race([settled, timeout.promise]))) {
365
+ logger.warn("vibe: detached cancelled turn that did not settle within teardown grace period", {
366
+ jobCount: jobs.size,
367
+ graceMs: CANCELLED_TURN_SETTLE_GRACE_MS,
368
+ });
369
+ }
370
+ } finally {
371
+ clearTimeout(timer);
372
+ }
373
+ }
374
+
375
+ /**
376
+ * Process-global registry of vibe worker sessions, scoped by both owner agent
377
+ * id and stable parent session id. Persisted lifecycle events rebuild idle
378
+ * records after a process restart; live turn jobs remain process-local.
379
+ */
380
+ export class VibeSessionRegistry {
381
+ static #global: VibeSessionRegistry | undefined;
382
+
383
+ static global(): VibeSessionRegistry {
384
+ if (!VibeSessionRegistry.#global) {
385
+ VibeSessionRegistry.#global = new VibeSessionRegistry();
386
+ }
387
+ return VibeSessionRegistry.#global;
388
+ }
389
+
390
+ /** Reset the global registry. Test-only. */
391
+ static resetGlobalForTests(): void {
392
+ VibeSessionRegistry.#global = undefined;
393
+ }
394
+
395
+ /**
396
+ * Insert a bare worker record without the spawn/job machinery. Test-only —
397
+ * lets {@link aggregateVibeWorkerTokensPerSecond} be exercised against a
398
+ * fake roster + AgentRegistry session without driving a real turn.
399
+ */
400
+ registerRecordForTests(record: { id: string; cli?: VibeCli; ownerId: string; state?: VibeSessionState }): void {
401
+ this.#records.set(record.id, {
402
+ id: record.id,
403
+ cli: record.cli ?? "fast",
404
+ ownerId: record.ownerId,
405
+ parentSessionId: "test-parent-session",
406
+ parentSessionFile: null,
407
+ agent: getBundledAgent("sonic")!,
408
+ state: record.state ?? "running",
409
+ createdAt: Date.now(),
410
+ lastActivityAt: Date.now(),
411
+ queue: [],
412
+ turnCount: 0,
413
+ killed: false,
414
+ suspended: false,
415
+ terminalPersisted: false,
416
+ });
417
+ }
418
+
419
+ readonly #records = new Map<string, VibeRecord>();
420
+ readonly #terminationTails = new Map<string, Promise<void>>();
421
+ readonly #terminatedScopes = new Set<string>();
422
+
423
+ ownerScope(session: VibeParentSession): VibeOwnerScope {
424
+ const parentSessionId = session.getSessionId?.();
425
+ if (!parentSessionId) {
426
+ throw new ToolError("Vibe sessions require a stable parent session id.");
427
+ }
428
+ const parentSessionFile = session.getSessionFile();
429
+ return {
430
+ ownerId: session.getAgentId?.() ?? MAIN_AGENT_ID,
431
+ parentSessionId,
432
+ parentSessionFile: parentSessionFile ? path.resolve(parentSessionFile) : null,
433
+ };
434
+ }
435
+
436
+ /** Re-open spawn admission after an explicit Vibe-mode entry. */
437
+ activateScope(scope: VibeOwnerScope): void {
438
+ this.#terminatedScopes.delete(scopeKey(scope, ""));
439
+ }
440
+
441
+ async #withTerminationLock<T>(scope: VibeOwnerScope, operation: () => Promise<T>): Promise<T> {
442
+ const key = scopeKey(scope, "");
443
+ const predecessor = this.#terminationTails.get(key) ?? Promise.resolve();
444
+ const released = Promise.withResolvers<void>();
445
+ const tail = predecessor.then(() => released.promise);
446
+ this.#terminationTails.set(key, tail);
447
+ await predecessor;
448
+ try {
449
+ return await operation();
450
+ } finally {
451
+ released.resolve();
452
+ if (this.#terminationTails.get(key) === tail) this.#terminationTails.delete(key);
453
+ }
454
+ }
455
+
456
+ #resolveWorker(session: VibeParentSession, cli: VibeCli): ResolvedVibeWorker {
457
+ const agentName = VIBE_CLI_AGENT[cli];
458
+ const agent = getBundledAgent(agentName);
459
+ if (!agent) {
460
+ throw new ToolError(`Bundled agent "${agentName}" for vibe cli "${cli}" is unavailable.`);
461
+ }
462
+ const agentModelOverrides = session.settings.get("task.agentModelOverrides");
463
+ return {
464
+ agent,
465
+ modelOverride: resolveAgentModelPatterns({
466
+ settingsOverride: agentModelOverrides[agentName],
467
+ agentModel: agent.model,
468
+ settings: session.settings,
469
+ activeModelPattern: session.getActiveModelString?.(),
470
+ fallbackModelPattern: session.getModelString?.(),
471
+ }),
472
+ };
473
+ }
474
+
475
+ async #appendLifecycleEvent(
476
+ session: VibeParentSession,
477
+ event: VibeLifecycleEvent,
478
+ expectedParentSessionFile: string | null,
479
+ ): Promise<boolean> {
480
+ if (!expectedParentSessionFile || !session.sessionManager) return false;
481
+ const matchesCurrentScope = (): boolean => {
482
+ const currentSessionFile = session.getSessionFile();
483
+ return (
484
+ session.getSessionId?.() === event.parentSessionId &&
485
+ (session.getAgentId?.() ?? MAIN_AGENT_ID) === event.ownerId &&
486
+ currentSessionFile !== null &&
487
+ path.resolve(currentSessionFile) === expectedParentSessionFile
488
+ );
489
+ };
490
+ if (!matchesCurrentScope()) return false;
491
+ await session.sessionManager.ensureOnDisk();
492
+ if (!matchesCurrentScope()) return false;
493
+ session.sessionManager.appendCustomEntry(VIBE_LIFECYCLE_CUSTOM_TYPE, event);
494
+ await session.sessionManager.flush();
495
+ return true;
496
+ }
497
+
498
+ #eventBase(record: VibeRecord): VibeLifecycleBase {
499
+ return {
500
+ version: VIBE_LIFECYCLE_VERSION,
501
+ id: record.id,
502
+ ownerId: record.ownerId,
503
+ parentSessionId: record.parentSessionId,
504
+ };
505
+ }
506
+
507
+ async #appendTombstone(
508
+ session: VibeParentSession,
509
+ record: VibeRecord,
510
+ reason: VibeTombstoneReason,
511
+ ): Promise<boolean> {
512
+ return this.#appendLifecycleEvent(
513
+ session,
514
+ {
515
+ ...this.#eventBase(record),
516
+ action: "tombstone",
517
+ reason,
518
+ },
519
+ record.parentSessionFile,
520
+ );
521
+ }
522
+
523
+ #hasInMemoryTombstone(session: VibeParentSession, record: VibeRecord): boolean {
524
+ let terminalReason: VibeTombstoneReason | undefined;
525
+ for (const entry of session.sessionManager?.getEntries() ?? []) {
526
+ if (entry.type !== "custom" || entry.customType !== VIBE_LIFECYCLE_CUSTOM_TYPE) continue;
527
+ const event = parseLifecycleEvent(entry.data);
528
+ if (
529
+ !event ||
530
+ event.id !== record.id ||
531
+ event.ownerId !== record.ownerId ||
532
+ event.parentSessionId !== record.parentSessionId
533
+ ) {
534
+ continue;
535
+ }
536
+ if (event.action === "tombstone") terminalReason = event.reason;
537
+ else if (event.action === "tombstone-revoked" && terminalReason === "mode-exit") terminalReason = undefined;
538
+ }
539
+ return terminalReason !== undefined;
540
+ }
541
+
542
+ async #persistModeExit(
543
+ session: VibeParentSession,
544
+ scope: VibeOwnerScope,
545
+ records: readonly VibeRecord[],
546
+ ): Promise<void> {
547
+ const pending = records.filter(record => !record.terminalPersisted);
548
+ const sessionManager = session.sessionManager;
549
+ if (!sessionManager) {
550
+ if (pending.some(record => record.childSessionFile)) {
551
+ throw new ToolError("Vibe mode exit cannot persist worker tombstones without the parent session manager.");
552
+ }
553
+ for (const record of pending) record.terminalPersisted = true;
554
+ return;
555
+ }
556
+ const currentScope = this.ownerScope(session);
557
+ if (
558
+ currentScope.ownerId !== scope.ownerId ||
559
+ currentScope.parentSessionId !== scope.parentSessionId ||
560
+ currentScope.parentSessionFile !== scope.parentSessionFile
561
+ ) {
562
+ throw new ToolError("Vibe parent session changed before mode exit could be persisted.");
563
+ }
564
+ const parentSessionFile = currentScope.parentSessionFile;
565
+ const persistedPending = pending.filter(record => record.childSessionFile !== undefined);
566
+ for (const record of persistedPending) {
567
+ if (
568
+ !parentSessionFile ||
569
+ path.resolve(parentSessionFile.slice(0, -6), `${record.id}.jsonl`) !== record.childSessionFile
570
+ ) {
571
+ throw new ToolError(`Vibe session "${record.id}" changed parent scope before termination.`);
572
+ }
573
+ }
574
+ const appendEntriesAtomically = sessionManager.appendEntriesAtomically;
575
+ if (!appendEntriesAtomically) {
576
+ throw new ToolError("Vibe mode exit requires atomic parent-session persistence.");
577
+ }
578
+ await appendEntriesAtomically.call(sessionManager, () => {
579
+ for (const record of persistedPending) {
580
+ sessionManager.appendCustomEntry(VIBE_LIFECYCLE_CUSTOM_TYPE, {
581
+ ...this.#eventBase(record),
582
+ action: "tombstone",
583
+ reason: "mode-exit",
584
+ });
585
+ }
586
+ sessionManager.appendModeChange?.("none");
587
+ });
588
+ for (const record of pending) record.terminalPersisted = true;
589
+ }
590
+
591
+ #manager(session: ToolSession): AsyncJobManager {
592
+ const manager = session.asyncJobManager;
593
+ if (!manager) {
594
+ throw new ToolError("Vibe sessions require async execution (no background job manager is available).");
595
+ }
596
+ return manager;
597
+ }
598
+
599
+ #record(scope: VibeOwnerScope, id: string): VibeRecord {
600
+ const record = this.#records.get(scopeKey(scope, id.trim()));
601
+ if (!record || !matchesScope(record, scope)) {
602
+ const roster = this.#listIds(scope);
603
+ throw new ToolError(
604
+ `Unknown vibe session "${id}".${roster.length > 0 ? ` Active sessions: ${roster.join(", ")}` : " No sessions — spawn one with vibe_spawn."}`,
605
+ );
606
+ }
607
+ return record;
608
+ }
609
+
610
+ #registeredAgent(record: VibeRecord): AgentRef | undefined {
611
+ const ref = AgentRegistry.global().get(record.id);
612
+ if (ref?.kind !== "sub" || ref.parentId !== record.ownerId) return undefined;
613
+ if (record.childSessionFile && ref.sessionFile !== record.childSessionFile) return undefined;
614
+ return ref;
615
+ }
616
+
617
+ #listIds(scope: VibeOwnerScope): string[] {
618
+ const ids: string[] = [];
619
+ for (const record of this.#records.values()) {
620
+ if (matchesScope(record, scope) && record.state !== "dead") ids.push(record.id);
621
+ }
622
+ return ids;
623
+ }
624
+
625
+ listIds(session: ToolSession): string[] {
626
+ return this.#listIds(this.ownerScope(session));
627
+ }
628
+
629
+ /** Ids of every live worker owned by `ownerId`, across all parent scopes (status-line tok/s aggregation). */
630
+ listIdsByOwner(ownerId: string): string[] {
631
+ const ids: string[] = [];
632
+ for (const record of this.#records.values()) {
633
+ if (record.ownerId === ownerId && record.state !== "dead") ids.push(record.id);
634
+ }
635
+ return ids;
636
+ }
637
+
638
+ /**
639
+ * Live screen snapshots for rich rendering (the "TV wall"): one entry per
640
+ * session in creation order, carrying the in-flight turn's trace, current
641
+ * tool, and streamed text tail. All strings are one-line sanitized here so
642
+ * renderers can print them verbatim.
643
+ */
644
+ screens(session: ToolSession, ids?: string[]): VibeScreenSnapshot[] {
645
+ const scope = this.ownerScope(session);
646
+ const wanted = ids?.length ? new Set(ids.map(id => id.trim())) : undefined;
647
+ const records: VibeRecord[] = [];
648
+ for (const record of this.#records.values()) {
649
+ if (!matchesScope(record, scope)) continue;
650
+ if (wanted && !wanted.has(record.id)) continue;
651
+ records.push(record);
652
+ }
653
+ // Stable TV-wall ordering: spawn order, not activity order.
654
+ records.sort((a, b) => a.createdAt - b.createdAt);
655
+ return records.map(record => ({
656
+ id: record.id,
657
+ cli: record.cli,
658
+ state: record.state,
659
+ model: record.resolvedModel,
660
+ turns: record.turnCount,
661
+ queued: record.queue.length,
662
+ turnStartedAt: record.turn?.startedAt,
663
+ turnMessage: record.turn ? firstLine(record.turn.message, 80) : undefined,
664
+ currentTool: record.live?.currentTool,
665
+ currentToolArgs: record.live?.currentToolArgs ? firstLine(record.live.currentToolArgs, 60) : undefined,
666
+ lastIntent: record.live?.lastIntent ? firstLine(record.live.lastIntent, 80) : undefined,
667
+ trace: record.turn
668
+ ? record.turn.trace
669
+ .slice(-6)
670
+ .map(entry => firstLine(`${entry.tool}${entry.args ? `(${entry.args})` : ""}`, TRACE_LINE_MAX))
671
+ : [],
672
+ outputTail: (record.live?.outputTail ?? []).map(line => firstLine(line, 100)),
673
+ lastActivity: record.lastActivity,
674
+ lastActivityAt: record.lastActivityAt,
675
+ }));
676
+ }
677
+
678
+ #persistedIds(session: VibeParentSession, scope: VibeOwnerScope): Set<string> {
679
+ const ids = new Set<string>();
680
+ for (const entry of session.sessionManager?.getEntries() ?? []) {
681
+ if (entry.type !== "custom" || entry.customType !== VIBE_LIFECYCLE_CUSTOM_TYPE) continue;
682
+ const event = parseLifecycleEvent(entry.data);
683
+ if (event?.ownerId === scope.ownerId && event.parentSessionId === scope.parentSessionId) ids.add(event.id);
684
+ }
685
+ for (const record of this.#records.values()) {
686
+ if (matchesScope(record, scope)) ids.add(record.id);
687
+ }
688
+ return ids;
689
+ }
690
+
691
+ async #resolvePersistedChild(
692
+ parentSessionFile: string,
693
+ spawn: VibeSpawnLifecycleEvent,
694
+ options?: { requireAgentMatch?: boolean },
695
+ ): Promise<string | undefined> {
696
+ if (options?.requireAgentMatch !== false && spawn.agent !== VIBE_CLI_AGENT[spawn.cli]) return undefined;
697
+ if (!/^[A-Za-z0-9_-]+$/.test(spawn.id) || spawn.childSessionFile !== `${spawn.id}.jsonl`) return undefined;
698
+ const artifactsDir = path.resolve(parentSessionFile.slice(0, -6));
699
+ const childSessionFile = path.resolve(artifactsDir, spawn.childSessionFile);
700
+ const relative = path.relative(artifactsDir, childSessionFile);
701
+ if (!relative || path.isAbsolute(relative) || relative.startsWith(`..${path.sep}`) || relative === "..") {
702
+ return undefined;
703
+ }
704
+ try {
705
+ const persisted = await SessionManager.peekSessionInit(childSessionFile);
706
+ return persisted?.init ? childSessionFile : undefined;
707
+ } catch {
708
+ return undefined;
709
+ }
710
+ }
711
+
712
+ async #markTerminalRef(
713
+ id: string,
714
+ ownerId: string,
715
+ childSessionFile: string,
716
+ expected?: AgentRef | null,
717
+ ): Promise<void> {
718
+ const registry = AgentRegistry.global();
719
+ const existing = registry.get(id);
720
+ if (expected !== undefined && existing !== undefined && existing !== expected) return;
721
+ if (
722
+ existing &&
723
+ (existing.kind !== "sub" || existing.parentId !== ownerId || existing.sessionFile !== childSessionFile)
724
+ ) {
725
+ return;
726
+ }
727
+ if (existing?.status === "aborted" && !existing.session) return;
728
+ if (existing && !registry.setStatus(id, "aborted", existing)) return;
729
+ if (existing && AgentLifecycleManager.global().has(id, existing)) {
730
+ await AgentLifecycleManager.global().release(id, existing);
731
+ } else if (existing?.session) {
732
+ await existing.session.dispose();
733
+ }
734
+ const current = registry.get(id);
735
+ if (current && current !== existing) return;
736
+ if (current) registry.unregister(id, current);
737
+ registry.register({
738
+ id,
739
+ displayName: id,
740
+ kind: "sub",
741
+ parentId: ownerId,
742
+ session: null,
743
+ sessionFile: childSessionFile,
744
+ status: "aborted",
745
+ });
746
+ }
747
+
748
+ /** Reconcile resumable and terminal workers from the persisted parent journal. */
749
+ async rehydrate(session: VibeParentSession): Promise<number> {
750
+ const sessionFile = session.getSessionFile();
751
+ const sessionManager = session.sessionManager;
752
+ if (!sessionFile || !sessionManager) return 0;
753
+ const scope = this.ownerScope(session);
754
+ const allSpawns = new Map<string, VibeSpawnLifecycleEvent>();
755
+ const terminalIntents = new Map<string, VibeTombstoneReason>();
756
+ for (const entry of sessionManager.getEntries()) {
757
+ if (entry.type !== "custom" || entry.customType !== VIBE_LIFECYCLE_CUSTOM_TYPE) continue;
758
+ const event = parseLifecycleEvent(entry.data);
759
+ if (!event || event.ownerId !== scope.ownerId || event.parentSessionId !== scope.parentSessionId) continue;
760
+ if (event.action === "spawn") allSpawns.set(event.id, event);
761
+ else if (event.action === "tombstone") terminalIntents.set(event.id, event.reason);
762
+ else if (event.action === "tombstone-revoked" && terminalIntents.get(event.id) === "mode-exit") {
763
+ terminalIntents.delete(event.id);
764
+ }
765
+ }
766
+
767
+ const candidates = new Map<string, VibeRestoreCandidate>();
768
+ for (const entry of sessionManager.getBranch()) {
769
+ if (entry.type !== "custom" || entry.customType !== VIBE_LIFECYCLE_CUSTOM_TYPE) continue;
770
+ const event = parseLifecycleEvent(entry.data);
771
+ if (!event || event.ownerId !== scope.ownerId || event.parentSessionId !== scope.parentSessionId) continue;
772
+ const eventTime = Date.parse(entry.timestamp);
773
+ if (event.action === "spawn") {
774
+ candidates.set(event.id, {
775
+ spawn: event,
776
+ turnCount: 0,
777
+ lastActivityAt: Number.isFinite(eventTime) ? eventTime : event.createdAt,
778
+ inFlight: false,
779
+ });
780
+ continue;
781
+ }
782
+ const candidate = candidates.get(event.id);
783
+ if (!candidate) continue;
784
+ candidate.lastActivityAt = Number.isFinite(eventTime) ? eventTime : candidate.lastActivityAt;
785
+ if (event.action === "turn-started" && event.turn >= candidate.turnCount) {
786
+ candidate.turnCount = event.turn;
787
+ candidate.inFlight = true;
788
+ } else if (event.action === "turn-settled" && event.turn >= candidate.turnCount) {
789
+ candidate.turnCount = event.turn;
790
+ candidate.inFlight = false;
791
+ } else if (event.action === "tombstone") {
792
+ candidate.tombstoneReason = event.reason;
793
+ } else if (event.action === "tombstone-revoked" && candidate.tombstoneReason === "mode-exit") {
794
+ candidate.tombstoneReason = undefined;
795
+ }
796
+ }
797
+
798
+ for (const id of terminalIntents.keys()) {
799
+ const spawn = allSpawns.get(id);
800
+ if (!spawn) continue;
801
+ const childSessionFile = await this.#resolvePersistedChild(sessionFile, spawn, { requireAgentMatch: false });
802
+ if (!childSessionFile) continue;
803
+ await this.#markTerminalRef(id, scope.ownerId, childSessionFile);
804
+ this.#records.delete(scopeKey(scope, id));
805
+ }
806
+
807
+ let restored = 0;
808
+ for (const candidate of candidates.values()) {
809
+ const { spawn } = candidate;
810
+ if (candidate.tombstoneReason || terminalIntents.has(spawn.id) || candidate.turnCount < 1) continue;
811
+ const childSessionFile = await this.#resolvePersistedChild(sessionFile, spawn);
812
+ if (!childSessionFile) continue;
813
+ const key = scopeKey(scope, spawn.id);
814
+ if (this.#records.has(key)) continue;
815
+ const existing = AgentRegistry.global().get(spawn.id);
816
+ const existingIsResumable =
817
+ existing?.kind === "sub" &&
818
+ existing.parentId === scope.ownerId &&
819
+ existing.sessionFile === childSessionFile &&
820
+ (existing.status === "idle" || existing.status === "parked");
821
+ const blockedByCollision = Boolean(existing && !existingIsResumable);
822
+ const { agent, modelOverride } = this.#resolveWorker(session, spawn.cli);
823
+ if (!existing) {
824
+ AgentRegistry.global().register({
825
+ id: spawn.id,
826
+ displayName: spawn.id,
827
+ kind: "sub",
828
+ parentId: scope.ownerId,
829
+ session: null,
830
+ sessionFile: childSessionFile,
831
+ status: "parked",
832
+ });
833
+ }
834
+ this.#records.set(key, {
835
+ id: spawn.id,
836
+ cli: spawn.cli,
837
+ ownerId: scope.ownerId,
838
+ parentSessionId: scope.parentSessionId,
839
+ parentSessionFile: scope.parentSessionFile,
840
+ childSessionFile,
841
+ agent,
842
+ modelOverride,
843
+ state: "idle",
844
+ createdAt: spawn.createdAt,
845
+ lastActivityAt: candidate.lastActivityAt,
846
+ lastActivity: blockedByCollision
847
+ ? "blocked by an agent id collision"
848
+ : candidate.inFlight
849
+ ? `turn ${candidate.turnCount} interrupted by process restart`
850
+ : undefined,
851
+ queue: [],
852
+ turnCount: candidate.turnCount,
853
+ killed: false,
854
+ suspended: false,
855
+ terminalPersisted: false,
856
+ });
857
+ restored++;
858
+ }
859
+ return restored;
860
+ }
861
+
862
+ /** Spawn a persistent worker session and start its first turn in the background. */
863
+ async spawn(session: ToolSession, args: { cli: VibeCli; name?: string; prompt: string }): Promise<VibeSpawnOutcome> {
864
+ const scope = this.ownerScope(session);
865
+ return this.#withTerminationLock(scope, () => this.#spawnLocked(session, scope, args));
866
+ }
867
+
868
+ async #spawnLocked(
869
+ session: ToolSession,
870
+ scope: VibeOwnerScope,
871
+ args: { cli: VibeCli; name?: string; prompt: string },
872
+ ): Promise<VibeSpawnOutcome> {
873
+ if (this.#terminatedScopes.has(scopeKey(scope, ""))) {
874
+ throw new ToolError("Vibe mode has exited; enter Vibe mode again before spawning a worker.");
875
+ }
876
+ const manager = this.#manager(session);
877
+ const { agent, modelOverride } = this.#resolveWorker(session, args.cli);
878
+ if (!session.agentOutputManager) {
879
+ session.agentOutputManager = new AgentOutputManager(session.getArtifactsDir ?? (() => null));
880
+ }
881
+ const reservedIds = this.#persistedIds(session, scope);
882
+ for (const ref of AgentRegistry.global().list()) reservedIds.add(ref.id);
883
+ await session.agentOutputManager.reserve(reservedIds);
884
+ const requestedName = args.name?.replace(/[^A-Za-z0-9_-]+/g, "").slice(0, 48);
885
+ const id = await session.agentOutputManager.allocate(requestedName || generateTaskName());
886
+ const parentSessionFile = scope.parentSessionFile;
887
+ const childSessionName = `${id}.jsonl`;
888
+ const childSessionFile = parentSessionFile
889
+ ? path.resolve(parentSessionFile.slice(0, -6), childSessionName)
890
+ : undefined;
891
+ const createdAt = Date.now();
892
+ const record: VibeRecord = {
893
+ id,
894
+ cli: args.cli,
895
+ ownerId: scope.ownerId,
896
+ parentSessionId: scope.parentSessionId,
897
+ parentSessionFile,
898
+ childSessionFile,
899
+ agent,
900
+ modelOverride,
901
+ state: "starting",
902
+ createdAt,
903
+ lastActivityAt: createdAt,
904
+ queue: [],
905
+ turnCount: 0,
906
+ killed: false,
907
+ suspended: false,
908
+ terminalPersisted: false,
909
+ };
910
+ const key = scopeKey(scope, id);
911
+ this.#records.set(key, record);
912
+ let spawnPersisted = false;
913
+ try {
914
+ if (childSessionFile) {
915
+ spawnPersisted = await this.#appendLifecycleEvent(
916
+ session,
917
+ {
918
+ ...this.#eventBase(record),
919
+ action: "spawn",
920
+ cli: args.cli,
921
+ agent: agent.name,
922
+ childSessionFile: childSessionName,
923
+ createdAt,
924
+ },
925
+ record.parentSessionFile,
926
+ );
927
+ if (!spawnPersisted) throw new ToolError("Vibe parent session changed before the worker could start.");
928
+ }
929
+ const jobId = this.#registerTurnJob(session, manager, record, args.prompt, { first: true });
930
+ return { id, jobId };
931
+ } catch (error) {
932
+ record.killed = true;
933
+ record.state = "dead";
934
+ record.lastActivityAt = Date.now();
935
+ record.lastActivity = "spawn failed";
936
+ if (childSessionFile) {
937
+ // A rejected terminal write leaves this dead record in the map so mode exit can retry it.
938
+ record.terminalPersisted = await this.#appendTombstone(session, record, "spawn-failed");
939
+ if (!record.terminalPersisted) {
940
+ throw new ToolError("Vibe parent session changed before spawn failure could be persisted.");
941
+ }
942
+ }
943
+ this.#records.delete(key);
944
+ throw error;
945
+ }
946
+ }
947
+
948
+ /**
949
+ * Send a message to a worker. Mid-turn and streaming → steering; mid-turn
950
+ * otherwise → queued for the next turn; idle/parked → starts a new
951
+ * background turn immediately.
952
+ */
953
+ async send(session: ToolSession, args: { session: string; message: string }): Promise<VibeSendOutcome> {
954
+ const scope = this.ownerScope(session);
955
+ const record = this.#record(scope, args.session);
956
+ if (record.state === "dead") {
957
+ throw new ToolError(`Vibe session "${record.id}" is dead. Spawn a new one with vibe_spawn.`);
958
+ }
959
+ const message = args.message.trim();
960
+ if (!message) throw new ToolError("Message must not be empty.");
961
+ const registered = this.#registeredAgent(record);
962
+ if (AgentRegistry.global().get(record.id) && !registered) {
963
+ throw new ToolError(`Vibe session "${record.id}" no longer resolves to this parent session.`);
964
+ }
965
+
966
+ if (record.turn) {
967
+ const live = registered?.session;
968
+ if (live?.isStreaming) {
969
+ await live.steer(message);
970
+ record.lastActivityAt = Date.now();
971
+ return { id: record.id, mode: "steered" };
972
+ }
973
+ record.queue.push(message);
974
+ record.lastActivityAt = Date.now();
975
+ return { id: record.id, mode: "queued" };
976
+ }
977
+
978
+ if (!registered || (registered.status !== "idle" && registered.status !== "parked")) {
979
+ throw new ToolError(`Vibe session "${record.id}" no longer resolves to this parent session.`);
980
+ }
981
+
982
+ const manager = this.#manager(session);
983
+ const jobId = this.#registerTurnJob(session, manager, record, message, { first: false });
984
+ return { id: record.id, mode: "turn", jobId };
985
+ }
986
+
987
+ /**
988
+ * Block until one watched session's in-flight turn settles, the timeout
989
+ * elapses, or `signal` aborts — `hub` wait semantics. Settled turns are
990
+ * acknowledged against the job manager so their results are not delivered
991
+ * a second time as async follow-ups.
992
+ */
993
+ async wait(
994
+ session: ToolSession,
995
+ args: { sessions?: string[]; timeoutMs?: number; signal?: AbortSignal },
996
+ ): Promise<VibeWaitOutcome> {
997
+ const scope = this.ownerScope(session);
998
+ const manager = this.#manager(session);
999
+ // Named sessions are watched regardless of state (a just-settled turn is
1000
+ // reported from its retained job); the no-args form watches every
1001
+ // session with a turn actually in flight.
1002
+ const watched = args.sessions?.length
1003
+ ? args.sessions.map(id => this.#record(scope, id))
1004
+ : [...this.#records.values()].filter(record => matchesScope(record, scope) && record.turn !== undefined);
1005
+
1006
+ // Snapshot each watched turn's job at entry: #finishTurn installs a
1007
+ // queued follow-up turn inside the settling job's callback (before that
1008
+ // job's promise resolves), so re-reading record.turn after the race
1009
+ // would inspect the *next* running job and silently drop the settled
1010
+ // result — whose async delivery watchJobs is suppressing on our behalf.
1011
+ const snapshots: Array<{ record: VibeRecord; jobId: string }> = [];
1012
+ for (const record of watched) {
1013
+ const jobId = record.turn?.jobId ?? record.lastJobId;
1014
+ if (jobId) snapshots.push({ record, jobId });
1015
+ }
1016
+
1017
+ const collectSettled = (): VibeWaitOutcome["settled"] => {
1018
+ const settled: VibeWaitOutcome["settled"] = [];
1019
+ for (const { record, jobId } of snapshots) {
1020
+ const job = manager.getJob(jobId);
1021
+ if (!job || job.status === "running") continue;
1022
+ settled.push({
1023
+ id: record.id,
1024
+ jobId,
1025
+ status: job.status,
1026
+ resultText: job.resultText ?? job.errorText ?? "(no output)",
1027
+ });
1028
+ }
1029
+ return settled;
1030
+ };
1031
+
1032
+ const runningJobs: AsyncJob[] = [];
1033
+ for (const { jobId } of snapshots) {
1034
+ const job = manager.getJob(jobId);
1035
+ if (job?.status === "running") runningJobs.push(job);
1036
+ }
1037
+
1038
+ let waited = false;
1039
+ if (runningJobs.length > 0 && collectSettled().length === 0) {
1040
+ waited = true;
1041
+ const timeoutMs = Math.max(1, Math.trunc(args.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS));
1042
+ const watchedJobIds = runningJobs.map(job => job.id);
1043
+ manager.watchJobs(watchedJobIds);
1044
+ const { promise: timeoutPromise, resolve: timeoutResolve } = Promise.withResolvers<void>();
1045
+ const timeoutHandle = setTimeout(() => timeoutResolve(), timeoutMs);
1046
+ const racePromises: Promise<unknown>[] = [...runningJobs.map(job => job.promise), timeoutPromise];
1047
+ let abortCleanup: (() => void) | undefined;
1048
+ if (args.signal) {
1049
+ const { promise: abortPromise, resolve: abortResolve } = Promise.withResolvers<void>();
1050
+ const onAbort = () => abortResolve();
1051
+ args.signal.addEventListener("abort", onAbort, { once: true });
1052
+ abortCleanup = () => args.signal?.removeEventListener("abort", onAbort);
1053
+ racePromises.push(abortPromise);
1054
+ }
1055
+ try {
1056
+ await Promise.race(racePromises);
1057
+ } finally {
1058
+ manager.unwatchJobs(watchedJobIds);
1059
+ clearTimeout(timeoutHandle);
1060
+ abortCleanup?.();
1061
+ }
1062
+ }
1063
+
1064
+ const settled = collectSettled();
1065
+ manager.acknowledgeDeliveries(settled.map(entry => entry.jobId));
1066
+ // Current in-flight state, independent of the snapshot: a session whose
1067
+ // watched turn settled may already be mid queued follow-up.
1068
+ const stillRunning = watched.filter(record => record.turn !== undefined).map(record => record.id);
1069
+ return { settled, stillRunning, timedOut: waited && settled.length === 0 };
1070
+ }
1071
+
1072
+ /** Detach one parent's process-local workers without tombstoning their persisted conversations. */
1073
+ async suspendScope(scope: VibeOwnerScope, manager?: AsyncJobManager): Promise<number> {
1074
+ const records = [...this.#records.values()].filter(record => matchesScope(record, scope));
1075
+ const teardown = records.map(record => ({
1076
+ record,
1077
+ ref: this.#registeredAgent(record),
1078
+ job: record.turn && manager ? manager.getJob(record.turn.jobId) : undefined,
1079
+ }));
1080
+ for (const { record } of teardown) {
1081
+ record.suspended = true;
1082
+ record.queue.length = 0;
1083
+ record.state = "dead";
1084
+ record.lastActivityAt = Date.now();
1085
+ record.lastActivity = "suspended for parent-session switch";
1086
+ this.#records.delete(scopeKey(scope, record.id));
1087
+ if (record.turn && manager) manager.cancel(record.turn.jobId, { ownerId: record.ownerId });
1088
+ }
1089
+ for (const { record, ref } of teardown) {
1090
+ if (!ref) continue;
1091
+ try {
1092
+ await AgentLifecycleManager.global().release(record.id, ref);
1093
+ } catch (error) {
1094
+ logger.warn("vibe: failed to detach worker session", {
1095
+ id: record.id,
1096
+ error: error instanceof Error ? error.message : String(error),
1097
+ });
1098
+ }
1099
+ }
1100
+ await awaitCancelledTurnJobs(new Set(teardown.flatMap(entry => (entry.job ? [entry.job] : []))));
1101
+ return records.length;
1102
+ }
1103
+
1104
+ /** Terminate one worker; a tombstone failure still tears it down before reconciliation and error delivery. */
1105
+ async kill(session: ToolSession, id: string): Promise<VibeKillOutcome> {
1106
+ const scope = this.ownerScope(session);
1107
+ return this.#withTerminationLock(scope, () => {
1108
+ const record = this.#record(scope, id);
1109
+ return this.#killRecord(record, session.asyncJobManager, session, "explicit-kill");
1110
+ });
1111
+ }
1112
+
1113
+ /** Kill every live session in one parent scope after durably recording the complete mode-exit intent. */
1114
+ async killAll(session: VibeParentSession, ownerScope?: VibeOwnerScope): Promise<number> {
1115
+ const scope = ownerScope ?? this.ownerScope(session);
1116
+ return this.#withTerminationLock(scope, async () => {
1117
+ try {
1118
+ const killed = await this.#killAllLocked(session, scope);
1119
+ this.#terminatedScopes.add(scopeKey(scope, ""));
1120
+ return killed;
1121
+ } catch (error) {
1122
+ if (error instanceof SessionPersistenceIndeterminateError) {
1123
+ this.#terminatedScopes.add(scopeKey(scope, ""));
1124
+ }
1125
+ throw error;
1126
+ }
1127
+ });
1128
+ }
1129
+
1130
+ async #killAllLocked(session: VibeParentSession, scope: VibeOwnerScope): Promise<number> {
1131
+ const records = [...this.#records.values()].filter(
1132
+ record => matchesScope(record, scope) && !(record.state === "dead" && record.terminalPersisted),
1133
+ );
1134
+ if (records.length === 0) {
1135
+ const entries = session.sessionManager?.getBranch() ?? [];
1136
+ for (let index = entries.length - 1; index >= 0; index--) {
1137
+ const entry = entries[index];
1138
+ if (entry.type !== "mode_change") continue;
1139
+ if (entry.mode === "none") return 0;
1140
+ break;
1141
+ }
1142
+ }
1143
+ try {
1144
+ await this.#persistModeExit(session, scope, records);
1145
+ } catch (error) {
1146
+ if (error instanceof SessionPersistenceIndeterminateError) {
1147
+ for (const record of records) {
1148
+ await this.#killRecord(record, session.asyncJobManager, session, "mode-exit", false);
1149
+ }
1150
+ }
1151
+ throw error;
1152
+ }
1153
+ for (const record of records) {
1154
+ await this.#killRecord(record, session.asyncJobManager, session, "mode-exit");
1155
+ }
1156
+ return records.length;
1157
+ }
1158
+
1159
+ async #killRecord(
1160
+ record: VibeRecord,
1161
+ manager: AsyncJobManager | undefined,
1162
+ session: VibeParentSession,
1163
+ reason: VibeTombstoneReason,
1164
+ persistTerminal = true,
1165
+ ): Promise<VibeKillOutcome> {
1166
+ const registered = this.#registeredAgent(record);
1167
+ const settlingJobs = new Set<AsyncJob>();
1168
+ if (record.turn && manager) {
1169
+ const job = manager.getJob(record.turn.jobId);
1170
+ if (job) settlingJobs.add(job);
1171
+ }
1172
+ let persistenceError: unknown;
1173
+ if (persistTerminal && !record.terminalPersisted) {
1174
+ try {
1175
+ if (record.killed) {
1176
+ const recover = session.sessionManager?.recoverPersistenceFromCurrentState;
1177
+ if (!recover) throw new ToolError("Vibe tombstone recovery requires parent-session persistence.");
1178
+ await recover.call(session.sessionManager);
1179
+ }
1180
+ if (!this.#hasInMemoryTombstone(session, record) && record.childSessionFile) {
1181
+ if (!(await this.#appendTombstone(session, record, reason))) {
1182
+ throw new ToolError(`Vibe session "${record.id}" changed parent scope before termination.`);
1183
+ }
1184
+ }
1185
+ record.terminalPersisted = true;
1186
+ } catch (error) {
1187
+ persistenceError = error;
1188
+ }
1189
+ }
1190
+ record.killed = true;
1191
+ record.queue.length = 0;
1192
+ let cancelledTurn = false;
1193
+ if (record.turn && manager) {
1194
+ const job = manager.getJob(record.turn.jobId);
1195
+ if (job) settlingJobs.add(job);
1196
+ cancelledTurn = manager.cancel(record.turn.jobId, { ownerId: record.ownerId });
1197
+ }
1198
+ record.state = "dead";
1199
+ record.lastActivityAt = Date.now();
1200
+ record.lastActivity = "killed";
1201
+ if (registered) {
1202
+ try {
1203
+ await AgentLifecycleManager.global().release(record.id, registered);
1204
+ } catch (error) {
1205
+ logger.warn("vibe: failed to release worker session", {
1206
+ id: record.id,
1207
+ error: error instanceof Error ? error.message : String(error),
1208
+ });
1209
+ }
1210
+ }
1211
+ await awaitCancelledTurnJobs(settlingJobs);
1212
+ const terminalRef = registered ?? this.#registeredAgent(record) ?? null;
1213
+ if (record.childSessionFile) {
1214
+ try {
1215
+ const persisted = await SessionManager.peekSessionInit(record.childSessionFile);
1216
+ if (persisted?.init)
1217
+ await this.#markTerminalRef(record.id, record.ownerId, record.childSessionFile, terminalRef);
1218
+ } catch {
1219
+ // A turn killed before session initialization has no readable history to retain.
1220
+ }
1221
+ }
1222
+ if (persistenceError) {
1223
+ let finalPersistenceError = persistenceError;
1224
+ const recover = session.sessionManager?.recoverPersistenceFromCurrentState;
1225
+ if (recover) {
1226
+ try {
1227
+ await recover.call(session.sessionManager);
1228
+ if (!this.#hasInMemoryTombstone(session, record) && record.childSessionFile) {
1229
+ if (!(await this.#appendTombstone(session, record, reason))) {
1230
+ throw new ToolError(`Vibe session "${record.id}" changed parent scope before termination.`);
1231
+ }
1232
+ }
1233
+ record.terminalPersisted = true;
1234
+ } catch (recoveryError) {
1235
+ if (recoveryError instanceof SessionPersistenceIndeterminateError) {
1236
+ finalPersistenceError = recoveryError;
1237
+ }
1238
+ logger.warn("vibe: failed to reconcile explicit tombstone persistence", {
1239
+ id: record.id,
1240
+ error: recoveryError instanceof Error ? recoveryError.message : String(recoveryError),
1241
+ });
1242
+ }
1243
+ }
1244
+ throw finalPersistenceError;
1245
+ }
1246
+ return { id: record.id, cancelledTurn };
1247
+ }
1248
+
1249
+ /** Build the ExecutorOptions for a first spawn, mirroring the `task`/eval-bridge plumbing. */
1250
+ async #buildSpawnOptions(
1251
+ session: ToolSession,
1252
+ record: VibeRecord,
1253
+ message: string,
1254
+ signal: AbortSignal,
1255
+ onProgress: (progress: AgentProgress) => void,
1256
+ ): Promise<ExecutorOptions> {
1257
+ const sessionFile = session.getSessionFile();
1258
+ const sessionArtifactsDir = sessionFile ? sessionFile.slice(0, -6) : null;
1259
+ const artifactsDir = sessionArtifactsDir ?? path.join(os.tmpdir(), `omp-vibe-${Snowflake.next()}`);
1260
+ await fs.mkdir(artifactsDir, { recursive: true });
1261
+ if (!sessionArtifactsDir) registerArtifactsDir(artifactsDir);
1262
+ const localProtocolOptions: LocalProtocolOptions = session.localProtocolOptions ?? {
1263
+ getArtifactsDir: session.getArtifactsDir ?? (() => null),
1264
+ getSessionId: session.getSessionId ?? (() => null),
1265
+ };
1266
+ return {
1267
+ cwd: session.cwd,
1268
+ agent: record.agent,
1269
+ task: message,
1270
+ assignment: message,
1271
+ description: `vibe ${record.cli} session`,
1272
+ index: 0,
1273
+ id: record.id,
1274
+ taskDepth: session.taskDepth ?? 0,
1275
+ detached: true,
1276
+ modelOverride: record.modelOverride,
1277
+ parentActiveModelPattern: session.getActiveModelString?.(),
1278
+ thinkingLevel: record.agent.thinkingLevel,
1279
+ sessionFile,
1280
+ persistArtifacts: Boolean(sessionFile),
1281
+ artifactsDir,
1282
+ enableLsp: (session.enableLsp ?? true) && session.settings.get("task.enableLsp"),
1283
+ signal,
1284
+ eventBus: session.eventBus,
1285
+ onProgress,
1286
+ authStorage: session.authStorage,
1287
+ modelRegistry: session.modelRegistry,
1288
+ settings: session.settings,
1289
+ mcpManager: session.mcpManager ?? MCPManager.instance(),
1290
+ contextFiles: session.contextFiles?.filter(file => path.basename(file.path).toLowerCase() !== "agents.md"),
1291
+ skills: [...(session.skills ?? [])],
1292
+ workspaceTree: session.workspaceTree,
1293
+ promptTemplates: session.promptTemplates,
1294
+ rules: session.rules,
1295
+ preloadedExtensionPaths: session.extensionPaths,
1296
+ preloadedCustomToolPaths: session.customToolPaths,
1297
+ localProtocolOptions,
1298
+ parentArtifactManager: session.getArtifactManager?.() ?? undefined,
1299
+ parentHindsightSessionState: session.getHindsightSessionState?.(),
1300
+ parentMnemopiSessionState: session.getMnemopiSessionState?.(),
1301
+ parentTelemetry: session.getTelemetry?.(),
1302
+ parentEvalSessionId: session.getEvalSessionId?.() ?? undefined,
1303
+ parentAgentId: session.getAgentId?.() ?? MAIN_AGENT_ID,
1304
+ parentServiceTier: session.getServiceTierByFamily ? (session.getServiceTierByFamily() ?? null) : undefined,
1305
+ keepAlive: true,
1306
+ };
1307
+ }
1308
+
1309
+ /** Register one background job that runs a single worker turn and self-delivers its result. */
1310
+ #registerTurnJob(
1311
+ session: ToolSession,
1312
+ manager: AsyncJobManager,
1313
+ record: VibeRecord,
1314
+ message: string,
1315
+ options: { first: boolean },
1316
+ ): string {
1317
+ const turnIndex = record.turnCount + 1;
1318
+ const turn: VibeTurn = {
1319
+ jobId: "",
1320
+ message,
1321
+ startedAt: Date.now(),
1322
+ trace: [],
1323
+ toolCount: 0,
1324
+ };
1325
+ const onProgress = (progress: AgentProgress): void => {
1326
+ mergeTrace(turn, progress);
1327
+ record.resolvedModel = progress.resolvedModel ?? record.resolvedModel;
1328
+ // recentOutput is newest-first; keep the latest lines oldest-first for display.
1329
+ record.live = {
1330
+ currentTool: progress.currentTool,
1331
+ currentToolArgs: progress.currentToolArgs,
1332
+ lastIntent: progress.lastIntent,
1333
+ outputTail: progress.recentOutput.slice(0, 3).reverse(),
1334
+ };
1335
+ const gist =
1336
+ progress.lastIntent ??
1337
+ (progress.currentTool ? `${progress.currentTool} ${progress.currentToolArgs ?? ""}` : undefined);
1338
+ if (gist) record.lastActivity = firstLine(gist);
1339
+ record.lastActivityAt = Date.now();
1340
+ };
1341
+
1342
+ const jobId = manager.register(
1343
+ "task",
1344
+ `vibe ${record.cli} ${record.id}: ${firstLine(message, 60)}`,
1345
+ async ({ jobId: ownJobId, signal }) => {
1346
+ record.state = "running";
1347
+ record.turnCount = turnIndex;
1348
+ record.lastActivityAt = Date.now();
1349
+ try {
1350
+ const turnStartedPersisted = await this.#appendLifecycleEvent(
1351
+ session,
1352
+ {
1353
+ ...this.#eventBase(record),
1354
+ action: "turn-started",
1355
+ turn: turnIndex,
1356
+ },
1357
+ record.parentSessionFile,
1358
+ );
1359
+ if (record.childSessionFile && !turnStartedPersisted) {
1360
+ throw new ToolError(`Vibe session "${record.id}" changed parent scope before its turn started.`);
1361
+ }
1362
+ const result = options.first
1363
+ ? await runSubprocess(await this.#buildSpawnOptions(session, record, message, signal, onProgress))
1364
+ : await runSubagentFollowUpTurn({
1365
+ id: record.id,
1366
+ agent: record.agent,
1367
+ message,
1368
+ description: `vibe ${record.cli} session`,
1369
+ signal,
1370
+ onProgress,
1371
+ eventBus: session.eventBus,
1372
+ artifactsDir: session.getSessionFile()?.slice(0, -6),
1373
+ });
1374
+ return await this.#settleTurn(session, manager, record, turn, ownJobId, turnIndex, result);
1375
+ } catch (error) {
1376
+ if (error instanceof VibeTurnError) throw error;
1377
+ await this.#finishTurn(session, manager, record, ownJobId);
1378
+ const reason = error instanceof Error ? error.message : String(error);
1379
+ record.lastActivity = firstLine(`turn failed: ${reason}`);
1380
+ throw new VibeTurnError(
1381
+ `[vibe:${record.id} cli=${record.cli} turn=${turnIndex}] turn failed: ${reason}`,
1382
+ );
1383
+ }
1384
+ },
1385
+ { id: `${record.id}-t${turnIndex}`, agentId: record.id, ownerId: record.ownerId },
1386
+ );
1387
+ turn.jobId = jobId;
1388
+ record.turn = turn;
1389
+ return jobId;
1390
+ }
1391
+
1392
+ /** Post-turn bookkeeping shared by success and failure paths: clear the in-flight turn, flush the queue. */
1393
+ async #finishTurn(
1394
+ session: ToolSession,
1395
+ manager: AsyncJobManager,
1396
+ record: VibeRecord,
1397
+ settledJobId: string,
1398
+ ): Promise<void> {
1399
+ record.lastJobId = settledJobId;
1400
+ record.turn = undefined;
1401
+ record.live = undefined;
1402
+ record.lastActivityAt = Date.now();
1403
+ if (record.killed || record.suspended) {
1404
+ record.state = "dead";
1405
+ return;
1406
+ }
1407
+ // Only an idle/parked ref with this parent's exact child file is resumable.
1408
+ const registered = this.#registeredAgent(record);
1409
+ record.state = registered && (registered.status === "idle" || registered.status === "parked") ? "idle" : "dead";
1410
+ if (record.state === "dead") {
1411
+ record.terminalPersisted = await this.#appendTombstone(session, record, "unrecoverable");
1412
+ return;
1413
+ }
1414
+ const settledPersisted = await this.#appendLifecycleEvent(
1415
+ session,
1416
+ {
1417
+ ...this.#eventBase(record),
1418
+ action: "turn-settled",
1419
+ turn: record.turnCount,
1420
+ },
1421
+ record.parentSessionFile,
1422
+ );
1423
+ if (record.childSessionFile && !settledPersisted) {
1424
+ record.state = "dead";
1425
+ return;
1426
+ }
1427
+ if (record.queue.length === 0) return;
1428
+ const nextMessage = record.queue.splice(0, record.queue.length).join("\n\n");
1429
+ try {
1430
+ this.#registerTurnJob(session, manager, record, nextMessage, { first: false });
1431
+ } catch (error) {
1432
+ // Leave the messages recoverable: a later vibe_send flushes again.
1433
+ record.queue.unshift(nextMessage);
1434
+ logger.warn("vibe: failed to start queued follow-up turn", {
1435
+ id: record.id,
1436
+ error: error instanceof Error ? error.message : String(error),
1437
+ });
1438
+ }
1439
+ }
1440
+
1441
+ /** Format a settled turn into the self-delivering result text (activity trace + response). */
1442
+ async #settleTurn(
1443
+ session: ToolSession,
1444
+ manager: AsyncJobManager,
1445
+ record: VibeRecord,
1446
+ turn: VibeTurn,
1447
+ settledJobId: string,
1448
+ turnIndex: number,
1449
+ result: SingleResult,
1450
+ ): Promise<string> {
1451
+ await this.#finishTurn(session, manager, record, settledJobId);
1452
+ const failed = result.exitCode !== 0 || result.aborted === true;
1453
+ const status = result.aborted ? "aborted" : failed ? "failed" : "completed";
1454
+ record.lastActivity = firstLine(
1455
+ failed
1456
+ ? `turn ${turnIndex} ${status}: ${result.abortReason ?? result.error ?? ""}`
1457
+ : (result.lastIntent ?? result.output),
1458
+ );
1459
+
1460
+ const traceLines = turn.trace.map(entry =>
1461
+ firstLine(`${entry.tool}${entry.args ? `(${entry.args})` : ""}`, TRACE_LINE_MAX),
1462
+ );
1463
+ const traceOverflow = Math.max(0, turn.toolCount - turn.trace.length);
1464
+ let response = result.output.trim() || "(no output)";
1465
+ let responseTruncated = false;
1466
+ if (response.length > RESPONSE_PREVIEW_MAX) {
1467
+ const slice = response.slice(0, RESPONSE_PREVIEW_MAX);
1468
+ const lastNewline = slice.lastIndexOf("\n");
1469
+ response = lastNewline > 0 ? slice.slice(0, lastNewline) : slice;
1470
+ responseTruncated = true;
1471
+ }
1472
+ let text: string;
1473
+ try {
1474
+ text = prompt
1475
+ .render(vibeTurnResultTemplate, {
1476
+ id: record.id,
1477
+ cli: record.cli,
1478
+ turn: turnIndex,
1479
+ status,
1480
+ duration: formatDuration(result.durationMs),
1481
+ requests: result.requests,
1482
+ toolCount: turn.toolCount,
1483
+ model: result.resolvedModel ?? record.resolvedModel ?? "",
1484
+ trace: traceLines,
1485
+ traceOverflow: traceOverflow > 0 ? traceOverflow : undefined,
1486
+ response,
1487
+ responseTruncated,
1488
+ error: failed ? (result.abortReason ?? result.error ?? result.stderr ?? "") : "",
1489
+ alive: record.state !== "dead",
1490
+ })
1491
+ .trim();
1492
+ } catch (error) {
1493
+ // A formatting bug must never turn a finished worker turn into a false
1494
+ // failure — the work is done; degrade to a plain-text assembly.
1495
+ logger.warn("vibe: turn-result template render failed; using plain fallback", {
1496
+ id: record.id,
1497
+ error: error instanceof Error ? error.message : String(error),
1498
+ });
1499
+ text = [
1500
+ `[vibe:${record.id} cli=${record.cli} turn=${turnIndex} status=${status}]`,
1501
+ `Activity (${turn.toolCount} tool calls, ${result.requests} requests):`,
1502
+ ...traceLines.map(line => `- ${line}`),
1503
+ "",
1504
+ "Response:",
1505
+ response,
1506
+ ].join("\n");
1507
+ }
1508
+ if (failed) throw new VibeTurnError(text);
1509
+ return text;
1510
+ }
1511
+ }
1512
+
1513
+ /**
1514
+ * Aggregate tok/s across every live vibe worker session owned by `ownerId`.
1515
+ * Returns null when no workers are streaming (so callers can fall back to
1516
+ * their own rate unchanged). The director is often idle while workers stream,
1517
+ * so without this aggregation the status-line tok/s badge would show a stale
1518
+ * value while parallel work is actively generating tokens.
1519
+ *
1520
+ * Reads each worker's last assistant message via {@link calculateTokensPerSecond}
1521
+ * — the same leaf calculator the main status line uses — so worker rates are
1522
+ * computed identically to the main session's rate.
1523
+ */
1524
+ export function aggregateVibeWorkerTokensPerSecond(ownerId: string): number | null {
1525
+ const ids = VibeSessionRegistry.global().listIdsByOwner(ownerId);
1526
+ if (ids.length === 0) return null;
1527
+ let total = 0;
1528
+ let any = false;
1529
+ const registry = AgentRegistry.global();
1530
+ for (const id of ids) {
1531
+ const workerSession = registry.get(id)?.session;
1532
+ if (!workerSession?.isStreaming) continue;
1533
+ const rate = calculateTokensPerSecond(workerSession.state.messages, true);
1534
+ if (rate !== null) {
1535
+ total += rate;
1536
+ any = true;
1537
+ }
1538
+ }
1539
+ return any ? total : null;
1540
+ }