@bastani/atomic 0.7.17-1 → 0.8.0-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1233) hide show
  1. package/CHANGELOG.md +4183 -0
  2. package/README.md +655 -0
  3. package/dist/builtin/intercom/CHANGELOG.md +195 -0
  4. package/dist/builtin/intercom/LICENSE +21 -0
  5. package/dist/builtin/intercom/README.md +484 -0
  6. package/dist/builtin/intercom/broker/broker.ts +346 -0
  7. package/dist/builtin/intercom/broker/client.ts +535 -0
  8. package/dist/builtin/intercom/broker/framing.ts +57 -0
  9. package/dist/builtin/intercom/broker/paths.ts +21 -0
  10. package/dist/builtin/intercom/broker/spawn.ts +308 -0
  11. package/dist/builtin/intercom/config.ts +109 -0
  12. package/dist/builtin/intercom/index.ts +1780 -0
  13. package/dist/builtin/intercom/package.json +59 -0
  14. package/dist/builtin/intercom/reply-tracker.ts +102 -0
  15. package/dist/builtin/intercom/skills/intercom/SKILL.md +513 -0
  16. package/dist/builtin/intercom/types.ts +46 -0
  17. package/dist/builtin/intercom/ui/compose.ts +139 -0
  18. package/dist/builtin/intercom/ui/inline-message.ts +76 -0
  19. package/dist/builtin/intercom/ui/session-list.ts +162 -0
  20. package/dist/builtin/mcp/CHANGELOG.md +346 -0
  21. package/dist/builtin/mcp/LICENSE +21 -0
  22. package/dist/builtin/mcp/OAUTH.md +324 -0
  23. package/dist/builtin/mcp/README.md +373 -0
  24. package/dist/builtin/mcp/agent-dir.ts +21 -0
  25. package/dist/builtin/mcp/app-bridge.bundle.js +67 -0
  26. package/dist/builtin/mcp/cli.js +186 -0
  27. package/dist/builtin/mcp/commands.ts +420 -0
  28. package/dist/builtin/mcp/config.ts +667 -0
  29. package/dist/builtin/mcp/consent-manager.ts +64 -0
  30. package/dist/builtin/mcp/direct-tools.ts +427 -0
  31. package/dist/builtin/mcp/errors.ts +219 -0
  32. package/dist/builtin/mcp/glimpse-ui.ts +80 -0
  33. package/dist/builtin/mcp/host-html-template.ts +427 -0
  34. package/dist/builtin/mcp/index.ts +334 -0
  35. package/dist/builtin/mcp/init.ts +336 -0
  36. package/dist/builtin/mcp/lifecycle.ts +93 -0
  37. package/dist/builtin/mcp/logger.ts +169 -0
  38. package/dist/builtin/mcp/mcp-auth-flow.ts +362 -0
  39. package/dist/builtin/mcp/mcp-auth.ts +297 -0
  40. package/dist/builtin/mcp/mcp-callback-server.ts +284 -0
  41. package/dist/builtin/mcp/mcp-oauth-provider.ts +302 -0
  42. package/dist/builtin/mcp/mcp-panel.ts +826 -0
  43. package/dist/builtin/mcp/mcp-setup-panel.ts +577 -0
  44. package/dist/builtin/mcp/metadata-cache.ts +201 -0
  45. package/dist/builtin/mcp/npx-resolver.ts +424 -0
  46. package/dist/builtin/mcp/oauth-handler.ts +60 -0
  47. package/dist/builtin/mcp/onboarding-state.ts +68 -0
  48. package/dist/builtin/mcp/package.json +61 -0
  49. package/dist/builtin/mcp/proxy-modes.ts +803 -0
  50. package/dist/builtin/mcp/resource-tools.ts +17 -0
  51. package/dist/builtin/mcp/sampling-handler.ts +268 -0
  52. package/dist/builtin/mcp/server-manager.ts +375 -0
  53. package/dist/builtin/mcp/state.ts +41 -0
  54. package/dist/builtin/mcp/tool-metadata.ts +152 -0
  55. package/dist/builtin/mcp/tool-registrar.ts +46 -0
  56. package/dist/builtin/mcp/tool-result-renderer.ts +65 -0
  57. package/dist/builtin/mcp/types.ts +441 -0
  58. package/dist/builtin/mcp/ui-resource-handler.ts +145 -0
  59. package/dist/builtin/mcp/ui-server.ts +623 -0
  60. package/dist/builtin/mcp/ui-session.ts +384 -0
  61. package/dist/builtin/mcp/ui-stream-types.ts +89 -0
  62. package/dist/builtin/mcp/utils.ts +129 -0
  63. package/dist/builtin/subagents/CHANGELOG.md +1019 -0
  64. package/dist/builtin/subagents/README.md +991 -0
  65. package/dist/builtin/subagents/agents/code-simplifier.md +84 -0
  66. package/dist/builtin/subagents/agents/codebase-analyzer.md +158 -0
  67. package/dist/builtin/subagents/agents/codebase-locator.md +113 -0
  68. package/dist/builtin/subagents/agents/codebase-online-researcher.md +317 -0
  69. package/dist/builtin/subagents/agents/codebase-pattern-finder.md +236 -0
  70. package/dist/builtin/subagents/agents/codebase-research-analyzer.md +181 -0
  71. package/dist/builtin/subagents/agents/codebase-research-locator.md +146 -0
  72. package/dist/builtin/subagents/agents/debugger.md +92 -0
  73. package/dist/builtin/subagents/package.json +67 -0
  74. package/dist/builtin/subagents/prompts/gather-context-and-clarify.md +20 -0
  75. package/dist/builtin/subagents/prompts/parallel-cleanup.md +60 -0
  76. package/dist/builtin/subagents/prompts/parallel-context-build.md +55 -0
  77. package/dist/builtin/subagents/prompts/parallel-handoff-plan.md +77 -0
  78. package/dist/builtin/subagents/prompts/parallel-research.md +58 -0
  79. package/dist/builtin/subagents/prompts/parallel-review.md +52 -0
  80. package/dist/builtin/subagents/prompts/review-loop.md +48 -0
  81. package/dist/builtin/subagents/skills/subagent/SKILL.md +734 -0
  82. package/dist/builtin/subagents/src/agents/agent-management.ts +644 -0
  83. package/dist/builtin/subagents/src/agents/agent-scope.ts +6 -0
  84. package/dist/builtin/subagents/src/agents/agent-selection.ts +23 -0
  85. package/dist/builtin/subagents/src/agents/agent-serializer.ts +84 -0
  86. package/dist/builtin/subagents/src/agents/agents.ts +809 -0
  87. package/dist/builtin/subagents/src/agents/chain-serializer.ts +137 -0
  88. package/dist/builtin/subagents/src/agents/frontmatter.ts +29 -0
  89. package/dist/builtin/subagents/src/agents/identity.ts +30 -0
  90. package/dist/builtin/subagents/src/agents/skills.ts +630 -0
  91. package/dist/builtin/subagents/src/extension/control-notices.ts +92 -0
  92. package/dist/builtin/subagents/src/extension/doctor.ts +199 -0
  93. package/dist/builtin/subagents/src/extension/index.ts +586 -0
  94. package/dist/builtin/subagents/src/extension/schemas.ts +168 -0
  95. package/dist/builtin/subagents/src/intercom/intercom-bridge.ts +378 -0
  96. package/dist/builtin/subagents/src/intercom/result-intercom.ts +269 -0
  97. package/dist/builtin/subagents/src/runs/background/async-execution.ts +612 -0
  98. package/dist/builtin/subagents/src/runs/background/async-job-tracker.ts +267 -0
  99. package/dist/builtin/subagents/src/runs/background/async-resume.ts +332 -0
  100. package/dist/builtin/subagents/src/runs/background/async-status.ts +295 -0
  101. package/dist/builtin/subagents/src/runs/background/completion-dedupe.ts +63 -0
  102. package/dist/builtin/subagents/src/runs/background/notify.ts +108 -0
  103. package/dist/builtin/subagents/src/runs/background/parallel-groups.ts +45 -0
  104. package/dist/builtin/subagents/src/runs/background/result-watcher.ts +250 -0
  105. package/dist/builtin/subagents/src/runs/background/run-status.ts +193 -0
  106. package/dist/builtin/subagents/src/runs/background/stale-run-reconciler.ts +291 -0
  107. package/dist/builtin/subagents/src/runs/background/subagent-runner.ts +1760 -0
  108. package/dist/builtin/subagents/src/runs/background/top-level-async.ts +13 -0
  109. package/dist/builtin/subagents/src/runs/foreground/chain-clarify.ts +1333 -0
  110. package/dist/builtin/subagents/src/runs/foreground/chain-execution.ts +932 -0
  111. package/dist/builtin/subagents/src/runs/foreground/execution.ts +902 -0
  112. package/dist/builtin/subagents/src/runs/foreground/subagent-executor.ts +2231 -0
  113. package/dist/builtin/subagents/src/runs/shared/completion-guard.ts +125 -0
  114. package/dist/builtin/subagents/src/runs/shared/long-running-guard.ts +175 -0
  115. package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +103 -0
  116. package/dist/builtin/subagents/src/runs/shared/parallel-utils.ts +108 -0
  117. package/dist/builtin/subagents/src/runs/shared/pi-args.ts +163 -0
  118. package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +115 -0
  119. package/dist/builtin/subagents/src/runs/shared/run-history.ts +56 -0
  120. package/dist/builtin/subagents/src/runs/shared/single-output.ts +154 -0
  121. package/dist/builtin/subagents/src/runs/shared/subagent-control.ts +226 -0
  122. package/dist/builtin/subagents/src/runs/shared/subagent-prompt-runtime.ts +152 -0
  123. package/dist/builtin/subagents/src/runs/shared/worktree.ts +577 -0
  124. package/dist/builtin/subagents/src/shared/artifacts.ts +99 -0
  125. package/dist/builtin/subagents/src/shared/atomic-json.ts +16 -0
  126. package/dist/builtin/subagents/src/shared/file-coalescer.ts +40 -0
  127. package/dist/builtin/subagents/src/shared/fork-context.ts +76 -0
  128. package/dist/builtin/subagents/src/shared/formatters.ts +133 -0
  129. package/dist/builtin/subagents/src/shared/jsonl-writer.ts +81 -0
  130. package/dist/builtin/subagents/src/shared/model-info.ts +78 -0
  131. package/dist/builtin/subagents/src/shared/post-exit-stdio-guard.ts +85 -0
  132. package/dist/builtin/subagents/src/shared/session-identity.ts +10 -0
  133. package/dist/builtin/subagents/src/shared/session-tokens.ts +44 -0
  134. package/dist/builtin/subagents/src/shared/settings.ts +397 -0
  135. package/dist/builtin/subagents/src/shared/status-format.ts +49 -0
  136. package/dist/builtin/subagents/src/shared/types.ts +732 -0
  137. package/dist/builtin/subagents/src/shared/utils.ts +440 -0
  138. package/dist/builtin/subagents/src/slash/prompt-template-bridge.ts +397 -0
  139. package/dist/builtin/subagents/src/slash/slash-bridge.ts +174 -0
  140. package/dist/builtin/subagents/src/slash/slash-commands.ts +528 -0
  141. package/dist/builtin/subagents/src/slash/slash-live-state.ts +292 -0
  142. package/dist/builtin/subagents/src/tui/render-helpers.ts +80 -0
  143. package/dist/builtin/subagents/src/tui/render.ts +1257 -0
  144. package/dist/builtin/web-access/CHANGELOG.md +387 -0
  145. package/dist/builtin/web-access/LICENSE +21 -0
  146. package/dist/builtin/web-access/README.md +346 -0
  147. package/dist/builtin/web-access/activity.ts +101 -0
  148. package/dist/builtin/web-access/chrome-cookies.ts +322 -0
  149. package/dist/builtin/web-access/code-search.ts +107 -0
  150. package/dist/builtin/web-access/curator-page.ts +3359 -0
  151. package/dist/builtin/web-access/curator-server.ts +605 -0
  152. package/dist/builtin/web-access/exa.ts +521 -0
  153. package/dist/builtin/web-access/extract.ts +701 -0
  154. package/dist/builtin/web-access/gemini-api.ts +113 -0
  155. package/dist/builtin/web-access/gemini-search.ts +362 -0
  156. package/dist/builtin/web-access/gemini-url-context.ts +126 -0
  157. package/dist/builtin/web-access/gemini-web-config.ts +54 -0
  158. package/dist/builtin/web-access/gemini-web.ts +396 -0
  159. package/dist/builtin/web-access/github-api.ts +196 -0
  160. package/dist/builtin/web-access/github-extract.ts +635 -0
  161. package/dist/builtin/web-access/index.ts +2347 -0
  162. package/dist/builtin/web-access/package.json +54 -0
  163. package/dist/builtin/web-access/pdf-extract.ts +192 -0
  164. package/dist/builtin/web-access/perplexity.ts +196 -0
  165. package/dist/builtin/web-access/rsc-extract.ts +338 -0
  166. package/dist/builtin/web-access/storage.ts +72 -0
  167. package/dist/builtin/web-access/summary-review.ts +276 -0
  168. package/dist/builtin/web-access/utils.ts +44 -0
  169. package/dist/builtin/web-access/video-extract.ts +379 -0
  170. package/dist/builtin/web-access/youtube-extract.ts +311 -0
  171. package/dist/builtin/workflows/CHANGELOG.md +20 -0
  172. package/dist/builtin/workflows/README.md +323 -0
  173. package/dist/builtin/workflows/builtin/deep-research-codebase.ts +567 -0
  174. package/dist/builtin/workflows/builtin/index.ts +10 -0
  175. package/dist/builtin/workflows/builtin/open-claude-design.ts +985 -0
  176. package/dist/builtin/workflows/builtin/ralph.ts +613 -0
  177. package/dist/builtin/workflows/package.json +89 -0
  178. package/dist/builtin/workflows/skills/create-spec/SKILL.md +247 -0
  179. package/dist/builtin/workflows/skills/impeccable/SKILL.md +173 -0
  180. package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +190 -0
  181. package/dist/builtin/workflows/skills/impeccable/reference/animate.md +175 -0
  182. package/dist/builtin/workflows/skills/impeccable/reference/audit.md +133 -0
  183. package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +113 -0
  184. package/dist/builtin/workflows/skills/impeccable/reference/brand.md +118 -0
  185. package/dist/builtin/workflows/skills/impeccable/reference/clarify.md +174 -0
  186. package/dist/builtin/workflows/skills/impeccable/reference/codex.md +105 -0
  187. package/dist/builtin/workflows/skills/impeccable/reference/cognitive-load.md +106 -0
  188. package/dist/builtin/workflows/skills/impeccable/reference/color-and-contrast.md +105 -0
  189. package/dist/builtin/workflows/skills/impeccable/reference/colorize.md +154 -0
  190. package/dist/builtin/workflows/skills/impeccable/reference/craft.md +123 -0
  191. package/dist/builtin/workflows/skills/impeccable/reference/critique.md +261 -0
  192. package/dist/builtin/workflows/skills/impeccable/reference/delight.md +302 -0
  193. package/dist/builtin/workflows/skills/impeccable/reference/distill.md +111 -0
  194. package/dist/builtin/workflows/skills/impeccable/reference/document.md +427 -0
  195. package/dist/builtin/workflows/skills/impeccable/reference/extract.md +69 -0
  196. package/dist/builtin/workflows/skills/impeccable/reference/harden.md +347 -0
  197. package/dist/builtin/workflows/skills/impeccable/reference/heuristics-scoring.md +234 -0
  198. package/dist/builtin/workflows/skills/impeccable/reference/interaction-design.md +195 -0
  199. package/dist/builtin/workflows/skills/impeccable/reference/layout.md +141 -0
  200. package/dist/builtin/workflows/skills/impeccable/reference/live.md +622 -0
  201. package/dist/builtin/workflows/skills/impeccable/reference/motion-design.md +109 -0
  202. package/dist/builtin/workflows/skills/impeccable/reference/onboard.md +234 -0
  203. package/dist/builtin/workflows/skills/impeccable/reference/optimize.md +258 -0
  204. package/dist/builtin/workflows/skills/impeccable/reference/overdrive.md +130 -0
  205. package/dist/builtin/workflows/skills/impeccable/reference/personas.md +179 -0
  206. package/dist/builtin/workflows/skills/impeccable/reference/polish.md +242 -0
  207. package/dist/builtin/workflows/skills/impeccable/reference/product.md +62 -0
  208. package/dist/builtin/workflows/skills/impeccable/reference/quieter.md +99 -0
  209. package/dist/builtin/workflows/skills/impeccable/reference/responsive-design.md +114 -0
  210. package/dist/builtin/workflows/skills/impeccable/reference/shape.md +165 -0
  211. package/dist/builtin/workflows/skills/impeccable/reference/spatial-design.md +100 -0
  212. package/dist/builtin/workflows/skills/impeccable/reference/teach.md +156 -0
  213. package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +124 -0
  214. package/dist/builtin/workflows/skills/impeccable/reference/typography.md +159 -0
  215. package/dist/builtin/workflows/skills/impeccable/reference/ux-writing.md +107 -0
  216. package/dist/builtin/workflows/skills/impeccable/scripts/cleanup-deprecated.mjs +284 -0
  217. package/dist/builtin/workflows/skills/impeccable/scripts/command-metadata.json +94 -0
  218. package/dist/builtin/workflows/skills/impeccable/scripts/critique-storage.mjs +226 -0
  219. package/dist/builtin/workflows/skills/impeccable/scripts/design-parser.mjs +820 -0
  220. package/dist/builtin/workflows/skills/impeccable/scripts/detect-csp.mjs +198 -0
  221. package/dist/builtin/workflows/skills/impeccable/scripts/impeccable-paths.mjs +110 -0
  222. package/dist/builtin/workflows/skills/impeccable/scripts/is-generated.mjs +69 -0
  223. package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +646 -0
  224. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser-session.js +123 -0
  225. package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +4865 -0
  226. package/dist/builtin/workflows/skills/impeccable/scripts/live-complete.mjs +75 -0
  227. package/dist/builtin/workflows/skills/impeccable/scripts/live-completion.mjs +18 -0
  228. package/dist/builtin/workflows/skills/impeccable/scripts/live-inject.mjs +446 -0
  229. package/dist/builtin/workflows/skills/impeccable/scripts/live-poll.mjs +200 -0
  230. package/dist/builtin/workflows/skills/impeccable/scripts/live-resume.mjs +48 -0
  231. package/dist/builtin/workflows/skills/impeccable/scripts/live-server.mjs +847 -0
  232. package/dist/builtin/workflows/skills/impeccable/scripts/live-session-store.mjs +254 -0
  233. package/dist/builtin/workflows/skills/impeccable/scripts/live-status.mjs +47 -0
  234. package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +632 -0
  235. package/dist/builtin/workflows/skills/impeccable/scripts/live.mjs +247 -0
  236. package/dist/builtin/workflows/skills/impeccable/scripts/load-context.mjs +141 -0
  237. package/dist/builtin/workflows/skills/impeccable/scripts/modern-screenshot.umd.js +14 -0
  238. package/dist/builtin/workflows/skills/impeccable/scripts/pin.mjs +214 -0
  239. package/dist/builtin/workflows/skills/playwright-cli/SKILL.md +392 -0
  240. package/dist/builtin/workflows/skills/playwright-cli/references/element-attributes.md +23 -0
  241. package/dist/builtin/workflows/skills/playwright-cli/references/playwright-tests.md +39 -0
  242. package/dist/builtin/workflows/skills/playwright-cli/references/request-mocking.md +87 -0
  243. package/dist/builtin/workflows/skills/playwright-cli/references/running-code.md +241 -0
  244. package/dist/builtin/workflows/skills/playwright-cli/references/session-management.md +225 -0
  245. package/dist/builtin/workflows/skills/playwright-cli/references/spec-driven-testing.md +305 -0
  246. package/dist/builtin/workflows/skills/playwright-cli/references/storage-state.md +275 -0
  247. package/dist/builtin/workflows/skills/playwright-cli/references/test-generation.md +134 -0
  248. package/dist/builtin/workflows/skills/playwright-cli/references/tracing.md +139 -0
  249. package/dist/builtin/workflows/skills/playwright-cli/references/video-recording.md +143 -0
  250. package/dist/builtin/workflows/skills/prompt-engineer/SKILL.md +263 -0
  251. package/dist/builtin/workflows/skills/prompt-engineer/references/advanced_patterns.md +271 -0
  252. package/dist/builtin/workflows/skills/prompt-engineer/references/core_prompting.md +137 -0
  253. package/dist/builtin/workflows/skills/prompt-engineer/references/quality_improvement.md +193 -0
  254. package/dist/builtin/workflows/skills/research-codebase/SKILL.md +226 -0
  255. package/dist/builtin/workflows/skills/tdd/SKILL.md +109 -0
  256. package/dist/builtin/workflows/skills/tdd/deep-modules.md +33 -0
  257. package/dist/builtin/workflows/skills/tdd/interface-design.md +31 -0
  258. package/dist/builtin/workflows/skills/tdd/mocking.md +59 -0
  259. package/dist/builtin/workflows/skills/tdd/refactoring.md +10 -0
  260. package/dist/builtin/workflows/skills/tdd/tests.md +61 -0
  261. package/dist/builtin/workflows/skills/workflow/SKILL.md +255 -0
  262. package/dist/builtin/workflows/skills/workflow/references/context-engineering/advanced-evaluation.md +404 -0
  263. package/dist/builtin/workflows/skills/workflow/references/context-engineering/bdi-mental-states.md +313 -0
  264. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-compression.md +274 -0
  265. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-degradation.md +208 -0
  266. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-fundamentals.md +203 -0
  267. package/dist/builtin/workflows/skills/workflow/references/context-engineering/context-optimization.md +197 -0
  268. package/dist/builtin/workflows/skills/workflow/references/context-engineering/evaluation.md +253 -0
  269. package/dist/builtin/workflows/skills/workflow/references/context-engineering/filesystem-context.md +289 -0
  270. package/dist/builtin/workflows/skills/workflow/references/context-engineering/hosted-agents.md +262 -0
  271. package/dist/builtin/workflows/skills/workflow/references/context-engineering/memory-systems.md +221 -0
  272. package/dist/builtin/workflows/skills/workflow/references/context-engineering/multi-agent-patterns.md +259 -0
  273. package/dist/builtin/workflows/skills/workflow/references/context-engineering/project-development.md +293 -0
  274. package/dist/builtin/workflows/skills/workflow/references/context-engineering/tool-design.md +273 -0
  275. package/dist/builtin/workflows/skills/workflow/references/context-engineering.md +23 -0
  276. package/dist/builtin/workflows/skills/workflow/references/design-checklist.md +79 -0
  277. package/dist/builtin/workflows/skills/workflow/references/running-workflows.md +107 -0
  278. package/dist/builtin/workflows/skills/workflow/references/sdk-authoring.md +140 -0
  279. package/dist/builtin/workflows/src/extension/background-ui-adapter.ts +168 -0
  280. package/dist/builtin/workflows/src/extension/companions.ts +210 -0
  281. package/dist/builtin/workflows/src/extension/config-loader.ts +493 -0
  282. package/dist/builtin/workflows/src/extension/discovery.ts +501 -0
  283. package/dist/builtin/workflows/src/extension/dispatcher.ts +173 -0
  284. package/dist/builtin/workflows/src/extension/index.ts +2143 -0
  285. package/dist/builtin/workflows/src/extension/mcp.ts +110 -0
  286. package/dist/builtin/workflows/src/extension/render-call.ts +39 -0
  287. package/dist/builtin/workflows/src/extension/render-result.ts +214 -0
  288. package/dist/builtin/workflows/src/extension/renderers.ts +87 -0
  289. package/dist/builtin/workflows/src/extension/runtime.ts +360 -0
  290. package/dist/builtin/workflows/src/extension/status-writer.ts +167 -0
  291. package/dist/builtin/workflows/src/extension/wiring.ts +555 -0
  292. package/dist/builtin/workflows/src/extension/workflow-schema.ts +102 -0
  293. package/dist/builtin/workflows/src/index.ts +25 -0
  294. package/dist/builtin/workflows/src/intercom/intercom-bridge.ts +93 -0
  295. package/dist/builtin/workflows/src/intercom/intercom-routing.ts +125 -0
  296. package/dist/builtin/workflows/src/intercom/result-intercom.ts +240 -0
  297. package/dist/builtin/workflows/src/runs/background/cancellation-registry.ts +113 -0
  298. package/dist/builtin/workflows/src/runs/background/job-tracker.ts +81 -0
  299. package/dist/builtin/workflows/src/runs/background/runner.ts +152 -0
  300. package/dist/builtin/workflows/src/runs/background/status.ts +354 -0
  301. package/dist/builtin/workflows/src/runs/foreground/executor.ts +1522 -0
  302. package/dist/builtin/workflows/src/runs/foreground/stage-control-registry.ts +233 -0
  303. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +712 -0
  304. package/dist/builtin/workflows/src/runs/shared/concurrency.ts +76 -0
  305. package/dist/builtin/workflows/src/runs/shared/graph-inference.ts +69 -0
  306. package/dist/builtin/workflows/src/runs/shared/model-fallback.ts +293 -0
  307. package/dist/builtin/workflows/src/runs/shared/validate-inputs.ts +83 -0
  308. package/dist/builtin/workflows/src/runs/shared/workflow-runner.ts +170 -0
  309. package/dist/builtin/workflows/src/runs/shared/worktree.ts +577 -0
  310. package/dist/builtin/workflows/src/shared/persistence-compaction-policy.ts +72 -0
  311. package/dist/builtin/workflows/src/shared/persistence-restore.ts +257 -0
  312. package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +145 -0
  313. package/dist/builtin/workflows/src/shared/render-inputs-schema.ts +196 -0
  314. package/dist/builtin/workflows/src/shared/store-types.ts +160 -0
  315. package/dist/builtin/workflows/src/shared/store.ts +579 -0
  316. package/dist/builtin/workflows/src/shared/types.ts +566 -0
  317. package/dist/builtin/workflows/src/tui/chat-surface-message.ts +224 -0
  318. package/dist/builtin/workflows/src/tui/chat-surface.ts +511 -0
  319. package/dist/builtin/workflows/src/tui/color-utils.ts +64 -0
  320. package/dist/builtin/workflows/src/tui/connectors.ts +88 -0
  321. package/dist/builtin/workflows/src/tui/dispatch-confirm.ts +307 -0
  322. package/dist/builtin/workflows/src/tui/edge.ts +24 -0
  323. package/dist/builtin/workflows/src/tui/graph-canvas.ts +108 -0
  324. package/dist/builtin/workflows/src/tui/graph-theme.ts +283 -0
  325. package/dist/builtin/workflows/src/tui/graph-view.ts +1217 -0
  326. package/dist/builtin/workflows/src/tui/header.ts +172 -0
  327. package/dist/builtin/workflows/src/tui/inline-form-card.ts +421 -0
  328. package/dist/builtin/workflows/src/tui/inline-form-editor.ts +638 -0
  329. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +326 -0
  330. package/dist/builtin/workflows/src/tui/inline-form-store.ts +78 -0
  331. package/dist/builtin/workflows/src/tui/inputs-overlay.ts +163 -0
  332. package/dist/builtin/workflows/src/tui/inputs-picker.ts +888 -0
  333. package/dist/builtin/workflows/src/tui/keybindings-adapter.ts +154 -0
  334. package/dist/builtin/workflows/src/tui/layout.ts +153 -0
  335. package/dist/builtin/workflows/src/tui/node-card.ts +274 -0
  336. package/dist/builtin/workflows/src/tui/overlay-adapter.ts +277 -0
  337. package/dist/builtin/workflows/src/tui/prompt-card.ts +501 -0
  338. package/dist/builtin/workflows/src/tui/renderers.ts +15 -0
  339. package/dist/builtin/workflows/src/tui/run-detail.ts +339 -0
  340. package/dist/builtin/workflows/src/tui/session-confirm.ts +202 -0
  341. package/dist/builtin/workflows/src/tui/session-list.ts +32 -0
  342. package/dist/builtin/workflows/src/tui/session-overlays.ts +239 -0
  343. package/dist/builtin/workflows/src/tui/session-picker.ts +399 -0
  344. package/dist/builtin/workflows/src/tui/stage-chat-view.ts +1873 -0
  345. package/dist/builtin/workflows/src/tui/status-helpers.ts +73 -0
  346. package/dist/builtin/workflows/src/tui/status-list.ts +361 -0
  347. package/dist/builtin/workflows/src/tui/store-widget-installer.ts +206 -0
  348. package/dist/builtin/workflows/src/tui/switcher.ts +121 -0
  349. package/dist/builtin/workflows/src/tui/text-helpers.ts +31 -0
  350. package/dist/builtin/workflows/src/tui/toast.ts +106 -0
  351. package/dist/builtin/workflows/src/tui/widget.ts +348 -0
  352. package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +285 -0
  353. package/dist/builtin/workflows/src/tui/workflow-list.ts +224 -0
  354. package/dist/builtin/workflows/src/workflows/define-workflow.ts +150 -0
  355. package/dist/builtin/workflows/src/workflows/identity.ts +39 -0
  356. package/dist/builtin/workflows/src/workflows/registry.ts +113 -0
  357. package/dist/bun/cli.d.ts +3 -0
  358. package/dist/bun/cli.d.ts.map +1 -0
  359. package/dist/bun/cli.js +9 -0
  360. package/dist/bun/cli.js.map +1 -0
  361. package/dist/bun/register-bedrock.d.ts +2 -0
  362. package/dist/bun/register-bedrock.d.ts.map +1 -0
  363. package/dist/bun/register-bedrock.js +4 -0
  364. package/dist/bun/register-bedrock.js.map +1 -0
  365. package/dist/bun/restore-sandbox-env.d.ts +13 -0
  366. package/dist/bun/restore-sandbox-env.d.ts.map +1 -0
  367. package/dist/bun/restore-sandbox-env.js +32 -0
  368. package/dist/bun/restore-sandbox-env.js.map +1 -0
  369. package/dist/cli/args.d.ts +53 -0
  370. package/dist/cli/args.d.ts.map +1 -0
  371. package/dist/cli/args.js +341 -0
  372. package/dist/cli/args.js.map +1 -0
  373. package/dist/cli/config-selector.d.ts +14 -0
  374. package/dist/cli/config-selector.d.ts.map +1 -0
  375. package/dist/cli/config-selector.js +31 -0
  376. package/dist/cli/config-selector.js.map +1 -0
  377. package/dist/cli/file-processor.d.ts +15 -0
  378. package/dist/cli/file-processor.d.ts.map +1 -0
  379. package/dist/cli/file-processor.js +83 -0
  380. package/dist/cli/file-processor.js.map +1 -0
  381. package/dist/cli/initial-message.d.ts +18 -0
  382. package/dist/cli/initial-message.d.ts.map +1 -0
  383. package/dist/cli/initial-message.js +22 -0
  384. package/dist/cli/initial-message.js.map +1 -0
  385. package/dist/cli/list-models.d.ts +9 -0
  386. package/dist/cli/list-models.d.ts.map +1 -0
  387. package/dist/cli/list-models.js +98 -0
  388. package/dist/cli/list-models.js.map +1 -0
  389. package/dist/cli/session-picker.d.ts +9 -0
  390. package/dist/cli/session-picker.d.ts.map +1 -0
  391. package/dist/cli/session-picker.js +35 -0
  392. package/dist/cli/session-picker.js.map +1 -0
  393. package/dist/cli.d.ts +3 -0
  394. package/dist/cli.d.ts.map +1 -0
  395. package/dist/cli.js +20 -0
  396. package/dist/cli.js.map +1 -0
  397. package/dist/config.d.ts +102 -0
  398. package/dist/config.d.ts.map +1 -0
  399. package/dist/config.js +411 -0
  400. package/dist/config.js.map +1 -0
  401. package/dist/core/agent-session-runtime.d.ts +117 -0
  402. package/dist/core/agent-session-runtime.d.ts.map +1 -0
  403. package/dist/core/agent-session-runtime.js +292 -0
  404. package/dist/core/agent-session-runtime.js.map +1 -0
  405. package/dist/core/agent-session-services.d.ts +86 -0
  406. package/dist/core/agent-session-services.d.ts.map +1 -0
  407. package/dist/core/agent-session-services.js +117 -0
  408. package/dist/core/agent-session-services.js.map +1 -0
  409. package/dist/core/agent-session.d.ts +595 -0
  410. package/dist/core/agent-session.d.ts.map +1 -0
  411. package/dist/core/agent-session.js +2518 -0
  412. package/dist/core/agent-session.js.map +1 -0
  413. package/dist/core/auth-guidance.d.ts +5 -0
  414. package/dist/core/auth-guidance.d.ts.map +1 -0
  415. package/dist/core/auth-guidance.js +21 -0
  416. package/dist/core/auth-guidance.js.map +1 -0
  417. package/dist/core/auth-storage.d.ts +141 -0
  418. package/dist/core/auth-storage.d.ts.map +1 -0
  419. package/dist/core/auth-storage.js +437 -0
  420. package/dist/core/auth-storage.js.map +1 -0
  421. package/dist/core/bash-executor.d.ts +32 -0
  422. package/dist/core/bash-executor.d.ts.map +1 -0
  423. package/dist/core/bash-executor.js +111 -0
  424. package/dist/core/bash-executor.js.map +1 -0
  425. package/dist/core/builtin-packages.d.ts +14 -0
  426. package/dist/core/builtin-packages.d.ts.map +1 -0
  427. package/dist/core/builtin-packages.js +113 -0
  428. package/dist/core/builtin-packages.js.map +1 -0
  429. package/dist/core/compaction/branch-summarization.d.ts +88 -0
  430. package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
  431. package/dist/core/compaction/branch-summarization.js +243 -0
  432. package/dist/core/compaction/branch-summarization.js.map +1 -0
  433. package/dist/core/compaction/compaction.d.ts +121 -0
  434. package/dist/core/compaction/compaction.d.ts.map +1 -0
  435. package/dist/core/compaction/compaction.js +615 -0
  436. package/dist/core/compaction/compaction.js.map +1 -0
  437. package/dist/core/compaction/index.d.ts +7 -0
  438. package/dist/core/compaction/index.d.ts.map +1 -0
  439. package/dist/core/compaction/index.js +7 -0
  440. package/dist/core/compaction/index.js.map +1 -0
  441. package/dist/core/compaction/utils.d.ts +38 -0
  442. package/dist/core/compaction/utils.d.ts.map +1 -0
  443. package/dist/core/compaction/utils.js +153 -0
  444. package/dist/core/compaction/utils.js.map +1 -0
  445. package/dist/core/defaults.d.ts +3 -0
  446. package/dist/core/defaults.d.ts.map +1 -0
  447. package/dist/core/defaults.js +2 -0
  448. package/dist/core/defaults.js.map +1 -0
  449. package/dist/core/diagnostics.d.ts +15 -0
  450. package/dist/core/diagnostics.d.ts.map +1 -0
  451. package/dist/core/diagnostics.js +2 -0
  452. package/dist/core/diagnostics.js.map +1 -0
  453. package/dist/core/event-bus.d.ts +9 -0
  454. package/dist/core/event-bus.d.ts.map +1 -0
  455. package/dist/core/event-bus.js +25 -0
  456. package/dist/core/event-bus.js.map +1 -0
  457. package/dist/core/exec.d.ts +29 -0
  458. package/dist/core/exec.d.ts.map +1 -0
  459. package/dist/core/exec.js +75 -0
  460. package/dist/core/exec.js.map +1 -0
  461. package/dist/core/export-html/ansi-to-html.d.ts +22 -0
  462. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  463. package/dist/core/export-html/ansi-to-html.js +249 -0
  464. package/dist/core/export-html/ansi-to-html.js.map +1 -0
  465. package/dist/core/export-html/index.d.ts +37 -0
  466. package/dist/core/export-html/index.d.ts.map +1 -0
  467. package/dist/core/export-html/index.js +224 -0
  468. package/dist/core/export-html/index.js.map +1 -0
  469. package/dist/core/export-html/template.css +1066 -0
  470. package/dist/core/export-html/template.html +55 -0
  471. package/dist/core/export-html/template.js +1834 -0
  472. package/dist/core/export-html/tool-renderer.d.ts +34 -0
  473. package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  474. package/dist/core/export-html/tool-renderer.js +108 -0
  475. package/dist/core/export-html/tool-renderer.js.map +1 -0
  476. package/dist/core/export-html/vendor/highlight.min.js +1213 -0
  477. package/dist/core/export-html/vendor/marked.min.js +6 -0
  478. package/dist/core/extensions/index.d.ts +12 -0
  479. package/dist/core/extensions/index.d.ts.map +1 -0
  480. package/dist/core/extensions/index.js +9 -0
  481. package/dist/core/extensions/index.js.map +1 -0
  482. package/dist/core/extensions/loader.d.ts +24 -0
  483. package/dist/core/extensions/loader.d.ts.map +1 -0
  484. package/dist/core/extensions/loader.js +501 -0
  485. package/dist/core/extensions/loader.js.map +1 -0
  486. package/dist/core/extensions/runner.d.ts +159 -0
  487. package/dist/core/extensions/runner.d.ts.map +1 -0
  488. package/dist/core/extensions/runner.js +817 -0
  489. package/dist/core/extensions/runner.js.map +1 -0
  490. package/dist/core/extensions/types.d.ts +1173 -0
  491. package/dist/core/extensions/types.d.ts.map +1 -0
  492. package/dist/core/extensions/types.js +45 -0
  493. package/dist/core/extensions/types.js.map +1 -0
  494. package/dist/core/extensions/wrapper.d.ts +20 -0
  495. package/dist/core/extensions/wrapper.d.ts.map +1 -0
  496. package/dist/core/extensions/wrapper.js +22 -0
  497. package/dist/core/extensions/wrapper.js.map +1 -0
  498. package/dist/core/footer-data-provider.d.ts +52 -0
  499. package/dist/core/footer-data-provider.d.ts.map +1 -0
  500. package/dist/core/footer-data-provider.js +309 -0
  501. package/dist/core/footer-data-provider.js.map +1 -0
  502. package/dist/core/index.d.ts +12 -0
  503. package/dist/core/index.d.ts.map +1 -0
  504. package/dist/core/index.js +12 -0
  505. package/dist/core/index.js.map +1 -0
  506. package/dist/core/keybindings.d.ts +353 -0
  507. package/dist/core/keybindings.d.ts.map +1 -0
  508. package/dist/core/keybindings.js +294 -0
  509. package/dist/core/keybindings.js.map +1 -0
  510. package/dist/core/messages.d.ts +77 -0
  511. package/dist/core/messages.d.ts.map +1 -0
  512. package/dist/core/messages.js +123 -0
  513. package/dist/core/messages.js.map +1 -0
  514. package/dist/core/model-registry.d.ts +150 -0
  515. package/dist/core/model-registry.d.ts.map +1 -0
  516. package/dist/core/model-registry.js +726 -0
  517. package/dist/core/model-registry.js.map +1 -0
  518. package/dist/core/model-resolver.d.ts +110 -0
  519. package/dist/core/model-resolver.d.ts.map +1 -0
  520. package/dist/core/model-resolver.js +493 -0
  521. package/dist/core/model-resolver.js.map +1 -0
  522. package/dist/core/output-guard.d.ts +6 -0
  523. package/dist/core/output-guard.d.ts.map +1 -0
  524. package/dist/core/output-guard.js +59 -0
  525. package/dist/core/output-guard.js.map +1 -0
  526. package/dist/core/package-manager.d.ts +198 -0
  527. package/dist/core/package-manager.d.ts.map +1 -0
  528. package/dist/core/package-manager.js +1970 -0
  529. package/dist/core/package-manager.js.map +1 -0
  530. package/dist/core/prompt-templates.d.ts +52 -0
  531. package/dist/core/prompt-templates.d.ts.map +1 -0
  532. package/dist/core/prompt-templates.js +250 -0
  533. package/dist/core/prompt-templates.js.map +1 -0
  534. package/dist/core/provider-display-names.d.ts +2 -0
  535. package/dist/core/provider-display-names.d.ts.map +1 -0
  536. package/dist/core/provider-display-names.js +33 -0
  537. package/dist/core/provider-display-names.js.map +1 -0
  538. package/dist/core/resolve-config-value.d.ts +23 -0
  539. package/dist/core/resolve-config-value.d.ts.map +1 -0
  540. package/dist/core/resolve-config-value.js +126 -0
  541. package/dist/core/resolve-config-value.js.map +1 -0
  542. package/dist/core/resource-loader.d.ts +196 -0
  543. package/dist/core/resource-loader.d.ts.map +1 -0
  544. package/dist/core/resource-loader.js +698 -0
  545. package/dist/core/resource-loader.js.map +1 -0
  546. package/dist/core/sdk.d.ts +107 -0
  547. package/dist/core/sdk.d.ts.map +1 -0
  548. package/dist/core/sdk.js +291 -0
  549. package/dist/core/sdk.js.map +1 -0
  550. package/dist/core/session-cwd.d.ts +19 -0
  551. package/dist/core/session-cwd.d.ts.map +1 -0
  552. package/dist/core/session-cwd.js +37 -0
  553. package/dist/core/session-cwd.js.map +1 -0
  554. package/dist/core/session-manager.d.ts +333 -0
  555. package/dist/core/session-manager.d.ts.map +1 -0
  556. package/dist/core/session-manager.js +1118 -0
  557. package/dist/core/session-manager.js.map +1 -0
  558. package/dist/core/settings-manager.d.ts +261 -0
  559. package/dist/core/settings-manager.d.ts.map +1 -0
  560. package/dist/core/settings-manager.js +773 -0
  561. package/dist/core/settings-manager.js.map +1 -0
  562. package/dist/core/skills.d.ts +60 -0
  563. package/dist/core/skills.d.ts.map +1 -0
  564. package/dist/core/skills.js +404 -0
  565. package/dist/core/skills.js.map +1 -0
  566. package/dist/core/slash-commands.d.ts +14 -0
  567. package/dist/core/slash-commands.d.ts.map +1 -0
  568. package/dist/core/slash-commands.js +25 -0
  569. package/dist/core/slash-commands.js.map +1 -0
  570. package/dist/core/source-info.d.ts +18 -0
  571. package/dist/core/source-info.d.ts.map +1 -0
  572. package/dist/core/source-info.js +19 -0
  573. package/dist/core/source-info.js.map +1 -0
  574. package/dist/core/system-prompt.d.ts +28 -0
  575. package/dist/core/system-prompt.d.ts.map +1 -0
  576. package/dist/core/system-prompt.js +120 -0
  577. package/dist/core/system-prompt.js.map +1 -0
  578. package/dist/core/telemetry.d.ts +3 -0
  579. package/dist/core/telemetry.d.ts.map +1 -0
  580. package/dist/core/telemetry.js +10 -0
  581. package/dist/core/telemetry.js.map +1 -0
  582. package/dist/core/timings.d.ts +8 -0
  583. package/dist/core/timings.d.ts.map +1 -0
  584. package/dist/core/timings.js +32 -0
  585. package/dist/core/timings.js.map +1 -0
  586. package/dist/core/tools/ask-user-question/ask-user-question.d.ts +10 -0
  587. package/dist/core/tools/ask-user-question/ask-user-question.d.ts.map +1 -0
  588. package/dist/core/tools/ask-user-question/ask-user-question.js +82 -0
  589. package/dist/core/tools/ask-user-question/ask-user-question.js.map +1 -0
  590. package/dist/core/tools/ask-user-question/config.d.ts +11 -0
  591. package/dist/core/tools/ask-user-question/config.d.ts.map +1 -0
  592. package/dist/core/tools/ask-user-question/config.js +34 -0
  593. package/dist/core/tools/ask-user-question/config.js.map +1 -0
  594. package/dist/core/tools/ask-user-question/index.d.ts +19 -0
  595. package/dist/core/tools/ask-user-question/index.d.ts.map +1 -0
  596. package/dist/core/tools/ask-user-question/index.js +19 -0
  597. package/dist/core/tools/ask-user-question/index.js.map +1 -0
  598. package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts +36 -0
  599. package/dist/core/tools/ask-user-question/state/build-questionnaire.d.ts.map +1 -0
  600. package/dist/core/tools/ask-user-question/state/build-questionnaire.js +213 -0
  601. package/dist/core/tools/ask-user-question/state/build-questionnaire.js.map +1 -0
  602. package/dist/core/tools/ask-user-question/state/key-router.d.ts +53 -0
  603. package/dist/core/tools/ask-user-question/state/key-router.d.ts.map +1 -0
  604. package/dist/core/tools/ask-user-question/state/key-router.js +240 -0
  605. package/dist/core/tools/ask-user-question/state/key-router.js.map +1 -0
  606. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts +61 -0
  607. package/dist/core/tools/ask-user-question/state/questionnaire-session.d.ts.map +1 -0
  608. package/dist/core/tools/ask-user-question/state/questionnaire-session.js +147 -0
  609. package/dist/core/tools/ask-user-question/state/questionnaire-session.js.map +1 -0
  610. package/dist/core/tools/ask-user-question/state/row-intent.d.ts +91 -0
  611. package/dist/core/tools/ask-user-question/state/row-intent.d.ts.map +1 -0
  612. package/dist/core/tools/ask-user-question/state/row-intent.js +91 -0
  613. package/dist/core/tools/ask-user-question/state/row-intent.js.map +1 -0
  614. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts +21 -0
  615. package/dist/core/tools/ask-user-question/state/selectors/contract.d.ts.map +1 -0
  616. package/dist/core/tools/ask-user-question/state/selectors/contract.js +2 -0
  617. package/dist/core/tools/ask-user-question/state/selectors/contract.js.map +1 -0
  618. package/dist/core/tools/ask-user-question/state/selectors/derivations.d.ts +44 -0
  619. package/dist/core/tools/ask-user-question/state/selectors/derivations.d.ts.map +1 -0
  620. package/dist/core/tools/ask-user-question/state/selectors/derivations.js +76 -0
  621. package/dist/core/tools/ask-user-question/state/selectors/derivations.js.map +1 -0
  622. package/dist/core/tools/ask-user-question/state/selectors/focus.d.ts +15 -0
  623. package/dist/core/tools/ask-user-question/state/selectors/focus.d.ts.map +1 -0
  624. package/dist/core/tools/ask-user-question/state/selectors/focus.js +18 -0
  625. package/dist/core/tools/ask-user-question/state/selectors/focus.js.map +1 -0
  626. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts +16 -0
  627. package/dist/core/tools/ask-user-question/state/selectors/projections.d.ts.map +1 -0
  628. package/dist/core/tools/ask-user-question/state/selectors/projections.js +71 -0
  629. package/dist/core/tools/ask-user-question/state/selectors/projections.js.map +1 -0
  630. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts +44 -0
  631. package/dist/core/tools/ask-user-question/state/state-reducer.d.ts.map +1 -0
  632. package/dist/core/tools/ask-user-question/state/state-reducer.js +239 -0
  633. package/dist/core/tools/ask-user-question/state/state-reducer.js.map +1 -0
  634. package/dist/core/tools/ask-user-question/state/state.d.ts +42 -0
  635. package/dist/core/tools/ask-user-question/state/state.d.ts.map +1 -0
  636. package/dist/core/tools/ask-user-question/state/state.js +2 -0
  637. package/dist/core/tools/ask-user-question/state/state.js.map +1 -0
  638. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts +30 -0
  639. package/dist/core/tools/ask-user-question/tool/format-answer.d.ts.map +1 -0
  640. package/dist/core/tools/ask-user-question/tool/format-answer.js +39 -0
  641. package/dist/core/tools/ask-user-question/tool/format-answer.js.map +1 -0
  642. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts +29 -0
  643. package/dist/core/tools/ask-user-question/tool/response-envelope.d.ts.map +1 -0
  644. package/dist/core/tools/ask-user-question/tool/response-envelope.js +46 -0
  645. package/dist/core/tools/ask-user-question/tool/response-envelope.js.map +1 -0
  646. package/dist/core/tools/ask-user-question/tool/types.d.ts +113 -0
  647. package/dist/core/tools/ask-user-question/tool/types.d.ts.map +1 -0
  648. package/dist/core/tools/ask-user-question/tool/types.js +81 -0
  649. package/dist/core/tools/ask-user-question/tool/types.js.map +1 -0
  650. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.d.ts +21 -0
  651. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.d.ts.map +1 -0
  652. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.js +49 -0
  653. package/dist/core/tools/ask-user-question/tool/validate-questionnaire.js.map +1 -0
  654. package/dist/core/tools/ask-user-question/view/body-residual-spacer.d.ts +18 -0
  655. package/dist/core/tools/ask-user-question/view/body-residual-spacer.d.ts.map +1 -0
  656. package/dist/core/tools/ask-user-question/view/body-residual-spacer.js +21 -0
  657. package/dist/core/tools/ask-user-question/view/body-residual-spacer.js.map +1 -0
  658. package/dist/core/tools/ask-user-question/view/component-binding.d.ts +23 -0
  659. package/dist/core/tools/ask-user-question/view/component-binding.d.ts.map +1 -0
  660. package/dist/core/tools/ask-user-question/view/component-binding.js +16 -0
  661. package/dist/core/tools/ask-user-question/view/component-binding.js.map +1 -0
  662. package/dist/core/tools/ask-user-question/view/components/chat-row-view.d.ts +40 -0
  663. package/dist/core/tools/ask-user-question/view/components/chat-row-view.d.ts.map +1 -0
  664. package/dist/core/tools/ask-user-question/view/components/chat-row-view.js +31 -0
  665. package/dist/core/tools/ask-user-question/view/components/chat-row-view.js.map +1 -0
  666. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts +35 -0
  667. package/dist/core/tools/ask-user-question/view/components/multi-select-view.d.ts.map +1 -0
  668. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js +91 -0
  669. package/dist/core/tools/ask-user-question/view/components/multi-select-view.js.map +1 -0
  670. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts +43 -0
  671. package/dist/core/tools/ask-user-question/view/components/option-list-view.d.ts.map +1 -0
  672. package/dist/core/tools/ask-user-question/view/components/option-list-view.js +37 -0
  673. package/dist/core/tools/ask-user-question/view/components/option-list-view.js.map +1 -0
  674. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts +36 -0
  675. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.d.ts.map +1 -0
  676. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.js +66 -0
  677. package/dist/core/tools/ask-user-question/view/components/preview/markdown-content-cache.js.map +1 -0
  678. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts +46 -0
  679. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.d.ts.map +1 -0
  680. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js +69 -0
  681. package/dist/core/tools/ask-user-question/view/components/preview/preview-block-renderer.js.map +1 -0
  682. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.d.ts +39 -0
  683. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.d.ts.map +1 -0
  684. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.js +76 -0
  685. package/dist/core/tools/ask-user-question/view/components/preview/preview-box-renderer.js.map +1 -0
  686. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.d.ts +116 -0
  687. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.d.ts.map +1 -0
  688. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.js +173 -0
  689. package/dist/core/tools/ask-user-question/view/components/preview/preview-layout-decider.js.map +1 -0
  690. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.d.ts +66 -0
  691. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.d.ts.map +1 -0
  692. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.js +124 -0
  693. package/dist/core/tools/ask-user-question/view/components/preview/preview-pane.js.map +1 -0
  694. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts +37 -0
  695. package/dist/core/tools/ask-user-question/view/components/submit-picker.d.ts.map +1 -0
  696. package/dist/core/tools/ask-user-question/view/components/submit-picker.js +44 -0
  697. package/dist/core/tools/ask-user-question/view/components/submit-picker.js.map +1 -0
  698. package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts +32 -0
  699. package/dist/core/tools/ask-user-question/view/components/tab-bar.d.ts.map +1 -0
  700. package/dist/core/tools/ask-user-question/view/components/tab-bar.js +33 -0
  701. package/dist/core/tools/ask-user-question/view/components/tab-bar.js.map +1 -0
  702. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts +122 -0
  703. package/dist/core/tools/ask-user-question/view/components/wrapping-select.d.ts.map +1 -0
  704. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js +161 -0
  705. package/dist/core/tools/ask-user-question/view/components/wrapping-select.js.map +1 -0
  706. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts +66 -0
  707. package/dist/core/tools/ask-user-question/view/dialog-builder.d.ts.map +1 -0
  708. package/dist/core/tools/ask-user-question/view/dialog-builder.js +85 -0
  709. package/dist/core/tools/ask-user-question/view/dialog-builder.js.map +1 -0
  710. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts +58 -0
  711. package/dist/core/tools/ask-user-question/view/props-adapter.d.ts.map +1 -0
  712. package/dist/core/tools/ask-user-question/view/props-adapter.js +67 -0
  713. package/dist/core/tools/ask-user-question/view/props-adapter.js.map +1 -0
  714. package/dist/core/tools/ask-user-question/view/stateful-view.d.ts +24 -0
  715. package/dist/core/tools/ask-user-question/view/stateful-view.d.ts.map +1 -0
  716. package/dist/core/tools/ask-user-question/view/stateful-view.js +2 -0
  717. package/dist/core/tools/ask-user-question/view/stateful-view.js.map +1 -0
  718. package/dist/core/tools/ask-user-question/view/tab-components.d.ts +15 -0
  719. package/dist/core/tools/ask-user-question/view/tab-components.d.ts.map +1 -0
  720. package/dist/core/tools/ask-user-question/view/tab-components.js +2 -0
  721. package/dist/core/tools/ask-user-question/view/tab-components.js.map +1 -0
  722. package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts +71 -0
  723. package/dist/core/tools/ask-user-question/view/tab-content-strategy.d.ts.map +1 -0
  724. package/dist/core/tools/ask-user-question/view/tab-content-strategy.js +129 -0
  725. package/dist/core/tools/ask-user-question/view/tab-content-strategy.js.map +1 -0
  726. package/dist/core/tools/bash.d.ts +68 -0
  727. package/dist/core/tools/bash.d.ts.map +1 -0
  728. package/dist/core/tools/bash.js +338 -0
  729. package/dist/core/tools/bash.js.map +1 -0
  730. package/dist/core/tools/edit-diff.d.ts +85 -0
  731. package/dist/core/tools/edit-diff.d.ts.map +1 -0
  732. package/dist/core/tools/edit-diff.js +338 -0
  733. package/dist/core/tools/edit-diff.js.map +1 -0
  734. package/dist/core/tools/edit.d.ts +49 -0
  735. package/dist/core/tools/edit.d.ts.map +1 -0
  736. package/dist/core/tools/edit.js +324 -0
  737. package/dist/core/tools/edit.js.map +1 -0
  738. package/dist/core/tools/file-mutation-queue.d.ts +6 -0
  739. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -0
  740. package/dist/core/tools/file-mutation-queue.js +37 -0
  741. package/dist/core/tools/file-mutation-queue.js.map +1 -0
  742. package/dist/core/tools/find.d.ts +35 -0
  743. package/dist/core/tools/find.d.ts.map +1 -0
  744. package/dist/core/tools/find.js +298 -0
  745. package/dist/core/tools/find.js.map +1 -0
  746. package/dist/core/tools/grep.d.ts +37 -0
  747. package/dist/core/tools/grep.d.ts.map +1 -0
  748. package/dist/core/tools/grep.js +304 -0
  749. package/dist/core/tools/grep.js.map +1 -0
  750. package/dist/core/tools/index.d.ts +42 -0
  751. package/dist/core/tools/index.d.ts.map +1 -0
  752. package/dist/core/tools/index.js +139 -0
  753. package/dist/core/tools/index.js.map +1 -0
  754. package/dist/core/tools/ls.d.ts +37 -0
  755. package/dist/core/tools/ls.d.ts.map +1 -0
  756. package/dist/core/tools/ls.js +169 -0
  757. package/dist/core/tools/ls.js.map +1 -0
  758. package/dist/core/tools/output-accumulator.d.ts +50 -0
  759. package/dist/core/tools/output-accumulator.d.ts.map +1 -0
  760. package/dist/core/tools/output-accumulator.js +172 -0
  761. package/dist/core/tools/output-accumulator.js.map +1 -0
  762. package/dist/core/tools/path-utils.d.ts +8 -0
  763. package/dist/core/tools/path-utils.d.ts.map +1 -0
  764. package/dist/core/tools/path-utils.js +81 -0
  765. package/dist/core/tools/path-utils.js.map +1 -0
  766. package/dist/core/tools/read.d.ts +35 -0
  767. package/dist/core/tools/read.d.ts.map +1 -0
  768. package/dist/core/tools/read.js +289 -0
  769. package/dist/core/tools/read.js.map +1 -0
  770. package/dist/core/tools/render-utils.d.ts +21 -0
  771. package/dist/core/tools/render-utils.d.ts.map +1 -0
  772. package/dist/core/tools/render-utils.js +49 -0
  773. package/dist/core/tools/render-utils.js.map +1 -0
  774. package/dist/core/tools/todos.d.ts +35 -0
  775. package/dist/core/tools/todos.d.ts.map +1 -0
  776. package/dist/core/tools/todos.js +906 -0
  777. package/dist/core/tools/todos.js.map +1 -0
  778. package/dist/core/tools/tool-definition-wrapper.d.ts +14 -0
  779. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -0
  780. package/dist/core/tools/tool-definition-wrapper.js +34 -0
  781. package/dist/core/tools/tool-definition-wrapper.js.map +1 -0
  782. package/dist/core/tools/truncate.d.ts +70 -0
  783. package/dist/core/tools/truncate.d.ts.map +1 -0
  784. package/dist/core/tools/truncate.js +205 -0
  785. package/dist/core/tools/truncate.js.map +1 -0
  786. package/dist/core/tools/write.d.ts +26 -0
  787. package/dist/core/tools/write.d.ts.map +1 -0
  788. package/dist/core/tools/write.js +212 -0
  789. package/dist/core/tools/write.js.map +1 -0
  790. package/dist/index.d.ts +28 -0
  791. package/dist/index.d.ts.map +1 -0
  792. package/dist/index.js +41 -0
  793. package/dist/index.js.map +1 -0
  794. package/dist/main.d.ts +13 -0
  795. package/dist/main.d.ts.map +1 -0
  796. package/dist/main.js +586 -0
  797. package/dist/main.js.map +1 -0
  798. package/dist/migrations.d.ts +33 -0
  799. package/dist/migrations.d.ts.map +1 -0
  800. package/dist/migrations.js +281 -0
  801. package/dist/migrations.js.map +1 -0
  802. package/dist/modes/index.d.ts +9 -0
  803. package/dist/modes/index.d.ts.map +1 -0
  804. package/dist/modes/index.js +8 -0
  805. package/dist/modes/index.js.map +1 -0
  806. package/dist/modes/interactive/assets/clankolas.png +3 -0
  807. package/dist/modes/interactive/components/armin.d.ts +34 -0
  808. package/dist/modes/interactive/components/armin.d.ts.map +1 -0
  809. package/dist/modes/interactive/components/armin.js +329 -0
  810. package/dist/modes/interactive/components/armin.js.map +1 -0
  811. package/dist/modes/interactive/components/assistant-message.d.ts +20 -0
  812. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
  813. package/dist/modes/interactive/components/assistant-message.js +116 -0
  814. package/dist/modes/interactive/components/assistant-message.js.map +1 -0
  815. package/dist/modes/interactive/components/bash-execution.d.ts +34 -0
  816. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
  817. package/dist/modes/interactive/components/bash-execution.js +170 -0
  818. package/dist/modes/interactive/components/bash-execution.js.map +1 -0
  819. package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
  820. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
  821. package/dist/modes/interactive/components/bordered-loader.js +51 -0
  822. package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
  823. package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
  824. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
  825. package/dist/modes/interactive/components/branch-summary-message.js +42 -0
  826. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
  827. package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
  828. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
  829. package/dist/modes/interactive/components/compaction-summary-message.js +43 -0
  830. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
  831. package/dist/modes/interactive/components/config-selector.d.ts +71 -0
  832. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
  833. package/dist/modes/interactive/components/config-selector.js +496 -0
  834. package/dist/modes/interactive/components/config-selector.js.map +1 -0
  835. package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
  836. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
  837. package/dist/modes/interactive/components/countdown-timer.js +28 -0
  838. package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
  839. package/dist/modes/interactive/components/custom-editor.d.ts +29 -0
  840. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
  841. package/dist/modes/interactive/components/custom-editor.js +113 -0
  842. package/dist/modes/interactive/components/custom-editor.js.map +1 -0
  843. package/dist/modes/interactive/components/custom-message.d.ts +20 -0
  844. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
  845. package/dist/modes/interactive/components/custom-message.js +74 -0
  846. package/dist/modes/interactive/components/custom-message.js.map +1 -0
  847. package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
  848. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
  849. package/dist/modes/interactive/components/daxnuts.js +138 -0
  850. package/dist/modes/interactive/components/daxnuts.js.map +1 -0
  851. package/dist/modes/interactive/components/diff.d.ts +12 -0
  852. package/dist/modes/interactive/components/diff.d.ts.map +1 -0
  853. package/dist/modes/interactive/components/diff.js +151 -0
  854. package/dist/modes/interactive/components/diff.js.map +1 -0
  855. package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
  856. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
  857. package/dist/modes/interactive/components/dynamic-border.js +20 -0
  858. package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
  859. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  860. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  861. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  862. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  863. package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
  864. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
  865. package/dist/modes/interactive/components/extension-editor.js +106 -0
  866. package/dist/modes/interactive/components/extension-editor.js.map +1 -0
  867. package/dist/modes/interactive/components/extension-input.d.ts +23 -0
  868. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
  869. package/dist/modes/interactive/components/extension-input.js +55 -0
  870. package/dist/modes/interactive/components/extension-input.js.map +1 -0
  871. package/dist/modes/interactive/components/extension-selector.d.ts +26 -0
  872. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
  873. package/dist/modes/interactive/components/extension-selector.js +75 -0
  874. package/dist/modes/interactive/components/extension-selector.js.map +1 -0
  875. package/dist/modes/interactive/components/footer.d.ts +27 -0
  876. package/dist/modes/interactive/components/footer.d.ts.map +1 -0
  877. package/dist/modes/interactive/components/footer.js +199 -0
  878. package/dist/modes/interactive/components/footer.js.map +1 -0
  879. package/dist/modes/interactive/components/index.d.ts +32 -0
  880. package/dist/modes/interactive/components/index.d.ts.map +1 -0
  881. package/dist/modes/interactive/components/index.js +33 -0
  882. package/dist/modes/interactive/components/index.js.map +1 -0
  883. package/dist/modes/interactive/components/keybinding-hints.d.ts +13 -0
  884. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
  885. package/dist/modes/interactive/components/keybinding-hints.js +36 -0
  886. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
  887. package/dist/modes/interactive/components/login-dialog.d.ts +46 -0
  888. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
  889. package/dist/modes/interactive/components/login-dialog.js +158 -0
  890. package/dist/modes/interactive/components/login-dialog.js.map +1 -0
  891. package/dist/modes/interactive/components/model-selector.d.ts +47 -0
  892. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
  893. package/dist/modes/interactive/components/model-selector.js +266 -0
  894. package/dist/modes/interactive/components/model-selector.js.map +1 -0
  895. package/dist/modes/interactive/components/oauth-selector.d.ts +31 -0
  896. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
  897. package/dist/modes/interactive/components/oauth-selector.js +156 -0
  898. package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
  899. package/dist/modes/interactive/components/scoped-models-selector.d.ts +42 -0
  900. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
  901. package/dist/modes/interactive/components/scoped-models-selector.js +286 -0
  902. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
  903. package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
  904. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
  905. package/dist/modes/interactive/components/session-selector-search.js +155 -0
  906. package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
  907. package/dist/modes/interactive/components/session-selector.d.ts +96 -0
  908. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
  909. package/dist/modes/interactive/components/session-selector.js +836 -0
  910. package/dist/modes/interactive/components/session-selector.js.map +1 -0
  911. package/dist/modes/interactive/components/settings-selector.d.ts +67 -0
  912. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
  913. package/dist/modes/interactive/components/settings-selector.js +371 -0
  914. package/dist/modes/interactive/components/settings-selector.js.map +1 -0
  915. package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
  916. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
  917. package/dist/modes/interactive/components/show-images-selector.js +38 -0
  918. package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
  919. package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
  920. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
  921. package/dist/modes/interactive/components/skill-invocation-message.js +45 -0
  922. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
  923. package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
  924. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
  925. package/dist/modes/interactive/components/theme-selector.js +48 -0
  926. package/dist/modes/interactive/components/theme-selector.js.map +1 -0
  927. package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
  928. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
  929. package/dist/modes/interactive/components/thinking-selector.js +50 -0
  930. package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
  931. package/dist/modes/interactive/components/tool-execution.d.ts +63 -0
  932. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
  933. package/dist/modes/interactive/components/tool-execution.js +280 -0
  934. package/dist/modes/interactive/components/tool-execution.js.map +1 -0
  935. package/dist/modes/interactive/components/tree-selector.d.ts +89 -0
  936. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
  937. package/dist/modes/interactive/components/tree-selector.js +1079 -0
  938. package/dist/modes/interactive/components/tree-selector.js.map +1 -0
  939. package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
  940. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
  941. package/dist/modes/interactive/components/user-message-selector.js +111 -0
  942. package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
  943. package/dist/modes/interactive/components/user-message.d.ts +10 -0
  944. package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
  945. package/dist/modes/interactive/components/user-message.js +28 -0
  946. package/dist/modes/interactive/components/user-message.js.map +1 -0
  947. package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
  948. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
  949. package/dist/modes/interactive/components/visual-truncate.js +33 -0
  950. package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
  951. package/dist/modes/interactive/interactive-mode.d.ts +369 -0
  952. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
  953. package/dist/modes/interactive/interactive-mode.js +4709 -0
  954. package/dist/modes/interactive/interactive-mode.js.map +1 -0
  955. package/dist/modes/interactive/theme/catppuccin-frappe.json +90 -0
  956. package/dist/modes/interactive/theme/catppuccin-latte.json +90 -0
  957. package/dist/modes/interactive/theme/catppuccin-macchiato.json +90 -0
  958. package/dist/modes/interactive/theme/catppuccin-mocha.json +90 -0
  959. package/dist/modes/interactive/theme/dark.json +85 -0
  960. package/dist/modes/interactive/theme/light.json +84 -0
  961. package/dist/modes/interactive/theme/theme-schema.json +335 -0
  962. package/dist/modes/interactive/theme/theme.d.ts +81 -0
  963. package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
  964. package/dist/modes/interactive/theme/theme.js +970 -0
  965. package/dist/modes/interactive/theme/theme.js.map +1 -0
  966. package/dist/modes/interactive/whimsical-messages.d.ts +5 -0
  967. package/dist/modes/interactive/whimsical-messages.d.ts.map +1 -0
  968. package/dist/modes/interactive/whimsical-messages.js +464 -0
  969. package/dist/modes/interactive/whimsical-messages.js.map +1 -0
  970. package/dist/modes/print-mode.d.ts +28 -0
  971. package/dist/modes/print-mode.d.ts.map +1 -0
  972. package/dist/modes/print-mode.js +131 -0
  973. package/dist/modes/print-mode.js.map +1 -0
  974. package/dist/modes/rpc/jsonl.d.ts +17 -0
  975. package/dist/modes/rpc/jsonl.d.ts.map +1 -0
  976. package/dist/modes/rpc/jsonl.js +49 -0
  977. package/dist/modes/rpc/jsonl.js.map +1 -0
  978. package/dist/modes/rpc/rpc-client.d.ts +224 -0
  979. package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
  980. package/dist/modes/rpc/rpc-client.js +409 -0
  981. package/dist/modes/rpc/rpc-client.js.map +1 -0
  982. package/dist/modes/rpc/rpc-mode.d.ts +20 -0
  983. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
  984. package/dist/modes/rpc/rpc-mode.js +601 -0
  985. package/dist/modes/rpc/rpc-mode.js.map +1 -0
  986. package/dist/modes/rpc/rpc-types.d.ts +419 -0
  987. package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
  988. package/dist/modes/rpc/rpc-types.js +8 -0
  989. package/dist/modes/rpc/rpc-types.js.map +1 -0
  990. package/dist/package-manager-cli.d.ts +4 -0
  991. package/dist/package-manager-cli.d.ts.map +1 -0
  992. package/dist/package-manager-cli.js +460 -0
  993. package/dist/package-manager-cli.js.map +1 -0
  994. package/dist/utils/ansi.d.ts +2 -0
  995. package/dist/utils/ansi.d.ts.map +1 -0
  996. package/dist/utils/ansi.js +52 -0
  997. package/dist/utils/ansi.js.map +1 -0
  998. package/dist/utils/changelog.d.ts +21 -0
  999. package/dist/utils/changelog.d.ts.map +1 -0
  1000. package/dist/utils/changelog.js +87 -0
  1001. package/dist/utils/changelog.js.map +1 -0
  1002. package/dist/utils/child-process.d.ts +12 -0
  1003. package/dist/utils/child-process.d.ts.map +1 -0
  1004. package/dist/utils/child-process.js +86 -0
  1005. package/dist/utils/child-process.js.map +1 -0
  1006. package/dist/utils/clipboard-image.d.ts +11 -0
  1007. package/dist/utils/clipboard-image.d.ts.map +1 -0
  1008. package/dist/utils/clipboard-image.js +245 -0
  1009. package/dist/utils/clipboard-image.js.map +1 -0
  1010. package/dist/utils/clipboard-native.d.ts +8 -0
  1011. package/dist/utils/clipboard-native.d.ts.map +1 -0
  1012. package/dist/utils/clipboard-native.js +14 -0
  1013. package/dist/utils/clipboard-native.js.map +1 -0
  1014. package/dist/utils/clipboard.d.ts +2 -0
  1015. package/dist/utils/clipboard.d.ts.map +1 -0
  1016. package/dist/utils/clipboard.js +117 -0
  1017. package/dist/utils/clipboard.js.map +1 -0
  1018. package/dist/utils/exif-orientation.d.ts +5 -0
  1019. package/dist/utils/exif-orientation.d.ts.map +1 -0
  1020. package/dist/utils/exif-orientation.js +158 -0
  1021. package/dist/utils/exif-orientation.js.map +1 -0
  1022. package/dist/utils/frontmatter.d.ts +8 -0
  1023. package/dist/utils/frontmatter.d.ts.map +1 -0
  1024. package/dist/utils/frontmatter.js +26 -0
  1025. package/dist/utils/frontmatter.js.map +1 -0
  1026. package/dist/utils/fs-watch.d.ts +5 -0
  1027. package/dist/utils/fs-watch.d.ts.map +1 -0
  1028. package/dist/utils/fs-watch.js +25 -0
  1029. package/dist/utils/fs-watch.js.map +1 -0
  1030. package/dist/utils/git.d.ts +26 -0
  1031. package/dist/utils/git.d.ts.map +1 -0
  1032. package/dist/utils/git.js +163 -0
  1033. package/dist/utils/git.js.map +1 -0
  1034. package/dist/utils/html.d.ts +7 -0
  1035. package/dist/utils/html.d.ts.map +1 -0
  1036. package/dist/utils/html.js +40 -0
  1037. package/dist/utils/html.js.map +1 -0
  1038. package/dist/utils/image-convert.d.ts +9 -0
  1039. package/dist/utils/image-convert.d.ts.map +1 -0
  1040. package/dist/utils/image-convert.js +39 -0
  1041. package/dist/utils/image-convert.js.map +1 -0
  1042. package/dist/utils/image-resize.d.ts +36 -0
  1043. package/dist/utils/image-resize.d.ts.map +1 -0
  1044. package/dist/utils/image-resize.js +137 -0
  1045. package/dist/utils/image-resize.js.map +1 -0
  1046. package/dist/utils/mime.d.ts +3 -0
  1047. package/dist/utils/mime.d.ts.map +1 -0
  1048. package/dist/utils/mime.js +69 -0
  1049. package/dist/utils/mime.js.map +1 -0
  1050. package/dist/utils/paths.d.ts +16 -0
  1051. package/dist/utils/paths.d.ts.map +1 -0
  1052. package/dist/utils/paths.js +50 -0
  1053. package/dist/utils/paths.js.map +1 -0
  1054. package/dist/utils/photon.d.ts +21 -0
  1055. package/dist/utils/photon.d.ts.map +1 -0
  1056. package/dist/utils/photon.js +121 -0
  1057. package/dist/utils/photon.js.map +1 -0
  1058. package/dist/utils/pi-user-agent.d.ts +2 -0
  1059. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  1060. package/dist/utils/pi-user-agent.js +5 -0
  1061. package/dist/utils/pi-user-agent.js.map +1 -0
  1062. package/dist/utils/shell.d.ts +30 -0
  1063. package/dist/utils/shell.d.ts.map +1 -0
  1064. package/dist/utils/shell.js +190 -0
  1065. package/dist/utils/shell.js.map +1 -0
  1066. package/dist/utils/sleep.d.ts +5 -0
  1067. package/dist/utils/sleep.d.ts.map +1 -0
  1068. package/dist/utils/sleep.js +17 -0
  1069. package/dist/utils/sleep.js.map +1 -0
  1070. package/dist/utils/syntax-highlight.d.ts +12 -0
  1071. package/dist/utils/syntax-highlight.d.ts.map +1 -0
  1072. package/dist/utils/syntax-highlight.js +118 -0
  1073. package/dist/utils/syntax-highlight.js.map +1 -0
  1074. package/dist/utils/tools-manager.d.ts +3 -0
  1075. package/dist/utils/tools-manager.d.ts.map +1 -0
  1076. package/dist/utils/tools-manager.js +325 -0
  1077. package/dist/utils/tools-manager.js.map +1 -0
  1078. package/dist/utils/version-check.d.ts +14 -0
  1079. package/dist/utils/version-check.d.ts.map +1 -0
  1080. package/dist/utils/version-check.js +76 -0
  1081. package/dist/utils/version-check.js.map +1 -0
  1082. package/docs/compaction.md +394 -0
  1083. package/docs/custom-provider.md +646 -0
  1084. package/docs/development.md +71 -0
  1085. package/docs/docs.json +148 -0
  1086. package/docs/extensions.md +2596 -0
  1087. package/docs/images/doom-extension.png +0 -0
  1088. package/docs/images/exy.png +3 -0
  1089. package/docs/images/interactive-mode.png +0 -0
  1090. package/docs/images/tree-view.png +0 -0
  1091. package/docs/index.md +70 -0
  1092. package/docs/json.md +82 -0
  1093. package/docs/keybindings.md +197 -0
  1094. package/docs/models.md +474 -0
  1095. package/docs/packages.md +223 -0
  1096. package/docs/prompt-templates.md +88 -0
  1097. package/docs/providers.md +243 -0
  1098. package/docs/quickstart.md +142 -0
  1099. package/docs/rpc.md +1407 -0
  1100. package/docs/sdk.md +1129 -0
  1101. package/docs/session-format.md +412 -0
  1102. package/docs/sessions.md +137 -0
  1103. package/docs/settings.md +279 -0
  1104. package/docs/shell-aliases.md +13 -0
  1105. package/docs/skills.md +232 -0
  1106. package/docs/terminal-setup.md +106 -0
  1107. package/docs/termux.md +127 -0
  1108. package/docs/themes.md +299 -0
  1109. package/docs/tmux.md +61 -0
  1110. package/docs/tui.md +918 -0
  1111. package/docs/usage.md +277 -0
  1112. package/docs/windows.md +17 -0
  1113. package/examples/README.md +25 -0
  1114. package/examples/extensions/README.md +208 -0
  1115. package/examples/extensions/auto-commit-on-exit.ts +49 -0
  1116. package/examples/extensions/bash-spawn-hook.ts +30 -0
  1117. package/examples/extensions/bookmark.ts +50 -0
  1118. package/examples/extensions/border-status-editor.ts +150 -0
  1119. package/examples/extensions/built-in-tool-renderer.ts +249 -0
  1120. package/examples/extensions/claude-rules.ts +86 -0
  1121. package/examples/extensions/commands.ts +72 -0
  1122. package/examples/extensions/confirm-destructive.ts +59 -0
  1123. package/examples/extensions/custom-compaction.ts +127 -0
  1124. package/examples/extensions/custom-footer.ts +64 -0
  1125. package/examples/extensions/custom-header.ts +73 -0
  1126. package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
  1127. package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
  1128. package/examples/extensions/custom-provider-anthropic/package.json +19 -0
  1129. package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
  1130. package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
  1131. package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
  1132. package/examples/extensions/dirty-repo-guard.ts +56 -0
  1133. package/examples/extensions/doom-overlay/README.md +46 -0
  1134. package/examples/extensions/doom-overlay/doom/build.sh +152 -0
  1135. package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
  1136. package/examples/extensions/doom-overlay/doom-component.ts +132 -0
  1137. package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
  1138. package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
  1139. package/examples/extensions/doom-overlay/index.ts +74 -0
  1140. package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
  1141. package/examples/extensions/dynamic-resources/SKILL.md +8 -0
  1142. package/examples/extensions/dynamic-resources/dynamic.json +79 -0
  1143. package/examples/extensions/dynamic-resources/dynamic.md +5 -0
  1144. package/examples/extensions/dynamic-resources/index.ts +15 -0
  1145. package/examples/extensions/dynamic-tools.ts +74 -0
  1146. package/examples/extensions/event-bus.ts +43 -0
  1147. package/examples/extensions/file-trigger.ts +41 -0
  1148. package/examples/extensions/git-checkpoint.ts +53 -0
  1149. package/examples/extensions/github-issue-autocomplete.ts +185 -0
  1150. package/examples/extensions/handoff.ts +191 -0
  1151. package/examples/extensions/hello.ts +26 -0
  1152. package/examples/extensions/hidden-thinking-label.ts +53 -0
  1153. package/examples/extensions/inline-bash.ts +94 -0
  1154. package/examples/extensions/input-transform.ts +43 -0
  1155. package/examples/extensions/interactive-shell.ts +196 -0
  1156. package/examples/extensions/mac-system-theme.ts +47 -0
  1157. package/examples/extensions/message-renderer.ts +59 -0
  1158. package/examples/extensions/minimal-mode.ts +426 -0
  1159. package/examples/extensions/modal-editor.ts +85 -0
  1160. package/examples/extensions/model-status.ts +31 -0
  1161. package/examples/extensions/notify.ts +55 -0
  1162. package/examples/extensions/overlay-qa-tests.ts +1348 -0
  1163. package/examples/extensions/overlay-test.ts +150 -0
  1164. package/examples/extensions/permission-gate.ts +34 -0
  1165. package/examples/extensions/pirate.ts +47 -0
  1166. package/examples/extensions/plan-mode/README.md +65 -0
  1167. package/examples/extensions/plan-mode/index.ts +340 -0
  1168. package/examples/extensions/plan-mode/utils.ts +168 -0
  1169. package/examples/extensions/preset.ts +430 -0
  1170. package/examples/extensions/prompt-customizer.ts +97 -0
  1171. package/examples/extensions/protected-paths.ts +30 -0
  1172. package/examples/extensions/provider-payload.ts +18 -0
  1173. package/examples/extensions/qna.ts +122 -0
  1174. package/examples/extensions/question.ts +264 -0
  1175. package/examples/extensions/questionnaire.ts +427 -0
  1176. package/examples/extensions/rainbow-editor.ts +88 -0
  1177. package/examples/extensions/reload-runtime.ts +37 -0
  1178. package/examples/extensions/rpc-demo.ts +118 -0
  1179. package/examples/extensions/sandbox/index.ts +321 -0
  1180. package/examples/extensions/sandbox/package-lock.json +92 -0
  1181. package/examples/extensions/sandbox/package.json +19 -0
  1182. package/examples/extensions/send-user-message.ts +97 -0
  1183. package/examples/extensions/session-name.ts +27 -0
  1184. package/examples/extensions/shutdown-command.ts +63 -0
  1185. package/examples/extensions/snake.ts +343 -0
  1186. package/examples/extensions/space-invaders.ts +560 -0
  1187. package/examples/extensions/ssh.ts +220 -0
  1188. package/examples/extensions/status-line.ts +32 -0
  1189. package/examples/extensions/structured-output.ts +65 -0
  1190. package/examples/extensions/subagent/README.md +172 -0
  1191. package/examples/extensions/subagent/agents/planner.md +37 -0
  1192. package/examples/extensions/subagent/agents/reviewer.md +35 -0
  1193. package/examples/extensions/subagent/agents/scout.md +50 -0
  1194. package/examples/extensions/subagent/agents/worker.md +24 -0
  1195. package/examples/extensions/subagent/agents.ts +126 -0
  1196. package/examples/extensions/subagent/index.ts +987 -0
  1197. package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
  1198. package/examples/extensions/subagent/prompts/implement.md +10 -0
  1199. package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
  1200. package/examples/extensions/summarize.ts +206 -0
  1201. package/examples/extensions/system-prompt-header.ts +17 -0
  1202. package/examples/extensions/tic-tac-toe.ts +1008 -0
  1203. package/examples/extensions/timed-confirm.ts +70 -0
  1204. package/examples/extensions/titlebar-spinner.ts +58 -0
  1205. package/examples/extensions/todo.ts +297 -0
  1206. package/examples/extensions/tool-override.ts +144 -0
  1207. package/examples/extensions/tools.ts +141 -0
  1208. package/examples/extensions/trigger-compact.ts +50 -0
  1209. package/examples/extensions/truncated-tool.ts +195 -0
  1210. package/examples/extensions/widget-placement.ts +9 -0
  1211. package/examples/extensions/with-deps/index.ts +32 -0
  1212. package/examples/extensions/with-deps/package-lock.json +31 -0
  1213. package/examples/extensions/with-deps/package.json +22 -0
  1214. package/examples/extensions/working-indicator.ts +123 -0
  1215. package/examples/extensions/working-message-test.ts +25 -0
  1216. package/examples/rpc-extension-ui.ts +632 -0
  1217. package/examples/sdk/01-minimal.ts +26 -0
  1218. package/examples/sdk/02-custom-model.ts +53 -0
  1219. package/examples/sdk/03-custom-prompt.ts +75 -0
  1220. package/examples/sdk/04-skills.ts +55 -0
  1221. package/examples/sdk/05-tools.ts +48 -0
  1222. package/examples/sdk/06-extensions.ts +99 -0
  1223. package/examples/sdk/07-context-files.ts +47 -0
  1224. package/examples/sdk/08-prompt-templates.ts +51 -0
  1225. package/examples/sdk/09-api-keys-and-oauth.ts +52 -0
  1226. package/examples/sdk/10-settings.ts +53 -0
  1227. package/examples/sdk/11-sessions.ts +52 -0
  1228. package/examples/sdk/12-full-control.ts +77 -0
  1229. package/examples/sdk/13-session-runtime.ts +67 -0
  1230. package/examples/sdk/README.md +144 -0
  1231. package/package.json +94 -19
  1232. package/bin/atomic +0 -82
  1233. /package/{LICENSE → dist/builtin/workflows/LICENSE} +0 -0
@@ -0,0 +1,1780 @@
1
+ import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
2
+ import { randomUUID } from "crypto";
3
+ import { Type } from "typebox";
4
+ import { Text } from "@mariozechner/pi-tui";
5
+ import { APP_NAME } from "@bastani/atomic";
6
+ import { IntercomClient } from "./broker/client.ts";
7
+ import { spawnBrokerIfNeeded } from "./broker/spawn.ts";
8
+ import { SessionListOverlay } from "./ui/session-list.ts";
9
+ import { ComposeOverlay, type ComposeResult } from "./ui/compose.ts";
10
+ import { InlineMessageComponent } from "./ui/inline-message.ts";
11
+ import { loadConfig, type IntercomConfig } from "./config.ts";
12
+ import type { SessionInfo, Message, Attachment } from "./types.ts";
13
+ import { ReplyTracker } from "./reply-tracker.ts";
14
+
15
+ const SUBAGENT_CONTROL_INTERCOM_EVENT = "subagent:control-intercom";
16
+ const SUBAGENT_RESULT_INTERCOM_EVENT = "subagent:result-intercom";
17
+ const SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT = "subagent:result-intercom-delivery";
18
+ const INBOUND_FLUSH_DELAY_MS = 200;
19
+ const INBOUND_IDLE_RETRY_MS = 500;
20
+ const DEFAULT_UNNAMED_SESSION_ALIAS_PREFIX = "subagent-chat";
21
+ const ENV_PREFIX = APP_NAME.toUpperCase();
22
+ const SUBAGENT_ORCHESTRATOR_TARGET_ENV = `${ENV_PREFIX}_SUBAGENT_ORCHESTRATOR_TARGET`;
23
+ const SUBAGENT_RUN_ID_ENV = `${ENV_PREFIX}_SUBAGENT_RUN_ID`;
24
+ const SUBAGENT_CHILD_AGENT_ENV = `${ENV_PREFIX}_SUBAGENT_CHILD_AGENT`;
25
+ const SUBAGENT_CHILD_INDEX_ENV = `${ENV_PREFIX}_SUBAGENT_CHILD_INDEX`;
26
+ const SUBAGENT_INTERCOM_SESSION_NAME_ENV = `${ENV_PREFIX}_SUBAGENT_INTERCOM_SESSION_NAME`;
27
+
28
+ interface ChildOrchestratorMetadata {
29
+ orchestratorTarget: string;
30
+ runId: string;
31
+ agent: string;
32
+ index: string;
33
+ sessionName?: string;
34
+ }
35
+
36
+ interface InboundMessageEntry {
37
+ from: SessionInfo;
38
+ message: Message;
39
+ replyCommand?: string;
40
+ bodyText: string;
41
+ }
42
+
43
+ type ContactSupervisorReason = "need_decision" | "progress_update" | "interview_request";
44
+
45
+ interface SupervisorInterviewQuestion extends Record<string, unknown> {
46
+ id: string;
47
+ type: "single" | "multi" | "text" | "image" | "info";
48
+ question: string;
49
+ options?: unknown[];
50
+ }
51
+
52
+ interface SupervisorInterviewRequest extends Record<string, unknown> {
53
+ title?: string;
54
+ description?: string;
55
+ questions: SupervisorInterviewQuestion[];
56
+ }
57
+
58
+ interface SupervisorInterviewReply {
59
+ responses: Array<{ id: string; value: unknown }>;
60
+ }
61
+
62
+ function getErrorMessage(error: unknown): string {
63
+ return error instanceof Error ? error.message : String(error);
64
+ }
65
+
66
+ function toError(error: unknown): Error {
67
+ return error instanceof Error ? error : new Error(String(error));
68
+ }
69
+
70
+ function formatAttachments(attachments: Attachment[]): string {
71
+ let text = "";
72
+ for (const att of attachments) {
73
+ if (att.language) {
74
+ text += `\n\n---\n📎 ${att.name}\n~~~${att.language}\n${att.content}\n~~~`;
75
+ } else {
76
+ text += `\n\n---\n📎 ${att.name}\n${att.content}`;
77
+ }
78
+ }
79
+ return text;
80
+ }
81
+ function readChildOrchestratorMetadata(): ChildOrchestratorMetadata | null {
82
+ const orchestratorTarget = process.env[SUBAGENT_ORCHESTRATOR_TARGET_ENV]?.trim();
83
+ const runId = process.env[SUBAGENT_RUN_ID_ENV]?.trim();
84
+ const agent = process.env[SUBAGENT_CHILD_AGENT_ENV]?.trim();
85
+ const index = process.env[SUBAGENT_CHILD_INDEX_ENV]?.trim();
86
+ if (!orchestratorTarget || !runId || !agent || !index) {
87
+ return null;
88
+ }
89
+ const sessionName = process.env[SUBAGENT_INTERCOM_SESSION_NAME_ENV]?.trim();
90
+ return {
91
+ orchestratorTarget,
92
+ runId,
93
+ agent,
94
+ index,
95
+ ...(sessionName ? { sessionName } : {}),
96
+ };
97
+ }
98
+ function formatChildOrchestratorMessage(kind: "ask" | "update" | "interview", metadata: ChildOrchestratorMetadata, message: string): string {
99
+ const heading = kind === "ask"
100
+ ? "Subagent needs a supervisor decision."
101
+ : kind === "interview"
102
+ ? "Subagent requests a structured supervisor interview."
103
+ : "Subagent progress update.";
104
+ return [
105
+ heading,
106
+ `Run: ${metadata.runId}`,
107
+ `Agent: ${metadata.agent}`,
108
+ `Child index: ${metadata.index}`,
109
+ metadata.sessionName ? `Child intercom target: ${metadata.sessionName}` : undefined,
110
+ "",
111
+ message,
112
+ ].filter((line): line is string => line !== undefined).join("\n");
113
+ }
114
+
115
+ function validateSupervisorInterviewRequest(input: unknown): { ok: true; interview: SupervisorInterviewRequest } | { ok: false; error: string } {
116
+ if (!input || typeof input !== "object" || Array.isArray(input)) {
117
+ return { ok: false, error: "interview must be an object with a questions array" };
118
+ }
119
+
120
+ const raw = input as Record<string, unknown>;
121
+ if (raw.title !== undefined && typeof raw.title !== "string") {
122
+ return { ok: false, error: "interview.title must be a string when provided" };
123
+ }
124
+ if (raw.description !== undefined && typeof raw.description !== "string") {
125
+ return { ok: false, error: "interview.description must be a string when provided" };
126
+ }
127
+ if (!Array.isArray(raw.questions) || raw.questions.length === 0) {
128
+ return { ok: false, error: "interview.questions must be a non-empty array" };
129
+ }
130
+
131
+ const validTypes = new Set(["single", "multi", "text", "image", "info"]);
132
+ const ids = new Set<string>();
133
+ const questions: SupervisorInterviewQuestion[] = [];
134
+
135
+ for (let index = 0; index < raw.questions.length; index++) {
136
+ const questionInput = raw.questions[index];
137
+ if (!questionInput || typeof questionInput !== "object" || Array.isArray(questionInput)) {
138
+ return { ok: false, error: `interview.questions[${index}] must be an object` };
139
+ }
140
+ const question = questionInput as Record<string, unknown>;
141
+ if (typeof question.id !== "string" || question.id.trim() === "") {
142
+ return { ok: false, error: `interview.questions[${index}].id must be a non-empty string` };
143
+ }
144
+ const id = question.id.trim();
145
+ if (ids.has(id)) {
146
+ return { ok: false, error: `interview question id must be unique: ${id}` };
147
+ }
148
+ ids.add(id);
149
+
150
+ if (typeof question.type !== "string" || !validTypes.has(question.type)) {
151
+ return { ok: false, error: `interview.questions[${index}].type must be one of: single, multi, text, image, info` };
152
+ }
153
+ if (typeof question.question !== "string" || question.question.trim() === "") {
154
+ return { ok: false, error: `interview.questions[${index}].question must be a non-empty string` };
155
+ }
156
+ if (question.context !== undefined && typeof question.context !== "string") {
157
+ return { ok: false, error: `interview.questions[${index}].context must be a string when provided` };
158
+ }
159
+ let options: unknown[] | undefined;
160
+ if (question.options !== undefined) {
161
+ if (!Array.isArray(question.options)) {
162
+ return { ok: false, error: `interview.questions[${index}].options must be an array when provided` };
163
+ }
164
+ options = [];
165
+ for (let optionIndex = 0; optionIndex < question.options.length; optionIndex++) {
166
+ const option = question.options[optionIndex];
167
+ if (typeof option === "string") {
168
+ const label = option.trim();
169
+ if (!label) {
170
+ return { ok: false, error: `interview.questions[${index}].options[${optionIndex}] must not be empty` };
171
+ }
172
+ options.push(label);
173
+ } else if (!option || typeof option !== "object" || Array.isArray(option) || typeof (option as { label?: unknown }).label !== "string" || (option as { label: string }).label.trim() === "") {
174
+ return { ok: false, error: `interview.questions[${index}].options[${optionIndex}] must be a non-empty string or an object with a non-empty label` };
175
+ } else {
176
+ options.push({ ...option, label: (option as { label: string }).label.trim() });
177
+ }
178
+ }
179
+ }
180
+ if ((question.type === "single" || question.type === "multi") && (!options || options.length === 0)) {
181
+ return { ok: false, error: `interview.questions[${index}].options must be a non-empty array for ${question.type} questions` };
182
+ }
183
+ if (question.type !== "single" && question.type !== "multi" && options) {
184
+ return { ok: false, error: `interview.questions[${index}].options is only valid for single and multi questions` };
185
+ }
186
+
187
+ questions.push({
188
+ ...question,
189
+ id,
190
+ type: question.type as SupervisorInterviewQuestion["type"],
191
+ question: question.question.trim(),
192
+ ...(options ? { options } : {}),
193
+ });
194
+ }
195
+
196
+ return {
197
+ ok: true,
198
+ interview: {
199
+ ...raw,
200
+ ...(typeof raw.title === "string" ? { title: raw.title.trim() } : {}),
201
+ ...(typeof raw.description === "string" ? { description: raw.description.trim() } : {}),
202
+ questions,
203
+ },
204
+ };
205
+ }
206
+
207
+ function interviewOptionLabel(option: unknown): string {
208
+ return typeof option === "string" ? option : (option as { label: string }).label;
209
+ }
210
+
211
+ function interviewExampleValue(question: SupervisorInterviewQuestion): unknown {
212
+ if (question.type === "multi") {
213
+ return question.options?.slice(0, 2).map(interviewOptionLabel) ?? [];
214
+ }
215
+ if (question.type === "single") {
216
+ return question.options?.[0] !== undefined ? interviewOptionLabel(question.options[0]) : "option label";
217
+ }
218
+ if (question.type === "image") {
219
+ return "image/file reference or description";
220
+ }
221
+ return "answer text";
222
+ }
223
+
224
+ function formatSupervisorInterviewRequest(interview: SupervisorInterviewRequest, message?: string): string {
225
+ const lines: string[] = [];
226
+ const title = interview.title?.trim();
227
+ if (title) lines.push(`Interview: ${title}`);
228
+ const description = interview.description?.trim();
229
+ if (description) lines.push(description);
230
+ const note = message?.trim();
231
+ if (note) lines.push(`Child note: ${note}`);
232
+ if (lines.length > 0) lines.push("");
233
+
234
+ lines.push("Questions:");
235
+ interview.questions.forEach((question, index) => {
236
+ lines.push(`${index + 1}. [${question.id}] (${question.type}) ${question.question}`);
237
+ if (typeof question.context === "string" && question.context.trim()) {
238
+ lines.push(` Context: ${question.context.trim()}`);
239
+ }
240
+ if (question.options?.length) {
241
+ lines.push(" Options:");
242
+ for (const option of question.options) {
243
+ lines.push(` - ${interviewOptionLabel(option)}`);
244
+ }
245
+ }
246
+ });
247
+
248
+ const responseExample = {
249
+ responses: interview.questions
250
+ .filter((question) => question.type !== "info")
251
+ .map((question) => ({
252
+ id: question.id,
253
+ value: interviewExampleValue(question),
254
+ })),
255
+ };
256
+
257
+ lines.push(
258
+ "",
259
+ "Supervisor reply instructions:",
260
+ "Reply with plain JSON or a fenced ```json block using this stable shape. Use the question ids exactly. Info questions are context-only and do not need responses. For single questions, value is one option label. For multi questions, value is an array of option labels. For text/image questions, value is a string unless the question asks otherwise.",
261
+ "",
262
+ "```json",
263
+ JSON.stringify(responseExample, null, 2),
264
+ "```",
265
+ );
266
+
267
+ return lines.join("\n");
268
+ }
269
+
270
+ function validateSupervisorInterviewReply(value: unknown, interview: SupervisorInterviewRequest): SupervisorInterviewReply {
271
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
272
+ throw new Error("reply JSON must be an object with a responses array");
273
+ }
274
+
275
+ const responsesInput = (value as Record<string, unknown>).responses;
276
+ if (!Array.isArray(responsesInput)) {
277
+ throw new Error("reply JSON must include a responses array");
278
+ }
279
+
280
+ const questionById = new Map(interview.questions
281
+ .filter((question) => question.type !== "info")
282
+ .map((question) => [question.id, question]));
283
+ const seenIds = new Set<string>();
284
+ const responses: SupervisorInterviewReply["responses"] = [];
285
+
286
+ for (let index = 0; index < responsesInput.length; index++) {
287
+ const response = responsesInput[index];
288
+ if (!response || typeof response !== "object" || Array.isArray(response)) {
289
+ throw new Error(`responses[${index}] must be an object`);
290
+ }
291
+
292
+ const raw = response as Record<string, unknown>;
293
+ if (typeof raw.id !== "string" || raw.id.trim() === "") {
294
+ throw new Error(`responses[${index}].id must be a non-empty string`);
295
+ }
296
+ const id = raw.id.trim();
297
+ const question = questionById.get(id);
298
+ if (!question) {
299
+ throw new Error(`responses[${index}].id must match a non-info interview question id`);
300
+ }
301
+ if (seenIds.has(id)) {
302
+ throw new Error(`responses[${index}].id is duplicated: ${id}`);
303
+ }
304
+ seenIds.add(id);
305
+ if (!Object.hasOwn(raw, "value")) {
306
+ throw new Error(`responses[${index}].value is required`);
307
+ }
308
+
309
+ const value = raw.value;
310
+ if (question.type === "single") {
311
+ if (typeof value !== "string") throw new Error(`responses[${index}].value must be a string for single questions`);
312
+ const optionLabels = new Set(question.options?.map(interviewOptionLabel));
313
+ if (!optionLabels.has(value.trim())) throw new Error(`responses[${index}].value must match one of the question options`);
314
+ responses.push({ id, value: value.trim() });
315
+ continue;
316
+ }
317
+
318
+ if (question.type === "multi") {
319
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string")) {
320
+ throw new Error(`responses[${index}].value must be an array of strings for multi questions`);
321
+ }
322
+ const optionLabels = new Set(question.options?.map(interviewOptionLabel));
323
+ const selected = value.map((item) => item.trim());
324
+ const invalid = selected.find((item) => !optionLabels.has(item));
325
+ if (invalid) throw new Error(`responses[${index}].value contains an option that is not in the question options: ${invalid}`);
326
+ responses.push({ id, value: selected });
327
+ continue;
328
+ }
329
+
330
+ if (typeof value !== "string") {
331
+ throw new Error(`responses[${index}].value must be a string for ${question.type} questions`);
332
+ }
333
+ responses.push({ id, value });
334
+ }
335
+
336
+ return { responses };
337
+ }
338
+
339
+ function parseStructuredSupervisorReply(text: string, interview: SupervisorInterviewRequest): { value?: SupervisorInterviewReply; error?: string } | undefined {
340
+ const fencedMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/i);
341
+ const candidate = (fencedMatch?.[1] ?? text).trim();
342
+ if (!candidate.startsWith("{") && !candidate.startsWith("[")) {
343
+ return undefined;
344
+ }
345
+ try {
346
+ return { value: validateSupervisorInterviewReply(JSON.parse(candidate), interview) };
347
+ } catch (error) {
348
+ return { error: getErrorMessage(error) };
349
+ }
350
+ }
351
+ function duplicateSessionNames(sessions: SessionInfo[]): Set<string> {
352
+ return new Set(
353
+ sessions
354
+ .map(s => s.name?.toLowerCase())
355
+ .filter((name): name is string => Boolean(name))
356
+ .filter((name, index, names) => names.indexOf(name) !== index)
357
+ );
358
+ }
359
+ function shortSessionId(sessionId: string): string {
360
+ return sessionId.slice(0, 8);
361
+ }
362
+ function parseSubagentIntercomPayload(payload: unknown): { to: string; message: string; requestId?: string } | null {
363
+ if (typeof payload !== "object" || payload === null) {
364
+ return null;
365
+ }
366
+ const record = payload as Record<string, unknown>;
367
+ if (typeof record.to !== "string" || typeof record.message !== "string") {
368
+ return null;
369
+ }
370
+ const requestId = typeof record.requestId === "string" ? record.requestId : undefined;
371
+ return { to: record.to, message: record.message, ...(requestId ? { requestId } : {}) };
372
+ }
373
+ function resolveIntercomPresenceName(sessionName: string | undefined, sessionId: string): string {
374
+ const trimmedName = sessionName?.trim();
375
+ if (trimmedName) {
376
+ return trimmedName;
377
+ }
378
+ const normalizedSessionId = sessionId.startsWith("session-") ? sessionId.slice("session-".length) : sessionId;
379
+ return `${DEFAULT_UNNAMED_SESSION_ALIAS_PREFIX}-${normalizedSessionId.slice(0, 8)}`;
380
+ }
381
+ function buildPresenceIdentity(pi: ExtensionAPI, sessionId: string): { name: string } {
382
+ return {
383
+ name: resolveIntercomPresenceName(pi.getSessionName(), sessionId),
384
+ };
385
+ }
386
+ function formatSessionLabel(session: SessionInfo, duplicates: Set<string>): string {
387
+ if (!session.name) {
388
+ return session.id;
389
+ }
390
+ return duplicates.has(session.name.toLowerCase())
391
+ ? `${session.name} (${shortSessionId(session.id)})`
392
+ : session.name;
393
+ }
394
+ function formatSessionListRow(session: SessionInfo, currentCwd: string, isSelf: boolean): string {
395
+ const name = session.name || "Unnamed session";
396
+ const tags = [isSelf ? "self" : session.cwd === currentCwd ? "same cwd" : undefined, session.status]
397
+ .filter((tag): tag is string => Boolean(tag));
398
+ const suffix = tags.length ? ` [${tags.join(", ")}]` : "";
399
+ return `• ${name} (${shortSessionId(session.id)}) — ${session.cwd} (${session.model})${suffix}`;
400
+ }
401
+ function previewText(value: unknown, maxLength = 72): string | undefined {
402
+ if (typeof value !== "string") {
403
+ return undefined;
404
+ }
405
+ const normalized = value.replace(/\s+/g, " ").trim();
406
+ if (!normalized) {
407
+ return undefined;
408
+ }
409
+ return normalized.length > maxLength ? `${normalized.slice(0, maxLength - 1)}…` : normalized;
410
+ }
411
+ function firstTextContent(result: { content?: Array<{ type: string; text?: string }> }): string {
412
+ return result.content?.find((item) => item.type === "text" && typeof item.text === "string")?.text?.replace(/\*\*/g, "") ?? "";
413
+ }
414
+ export default function piIntercomExtension(pi: ExtensionAPI) {
415
+ let client: IntercomClient | null = null;
416
+ const config: IntercomConfig = loadConfig();
417
+ let runtimeContext: ExtensionContext | null = null;
418
+ let currentSessionId: string | null = null;
419
+ let currentModel = "unknown";
420
+ let sessionStartedAt: number | null = null;
421
+ let reconnectTimer: NodeJS.Timeout | null = null;
422
+ let reconnectPromise: Promise<IntercomClient> | null = null;
423
+ let reconnectPromiseGeneration: number | null = null;
424
+ let startupConnectTimer: NodeJS.Timeout | null = null;
425
+ let reconnectAttempt = 0;
426
+ let shuttingDown = false;
427
+ let disposed = true;
428
+ let runtimeStarted = false;
429
+ let runtimeGeneration = 0;
430
+ let agentRunning = false;
431
+ const activeTools = new Map<string, string>();
432
+ const replyTracker = new ReplyTracker();
433
+ const pendingIdleMessages: InboundMessageEntry[] = [];
434
+ let inboundFlushTimer: NodeJS.Timeout | null = null;
435
+ let replyWaiter: {
436
+ from: string;
437
+ replyTo: string;
438
+ resolve: (message: Message) => void;
439
+ reject: (error: Error) => void;
440
+ } | null = null;
441
+ function waitForReply(from: string, replyTo: string, signal?: AbortSignal): Promise<Message> {
442
+ if (replyWaiter) {
443
+ return Promise.reject(new Error("Already waiting for a reply"));
444
+ }
445
+ if (signal?.aborted) {
446
+ return Promise.reject(new Error("Cancelled"));
447
+ }
448
+ return new Promise((resolve, reject) => {
449
+ const timeout = setTimeout(() => {
450
+ rejectReplyWaiter(new Error(`No reply from "${from}" within 10 minutes`));
451
+ }, 10 * 60 * 1000);
452
+ const cleanup = () => {
453
+ clearTimeout(timeout);
454
+ signal?.removeEventListener("abort", onAbort);
455
+ if (replyWaiter?.replyTo === replyTo) {
456
+ replyWaiter = null;
457
+ }
458
+ };
459
+ const onAbort = () => {
460
+ cleanup();
461
+ reject(new Error("Cancelled"));
462
+ };
463
+ signal?.addEventListener("abort", onAbort, { once: true });
464
+ replyWaiter = {
465
+ from,
466
+ replyTo,
467
+ resolve: (message) => {
468
+ cleanup();
469
+ resolve(message);
470
+ },
471
+ reject: (error) => {
472
+ cleanup();
473
+ reject(error);
474
+ },
475
+ };
476
+ });
477
+ }
478
+ function rejectReplyWaiter(error: Error): void {
479
+ replyWaiter?.reject(error);
480
+ }
481
+ function clearReconnectTimer(): void {
482
+ if (!reconnectTimer) {
483
+ return;
484
+ }
485
+ clearTimeout(reconnectTimer);
486
+ reconnectTimer = null;
487
+ }
488
+ function clearStartupConnectTimer(): void {
489
+ if (!startupConnectTimer) {
490
+ return;
491
+ }
492
+ clearTimeout(startupConnectTimer);
493
+ startupConnectTimer = null;
494
+ }
495
+ function clearInboundFlushTimer(): void {
496
+ if (!inboundFlushTimer) {
497
+ return;
498
+ }
499
+ clearTimeout(inboundFlushTimer);
500
+ inboundFlushTimer = null;
501
+ }
502
+ function getLiveContext(ctx: ExtensionContext | null = runtimeContext, generation = runtimeGeneration): ExtensionContext | null {
503
+ if (disposed || shuttingDown || generation !== runtimeGeneration || !ctx) {
504
+ return null;
505
+ }
506
+ try {
507
+ if (currentSessionId && ctx.sessionManager.getSessionId() !== currentSessionId) {
508
+ return null;
509
+ }
510
+ void ctx.hasUI;
511
+ return ctx;
512
+ } catch {
513
+ // A context that throws while reading session/UI state is no longer usable.
514
+ return null;
515
+ }
516
+ }
517
+ function notifyIfLive(ctx: ExtensionContext, message: string, level: "info" | "warning" | "error", generation = runtimeGeneration): void {
518
+ const liveContext = getLiveContext(ctx, generation);
519
+ if (!liveContext?.hasUI) {
520
+ return;
521
+ }
522
+ try {
523
+ liveContext.ui.notify(message, level);
524
+ } catch {
525
+ // The UI can disappear during session shutdown/reload while async overlay work is settling.
526
+ }
527
+ }
528
+ function getReconnectDelayMs(): number {
529
+ const backoffMs = [1000, 2000, 5000, 10000, 30000];
530
+ return backoffMs[Math.min(reconnectAttempt, backoffMs.length - 1)]!;
531
+ }
532
+ function currentStatus(): string {
533
+ const activeToolName = activeTools.values().next().value;
534
+ const lifecycleStatus = activeToolName ? `tool:${activeToolName}` : agentRunning ? "thinking" : "idle";
535
+ return config.status ? `${lifecycleStatus} · ${config.status}` : lifecycleStatus;
536
+ }
537
+ function buildRegistration(): Omit<SessionInfo, "id"> {
538
+ const liveContext = getLiveContext();
539
+ if (!liveContext || !currentSessionId || sessionStartedAt === null) {
540
+ throw new Error("Intercom runtime not initialized");
541
+ }
542
+
543
+ const identity = buildPresenceIdentity(pi, currentSessionId);
544
+ return {
545
+ name: identity.name,
546
+ cwd: liveContext.cwd ?? process.cwd(),
547
+ model: currentModel,
548
+ pid: process.pid,
549
+ startedAt: sessionStartedAt,
550
+ lastActivity: Date.now(),
551
+ status: currentStatus(),
552
+ };
553
+ }
554
+ function syncPresenceIdentity(sessionId: string): void {
555
+ if (!client || !getLiveContext()) {
556
+ return;
557
+ }
558
+ client.updatePresence({ ...buildPresenceIdentity(pi, sessionId), status: currentStatus() });
559
+ }
560
+ function syncPresenceStatus(): void {
561
+ if (!client || !currentSessionId || !getLiveContext()) {
562
+ return;
563
+ }
564
+ client.updatePresence({ status: currentStatus() });
565
+ }
566
+ function currentSessionTargetMatches(to: string, resolvedTo?: string | null, activeClient?: IntercomClient): boolean {
567
+ const targets = new Set<string>();
568
+ const addTarget = (target: string | undefined | null) => {
569
+ const trimmed = target?.trim();
570
+ if (trimmed) targets.add(trimmed.toLowerCase());
571
+ };
572
+ addTarget(currentSessionId);
573
+ addTarget(activeClient?.sessionId);
574
+ addTarget(pi.getSessionName());
575
+ if (currentSessionId) addTarget(buildPresenceIdentity(pi, currentSessionId).name);
576
+ return Boolean(resolvedTo && activeClient?.sessionId && resolvedTo === activeClient.sessionId)
577
+ || targets.has(to.trim().toLowerCase());
578
+ }
579
+ function sendIncomingMessage(entry: InboundMessageEntry, delivery: "trigger" | "followUp", generation = runtimeGeneration): void {
580
+ if (runtimeStarted && !getLiveContext(runtimeContext, generation)) {
581
+ return;
582
+ }
583
+ if (delivery !== "followUp") {
584
+ replyTracker.queueTurnContext({ from: entry.from, message: entry.message, receivedAt: Date.now() });
585
+ }
586
+ const senderDisplay = entry.from.name || entry.from.id.slice(0, 8);
587
+ const replyInstruction = entry.replyCommand ? `\n\nTo reply, use the intercom tool: ${entry.replyCommand}` : "";
588
+ pi.sendMessage(
589
+ {
590
+ customType: "intercom_message",
591
+ content: `**📨 From ${senderDisplay}** (${entry.from.cwd})${replyInstruction}\n\n${entry.bodyText}`,
592
+ display: true,
593
+ details: entry,
594
+ },
595
+ delivery === "trigger"
596
+ ? { triggerTurn: true }
597
+ : { deliverAs: "followUp" }
598
+ );
599
+ }
600
+ function scheduleInboundFlush(delayMs = INBOUND_FLUSH_DELAY_MS): void {
601
+ if (!getLiveContext()) {
602
+ return;
603
+ }
604
+ const scheduledGeneration = runtimeGeneration;
605
+ clearInboundFlushTimer();
606
+ inboundFlushTimer = setTimeout(() => {
607
+ inboundFlushTimer = null;
608
+ flushIdleMessages(scheduledGeneration);
609
+ }, delayMs);
610
+ }
611
+ function flushIdleMessages(generation = runtimeGeneration): void {
612
+ if (pendingIdleMessages.length === 0) {
613
+ return;
614
+ }
615
+ const ctx = getLiveContext(runtimeContext, generation);
616
+ if (!ctx) {
617
+ return;
618
+ }
619
+
620
+ let isIdle: boolean;
621
+ try {
622
+ isIdle = ctx.isIdle();
623
+ } catch {
624
+ // Stale contexts are cleaned up by shutdown/reload; do not deliver queued messages through them.
625
+ return;
626
+ }
627
+ if (!isIdle) {
628
+ scheduleInboundFlush(INBOUND_IDLE_RETRY_MS);
629
+ return;
630
+ }
631
+
632
+ const entries = pendingIdleMessages.splice(0, pendingIdleMessages.length);
633
+ entries.forEach((entry, index) => {
634
+ sendIncomingMessage(entry, index === 0 ? "trigger" : "followUp");
635
+ });
636
+ }
637
+ function queueIdleMessage(entry: InboundMessageEntry): void {
638
+ pendingIdleMessages.push(entry);
639
+ scheduleInboundFlush();
640
+ }
641
+ function handleIncomingMessage(ctx: ExtensionContext, from: SessionInfo, message: Message): void {
642
+ const messageGeneration = runtimeGeneration;
643
+ const liveContext = getLiveContext(ctx, messageGeneration);
644
+ if (!liveContext) {
645
+ return;
646
+ }
647
+ if (replyWaiter) {
648
+ const senderTarget = from.name || from.id;
649
+ const fromMatches = senderTarget.toLowerCase() === replyWaiter.from.toLowerCase()
650
+ || from.id === replyWaiter.from;
651
+ const replyMatches = message.replyTo === replyWaiter.replyTo;
652
+ if (fromMatches && replyMatches) {
653
+ replyWaiter.resolve(message);
654
+ return;
655
+ }
656
+ }
657
+ const attachmentText = message.content.attachments?.length
658
+ ? formatAttachments(message.content.attachments)
659
+ : "";
660
+ const bodyText = `${message.content.text}${attachmentText}`;
661
+ const replyCommand = config.replyHint && message.expectsReply
662
+ ? `intercom({ action: "reply", message: "..." })`
663
+ : undefined;
664
+ replyTracker.recordIncomingMessage(from, message);
665
+ const entry = { from, message, replyCommand, bodyText };
666
+ void (async () => {
667
+ const activeContext = getLiveContext(liveContext, messageGeneration);
668
+ if (!activeContext) {
669
+ return;
670
+ }
671
+ if (!activeContext.isIdle()) {
672
+ if (!activeContext.hasUI) {
673
+ const activeClient = client;
674
+ if (!message.replyTo && activeClient?.isConnected()) {
675
+ try {
676
+ const result = await activeClient.send(from.id, {
677
+ text: "This agent is running in non-interactive mode and cannot respond to intercom messages while it is working. It will continue its current task and exit when done.",
678
+ replyTo: message.id,
679
+ });
680
+ if (result.delivered && getLiveContext(liveContext, messageGeneration)) {
681
+ replyTracker.markReplied(message.id);
682
+ }
683
+ } catch {
684
+ // Best-effort reply; keep the busy non-interactive session running either way.
685
+ }
686
+ }
687
+ return;
688
+ }
689
+ queueIdleMessage(entry);
690
+ return;
691
+ }
692
+ if (getLiveContext(liveContext, messageGeneration)) {
693
+ sendIncomingMessage(entry, "trigger", messageGeneration);
694
+ }
695
+ })();
696
+ }
697
+ function attachClientHandlers(nextClient: IntercomClient): void {
698
+ nextClient.on("message", (from, message) => {
699
+ const liveContext = getLiveContext();
700
+ if (client !== nextClient || !liveContext) {
701
+ return;
702
+ }
703
+ handleIncomingMessage(liveContext, from, message);
704
+ });
705
+ nextClient.on("disconnected", (error: Error) => {
706
+ if (client !== nextClient) {
707
+ return;
708
+ }
709
+ rejectReplyWaiter(new Error(`Disconnected while waiting for reply: ${error.message}`, { cause: error }));
710
+ client = null;
711
+ if (!shuttingDown && !disposed) {
712
+ clearReconnectTimer();
713
+ scheduleReconnect();
714
+ }
715
+ });
716
+ nextClient.on("error", () => {
717
+ // Keep broker/socket noise out of the TUI. Reconnect logic runs from the disconnect path.
718
+ });
719
+ }
720
+ function scheduleReconnect(): void {
721
+ if (disposed || shuttingDown || reconnectTimer || reconnectPromise || !getLiveContext()) {
722
+ return;
723
+ }
724
+ const scheduledGeneration = runtimeGeneration;
725
+ reconnectTimer = setTimeout(() => {
726
+ reconnectTimer = null;
727
+ if (scheduledGeneration !== runtimeGeneration || !getLiveContext()) {
728
+ return;
729
+ }
730
+ reconnectAttempt += 1;
731
+ void ensureConnected("background").catch(() => {
732
+ // ensureConnected("background") already queued the next retry.
733
+ });
734
+ }, getReconnectDelayMs());
735
+ }
736
+ async function ensureConnected(reason: "startup" | "background" | "tool" | "overlay"): Promise<IntercomClient> {
737
+ if (!config.enabled) {
738
+ throw new Error("Intercom disabled");
739
+ }
740
+ if (disposed || shuttingDown) {
741
+ throw new Error("Intercom shutting down");
742
+ }
743
+ if (client && client.isConnected()) {
744
+ return client;
745
+ }
746
+ const contextAtStart = getLiveContext();
747
+ const generationAtStart = runtimeGeneration;
748
+ if (!contextAtStart || !currentSessionId || sessionStartedAt === null) {
749
+ throw new Error("Intercom runtime not initialized");
750
+ }
751
+ clearReconnectTimer();
752
+ if (reconnectPromise && reconnectPromiseGeneration === generationAtStart) {
753
+ return reconnectPromise;
754
+ }
755
+ const nextReconnectPromise = (async () => {
756
+ const nextClient = new IntercomClient();
757
+ client = nextClient;
758
+ attachClientHandlers(nextClient);
759
+ try {
760
+ await spawnBrokerIfNeeded(config.brokerCommand, config.brokerArgs);
761
+ await nextClient.connect(buildRegistration());
762
+ if (!getLiveContext(contextAtStart, generationAtStart)) {
763
+ await nextClient.disconnect();
764
+ throw new Error("Intercom runtime no longer active");
765
+ }
766
+ client = nextClient;
767
+ reconnectAttempt = 0;
768
+ return nextClient;
769
+ } catch (error) {
770
+ if (client === nextClient) {
771
+ client = null;
772
+ }
773
+ if (reason === "background" && getLiveContext(contextAtStart, generationAtStart)) {
774
+ scheduleReconnect();
775
+ }
776
+ throw toError(error);
777
+ } finally {
778
+ if (reconnectPromise === nextReconnectPromise) {
779
+ reconnectPromise = null;
780
+ reconnectPromiseGeneration = null;
781
+ }
782
+ }
783
+ })();
784
+ reconnectPromise = nextReconnectPromise;
785
+ reconnectPromiseGeneration = generationAtStart;
786
+ return nextReconnectPromise;
787
+ }
788
+ async function resolveSessionTarget(activeClient: IntercomClient, nameOrId: string): Promise<string | null> {
789
+ const sessions = await activeClient.listSessions();
790
+ const byId = sessions.find(s => s.id === nameOrId);
791
+ if (byId) {
792
+ return byId.id;
793
+ }
794
+ const lowerName = nameOrId.toLowerCase();
795
+ const byName = sessions.filter(s => s.name?.toLowerCase() === lowerName);
796
+ if (byName.length > 1) {
797
+ throw new Error(`Multiple sessions named "${nameOrId}" are connected. Use the session ID instead.`);
798
+ }
799
+ return byName[0]?.id ?? null;
800
+ }
801
+ function deliverLocalSubagentRelayMessage(sender: "subagent-control" | "subagent-result", status: string, messageText: string): void {
802
+ const now = Date.now();
803
+ sendIncomingMessage({
804
+ from: {
805
+ id: sender,
806
+ name: sender,
807
+ cwd: runtimeContext?.cwd ?? process.cwd(),
808
+ model: sender,
809
+ pid: process.pid,
810
+ startedAt: now,
811
+ lastActivity: now,
812
+ status,
813
+ },
814
+ message: {
815
+ id: randomUUID(),
816
+ timestamp: now,
817
+ content: { text: messageText },
818
+ },
819
+ bodyText: messageText,
820
+ }, "trigger");
821
+ }
822
+ function recordSubagentDeliveryError(entryType: string, to: string, message: string, error: unknown): void {
823
+ pi.appendEntry(entryType, {
824
+ to,
825
+ message,
826
+ error: getErrorMessage(error),
827
+ timestamp: Date.now(),
828
+ });
829
+ }
830
+ function emitResultDelivery(requestId: string | undefined, delivered: boolean, error?: unknown): void {
831
+ if (!requestId) return;
832
+ pi.events.emit(SUBAGENT_RESULT_INTERCOM_DELIVERY_EVENT, {
833
+ requestId,
834
+ delivered,
835
+ ...(error ? { error: getErrorMessage(error) } : {}),
836
+ });
837
+ }
838
+ function relaySubagentIntercomPayload(payload: unknown, options: {
839
+ sender: "subagent-control" | "subagent-result";
840
+ status: string;
841
+ errorEntryType: string;
842
+ acknowledge?: boolean;
843
+ }): void {
844
+ const parsed = parseSubagentIntercomPayload(payload);
845
+ if (!parsed) return;
846
+
847
+ const relayGeneration = runtimeGeneration;
848
+ void (async () => {
849
+ const relayStillLive = () => !runtimeStarted || Boolean(getLiveContext(runtimeContext, relayGeneration));
850
+ if (!relayStillLive()) {
851
+ return;
852
+ }
853
+ if (currentSessionTargetMatches(parsed.to)) {
854
+ deliverLocalSubagentRelayMessage(options.sender, options.status, parsed.message);
855
+ if (options.acknowledge) emitResultDelivery(parsed.requestId, true);
856
+ return;
857
+ }
858
+
859
+ let activeClient: IntercomClient;
860
+ let target: string;
861
+ try {
862
+ activeClient = await ensureConnected("background");
863
+ target = await resolveSessionTarget(activeClient, parsed.to) ?? parsed.to;
864
+ } catch (error) {
865
+ if (!relayStillLive()) return;
866
+ recordSubagentDeliveryError(options.errorEntryType, parsed.to, parsed.message, error);
867
+ if (options.acknowledge) emitResultDelivery(parsed.requestId, false, error);
868
+ return;
869
+ }
870
+
871
+ if (!relayStillLive()) {
872
+ return;
873
+ }
874
+ if (currentSessionTargetMatches(parsed.to, target, activeClient)) {
875
+ deliverLocalSubagentRelayMessage(options.sender, options.status, parsed.message);
876
+ if (options.acknowledge) emitResultDelivery(parsed.requestId, true);
877
+ return;
878
+ }
879
+
880
+ try {
881
+ const result = await activeClient.send(target, { text: parsed.message });
882
+ if (!relayStillLive()) return;
883
+ if (!result.delivered) {
884
+ const error = new Error(result.reason ?? "Session may not exist or has disconnected.");
885
+ recordSubagentDeliveryError(options.errorEntryType, parsed.to, parsed.message, error);
886
+ if (options.acknowledge) emitResultDelivery(parsed.requestId, false, error);
887
+ return;
888
+ }
889
+ if (options.acknowledge) emitResultDelivery(parsed.requestId, true);
890
+ } catch (error) {
891
+ if (!relayStillLive()) return;
892
+ recordSubagentDeliveryError(options.errorEntryType, parsed.to, parsed.message, error);
893
+ if (options.acknowledge) emitResultDelivery(parsed.requestId, false, error);
894
+ }
895
+ })();
896
+ }
897
+ pi.events.on(SUBAGENT_CONTROL_INTERCOM_EVENT, (payload) => {
898
+ relaySubagentIntercomPayload(payload, {
899
+ sender: "subagent-control",
900
+ status: "needs_attention",
901
+ errorEntryType: "intercom_control_error",
902
+ });
903
+ });
904
+ pi.events.on(SUBAGENT_RESULT_INTERCOM_EVENT, (payload) => {
905
+ relaySubagentIntercomPayload(payload, {
906
+ sender: "subagent-result",
907
+ status: "result",
908
+ errorEntryType: "intercom_result_error",
909
+ acknowledge: true,
910
+ });
911
+ });
912
+ pi.on("session_start", (_event, ctx) => {
913
+ if (!config.enabled) {
914
+ return;
915
+ }
916
+ shuttingDown = false;
917
+ disposed = false;
918
+ runtimeStarted = true;
919
+ runtimeGeneration += 1;
920
+ reconnectAttempt = 0;
921
+ clearReconnectTimer();
922
+ clearStartupConnectTimer();
923
+ runtimeContext = ctx;
924
+ currentSessionId = ctx.sessionManager.getSessionId();
925
+ currentModel = ctx.model?.id ?? "unknown";
926
+ sessionStartedAt = Date.now();
927
+ agentRunning = false;
928
+ activeTools.clear();
929
+ const startupGeneration = runtimeGeneration;
930
+ startupConnectTimer = setTimeout(() => {
931
+ startupConnectTimer = null;
932
+ if (!getLiveContext(ctx, startupGeneration)) {
933
+ return;
934
+ }
935
+ void ensureConnected("startup").catch(() => {
936
+ if (!getLiveContext(ctx, startupGeneration)) {
937
+ return;
938
+ }
939
+ client = null;
940
+ scheduleReconnect();
941
+ });
942
+ }, 0);
943
+ });
944
+
945
+ pi.on("session_shutdown", async () => {
946
+ shuttingDown = true;
947
+ disposed = true;
948
+ runtimeGeneration += 1;
949
+ clearStartupConnectTimer();
950
+ clearReconnectTimer();
951
+ rejectReplyWaiter(new Error("Session shutting down"));
952
+ replyTracker.reset();
953
+ pendingIdleMessages.length = 0;
954
+ clearInboundFlushTimer();
955
+ agentRunning = false;
956
+ activeTools.clear();
957
+ if (client) {
958
+ await client.disconnect();
959
+ client = null;
960
+ }
961
+ runtimeContext = null;
962
+ currentSessionId = null;
963
+ sessionStartedAt = null;
964
+ });
965
+ pi.on("turn_end", () => {
966
+ if (!getLiveContext()) {
967
+ return;
968
+ }
969
+ replyTracker.endTurn();
970
+ scheduleInboundFlush(0);
971
+ });
972
+ pi.on("agent_start", () => {
973
+ if (!getLiveContext()) {
974
+ return;
975
+ }
976
+ agentRunning = true;
977
+ activeTools.clear();
978
+ syncPresenceStatus();
979
+ });
980
+ pi.on("tool_execution_start", (event) => {
981
+ if (!getLiveContext()) {
982
+ return;
983
+ }
984
+ activeTools.set(event.toolCallId, event.toolName);
985
+ syncPresenceStatus();
986
+ });
987
+ pi.on("tool_execution_end", (event) => {
988
+ if (!getLiveContext()) {
989
+ return;
990
+ }
991
+ activeTools.delete(event.toolCallId);
992
+ syncPresenceStatus();
993
+ });
994
+ pi.on("agent_end", () => {
995
+ if (!getLiveContext()) {
996
+ return;
997
+ }
998
+ agentRunning = false;
999
+ activeTools.clear();
1000
+ syncPresenceStatus();
1001
+ scheduleInboundFlush(0);
1002
+ });
1003
+ pi.on("turn_start", (_event, ctx) => {
1004
+ if (!getLiveContext(ctx)) {
1005
+ return;
1006
+ }
1007
+ currentSessionId = ctx.sessionManager.getSessionId();
1008
+ syncPresenceIdentity(ctx.sessionManager.getSessionId());
1009
+ replyTracker.beginTurn();
1010
+ });
1011
+ pi.on("model_select", (event, ctx) => {
1012
+ if (!getLiveContext(ctx)) {
1013
+ return;
1014
+ }
1015
+ currentModel = event.model.id;
1016
+ if (client) {
1017
+ client.updatePresence({
1018
+ ...buildPresenceIdentity(pi, ctx.sessionManager.getSessionId()),
1019
+ model: event.model.id,
1020
+ status: currentStatus(),
1021
+ });
1022
+ }
1023
+ });
1024
+
1025
+ pi.registerMessageRenderer("intercom_message", (message, _options, theme) => {
1026
+ const details = message.details as { from: SessionInfo; message: Message; replyCommand?: string; bodyText?: string } | undefined;
1027
+ if (!details) return undefined;
1028
+ return new InlineMessageComponent(details.from, details.message, theme, details.replyCommand, details.bodyText);
1029
+ });
1030
+
1031
+ const childOrchestratorMetadata = readChildOrchestratorMetadata();
1032
+ if (childOrchestratorMetadata) {
1033
+ pi.registerTool({
1034
+ name: "contact_supervisor",
1035
+ label: "Contact Supervisor",
1036
+ description: "Subagent-only tool for contacting the supervisor agent that delegated this task. Use need_decision when blocked, uncertain, needing approval, or facing a product/API/scope decision before continuing; this waits for the supervisor's reply. Use interview_request when multiple structured questions need supervisor answers; this also waits for a reply. Use progress_update only for meaningful progress or unexpected discoveries that change the plan; this does not wait for a reply. Do not use for routine completion handoffs.",
1037
+ promptSnippet: "Subagent-only: contact the supervisor for decisions, structured interviews, or meaningful plan-changing updates. Do not use for routine completion handoffs.",
1038
+ promptGuidelines: [
1039
+ "Use contact_supervisor with reason='need_decision' when a subagent is blocked, uncertain, needs approval, or faces a product/API/scope decision before continuing.",
1040
+ "Use contact_supervisor with reason='interview_request' when the child needs multiple structured answers from the supervisor in one blocking exchange.",
1041
+ "Use contact_supervisor with reason='progress_update' only for meaningful progress or unexpected discoveries that change the plan.",
1042
+ "Do not use contact_supervisor for routine completion handoffs; return the final subagent result normally.",
1043
+ ],
1044
+ parameters: Type.Object({
1045
+ reason: Type.String({
1046
+ enum: ["need_decision", "progress_update", "interview_request"],
1047
+ description: "Contact reason: 'need_decision' waits for a reply; 'interview_request' sends structured questions and waits for a reply; 'progress_update' sends a non-blocking update",
1048
+ }),
1049
+ message: Type.Optional(Type.String({
1050
+ description: "Decision request, optional interview note, or meaningful progress update for the supervisor",
1051
+ })),
1052
+ interview: Type.Optional(Type.Object({
1053
+ title: Type.Optional(Type.String()),
1054
+ description: Type.Optional(Type.String()),
1055
+ questions: Type.Array(Type.Object({
1056
+ id: Type.String(),
1057
+ type: Type.String({ description: "Question type: single, multi, text, image, or info" }),
1058
+ question: Type.String(),
1059
+ options: Type.Optional(Type.Array(Type.Any())),
1060
+ context: Type.Optional(Type.String()),
1061
+ })),
1062
+ }, { description: "Structured interview request for reason='interview_request'" })),
1063
+ }),
1064
+ async execute(_toolCallId, params, signal, _onUpdate, ctx) {
1065
+ const reason = params.reason as ContactSupervisorReason;
1066
+ if (reason !== "need_decision" && reason !== "progress_update" && reason !== "interview_request") {
1067
+ return {
1068
+ content: [{ type: "text", text: "Invalid reason. Use 'need_decision', 'interview_request', or 'progress_update'." }],
1069
+ isError: true,
1070
+ details: { error: true },
1071
+ };
1072
+ }
1073
+ if ((reason === "need_decision" || reason === "progress_update") && typeof params.message !== "string") {
1074
+ return {
1075
+ content: [{ type: "text", text: `Missing 'message' parameter for reason '${reason}'.` }],
1076
+ isError: true,
1077
+ details: { error: true },
1078
+ };
1079
+ }
1080
+ const interviewValidation = reason === "interview_request"
1081
+ ? validateSupervisorInterviewRequest(params.interview)
1082
+ : undefined;
1083
+ if (interviewValidation?.ok === false) {
1084
+ return {
1085
+ content: [{ type: "text", text: `Invalid interview request: ${interviewValidation.error}` }],
1086
+ isError: true,
1087
+ details: { error: true },
1088
+ };
1089
+ }
1090
+ const supervisorInterview = interviewValidation?.ok === true ? interviewValidation.interview : undefined;
1091
+
1092
+ let connectedClient: IntercomClient;
1093
+ try {
1094
+ connectedClient = await ensureConnected("tool");
1095
+ } catch (error) {
1096
+ return {
1097
+ content: [{ type: "text", text: `Intercom not connected: ${getErrorMessage(error)}` }],
1098
+ isError: true,
1099
+ details: { error: true },
1100
+ };
1101
+ }
1102
+
1103
+ syncPresenceIdentity(ctx.sessionManager.getSessionId());
1104
+
1105
+ if (signal?.aborted) {
1106
+ return {
1107
+ content: [{ type: "text", text: "Cancelled" }],
1108
+ isError: true,
1109
+ details: { error: true },
1110
+ };
1111
+ }
1112
+
1113
+ const metadata = childOrchestratorMetadata;
1114
+ let sendTo: string;
1115
+ try {
1116
+ sendTo = await resolveSessionTarget(connectedClient, metadata.orchestratorTarget) ?? metadata.orchestratorTarget;
1117
+ } catch (error) {
1118
+ return {
1119
+ content: [{ type: "text", text: `Failed to resolve supervisor target: ${getErrorMessage(error)}` }],
1120
+ isError: true,
1121
+ details: { error: true },
1122
+ };
1123
+ }
1124
+ if (signal?.aborted) {
1125
+ return {
1126
+ content: [{ type: "text", text: "Cancelled" }],
1127
+ isError: true,
1128
+ details: { error: true },
1129
+ };
1130
+ }
1131
+ if (sendTo === connectedClient.sessionId) {
1132
+ return {
1133
+ content: [{ type: "text", text: "Cannot message the current session" }],
1134
+ isError: true,
1135
+ details: { error: true },
1136
+ };
1137
+ }
1138
+
1139
+ if (reason === "progress_update") {
1140
+ const message = params.message as string;
1141
+ try {
1142
+ const result = await connectedClient.send(sendTo, {
1143
+ text: formatChildOrchestratorMessage("update", metadata, message),
1144
+ });
1145
+ if (!result.delivered) {
1146
+ const errorText = result.reason ?? "Session may not exist or has disconnected.";
1147
+ return {
1148
+ content: [{ type: "text", text: `Message to "${metadata.orchestratorTarget}" was not delivered: ${errorText}` }],
1149
+ isError: true,
1150
+ details: { messageId: result.id, delivered: false, reason: result.reason },
1151
+ };
1152
+ }
1153
+ pi.appendEntry("intercom_sent", {
1154
+ to: metadata.orchestratorTarget,
1155
+ message: { text: message, reason },
1156
+ messageId: result.id,
1157
+ timestamp: Date.now(),
1158
+ subagent: { runId: metadata.runId, agent: metadata.agent, index: metadata.index },
1159
+ });
1160
+ return {
1161
+ content: [{ type: "text", text: `Progress update sent to supervisor ${metadata.orchestratorTarget}` }],
1162
+ isError: false,
1163
+ details: { messageId: result.id, delivered: true },
1164
+ };
1165
+ } catch (error) {
1166
+ return {
1167
+ content: [{ type: "text", text: `Failed to send progress update: ${getErrorMessage(error)}` }],
1168
+ isError: true,
1169
+ details: { error: true },
1170
+ };
1171
+ }
1172
+ }
1173
+
1174
+ if (replyWaiter) {
1175
+ return {
1176
+ content: [{ type: "text", text: "Already waiting for a reply" }],
1177
+ isError: true,
1178
+ details: { error: true },
1179
+ };
1180
+ }
1181
+
1182
+ let replyPromise: Promise<Message> | null = null;
1183
+ try {
1184
+ const questionId = randomUUID();
1185
+ replyPromise = waitForReply(sendTo, questionId, signal);
1186
+ replyPromise.catch(() => undefined);
1187
+ if (signal?.aborted) {
1188
+ rejectReplyWaiter(new Error("Cancelled"));
1189
+ try {
1190
+ await replyPromise;
1191
+ } catch {
1192
+ // The waiter was intentionally rejected above; the tool result reports cancellation.
1193
+ }
1194
+ return {
1195
+ content: [{ type: "text", text: "Cancelled" }],
1196
+ isError: true,
1197
+ details: { error: true },
1198
+ };
1199
+ }
1200
+ const requestText = reason === "interview_request"
1201
+ ? formatChildOrchestratorMessage("interview", metadata, formatSupervisorInterviewRequest(supervisorInterview!, typeof params.message === "string" ? params.message : undefined))
1202
+ : formatChildOrchestratorMessage("ask", metadata, params.message as string);
1203
+ const sendResult = await connectedClient.send(sendTo, {
1204
+ messageId: questionId,
1205
+ text: requestText,
1206
+ expectsReply: true,
1207
+ });
1208
+ if (!sendResult.delivered) {
1209
+ const errorText = sendResult.reason ?? "Session may not exist or has disconnected.";
1210
+ rejectReplyWaiter(new Error(`Message to "${metadata.orchestratorTarget}" was not delivered: ${errorText}`));
1211
+ if (replyPromise) {
1212
+ try {
1213
+ await replyPromise;
1214
+ } catch {
1215
+ // The waiter was already rejected above. Keep the delivery failure as the only error here.
1216
+ }
1217
+ }
1218
+ return {
1219
+ content: [{ type: "text", text: `Message to "${metadata.orchestratorTarget}" was not delivered: ${errorText}` }],
1220
+ isError: true,
1221
+ details: { error: true },
1222
+ };
1223
+ }
1224
+ pi.appendEntry("intercom_sent", {
1225
+ to: metadata.orchestratorTarget,
1226
+ message: {
1227
+ text: reason === "interview_request" ? requestText : params.message,
1228
+ reason,
1229
+ ...(reason === "interview_request" ? { interview: supervisorInterview } : {}),
1230
+ },
1231
+ messageId: sendResult.id,
1232
+ timestamp: Date.now(),
1233
+ subagent: { runId: metadata.runId, agent: metadata.agent, index: metadata.index },
1234
+ });
1235
+ const replyMessage = await replyPromise;
1236
+ const replyText = replyMessage.content.text;
1237
+ const replyAttachments = replyMessage.content.attachments?.length
1238
+ ? formatAttachments(replyMessage.content.attachments)
1239
+ : "";
1240
+ const structuredReply = reason === "interview_request" ? parseStructuredSupervisorReply(replyText, supervisorInterview!) : undefined;
1241
+ pi.appendEntry("intercom_received", {
1242
+ from: metadata.orchestratorTarget,
1243
+ message: { text: replyText, attachments: replyMessage.content.attachments },
1244
+ messageId: replyMessage.id,
1245
+ timestamp: replyMessage.timestamp,
1246
+ subagent: { runId: metadata.runId, agent: metadata.agent, index: metadata.index },
1247
+ });
1248
+ return {
1249
+ content: [{ type: "text", text: `**Reply from supervisor:**\n${replyText}${replyAttachments}` }],
1250
+ isError: false,
1251
+ ...(structuredReply
1252
+ ? { details: structuredReply.value !== undefined ? { structuredReply: structuredReply.value } : { structuredReplyParseError: structuredReply.error } }
1253
+ : {}),
1254
+ };
1255
+ } catch (error) {
1256
+ rejectReplyWaiter(toError(error));
1257
+ if (replyPromise) {
1258
+ try {
1259
+ await replyPromise;
1260
+ } catch {
1261
+ // The waiter is cleanup-only on this path. The real failure is the one from the outer catch.
1262
+ }
1263
+ }
1264
+ return {
1265
+ content: [{ type: "text", text: `Failed: ${getErrorMessage(error)}` }],
1266
+ isError: true,
1267
+ details: { error: true },
1268
+ };
1269
+ }
1270
+ },
1271
+ renderCall(args, theme) {
1272
+ const reason = typeof args.reason === "string" ? args.reason : "contact";
1273
+ const messagePreview = previewText(args.message, 96);
1274
+ const interview = args.interview && typeof args.interview === "object" ? args.interview as { title?: unknown } : undefined;
1275
+ let text = theme.fg("toolTitle", theme.bold("contact_supervisor "));
1276
+ text += theme.fg(reason === "need_decision" ? "warning" : reason === "progress_update" ? "muted" : "accent", reason);
1277
+ if (typeof interview?.title === "string" && interview.title.trim()) {
1278
+ text += " " + theme.fg("accent", interview.title.trim());
1279
+ }
1280
+ if (messagePreview) {
1281
+ text += "\n " + theme.fg("dim", messagePreview);
1282
+ }
1283
+ return new Text(text, 0, 0);
1284
+ },
1285
+ renderResult(result, { isPartial }, theme, context) {
1286
+ if (isPartial) {
1287
+ return new Text(theme.fg("warning", "Waiting for supervisor..."), 0, 0);
1288
+ }
1289
+ const details = result.details as { delivered?: boolean; error?: boolean; messageId?: string; reason?: string; structuredReplyParseError?: string } | undefined;
1290
+ const textContent = firstTextContent(result);
1291
+ const failed = Boolean(context.isError || details?.error === true || details?.delivered === false);
1292
+ const parseWarning = typeof details?.structuredReplyParseError === "string";
1293
+ let text = failed
1294
+ ? theme.fg("error", "✗ ")
1295
+ : parseWarning
1296
+ ? theme.fg("warning", "⚠ ")
1297
+ : theme.fg("success", "✓ ");
1298
+ text += theme.fg(failed ? "error" : "text", textContent);
1299
+ if (parseWarning) {
1300
+ text += "\n" + theme.fg("warning", `Structured reply parse issue: ${details.structuredReplyParseError}`);
1301
+ }
1302
+ return new Text(text, 0, 0);
1303
+ },
1304
+ });
1305
+ }
1306
+
1307
+ pi.registerTool({
1308
+ name: "intercom",
1309
+ label: "Intercom",
1310
+ description: `Send a message to another pi session running on this machine.
1311
+ Use this to communicate findings, request help, or coordinate work with other sessions.
1312
+
1313
+ Usage:
1314
+ intercom({ action: "list" }) → List active sessions
1315
+ intercom({ action: "send", to: "session-name", message: "..." }) → Send message
1316
+ intercom({ action: "ask", to: "session-name", message: "..." }) → Ask and wait for reply
1317
+ intercom({ action: "reply", message: "..." }) → Reply to the active/single pending ask
1318
+ intercom({ action: "pending" }) → List unresolved inbound asks
1319
+ intercom({ action: "status" }) → Show connection status`,
1320
+ promptSnippet:
1321
+ "Use to coordinate with other local pi sessions: list peers, send updates, ask for help, or check intercom connectivity.",
1322
+
1323
+ parameters: Type.Object({
1324
+ action: Type.String({
1325
+ description: "Action: 'list', 'send', 'ask', 'reply', 'pending', or 'status'",
1326
+ }),
1327
+ to: Type.Optional(Type.String({
1328
+ description: "Target session name or ID (for 'send', 'ask', or disambiguating 'reply')",
1329
+ })),
1330
+ message: Type.Optional(Type.String({
1331
+ description: "Message to send (for 'send', 'ask', or 'reply' action)",
1332
+ })),
1333
+ attachments: Type.Optional(Type.Array(Type.Object({
1334
+ type: Type.Union([Type.Literal("file"), Type.Literal("snippet"), Type.Literal("context")]),
1335
+ name: Type.String(),
1336
+ content: Type.String(),
1337
+ language: Type.Optional(Type.String()),
1338
+ }))),
1339
+ replyTo: Type.Optional(Type.String({
1340
+ description: "Message ID to reply to (for threading or responding to an 'ask')",
1341
+ })),
1342
+ }),
1343
+
1344
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
1345
+ let connectedClient: IntercomClient;
1346
+ try {
1347
+ connectedClient = await ensureConnected("tool");
1348
+ } catch (error) {
1349
+ return {
1350
+ content: [{ type: "text", text: `Intercom not connected: ${getErrorMessage(error)}` }],
1351
+ isError: true,
1352
+ details: { error: true },
1353
+ };
1354
+ }
1355
+
1356
+ syncPresenceIdentity(ctx.sessionManager.getSessionId());
1357
+
1358
+ const { action, to, message, attachments, replyTo } = params;
1359
+
1360
+ switch (action) {
1361
+ case "list": {
1362
+ try {
1363
+ const mySessionId = connectedClient.sessionId;
1364
+ const sessions = await connectedClient.listSessions();
1365
+ const currentSession = sessions.find(s => s.id === mySessionId);
1366
+ const otherSessions = sessions.filter(s => s.id !== mySessionId);
1367
+
1368
+ if (!currentSession) {
1369
+ return {
1370
+ content: [{ type: "text", text: "Current session is missing from intercom session list." }],
1371
+ isError: true,
1372
+ details: { error: true },
1373
+ };
1374
+ }
1375
+
1376
+ const currentSection = `**Current session:**\n${formatSessionListRow(currentSession, currentSession.cwd, true)}`;
1377
+ const otherSection = otherSessions.length === 0
1378
+ ? "**Other sessions:**\nNo other sessions connected."
1379
+ : `**Other sessions:**\n${otherSessions.map(s => formatSessionListRow(s, currentSession.cwd, false)).join("\n")}`;
1380
+
1381
+ return {
1382
+ content: [{ type: "text", text: `${currentSection}\n\n${otherSection}` }],
1383
+ isError: false,
1384
+ };
1385
+ } catch (error) {
1386
+ return {
1387
+ content: [{ type: "text", text: `Failed to list sessions: ${getErrorMessage(error)}` }],
1388
+ isError: true,
1389
+ details: { error: true },
1390
+ };
1391
+ }
1392
+ }
1393
+
1394
+ case "send": {
1395
+ if (!to || !message) {
1396
+ return {
1397
+ content: [{ type: "text", text: "Missing 'to' or 'message' parameter" }],
1398
+ isError: true,
1399
+ details: { error: true },
1400
+ };
1401
+ }
1402
+ try {
1403
+ const sendTo = await resolveSessionTarget(connectedClient, to) ?? to;
1404
+ if (sendTo === connectedClient.sessionId) {
1405
+ return {
1406
+ content: [{ type: "text", text: "Cannot message the current session" }],
1407
+ isError: true,
1408
+ details: { error: true },
1409
+ };
1410
+ }
1411
+ if (!replyTo && config.confirmSend && ctx.hasUI) {
1412
+ const attachmentText = attachments?.length ? formatAttachments(attachments) : "";
1413
+ const confirmed = await ctx.ui.confirm(
1414
+ "Send Message",
1415
+ `Send to "${to}":\n\n${message}${attachmentText}`,
1416
+ );
1417
+ if (!confirmed) {
1418
+ return {
1419
+ content: [{ type: "text", text: "Message cancelled by user" }],
1420
+ isError: false,
1421
+ };
1422
+ }
1423
+ }
1424
+ const result = await connectedClient.send(sendTo, {
1425
+ text: message,
1426
+ attachments,
1427
+ replyTo,
1428
+ });
1429
+ if (!result.delivered) {
1430
+ const errorText = result.reason ?? "Session may not exist or has disconnected.";
1431
+ return {
1432
+ content: [{ type: "text", text: `Message to "${to}" was not delivered: ${errorText}` }],
1433
+ isError: true,
1434
+ details: { messageId: result.id, delivered: false, reason: result.reason },
1435
+ };
1436
+ }
1437
+ pi.appendEntry("intercom_sent", {
1438
+ to,
1439
+ message: { text: message, attachments, replyTo },
1440
+ messageId: result.id,
1441
+ timestamp: Date.now(),
1442
+ });
1443
+ if (replyTo) {
1444
+ replyTracker.markReplied(replyTo);
1445
+ }
1446
+ return {
1447
+ content: [{ type: "text", text: `Message sent to ${to}` }],
1448
+ isError: false,
1449
+ details: { messageId: result.id, delivered: true },
1450
+ };
1451
+ } catch (error) {
1452
+ return {
1453
+ content: [{ type: "text", text: `Failed to send: ${getErrorMessage(error)}` }],
1454
+ isError: true,
1455
+ details: { error: true },
1456
+ };
1457
+ }
1458
+ }
1459
+
1460
+ case "ask": {
1461
+ if (!to || !message) {
1462
+ return {
1463
+ content: [{ type: "text", text: "Missing 'to' or 'message' parameter" }],
1464
+ isError: true,
1465
+ details: { error: true },
1466
+ };
1467
+ }
1468
+
1469
+ if (replyWaiter) {
1470
+ return {
1471
+ content: [{ type: "text", text: "Already waiting for a reply" }],
1472
+ isError: true,
1473
+ details: { error: true },
1474
+ };
1475
+ }
1476
+
1477
+ if (_signal?.aborted) {
1478
+ return {
1479
+ content: [{ type: "text", text: "Cancelled" }],
1480
+ isError: true,
1481
+ details: { error: true },
1482
+ };
1483
+ }
1484
+ let replyPromise: Promise<Message> | null = null;
1485
+
1486
+ try {
1487
+ const sendTo = await resolveSessionTarget(connectedClient, to) ?? to;
1488
+ if (_signal?.aborted) {
1489
+ return {
1490
+ content: [{ type: "text", text: "Cancelled" }],
1491
+ isError: true,
1492
+ details: { error: true },
1493
+ };
1494
+ }
1495
+ if (sendTo === connectedClient.sessionId) {
1496
+ return {
1497
+ content: [{ type: "text", text: "Cannot message the current session" }],
1498
+ isError: true,
1499
+ details: { error: true },
1500
+ };
1501
+ }
1502
+ const questionId = randomUUID();
1503
+ replyPromise = waitForReply(sendTo, questionId, _signal);
1504
+ const sendResult = await connectedClient.send(sendTo, {
1505
+ messageId: questionId,
1506
+ text: message,
1507
+ attachments,
1508
+ replyTo,
1509
+ expectsReply: true,
1510
+ });
1511
+
1512
+ if (!sendResult.delivered) {
1513
+ const errorText = sendResult.reason ?? "Session may not exist or has disconnected.";
1514
+ rejectReplyWaiter(new Error(`Message to "${to}" was not delivered: ${errorText}`));
1515
+ if (replyPromise) {
1516
+ try {
1517
+ await replyPromise;
1518
+ } catch {
1519
+ // The waiter was already rejected above. Keep the delivery failure as the only error here.
1520
+ }
1521
+ }
1522
+ return {
1523
+ content: [{ type: "text", text: `Message to "${to}" was not delivered: ${errorText}` }],
1524
+ isError: true,
1525
+ details: { error: true },
1526
+ };
1527
+ }
1528
+ pi.appendEntry("intercom_sent", {
1529
+ to,
1530
+ message: { text: message, attachments, replyTo },
1531
+ messageId: sendResult.id,
1532
+ timestamp: Date.now(),
1533
+ });
1534
+ const replyMessage = await replyPromise;
1535
+ const replyText = replyMessage.content.text;
1536
+ const replyAttachments = replyMessage.content.attachments?.length
1537
+ ? formatAttachments(replyMessage.content.attachments)
1538
+ : "";
1539
+ pi.appendEntry("intercom_received", {
1540
+ from: to,
1541
+ message: { text: replyText, attachments: replyMessage.content.attachments },
1542
+ messageId: replyMessage.id,
1543
+ timestamp: replyMessage.timestamp,
1544
+ });
1545
+ return {
1546
+ content: [{ type: "text", text: `**Reply from ${to}:**\n${replyText}${replyAttachments}` }],
1547
+ isError: false,
1548
+ };
1549
+ } catch (error) {
1550
+ rejectReplyWaiter(toError(error));
1551
+ if (replyPromise) {
1552
+ try {
1553
+ await replyPromise;
1554
+ } catch {
1555
+ // The waiter is cleanup-only on this path. The real failure is the one from the outer catch.
1556
+ }
1557
+ }
1558
+ return {
1559
+ content: [{ type: "text", text: `Failed: ${getErrorMessage(error)}` }],
1560
+ isError: true,
1561
+ details: { error: true },
1562
+ };
1563
+ }
1564
+ }
1565
+
1566
+ case "reply": {
1567
+ if (!message) {
1568
+ return {
1569
+ content: [{ type: "text", text: "Missing 'message' parameter" }],
1570
+ isError: true,
1571
+ details: { error: true },
1572
+ };
1573
+ }
1574
+
1575
+ try {
1576
+ const target = replyTracker.resolveReplyTarget({ to });
1577
+ if (target.from.id === connectedClient.sessionId) {
1578
+ return {
1579
+ content: [{ type: "text", text: "Cannot message the current session" }],
1580
+ isError: true,
1581
+ details: { error: true },
1582
+ };
1583
+ }
1584
+ const result = await connectedClient.send(target.from.id, {
1585
+ text: message,
1586
+ replyTo: target.message.id,
1587
+ });
1588
+ if (!result.delivered) {
1589
+ const errorText = result.reason ?? "Session may not exist or has disconnected.";
1590
+ return {
1591
+ content: [{ type: "text", text: `Reply to "${target.from.name || target.from.id}" was not delivered: ${errorText}` }],
1592
+ isError: true,
1593
+ details: { messageId: result.id, delivered: false, reason: result.reason },
1594
+ };
1595
+ }
1596
+ replyTracker.markReplied(target.message.id);
1597
+ pi.appendEntry("intercom_sent", {
1598
+ to: target.from.name || target.from.id,
1599
+ message: { text: message, replyTo: target.message.id },
1600
+ messageId: result.id,
1601
+ timestamp: Date.now(),
1602
+ });
1603
+ return {
1604
+ content: [{ type: "text", text: `Reply sent to ${target.from.name || target.from.id}` }],
1605
+ isError: false,
1606
+ details: { messageId: result.id, delivered: true, replyTo: target.message.id },
1607
+ };
1608
+ } catch (error) {
1609
+ return {
1610
+ content: [{ type: "text", text: `Failed to reply: ${getErrorMessage(error)}` }],
1611
+ isError: true,
1612
+ details: { error: true },
1613
+ };
1614
+ }
1615
+ }
1616
+
1617
+ case "pending": {
1618
+ const pendingAsks = replyTracker.listPending();
1619
+ if (pendingAsks.length === 0) {
1620
+ return {
1621
+ content: [{ type: "text", text: "No unresolved inbound asks." }],
1622
+ isError: false,
1623
+ };
1624
+ }
1625
+
1626
+ const now = Date.now();
1627
+ const lines = pendingAsks.map(({ from, message, receivedAt }) => {
1628
+ const preview = message.content.text.replace(/\s+/g, " ").slice(0, 80);
1629
+ const elapsedSeconds = Math.max(0, Math.floor((now - receivedAt) / 1000));
1630
+ return `- ${from.name || from.id} · ${message.id} · ${elapsedSeconds}s ago · ${preview}`;
1631
+ });
1632
+ return {
1633
+ content: [{ type: "text", text: `**Pending asks:**\n${lines.join("\n")}` }],
1634
+ isError: false,
1635
+ };
1636
+ }
1637
+
1638
+ case "status": {
1639
+ try {
1640
+ const mySessionId = connectedClient.sessionId;
1641
+ const sessions = await connectedClient.listSessions();
1642
+ return {
1643
+ content: [{
1644
+ type: "text",
1645
+ text: `**Intercom Status:**\nConnected: Yes\nSession ID: ${mySessionId}\nActive sessions: ${sessions.length}`,
1646
+ }],
1647
+ isError: false,
1648
+ };
1649
+ } catch (error) {
1650
+ return {
1651
+ content: [{ type: "text", text: `Failed to get status: ${getErrorMessage(error)}` }],
1652
+ isError: true,
1653
+ details: { error: true },
1654
+ };
1655
+ }
1656
+ }
1657
+
1658
+ default:
1659
+ return {
1660
+ content: [{ type: "text", text: `Unknown action: ${action}` }],
1661
+ isError: true,
1662
+ details: { error: true },
1663
+ };
1664
+ }
1665
+ },
1666
+ renderCall(args, theme) {
1667
+ const action = typeof args.action === "string" ? args.action : "intercom";
1668
+ const target = typeof args.to === "string" && args.to.trim() ? args.to.trim() : undefined;
1669
+ const messagePreview = previewText(args.message, 96);
1670
+ const attachmentCount = Array.isArray(args.attachments) ? args.attachments.length : 0;
1671
+ let text = theme.fg("toolTitle", theme.bold("intercom "));
1672
+ text += theme.fg(action === "ask" ? "warning" : action === "reply" ? "success" : "accent", action);
1673
+ if (target) {
1674
+ text += " " + theme.fg("muted", "→") + " " + theme.fg("accent", target);
1675
+ }
1676
+ if (attachmentCount > 0) {
1677
+ text += " " + theme.fg("dim", `(${attachmentCount} attachment${attachmentCount === 1 ? "" : "s"})`);
1678
+ }
1679
+ if (messagePreview) {
1680
+ text += "\n " + theme.fg("dim", messagePreview);
1681
+ }
1682
+ return new Text(text, 0, 0);
1683
+ },
1684
+ renderResult(result, { isPartial }, theme, context) {
1685
+ if (isPartial) {
1686
+ return new Text(theme.fg("warning", "Intercom working..."), 0, 0);
1687
+ }
1688
+ const details = result.details as { delivered?: boolean; error?: boolean; messageId?: string; reason?: string } | undefined;
1689
+ const failed = Boolean(context.isError || details?.error === true || details?.delivered === false);
1690
+ let text = failed ? theme.fg("error", "✗ ") : theme.fg("success", "✓ ");
1691
+ text += theme.fg(failed ? "error" : "text", firstTextContent(result));
1692
+ if (details?.messageId && !context.expanded) {
1693
+ text += theme.fg("dim", ` (${details.messageId.slice(0, 8)})`);
1694
+ }
1695
+ if (details?.reason && context.expanded) {
1696
+ text += "\n" + theme.fg("dim", `Reason: ${details.reason}`);
1697
+ }
1698
+ return new Text(text, 0, 0);
1699
+ },
1700
+ });
1701
+
1702
+ async function openIntercomOverlay(ctx: ExtensionContext): Promise<void> {
1703
+ const overlayGeneration = runtimeGeneration;
1704
+ const liveContext = getLiveContext(ctx, overlayGeneration);
1705
+ if (!liveContext?.hasUI) return;
1706
+
1707
+ let overlayClient: IntercomClient;
1708
+ try {
1709
+ overlayClient = await ensureConnected("overlay");
1710
+ } catch (error) {
1711
+ notifyIfLive(ctx, `Intercom unavailable: ${getErrorMessage(error)}`, "error", overlayGeneration);
1712
+ return;
1713
+ }
1714
+ if (!getLiveContext(ctx, overlayGeneration)) return;
1715
+
1716
+ syncPresenceIdentity(ctx.sessionManager.getSessionId());
1717
+
1718
+ let currentSession: SessionInfo;
1719
+ let sessions: SessionInfo[];
1720
+ let duplicates: Set<string>;
1721
+ try {
1722
+ const mySessionId = overlayClient.sessionId;
1723
+ const allSessions = await overlayClient.listSessions();
1724
+ if (!getLiveContext(ctx, overlayGeneration)) return;
1725
+ const foundCurrentSession = allSessions.find(s => s.id === mySessionId);
1726
+ if (!foundCurrentSession) {
1727
+ notifyIfLive(ctx, "Current session is missing from intercom session list", "error", overlayGeneration);
1728
+ return;
1729
+ }
1730
+ currentSession = foundCurrentSession;
1731
+ duplicates = duplicateSessionNames(allSessions);
1732
+ sessions = allSessions.filter(s => s.id !== mySessionId);
1733
+ } catch (error) {
1734
+ notifyIfLive(ctx, `Failed to list sessions: ${getErrorMessage(error)}`, "error", overlayGeneration);
1735
+ return;
1736
+ }
1737
+
1738
+ const selectedSession = await ctx.ui.custom<SessionInfo | undefined>(
1739
+ (_tui, theme, keybindings, done) => new SessionListOverlay(theme, keybindings, currentSession, sessions, done),
1740
+ { overlay: true }
1741
+ ).catch(() => undefined);
1742
+
1743
+ if (!selectedSession || !getLiveContext(ctx, overlayGeneration)) return;
1744
+
1745
+ try {
1746
+ overlayClient = await ensureConnected("overlay");
1747
+ } catch (error) {
1748
+ notifyIfLive(ctx, `Intercom unavailable: ${getErrorMessage(error)}`, "error", overlayGeneration);
1749
+ return;
1750
+ }
1751
+ if (!getLiveContext(ctx, overlayGeneration)) return;
1752
+
1753
+ const targetLabel = formatSessionLabel(selectedSession, duplicates);
1754
+
1755
+ const result = await ctx.ui.custom<ComposeResult>(
1756
+ (tui, theme, keybindings, done) => new ComposeOverlay(tui, theme, keybindings, selectedSession, targetLabel, overlayClient, done),
1757
+ { overlay: true }
1758
+ ).catch(() => undefined);
1759
+
1760
+ if (result?.sent && result.messageId && result.text && getLiveContext(ctx, overlayGeneration)) {
1761
+ pi.appendEntry("intercom_sent", {
1762
+ to: selectedSession.name || selectedSession.id,
1763
+ message: { text: result.text },
1764
+ messageId: result.messageId,
1765
+ timestamp: Date.now(),
1766
+ });
1767
+ notifyIfLive(ctx, `Message sent to ${targetLabel}`, "info", overlayGeneration);
1768
+ }
1769
+ }
1770
+
1771
+ pi.registerCommand("intercom", {
1772
+ description: "Open session intercom overlay",
1773
+ handler: async (_args, ctx) => openIntercomOverlay(ctx),
1774
+ });
1775
+
1776
+ pi.registerShortcut("alt+m", {
1777
+ description: "Open session intercom",
1778
+ handler: async (ctx) => openIntercomOverlay(ctx),
1779
+ });
1780
+ }