@fitchmultz/pi-subagents 0.44.7 → 0.45.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 (947) hide show
  1. package/CHANGELOG.md +258 -7
  2. package/LICENSE +1 -0
  3. package/README.md +58 -1483
  4. package/agents/context-builder.md +19 -1
  5. package/agents/debugger.md +10 -3
  6. package/agents/delegate.md +1 -0
  7. package/agents/fixer.md +4 -1
  8. package/agents/oracle.md +13 -2
  9. package/agents/planner.md +14 -3
  10. package/agents/researcher.md +11 -2
  11. package/agents/reviewer-claude.md +11 -2
  12. package/agents/reviewer-gpt.md +12 -2
  13. package/agents/reviewer-ponytail.md +11 -1
  14. package/agents/reviewer-security.md +13 -2
  15. package/agents/reviewer.md +12 -3
  16. package/agents/scout.md +12 -1
  17. package/agents/ui-designer.md +10 -3
  18. package/agents/watcher.md +1 -0
  19. package/agents/worker.md +8 -2
  20. package/agents/writer.md +6 -3
  21. package/dist/agents/agent-defaults.js +9 -0
  22. package/dist/agents/agent-definition.js +196 -0
  23. package/dist/agents/agent-management.js +64 -905
  24. package/dist/agents/agent-scope.js +4 -2
  25. package/dist/agents/agent-selection.js +10 -5
  26. package/dist/agents/agent-serializer.js +55 -67
  27. package/dist/agents/agents.js +75 -716
  28. package/dist/agents/builtin-overrides.js +218 -0
  29. package/dist/agents/chain-serializer.js +3 -367
  30. package/dist/agents/config-values.js +52 -0
  31. package/dist/agents/discovery-paths.js +91 -0
  32. package/dist/agents/frontmatter.js +15 -5
  33. package/dist/agents/identity.js +25 -8
  34. package/dist/agents/json-chain.js +254 -0
  35. package/dist/agents/management-config.js +332 -0
  36. package/dist/agents/management-format.js +231 -0
  37. package/dist/agents/management-persistence.js +287 -0
  38. package/dist/agents/management-targets.js +136 -0
  39. package/dist/agents/management-warnings.js +81 -0
  40. package/dist/agents/markdown-chain.js +210 -0
  41. package/dist/agents/package-agents.js +154 -0
  42. package/dist/agents/skill-files.js +157 -0
  43. package/dist/agents/skill-search-paths.js +246 -0
  44. package/dist/agents/skill-types.js +1 -0
  45. package/dist/agents/skills.js +54 -499
  46. package/dist/extension/acceptance-schema.js +55 -0
  47. package/dist/extension/build-info.js +1 -1
  48. package/dist/extension/chain-schema.js +196 -0
  49. package/dist/extension/child-runtime.js +237 -0
  50. package/dist/extension/compact-tools.js +122 -51
  51. package/dist/extension/config-schema.js +29 -0
  52. package/dist/extension/config.js +27 -11
  53. package/dist/extension/control-notice-schema.js +37 -0
  54. package/dist/extension/control-notices.js +13 -6
  55. package/dist/extension/delegation-bridges.js +43 -0
  56. package/dist/extension/doctor.js +48 -25
  57. package/dist/extension/everyday-schemas.js +207 -0
  58. package/dist/extension/fanout-child.js +18 -319
  59. package/dist/extension/index.js +8 -563
  60. package/dist/extension/message-renderers.js +225 -0
  61. package/dist/extension/nested-control-inbox.js +154 -0
  62. package/dist/extension/parent-runtime.js +339 -0
  63. package/dist/extension/primary-tool.js +69 -0
  64. package/dist/extension/result-snapshot.js +22 -0
  65. package/dist/extension/runtime-reload.js +62 -0
  66. package/dist/extension/runtime-storage.js +43 -0
  67. package/dist/extension/schema-overrides.js +75 -0
  68. package/dist/extension/schemas.js +265 -336
  69. package/dist/extension/tool-input.js +27 -12
  70. package/dist/extension/tool-result.js +19 -4
  71. package/dist/history/answer-texts.js +57 -0
  72. package/dist/history/canonical-result.js +76 -43
  73. package/dist/history/canonical-selection.js +40 -0
  74. package/dist/history/database-generation.js +82 -0
  75. package/dist/history/database.js +57 -33
  76. package/dist/history/entry-ingestion.js +61 -0
  77. package/dist/history/index.js +242 -97
  78. package/dist/history/ingest.js +168 -331
  79. package/dist/history/output-digests.js +40 -0
  80. package/dist/history/preview.js +210 -0
  81. package/dist/history/prune.js +33 -0
  82. package/dist/history/queries.js +60 -349
  83. package/dist/history/query-scope.js +190 -0
  84. package/dist/history/rows.js +77 -0
  85. package/dist/history/run-projection.js +137 -0
  86. package/dist/history/run-queries.js +153 -0
  87. package/dist/history/schema.js +31 -0
  88. package/dist/history/search-queries.js +163 -0
  89. package/dist/history/selected-record.js +108 -0
  90. package/dist/history/source-file.js +45 -0
  91. package/dist/history/source-watches.js +141 -0
  92. package/dist/history/store.js +164 -153
  93. package/dist/history/text-chunks.js +169 -0
  94. package/dist/history/text.js +35 -0
  95. package/dist/history/transcript-queries.js +177 -0
  96. package/dist/history/types.js +5 -1
  97. package/dist/history/values.js +36 -0
  98. package/dist/history/wire-inputs.js +122 -0
  99. package/dist/history/wire-models.js +38 -0
  100. package/dist/history/worker-runtime.js +441 -0
  101. package/dist/history/worker.js +66 -462
  102. package/dist/intercom/intercom-bridge.js +48 -20
  103. package/dist/intercom/live-intercom.js +80 -23
  104. package/dist/intercom/nested-result-tree.js +163 -0
  105. package/dist/intercom/result-delivery.js +40 -0
  106. package/dist/intercom/result-intercom.js +178 -261
  107. package/dist/pi-intercom/agent-dir.js +7 -3
  108. package/dist/pi-intercom/async.js +27 -0
  109. package/dist/pi-intercom/bridge-ask.js +57 -0
  110. package/dist/pi-intercom/bridge-config.js +79 -0
  111. package/dist/pi-intercom/bridge-http.js +86 -0
  112. package/dist/pi-intercom/bridge-protocol.js +106 -0
  113. package/dist/pi-intercom/bridge-routes.js +64 -0
  114. package/dist/pi-intercom/bridge-session.js +416 -0
  115. package/dist/pi-intercom/bridge.js +182 -603
  116. package/dist/pi-intercom/broker/broker.js +236 -244
  117. package/dist/pi-intercom/broker/client.js +189 -304
  118. package/dist/pi-intercom/broker/connection.js +165 -0
  119. package/dist/pi-intercom/broker/framing.js +5 -3
  120. package/dist/pi-intercom/broker/paths.js +4 -1
  121. package/dist/pi-intercom/broker/pid.js +53 -25
  122. package/dist/pi-intercom/broker/snapshot-reader.js +78 -0
  123. package/dist/pi-intercom/broker/snapshots.js +188 -0
  124. package/dist/pi-intercom/broker/spawn.js +36 -25
  125. package/dist/pi-intercom/config.js +85 -71
  126. package/dist/pi-intercom/connection.js +297 -0
  127. package/dist/pi-intercom/identity.js +58 -0
  128. package/dist/pi-intercom/inbound-delivery.js +356 -0
  129. package/dist/pi-intercom/inbound-journal.js +303 -0
  130. package/dist/pi-intercom/inbound-record.js +113 -0
  131. package/dist/pi-intercom/inbound.js +179 -0
  132. package/dist/pi-intercom/index.js +79 -2933
  133. package/dist/pi-intercom/inspection.js +62 -0
  134. package/dist/pi-intercom/interview.js +236 -0
  135. package/dist/pi-intercom/lifecycle.js +168 -0
  136. package/dist/pi-intercom/message-format.js +69 -0
  137. package/dist/pi-intercom/outbound.js +304 -0
  138. package/dist/pi-intercom/peer-awareness.js +66 -0
  139. package/dist/pi-intercom/reply-tracker.js +62 -43
  140. package/dist/pi-intercom/reply-wait.js +201 -0
  141. package/dist/pi-intercom/runtime-types.js +3 -0
  142. package/dist/pi-intercom/session-events.js +180 -0
  143. package/dist/pi-intercom/session-targets.js +42 -34
  144. package/dist/pi-intercom/subagent-events.js +238 -0
  145. package/dist/pi-intercom/subagent-live-events.js +129 -86
  146. package/dist/pi-intercom/supervisor.js +282 -0
  147. package/dist/pi-intercom/tool-arguments.js +74 -0
  148. package/dist/pi-intercom/tool-registration.js +95 -0
  149. package/dist/pi-intercom/tool-results.js +38 -0
  150. package/dist/pi-intercom/tool-schemas.js +82 -0
  151. package/dist/pi-intercom/tools.js +51 -0
  152. package/dist/pi-intercom/topic-actions.js +177 -0
  153. package/dist/pi-intercom/topics.js +177 -92
  154. package/dist/pi-intercom/transport.js +1 -0
  155. package/dist/pi-intercom/types.js +151 -114
  156. package/dist/pi-intercom/ui/compose-paste.js +93 -0
  157. package/dist/pi-intercom/ui/compose.js +121 -143
  158. package/dist/pi-intercom/ui/inline-message.js +59 -59
  159. package/dist/pi-intercom/ui/message-renderers.js +147 -0
  160. package/dist/pi-intercom/ui/overlay.js +181 -0
  161. package/dist/pi-intercom/ui/session-format.js +124 -0
  162. package/dist/pi-intercom/ui/session-list.js +76 -43
  163. package/dist/pi-intercom/ui/tool-renderers.js +110 -0
  164. package/dist/pi-intercom/ui/topic-view.js +88 -0
  165. package/dist/pi-intercom/validation.js +59 -0
  166. package/dist/runs/background/async-chain-plan.js +265 -0
  167. package/dist/runs/background/async-control.js +134 -58
  168. package/dist/runs/background/async-execution.js +136 -633
  169. package/dist/runs/background/async-job-admission.js +40 -0
  170. package/dist/runs/background/async-job-projection.js +169 -0
  171. package/dist/runs/background/async-job-tracker.js +297 -327
  172. package/dist/runs/background/async-launch.js +216 -0
  173. package/dist/runs/background/async-plan.js +116 -0
  174. package/dist/runs/background/async-result-file.js +47 -23
  175. package/dist/runs/background/async-resume.js +195 -253
  176. package/dist/runs/background/async-run-discovery.js +213 -0
  177. package/dist/runs/background/async-run-location.js +135 -0
  178. package/dist/runs/background/async-run-record.js +1 -0
  179. package/dist/runs/background/async-run-repair.js +223 -0
  180. package/dist/runs/background/async-run-summary.js +1 -0
  181. package/dist/runs/background/async-single-plan.js +105 -0
  182. package/dist/runs/background/async-status-projection.js +155 -0
  183. package/dist/runs/background/async-status-render.js +117 -0
  184. package/dist/runs/background/async-status-validation.js +181 -0
  185. package/dist/runs/background/async-status.js +3 -442
  186. package/dist/runs/background/async-value.js +21 -0
  187. package/dist/runs/background/completion-dedupe.js +36 -12
  188. package/dist/runs/background/completion-delivery.js +211 -205
  189. package/dist/runs/background/completion-receipts.js +237 -0
  190. package/dist/runs/background/legacy-status-acceptance.js +34 -0
  191. package/dist/runs/background/notify.js +96 -48
  192. package/dist/runs/background/parallel-groups.js +36 -19
  193. package/dist/runs/background/result-payload.js +178 -0
  194. package/dist/runs/background/result-watcher.js +348 -339
  195. package/dist/runs/background/run-id-resolver.js +53 -33
  196. package/dist/runs/background/run-schemas.js +189 -0
  197. package/dist/runs/background/run-status-contracts.js +14 -0
  198. package/dist/runs/background/run-status-render.js +270 -0
  199. package/dist/runs/background/run-status.js +231 -339
  200. package/dist/runs/background/runner-attempt-output.js +155 -0
  201. package/dist/runs/background/runner-attempt.js +263 -0
  202. package/dist/runs/background/runner-child-executor.js +166 -0
  203. package/dist/runs/background/runner-child-observer.js +192 -0
  204. package/dist/runs/background/runner-completion-summary.js +71 -0
  205. package/dist/runs/background/runner-completion.js +211 -0
  206. package/dist/runs/background/runner-config.js +1 -0
  207. package/dist/runs/background/runner-contract.js +1 -0
  208. package/dist/runs/background/runner-dynamic.js +121 -0
  209. package/dist/runs/background/runner-finalization.js +149 -0
  210. package/dist/runs/background/runner-graph.js +68 -0
  211. package/dist/runs/background/runner-initial-status.js +60 -0
  212. package/dist/runs/background/runner-lifecycle.js +142 -0
  213. package/dist/runs/background/runner-monitor.js +309 -0
  214. package/dist/runs/background/runner-parallel.js +204 -0
  215. package/dist/runs/background/runner-prepare-step.js +86 -0
  216. package/dist/runs/background/runner-reporting.js +153 -0
  217. package/dist/runs/background/runner-status.js +148 -0
  218. package/dist/runs/background/runner-step-output.js +92 -0
  219. package/dist/runs/background/runner-step-record.js +45 -0
  220. package/dist/runs/background/runner-step.js +112 -0
  221. package/dist/runs/background/runner-streaming.js +173 -0
  222. package/dist/runs/background/runner-workflow.js +213 -0
  223. package/dist/runs/background/stale-run-reconciler.js +155 -292
  224. package/dist/runs/background/subagent-runner-launcher.js +33 -13
  225. package/dist/runs/background/subagent-runner.js +51 -1842
  226. package/dist/runs/background/top-level-async.js +2 -1
  227. package/dist/runs/foreground/chain-clarify.js +293 -1017
  228. package/dist/runs/foreground/clarification-draft.js +87 -0
  229. package/dist/runs/foreground/clarify-contracts.js +1 -0
  230. package/dist/runs/foreground/clarify-invocation.js +129 -38
  231. package/dist/runs/foreground/clarify-text-editor.js +210 -0
  232. package/dist/runs/foreground/clarify-view.js +167 -0
  233. package/dist/runs/foreground/execution-input.js +226 -353
  234. package/dist/runs/foreground/execution-routing.js +33 -0
  235. package/dist/runs/foreground/execution-timeout.js +81 -0
  236. package/dist/runs/foreground/foreground-control.js +222 -763
  237. package/dist/runs/foreground/foreground-memory.js +99 -0
  238. package/dist/runs/foreground/invocation-context.js +55 -0
  239. package/dist/runs/foreground/invocation-execution.js +331 -0
  240. package/dist/runs/foreground/invocation-expansion.js +48 -0
  241. package/dist/runs/foreground/management-actions.js +295 -0
  242. package/dist/runs/foreground/nested-control.js +179 -0
  243. package/dist/runs/foreground/question-continuation.js +78 -0
  244. package/dist/runs/foreground/question-control.js +155 -50
  245. package/dist/runs/foreground/resume-target.js +221 -0
  246. package/dist/runs/foreground/revival-launch-policy.js +58 -0
  247. package/dist/runs/foreground/run-async-path.js +190 -178
  248. package/dist/runs/foreground/run-interrupt.js +164 -0
  249. package/dist/runs/foreground/run-nudge.js +278 -0
  250. package/dist/runs/foreground/saved-revival.js +251 -0
  251. package/dist/runs/foreground/subagent-executor.js +135 -424
  252. package/dist/runs/foreground/subagent-params.js +67 -30
  253. package/dist/runs/foreground/wait-observation.js +104 -0
  254. package/dist/runs/foreground/wait-registration.js +17 -0
  255. package/dist/runs/foreground/wait-run.js +283 -123
  256. package/dist/runs/shared/acceptance-contract.js +193 -99
  257. package/dist/runs/shared/acceptance-defaults.js +1 -0
  258. package/dist/runs/shared/acceptance-evaluation.js +201 -181
  259. package/dist/runs/shared/acceptance-finalization.js +256 -180
  260. package/dist/runs/shared/acceptance-outcome.js +53 -0
  261. package/dist/runs/shared/acceptance-reports.js +137 -72
  262. package/dist/runs/shared/acceptance-submission.js +167 -0
  263. package/dist/runs/shared/acceptance-verification.js +100 -0
  264. package/dist/runs/shared/chain-outputs.js +80 -52
  265. package/dist/runs/shared/child-attempt-types.js +1 -0
  266. package/dist/runs/shared/child-attempt.js +314 -667
  267. package/dist/runs/shared/child-boundaries.js +173 -0
  268. package/dist/runs/shared/child-context-filter.js +44 -0
  269. package/dist/runs/shared/child-event-observer.js +390 -0
  270. package/dist/runs/shared/child-execution-cwd.js +73 -43
  271. package/dist/runs/shared/child-execution-outcome.js +72 -0
  272. package/dist/runs/shared/child-invocation.js +54 -0
  273. package/dist/runs/shared/child-message-validation.js +215 -0
  274. package/dist/runs/shared/child-native-accounting.js +106 -0
  275. package/dist/runs/shared/child-native-observation.js +69 -0
  276. package/dist/runs/shared/child-observation-spool.js +164 -0
  277. package/dist/runs/shared/child-observations.js +157 -76
  278. package/dist/runs/shared/child-presence.js +3 -0
  279. package/dist/runs/shared/child-route-env.js +119 -0
  280. package/dist/runs/shared/child-stream-observer.js +221 -0
  281. package/dist/runs/shared/child-stream-projection.js +137 -0
  282. package/dist/runs/shared/child-structured-tool.js +27 -0
  283. package/dist/runs/shared/claude-code.js +121 -158
  284. package/dist/runs/shared/claude-model.js +42 -0
  285. package/dist/runs/shared/claude-session.js +83 -0
  286. package/dist/runs/shared/claude-types.js +1 -0
  287. package/dist/runs/shared/completion-guard.js +18 -18
  288. package/dist/runs/shared/control-event-policy.js +8 -0
  289. package/dist/runs/shared/control-notification-owner.js +13 -0
  290. package/dist/runs/shared/dynamic-fanout.js +188 -173
  291. package/dist/runs/shared/dynamic-item.js +102 -0
  292. package/dist/runs/shared/history-index.js +62 -36
  293. package/dist/runs/shared/legacy-async-recovery.js +114 -0
  294. package/dist/runs/shared/legacy-output-recovery.js +148 -0
  295. package/dist/runs/shared/mcp-config-schema.js +36 -0
  296. package/dist/runs/shared/mcp-direct-tool-allowlist.js +147 -116
  297. package/dist/runs/shared/model-fallback.js +97 -38
  298. package/dist/runs/shared/mutating-tool-guard.js +128 -88
  299. package/dist/runs/shared/native-finalization-types.js +1 -0
  300. package/dist/runs/shared/native-finalization.js +155 -76
  301. package/dist/runs/shared/native-usage.js +238 -98
  302. package/dist/runs/shared/nested-control-records.js +128 -0
  303. package/dist/runs/shared/nested-events.js +8 -700
  304. package/dist/runs/shared/nested-path.js +32 -28
  305. package/dist/runs/shared/nested-projection.js +155 -0
  306. package/dist/runs/shared/nested-protocol.js +18 -0
  307. package/dist/runs/shared/nested-registry.js +191 -0
  308. package/dist/runs/shared/nested-render.js +106 -58
  309. package/dist/runs/shared/nested-route.js +220 -0
  310. package/dist/runs/shared/nested-validation.js +216 -0
  311. package/dist/runs/shared/owned-child-evidence.js +125 -0
  312. package/dist/runs/shared/owned-run-list.js +146 -0
  313. package/dist/runs/shared/owned-run-observation.js +267 -0
  314. package/dist/runs/shared/owned-run-progress.js +109 -0
  315. package/dist/runs/shared/owned-run-read-state.js +1 -0
  316. package/dist/runs/shared/owned-run-results.js +202 -0
  317. package/dist/runs/shared/owned-run-status.js +180 -0
  318. package/dist/runs/shared/owned-run-view.js +51 -0
  319. package/dist/runs/shared/owned-workflow-details.js +17 -0
  320. package/dist/runs/shared/owner-output.js +43 -0
  321. package/dist/runs/shared/parallel-utils.js +36 -28
  322. package/dist/runs/shared/parent-receipts.js +90 -32
  323. package/dist/runs/shared/parent-usage.js +169 -57
  324. package/dist/runs/shared/pi-args.js +108 -201
  325. package/dist/runs/shared/pi-launch-input.js +1 -0
  326. package/dist/runs/shared/pi-session-launch.js +86 -0
  327. package/dist/runs/shared/pi-spawn.js +35 -21
  328. package/dist/runs/shared/run-history-queries.js +126 -35
  329. package/dist/runs/shared/run-history.js +101 -35
  330. package/dist/runs/shared/run-metadata-paths.js +14 -0
  331. package/dist/runs/shared/run-metadata.js +158 -0
  332. package/dist/runs/shared/run-persistence.js +131 -0
  333. package/dist/runs/shared/run-records.js +9 -679
  334. package/dist/runs/shared/run-restoration.js +338 -0
  335. package/dist/runs/shared/run-state-owner.js +26 -0
  336. package/dist/runs/shared/session-cwd-preload.js +27 -18
  337. package/dist/runs/shared/single-output.js +148 -70
  338. package/dist/runs/shared/stable-value.js +15 -0
  339. package/dist/runs/shared/streaming-text.js +23 -12
  340. package/dist/runs/shared/structured-output.js +25 -13
  341. package/dist/runs/shared/subagent-control.js +167 -100
  342. package/dist/runs/shared/subagent-prompt-runtime.js +27 -130
  343. package/dist/runs/shared/subagent-tool-loop-guard.js +81 -52
  344. package/dist/runs/shared/supervisor-question-state.js +145 -0
  345. package/dist/runs/shared/supervisor-questions.js +185 -254
  346. package/dist/runs/shared/workflow-graph.js +259 -167
  347. package/dist/runs/shared/workflow-policy.js +120 -48
  348. package/dist/runs/shared/worktree-contract.js +1 -0
  349. package/dist/runs/shared/worktree-hook.js +138 -0
  350. package/dist/runs/shared/worktree-location.js +47 -0
  351. package/dist/runs/shared/worktree-preservation.js +8 -0
  352. package/dist/runs/shared/worktree-process.js +107 -0
  353. package/dist/runs/shared/worktree.js +183 -322
  354. package/dist/shared/agent-context-policy.js +34 -44
  355. package/dist/shared/agent-dir.js +14 -0
  356. package/dist/shared/artifacts.js +30 -12
  357. package/dist/shared/atomic-json.js +4 -1
  358. package/dist/shared/chain-files.js +72 -0
  359. package/dist/shared/concurrency.js +18 -0
  360. package/dist/shared/content-preview.js +115 -0
  361. package/dist/shared/cooperative.js +5 -2
  362. package/dist/shared/execution-cwd.js +13 -5
  363. package/dist/shared/file-coalescer.js +2 -1
  364. package/dist/shared/fork-context.js +10 -12
  365. package/dist/shared/formatters.js +45 -19
  366. package/dist/shared/journal-frames.js +164 -0
  367. package/dist/shared/journal-projections.js +121 -0
  368. package/dist/shared/journal-reader.js +6 -407
  369. package/dist/shared/json-projection.js +191 -0
  370. package/dist/shared/lazy-tools.js +19 -8
  371. package/dist/shared/message-output.js +116 -0
  372. package/dist/shared/model-info.js +31 -14
  373. package/dist/shared/native-import.js +20 -0
  374. package/dist/shared/native-journal.js +140 -0
  375. package/dist/shared/native-session.js +5 -2
  376. package/dist/shared/native-tui.js +7 -2
  377. package/dist/shared/native-typebox.js +15 -3
  378. package/dist/shared/output-page.js +63 -0
  379. package/dist/shared/post-exit-stdio-guard.js +128 -88
  380. package/dist/shared/prompt-sections.js +2 -0
  381. package/dist/shared/session-entries.js +70 -35
  382. package/dist/shared/session-identity.js +5 -3
  383. package/dist/shared/settings.js +62 -192
  384. package/dist/shared/status-format.js +97 -37
  385. package/dist/shared/task-file-policy.js +24 -0
  386. package/dist/shared/temp-root.js +44 -15
  387. package/dist/shared/types/acceptance.js +1 -0
  388. package/dist/shared/types/async.js +1 -0
  389. package/dist/shared/types/config.js +1 -0
  390. package/dist/shared/types/details.js +1 -0
  391. package/dist/shared/types/history.js +1 -0
  392. package/dist/shared/types/inputs.js +1 -0
  393. package/dist/shared/types/intercom.js +1 -0
  394. package/dist/shared/types/launch.js +1 -0
  395. package/dist/shared/types/messages.js +1 -0
  396. package/dist/shared/types/nested.js +1 -0
  397. package/dist/shared/types/owned-runs.js +1 -0
  398. package/dist/shared/types/progress.js +1 -0
  399. package/dist/shared/types/questions.js +1 -0
  400. package/dist/shared/types/results.js +1 -0
  401. package/dist/shared/types/state.js +1 -0
  402. package/dist/shared/types/usage.js +1 -0
  403. package/dist/shared/types/workflow.js +1 -0
  404. package/dist/shared/types.js +75 -30
  405. package/dist/shared/unknown.js +52 -0
  406. package/dist/shared/utils.js +54 -260
  407. package/dist/slash/command-discovery.js +82 -0
  408. package/dist/slash/command-input.js +190 -0
  409. package/dist/slash/prompt-template-bridge.js +94 -270
  410. package/dist/slash/prompt-template-contract.js +77 -0
  411. package/dist/slash/prompt-template-results.js +125 -0
  412. package/dist/slash/request-protocol.js +68 -0
  413. package/dist/slash/result-delivery.js +237 -0
  414. package/dist/slash/saved-chain.js +78 -0
  415. package/dist/slash/slash-bridge.js +123 -89
  416. package/dist/slash/slash-commands.js +101 -572
  417. package/dist/slash/slash-live-state.js +68 -47
  418. package/dist/tui/action-hints.js +50 -22
  419. package/dist/tui/activity-lines.js +32 -0
  420. package/dist/tui/agent-browser.js +290 -0
  421. package/dist/tui/agent-controls.js +289 -0
  422. package/dist/tui/agent-conversation.js +444 -0
  423. package/dist/tui/agent-dock.js +171 -0
  424. package/dist/tui/agent-history.js +50 -183
  425. package/dist/tui/agent-model.js +62 -0
  426. package/dist/tui/agent-picker.js +262 -0
  427. package/dist/tui/agent-view.js +232 -1564
  428. package/dist/tui/compact-results.js +193 -0
  429. package/dist/tui/conversation-details.js +190 -0
  430. package/dist/tui/conversation-frame.js +135 -0
  431. package/dist/tui/conversation-history.js +201 -0
  432. package/dist/tui/conversation-menu.js +78 -0
  433. package/dist/tui/conversation-notices.js +79 -0
  434. package/dist/tui/conversation-selection.js +58 -0
  435. package/dist/tui/conversation-viewport.js +129 -0
  436. package/dist/tui/direction-message.js +27 -0
  437. package/dist/tui/display.js +282 -0
  438. package/dist/tui/editor-viewport.js +18 -0
  439. package/dist/tui/expanded-content.js +87 -0
  440. package/dist/tui/expanded-multi.js +170 -0
  441. package/dist/tui/expanded-single.js +65 -0
  442. package/dist/tui/history-cards.js +216 -0
  443. package/dist/tui/history-display.js +238 -0
  444. package/dist/tui/history-json.js +16 -0
  445. package/dist/tui/history-metadata.js +152 -0
  446. package/dist/tui/history-record.js +251 -0
  447. package/dist/tui/history-text.js +34 -0
  448. package/dist/tui/indexed-history.js +116 -0
  449. package/dist/tui/nested-widget.js +120 -0
  450. package/dist/tui/picker-page.js +59 -0
  451. package/dist/tui/render.js +58 -1501
  452. package/dist/tui/result-facts.js +64 -0
  453. package/dist/tui/task-observation.js +59 -0
  454. package/dist/tui/task-store.js +366 -0
  455. package/dist/tui/text-values.js +16 -0
  456. package/dist/tui/view-connections.js +47 -0
  457. package/dist/tui/view-model.js +94 -0
  458. package/dist/tui/view-persistence.js +51 -0
  459. package/dist/tui/view-ports.js +1 -0
  460. package/dist/tui/view-session.js +37 -0
  461. package/dist/tui/widget-details.js +144 -0
  462. package/dist/tui/widget-status.js +245 -0
  463. package/dist/tui/widget.js +145 -0
  464. package/dist/tui/workflow-labels.js +223 -0
  465. package/dist/tui/workflow-outcomes.js +124 -0
  466. package/docs/code-quality.md +38 -0
  467. package/docs/development.md +99 -0
  468. package/docs/intercom-bridge.md +22 -17
  469. package/docs/intercom.md +132 -106
  470. package/docs/performance.md +19 -17
  471. package/docs/reference.md +1472 -0
  472. package/generated/RunValidators.d.ts +28 -0
  473. package/generated/RunValidators.js +2 -0
  474. package/package.json +27 -6
  475. package/prompts/parallel-cleanup.md +3 -0
  476. package/prompts/parallel-context-build.md +3 -0
  477. package/prompts/parallel-handoff-plan.md +6 -0
  478. package/prompts/parallel-research.md +4 -0
  479. package/prompts/parallel-review.md +2 -0
  480. package/prompts/review-loop.md +2 -0
  481. package/scripts/build.mjs +129 -85
  482. package/scripts/check-compat.mjs +48 -11
  483. package/scripts/compat-host.mjs +35 -7
  484. package/scripts/generate-run-schemas.mjs +210 -0
  485. package/scripts/intercom-bridge-credentials.mjs +155 -28
  486. package/scripts/intercom-remote.mjs +175 -50
  487. package/scripts/local-install-smoke.mjs +47 -37
  488. package/scripts/native-package-smoke.mjs +135 -25
  489. package/scripts/package-smoke.mjs +360 -140
  490. package/scripts/prepare.mjs +54 -34
  491. package/scripts/real-pi-processes.mjs +261 -0
  492. package/scripts/real-pi-smoke.mjs +432 -351
  493. package/scripts/run-tests.mjs +29 -15
  494. package/skills/pi-intercom/SKILL.md +11 -11
  495. package/skills/pi-intercom/references/peer-sessions.md +7 -2
  496. package/skills/pi-subagents/SKILL.md +1 -1
  497. package/skills/pi-subagents/references/full-orchestration-guide.md +254 -112
  498. package/src/agents/agent-defaults.ts +13 -0
  499. package/src/agents/agent-definition.ts +253 -0
  500. package/src/agents/agent-management.ts +111 -808
  501. package/src/agents/agent-scope.ts +7 -3
  502. package/src/agents/agent-selection.ts +26 -16
  503. package/src/agents/agent-serializer.ts +84 -93
  504. package/src/agents/agents.ts +199 -906
  505. package/src/agents/builtin-overrides.ts +297 -0
  506. package/src/agents/chain-serializer.ts +3 -329
  507. package/src/agents/config-values.ts +57 -0
  508. package/src/agents/discovery-paths.ts +134 -0
  509. package/src/agents/frontmatter.ts +35 -17
  510. package/src/agents/identity.ts +49 -18
  511. package/src/agents/json-chain.ts +305 -0
  512. package/src/agents/management-config.ts +342 -0
  513. package/src/agents/management-format.ts +243 -0
  514. package/src/agents/management-persistence.ts +408 -0
  515. package/src/agents/management-targets.ts +260 -0
  516. package/src/agents/management-warnings.ts +115 -0
  517. package/src/agents/markdown-chain.ts +237 -0
  518. package/src/agents/package-agents.ts +231 -0
  519. package/src/agents/skill-files.ts +182 -0
  520. package/src/agents/skill-search-paths.ts +289 -0
  521. package/src/agents/skill-types.ts +31 -0
  522. package/src/agents/skills.ts +152 -610
  523. package/src/extension/acceptance-schema.ts +88 -0
  524. package/src/extension/chain-schema.ts +276 -0
  525. package/src/extension/child-runtime.ts +302 -0
  526. package/src/extension/compact-tools.ts +259 -102
  527. package/src/extension/config-schema.ts +59 -0
  528. package/src/extension/config.ts +39 -17
  529. package/src/extension/control-notice-schema.ts +55 -0
  530. package/src/extension/control-notices.ts +57 -33
  531. package/src/extension/delegation-bridges.ts +59 -0
  532. package/src/extension/doctor.ts +171 -135
  533. package/src/extension/everyday-schemas.ts +252 -0
  534. package/src/extension/fanout-child.ts +29 -308
  535. package/src/extension/index.ts +17 -642
  536. package/src/extension/message-renderers.ts +334 -0
  537. package/src/extension/nested-control-inbox.ts +196 -0
  538. package/src/extension/parent-runtime.ts +405 -0
  539. package/src/extension/primary-tool.ts +130 -0
  540. package/src/extension/result-snapshot.ts +35 -0
  541. package/src/extension/runtime-reload.ts +72 -0
  542. package/src/extension/runtime-storage.ts +49 -0
  543. package/src/extension/schema-overrides.ts +114 -0
  544. package/src/extension/schemas.ts +451 -418
  545. package/src/extension/tool-input.ts +40 -13
  546. package/src/extension/tool-result.ts +45 -14
  547. package/src/history/answer-texts.ts +74 -0
  548. package/src/history/canonical-result.ts +127 -51
  549. package/src/history/canonical-selection.ts +54 -0
  550. package/src/history/database-generation.ts +86 -0
  551. package/src/history/database.ts +86 -48
  552. package/src/history/entry-ingestion.ts +129 -0
  553. package/src/history/index.ts +426 -148
  554. package/src/history/ingest.ts +372 -342
  555. package/src/history/output-digests.ts +41 -0
  556. package/src/history/preview.ts +235 -0
  557. package/src/history/prune.ts +48 -0
  558. package/src/history/queries.ts +122 -256
  559. package/src/history/query-scope.ts +278 -0
  560. package/src/history/rows.ts +118 -0
  561. package/src/history/run-projection.ts +164 -0
  562. package/src/history/run-queries.ts +199 -0
  563. package/src/history/schema.ts +34 -0
  564. package/src/history/search-queries.ts +216 -0
  565. package/src/history/selected-record.ts +140 -0
  566. package/src/history/source-file.ts +51 -0
  567. package/src/history/source-watches.ts +156 -0
  568. package/src/history/store.ts +310 -197
  569. package/src/history/text-chunks.ts +181 -0
  570. package/src/history/text.ts +43 -0
  571. package/src/history/transcript-queries.ts +251 -0
  572. package/src/history/types.ts +27 -164
  573. package/src/history/values.ts +36 -0
  574. package/src/history/wire-inputs.ts +141 -0
  575. package/src/history/wire-models.ts +51 -0
  576. package/src/history/worker-runtime.ts +502 -0
  577. package/src/history/worker.ts +94 -336
  578. package/src/intercom/intercom-bridge.ts +136 -69
  579. package/src/intercom/live-intercom.ts +197 -92
  580. package/src/intercom/nested-result-tree.ts +213 -0
  581. package/src/intercom/result-delivery.ts +56 -0
  582. package/src/intercom/result-intercom.ts +364 -382
  583. package/src/pi-intercom/agent-dir.ts +9 -3
  584. package/src/pi-intercom/async.ts +33 -0
  585. package/src/pi-intercom/bridge-ask.ts +64 -0
  586. package/src/pi-intercom/bridge-config.ts +101 -0
  587. package/src/pi-intercom/bridge-http.ts +97 -0
  588. package/src/pi-intercom/bridge-protocol.ts +123 -0
  589. package/src/pi-intercom/bridge-routes.ts +90 -0
  590. package/src/pi-intercom/bridge-session.ts +506 -0
  591. package/src/pi-intercom/bridge.ts +258 -547
  592. package/src/pi-intercom/broker/broker.ts +326 -263
  593. package/src/pi-intercom/broker/client.ts +273 -354
  594. package/src/pi-intercom/broker/connection.ts +192 -0
  595. package/src/pi-intercom/broker/framing.ts +11 -6
  596. package/src/pi-intercom/broker/paths.ts +28 -25
  597. package/src/pi-intercom/broker/pid.ts +68 -24
  598. package/src/pi-intercom/broker/snapshot-reader.ts +91 -0
  599. package/src/pi-intercom/broker/snapshots.ts +241 -0
  600. package/src/pi-intercom/broker/spawn.ts +58 -34
  601. package/src/pi-intercom/config.ts +113 -108
  602. package/src/pi-intercom/connection.ts +346 -0
  603. package/src/pi-intercom/identity.ts +71 -0
  604. package/src/pi-intercom/inbound-delivery.ts +450 -0
  605. package/src/pi-intercom/inbound-journal.ts +350 -0
  606. package/src/pi-intercom/inbound-record.ts +141 -0
  607. package/src/pi-intercom/inbound.ts +237 -0
  608. package/src/pi-intercom/index.ts +86 -2923
  609. package/src/pi-intercom/inspection.ts +82 -0
  610. package/src/pi-intercom/interview.ts +295 -0
  611. package/src/pi-intercom/lifecycle.ts +183 -0
  612. package/src/pi-intercom/message-format.ts +77 -0
  613. package/src/pi-intercom/outbound.ts +418 -0
  614. package/src/pi-intercom/peer-awareness.ts +84 -0
  615. package/src/pi-intercom/reply-tracker.ts +121 -59
  616. package/src/pi-intercom/reply-wait.ts +247 -0
  617. package/src/pi-intercom/runtime-types.ts +97 -0
  618. package/src/pi-intercom/session-events.ts +247 -0
  619. package/src/pi-intercom/session-targets.ts +124 -72
  620. package/src/pi-intercom/subagent-events.ts +299 -0
  621. package/src/pi-intercom/subagent-live-events.ts +212 -109
  622. package/src/pi-intercom/supervisor.ts +362 -0
  623. package/src/pi-intercom/tool-arguments.ts +120 -0
  624. package/src/pi-intercom/tool-registration.ts +121 -0
  625. package/src/pi-intercom/tool-results.ts +54 -0
  626. package/src/pi-intercom/tool-schemas.ts +134 -0
  627. package/src/pi-intercom/tools.ts +80 -0
  628. package/src/pi-intercom/topic-actions.ts +243 -0
  629. package/src/pi-intercom/topics.ts +267 -121
  630. package/src/pi-intercom/transport.ts +14 -0
  631. package/src/pi-intercom/types.ts +288 -190
  632. package/src/pi-intercom/ui/compose-paste.ts +109 -0
  633. package/src/pi-intercom/ui/compose.ts +173 -157
  634. package/src/pi-intercom/ui/inline-message.ts +80 -62
  635. package/src/pi-intercom/ui/message-renderers.ts +182 -0
  636. package/src/pi-intercom/ui/overlay.ts +238 -0
  637. package/src/pi-intercom/ui/session-format.ts +146 -0
  638. package/src/pi-intercom/ui/session-list.ts +145 -62
  639. package/src/pi-intercom/ui/tool-renderers.ts +148 -0
  640. package/src/pi-intercom/ui/topic-view.ts +107 -0
  641. package/src/pi-intercom/validation.ts +69 -0
  642. package/src/runs/background/async-chain-plan.ts +451 -0
  643. package/src/runs/background/async-control.ts +201 -71
  644. package/src/runs/background/async-execution.ts +206 -829
  645. package/src/runs/background/async-job-admission.ts +54 -0
  646. package/src/runs/background/async-job-projection.ts +225 -0
  647. package/src/runs/background/async-job-tracker.ts +416 -360
  648. package/src/runs/background/async-launch.ts +319 -0
  649. package/src/runs/background/async-plan.ts +285 -0
  650. package/src/runs/background/async-result-file.ts +79 -37
  651. package/src/runs/background/async-resume.ts +338 -285
  652. package/src/runs/background/async-run-discovery.ts +270 -0
  653. package/src/runs/background/async-run-location.ts +194 -0
  654. package/src/runs/background/async-run-record.ts +14 -0
  655. package/src/runs/background/async-run-repair.ts +307 -0
  656. package/src/runs/background/async-run-summary.ts +71 -0
  657. package/src/runs/background/async-single-plan.ts +168 -0
  658. package/src/runs/background/async-status-projection.ts +188 -0
  659. package/src/runs/background/async-status-render.ts +164 -0
  660. package/src/runs/background/async-status-validation.ts +238 -0
  661. package/src/runs/background/async-status.ts +9 -481
  662. package/src/runs/background/async-value.ts +29 -0
  663. package/src/runs/background/completion-dedupe.ts +103 -54
  664. package/src/runs/background/completion-delivery.ts +313 -187
  665. package/src/runs/background/completion-receipts.ts +309 -0
  666. package/src/runs/background/legacy-status-acceptance.ts +38 -0
  667. package/src/runs/background/notify.ts +167 -106
  668. package/src/runs/background/parallel-groups.ts +95 -46
  669. package/src/runs/background/result-payload.ts +268 -0
  670. package/src/runs/background/result-watcher.ts +484 -387
  671. package/src/runs/background/run-id-resolver.ts +126 -57
  672. package/src/runs/background/run-schemas.ts +240 -0
  673. package/src/runs/background/run-status-contracts.ts +46 -0
  674. package/src/runs/background/run-status-render.ts +364 -0
  675. package/src/runs/background/run-status.ts +338 -356
  676. package/src/runs/background/runner-attempt-output.ts +281 -0
  677. package/src/runs/background/runner-attempt.ts +354 -0
  678. package/src/runs/background/runner-child-executor.ts +232 -0
  679. package/src/runs/background/runner-child-observer.ts +270 -0
  680. package/src/runs/background/runner-completion-summary.ts +106 -0
  681. package/src/runs/background/runner-completion.ts +274 -0
  682. package/src/runs/background/runner-config.ts +52 -0
  683. package/src/runs/background/runner-contract.ts +51 -0
  684. package/src/runs/background/runner-dynamic.ts +185 -0
  685. package/src/runs/background/runner-finalization.ts +203 -0
  686. package/src/runs/background/runner-graph.ts +91 -0
  687. package/src/runs/background/runner-initial-status.ts +72 -0
  688. package/src/runs/background/runner-lifecycle.ts +159 -0
  689. package/src/runs/background/runner-monitor.ts +399 -0
  690. package/src/runs/background/runner-parallel.ts +280 -0
  691. package/src/runs/background/runner-prepare-step.ts +128 -0
  692. package/src/runs/background/runner-reporting.ts +192 -0
  693. package/src/runs/background/runner-status.ts +220 -0
  694. package/src/runs/background/runner-step-output.ts +158 -0
  695. package/src/runs/background/runner-step-record.ts +76 -0
  696. package/src/runs/background/runner-step.ts +150 -0
  697. package/src/runs/background/runner-streaming.ts +220 -0
  698. package/src/runs/background/runner-workflow.ts +284 -0
  699. package/src/runs/background/stale-run-reconciler.ts +279 -336
  700. package/src/runs/background/subagent-runner-launcher.ts +67 -35
  701. package/src/runs/background/subagent-runner.ts +80 -2048
  702. package/src/runs/background/top-level-async.ts +9 -7
  703. package/src/runs/foreground/chain-clarify.ts +499 -1334
  704. package/src/runs/foreground/clarification-draft.ts +92 -0
  705. package/src/runs/foreground/clarify-contracts.ts +33 -0
  706. package/src/runs/foreground/clarify-invocation.ts +192 -65
  707. package/src/runs/foreground/clarify-text-editor.ts +229 -0
  708. package/src/runs/foreground/clarify-view.ts +222 -0
  709. package/src/runs/foreground/execution-input.ts +358 -424
  710. package/src/runs/foreground/execution-routing.ts +41 -0
  711. package/src/runs/foreground/execution-timeout.ts +92 -0
  712. package/src/runs/foreground/foreground-control.ts +333 -812
  713. package/src/runs/foreground/foreground-memory.ts +132 -0
  714. package/src/runs/foreground/invocation-context.ts +88 -0
  715. package/src/runs/foreground/invocation-execution.ts +465 -0
  716. package/src/runs/foreground/invocation-expansion.ts +58 -0
  717. package/src/runs/foreground/management-actions.ts +360 -0
  718. package/src/runs/foreground/nested-control.ts +248 -0
  719. package/src/runs/foreground/question-continuation.ts +112 -0
  720. package/src/runs/foreground/question-control.ts +297 -70
  721. package/src/runs/foreground/resume-target.ts +330 -0
  722. package/src/runs/foreground/revival-launch-policy.ts +112 -0
  723. package/src/runs/foreground/run-async-path.ts +307 -223
  724. package/src/runs/foreground/run-interrupt.ts +202 -0
  725. package/src/runs/foreground/run-nudge.ts +355 -0
  726. package/src/runs/foreground/saved-revival.ts +356 -0
  727. package/src/runs/foreground/subagent-executor.ts +195 -493
  728. package/src/runs/foreground/subagent-params.ts +314 -242
  729. package/src/runs/foreground/wait-observation.ts +160 -0
  730. package/src/runs/foreground/wait-registration.ts +18 -0
  731. package/src/runs/foreground/wait-run.ts +361 -119
  732. package/src/runs/shared/acceptance-contract.ts +410 -209
  733. package/src/runs/shared/acceptance-defaults.ts +1 -0
  734. package/src/runs/shared/acceptance-evaluation.ts +314 -240
  735. package/src/runs/shared/acceptance-finalization.ts +447 -305
  736. package/src/runs/shared/acceptance-outcome.ts +69 -0
  737. package/src/runs/shared/acceptance-reports.ts +220 -126
  738. package/src/runs/shared/acceptance-submission.ts +251 -0
  739. package/src/runs/shared/acceptance-verification.ts +118 -0
  740. package/src/runs/shared/acceptance.ts +25 -25
  741. package/src/runs/shared/chain-outputs.ts +190 -98
  742. package/src/runs/shared/child-attempt-types.ts +118 -0
  743. package/src/runs/shared/child-attempt.ts +372 -608
  744. package/src/runs/shared/child-boundaries.ts +217 -0
  745. package/src/runs/shared/child-context-filter.ts +53 -0
  746. package/src/runs/shared/child-event-observer.ts +496 -0
  747. package/src/runs/shared/child-execution-cwd.ts +139 -68
  748. package/src/runs/shared/child-execution-outcome.ts +103 -0
  749. package/src/runs/shared/child-invocation.ts +74 -0
  750. package/src/runs/shared/child-message-validation.ts +233 -0
  751. package/src/runs/shared/child-native-accounting.ts +154 -0
  752. package/src/runs/shared/child-native-observation.ts +79 -0
  753. package/src/runs/shared/child-observation-spool.ts +188 -0
  754. package/src/runs/shared/child-observations.ts +219 -89
  755. package/src/runs/shared/child-presence.ts +6 -0
  756. package/src/runs/shared/child-route-env.ts +142 -0
  757. package/src/runs/shared/child-stream-observer.ts +302 -0
  758. package/src/runs/shared/child-stream-projection.ts +160 -0
  759. package/src/runs/shared/child-structured-tool.ts +38 -0
  760. package/src/runs/shared/claude-code.ts +201 -228
  761. package/src/runs/shared/claude-model.ts +67 -0
  762. package/src/runs/shared/claude-session.ts +124 -0
  763. package/src/runs/shared/claude-types.ts +31 -0
  764. package/src/runs/shared/completion-guard.ts +35 -26
  765. package/src/runs/shared/control-event-policy.ts +15 -0
  766. package/src/runs/shared/control-notification-owner.ts +20 -0
  767. package/src/runs/shared/dynamic-fanout.ts +402 -238
  768. package/src/runs/shared/dynamic-item.ts +114 -0
  769. package/src/runs/shared/history-index.ts +112 -51
  770. package/src/runs/shared/legacy-async-recovery.ts +153 -0
  771. package/src/runs/shared/legacy-output-recovery.ts +214 -0
  772. package/src/runs/shared/mcp-config-schema.ts +46 -0
  773. package/src/runs/shared/mcp-direct-tool-allowlist.ts +396 -307
  774. package/src/runs/shared/model-fallback.ts +302 -180
  775. package/src/runs/shared/mutating-tool-guard.ts +259 -158
  776. package/src/runs/shared/native-finalization-types.ts +29 -0
  777. package/src/runs/shared/native-finalization.ts +233 -109
  778. package/src/runs/shared/native-usage.ts +379 -96
  779. package/src/runs/shared/nested-control-records.ts +178 -0
  780. package/src/runs/shared/nested-events.ts +45 -752
  781. package/src/runs/shared/nested-path.ts +47 -34
  782. package/src/runs/shared/nested-projection.ts +230 -0
  783. package/src/runs/shared/nested-protocol.ts +67 -0
  784. package/src/runs/shared/nested-registry.ts +273 -0
  785. package/src/runs/shared/nested-render.ts +198 -100
  786. package/src/runs/shared/nested-route.ts +292 -0
  787. package/src/runs/shared/nested-validation.ts +291 -0
  788. package/src/runs/shared/owned-child-evidence.ts +184 -0
  789. package/src/runs/shared/owned-run-list.ts +187 -0
  790. package/src/runs/shared/owned-run-observation.ts +368 -0
  791. package/src/runs/shared/owned-run-progress.ts +172 -0
  792. package/src/runs/shared/owned-run-read-state.ts +7 -0
  793. package/src/runs/shared/owned-run-results.ts +289 -0
  794. package/src/runs/shared/owned-run-status.ts +239 -0
  795. package/src/runs/shared/owned-run-view.ts +65 -0
  796. package/src/runs/shared/owned-workflow-details.ts +24 -0
  797. package/src/runs/shared/owner-output.ts +73 -0
  798. package/src/runs/shared/parallel-utils.ts +93 -129
  799. package/src/runs/shared/parent-receipts.ts +177 -50
  800. package/src/runs/shared/parent-usage.ts +314 -91
  801. package/src/runs/shared/pi-args.ts +241 -311
  802. package/src/runs/shared/pi-launch-input.ts +48 -0
  803. package/src/runs/shared/pi-session-launch.ts +94 -0
  804. package/src/runs/shared/pi-spawn.ts +57 -33
  805. package/src/runs/shared/run-history-queries.ts +189 -38
  806. package/src/runs/shared/run-history.ts +197 -76
  807. package/src/runs/shared/run-id-ambiguity.ts +7 -3
  808. package/src/runs/shared/run-metadata-paths.ts +17 -0
  809. package/src/runs/shared/run-metadata.ts +240 -0
  810. package/src/runs/shared/run-persistence.ts +181 -0
  811. package/src/runs/shared/run-records.ts +19 -607
  812. package/src/runs/shared/run-restoration.ts +455 -0
  813. package/src/runs/shared/run-state-owner.ts +31 -0
  814. package/src/runs/shared/session-cwd-preload.ts +39 -19
  815. package/src/runs/shared/single-output.ts +358 -205
  816. package/src/runs/shared/stable-value.ts +15 -0
  817. package/src/runs/shared/streaming-text.ts +39 -12
  818. package/src/runs/shared/structured-output.ts +76 -46
  819. package/src/runs/shared/subagent-control.ts +330 -197
  820. package/src/runs/shared/subagent-prompt-runtime.ts +92 -174
  821. package/src/runs/shared/subagent-tool-loop-guard.ts +118 -68
  822. package/src/runs/shared/supervisor-question-state.ts +221 -0
  823. package/src/runs/shared/supervisor-questions.ts +396 -401
  824. package/src/runs/shared/workflow-graph.ts +400 -198
  825. package/src/runs/shared/workflow-policy.ts +245 -110
  826. package/src/runs/shared/worktree-contract.ts +29 -0
  827. package/src/runs/shared/worktree-hook.ts +181 -0
  828. package/src/runs/shared/worktree-location.ts +61 -0
  829. package/src/runs/shared/worktree-preservation.ts +10 -0
  830. package/src/runs/shared/worktree-process.ts +132 -0
  831. package/src/runs/shared/worktree.ts +459 -587
  832. package/src/shared/agent-context-policy.ts +176 -145
  833. package/src/shared/agent-dir.ts +15 -0
  834. package/src/shared/artifacts.ts +99 -68
  835. package/src/shared/atomic-json.ts +14 -11
  836. package/src/shared/chain-files.ts +72 -0
  837. package/src/shared/concurrency.ts +27 -0
  838. package/src/shared/content-preview.ts +117 -0
  839. package/src/shared/cooperative.ts +17 -13
  840. package/src/shared/execution-cwd.ts +34 -9
  841. package/src/shared/file-coalescer.ts +24 -22
  842. package/src/shared/fork-context.ts +52 -48
  843. package/src/shared/formatters.ts +88 -47
  844. package/src/shared/journal-frames.ts +197 -0
  845. package/src/shared/journal-projections.ts +133 -0
  846. package/src/shared/journal-reader.ts +18 -333
  847. package/src/shared/json-projection.ts +224 -0
  848. package/src/shared/lazy-tools.ts +76 -27
  849. package/src/shared/message-output.ts +146 -0
  850. package/src/shared/model-info.ts +94 -58
  851. package/src/shared/native-import.ts +25 -0
  852. package/src/shared/native-journal.ts +172 -0
  853. package/src/shared/native-session.ts +8 -3
  854. package/src/shared/native-tui.ts +13 -3
  855. package/src/shared/native-typebox.ts +18 -3
  856. package/src/shared/output-page.ts +76 -0
  857. package/src/shared/post-exit-stdio-guard.ts +232 -172
  858. package/src/shared/prompt-sections.ts +13 -7
  859. package/src/shared/session-entries.ts +103 -44
  860. package/src/shared/session-identity.ts +17 -10
  861. package/src/shared/settings.ts +182 -367
  862. package/src/shared/status-format.ts +207 -98
  863. package/src/shared/stream-json.d.ts +10 -0
  864. package/src/shared/task-file-policy.ts +35 -0
  865. package/src/shared/temp-root.ts +122 -71
  866. package/src/shared/types/acceptance.ts +149 -0
  867. package/src/shared/types/async.ts +247 -0
  868. package/src/shared/types/config.ts +139 -0
  869. package/src/shared/types/details.ts +104 -0
  870. package/src/shared/types/history.ts +217 -0
  871. package/src/shared/types/inputs.ts +4 -0
  872. package/src/shared/types/intercom.ts +57 -0
  873. package/src/shared/types/launch.ts +39 -0
  874. package/src/shared/types/messages.ts +104 -0
  875. package/src/shared/types/nested.ts +153 -0
  876. package/src/shared/types/owned-runs.ts +148 -0
  877. package/src/shared/types/progress.ts +106 -0
  878. package/src/shared/types/questions.ts +103 -0
  879. package/src/shared/types/results.ts +119 -0
  880. package/src/shared/types/state.ts +56 -0
  881. package/src/shared/types/usage.ts +36 -0
  882. package/src/shared/types/workflow.ts +187 -0
  883. package/src/shared/types.ts +222 -1161
  884. package/src/shared/ui-mode.ts +1 -1
  885. package/src/shared/unknown.ts +59 -0
  886. package/src/shared/utils.ts +111 -305
  887. package/src/slash/command-discovery.ts +109 -0
  888. package/src/slash/command-input.ts +232 -0
  889. package/src/slash/prompt-template-bridge.ts +153 -400
  890. package/src/slash/prompt-template-contract.ts +152 -0
  891. package/src/slash/prompt-template-results.ts +189 -0
  892. package/src/slash/request-protocol.ts +87 -0
  893. package/src/slash/result-delivery.ts +312 -0
  894. package/src/slash/saved-chain.ts +115 -0
  895. package/src/slash/slash-bridge.ts +202 -156
  896. package/src/slash/slash-commands.ts +176 -598
  897. package/src/slash/slash-live-state.ts +287 -229
  898. package/src/tui/action-hints.ts +147 -61
  899. package/src/tui/activity-lines.ts +40 -0
  900. package/src/tui/agent-browser.ts +354 -0
  901. package/src/tui/agent-controls.ts +355 -0
  902. package/src/tui/agent-conversation.ts +514 -0
  903. package/src/tui/agent-dock.ts +250 -0
  904. package/src/tui/agent-history.ts +78 -203
  905. package/src/tui/agent-model.ts +78 -0
  906. package/src/tui/agent-picker.ts +325 -0
  907. package/src/tui/agent-view.ts +391 -1333
  908. package/src/tui/compact-results.ts +342 -0
  909. package/src/tui/conversation-details.ts +206 -0
  910. package/src/tui/conversation-frame.ts +184 -0
  911. package/src/tui/conversation-history.ts +246 -0
  912. package/src/tui/conversation-menu.ts +119 -0
  913. package/src/tui/conversation-notices.ts +116 -0
  914. package/src/tui/conversation-selection.ts +66 -0
  915. package/src/tui/conversation-viewport.ts +169 -0
  916. package/src/tui/direction-message.ts +35 -0
  917. package/src/tui/display.ts +409 -0
  918. package/src/tui/editor-viewport.ts +19 -0
  919. package/src/tui/expanded-content.ts +134 -0
  920. package/src/tui/expanded-multi.ts +264 -0
  921. package/src/tui/expanded-single.ts +92 -0
  922. package/src/tui/history-cards.ts +316 -0
  923. package/src/tui/history-display.ts +334 -0
  924. package/src/tui/history-json.ts +17 -0
  925. package/src/tui/history-metadata.ts +177 -0
  926. package/src/tui/history-record.ts +321 -0
  927. package/src/tui/history-text.ts +34 -0
  928. package/src/tui/indexed-history.ts +149 -0
  929. package/src/tui/nested-widget.ts +192 -0
  930. package/src/tui/picker-page.ts +80 -0
  931. package/src/tui/render.ts +100 -1546
  932. package/src/tui/result-facts.ts +99 -0
  933. package/src/tui/task-observation.ts +96 -0
  934. package/src/tui/task-store.ts +432 -0
  935. package/src/tui/text-values.ts +20 -0
  936. package/src/tui/view-connections.ts +64 -0
  937. package/src/tui/view-model.ts +181 -0
  938. package/src/tui/view-persistence.ts +57 -0
  939. package/src/tui/view-ports.ts +55 -0
  940. package/src/tui/view-session.ts +42 -0
  941. package/src/tui/widget-details.ts +220 -0
  942. package/src/tui/widget-status.ts +331 -0
  943. package/src/tui/widget.ts +208 -0
  944. package/src/tui/workflow-labels.ts +340 -0
  945. package/src/tui/workflow-outcomes.ts +150 -0
  946. package/tsconfig.build.json +11 -10
  947. package/tsconfig.json +30 -17
@@ -2,8 +2,10 @@ import { createHash } from "node:crypto";
2
2
  import * as fs from "node:fs";
3
3
  import * as os from "node:os";
4
4
  import * as path from "node:path";
5
- import { getAgentDir } from "../../shared/utils.js";
6
- const CACHE_VERSION = 1;
5
+ import { getAgentDir } from "../../shared/agent-dir.js";
6
+ import { Check, ServersSchema, CacheSchema } from "./mcp-config-schema.js";
7
+ import { stableStringify } from "./stable-value.js";
8
+ import { isRecord } from "../../shared/unknown.js";
7
9
  const CACHE_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000;
8
10
  const BUILTIN_TOOL_NAMES = new Set(["read", "bash", "edit", "write", "grep", "find", "ls", "mcp"]);
9
11
  const GENERIC_GLOBAL_CONFIG_PATH = path.join(os.homedir(), ".config", "mcp", "mcp.json");
@@ -14,27 +16,33 @@ const IMPORT_PATHS = {
14
16
  path.join(os.homedir(), ".claude.json"),
15
17
  path.join(os.homedir(), ".claude", "claude_desktop_config.json"),
16
18
  ],
17
- "claude-desktop": [path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json")],
19
+ "claude-desktop": [
20
+ path.join(os.homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json"),
21
+ ],
18
22
  codex: [path.join(os.homedir(), ".codex", "config.json")],
19
23
  windsurf: [path.join(os.homedir(), ".windsurf", "mcp.json")],
20
24
  vscode: [".vscode/mcp.json"],
21
25
  };
22
26
  export function resolveMcpDirectToolNames(mcpDirectTools, cwd = process.cwd()) {
23
- if (!mcpDirectTools?.length)
27
+ if (mcpDirectTools === undefined || mcpDirectTools.length === 0) {
24
28
  return [];
29
+ }
25
30
  const names = new Set();
26
31
  // Keep pre-v5 and independent Fitch configs paired with their own caches.
27
32
  for (const directory of ["", "fitch-mcp-adapter"]) {
28
33
  try {
29
34
  const config = loadMcpConfig(cwd, directory);
30
35
  const cache = loadMetadataCache(directory);
31
- if (!cache)
36
+ if (!cache) {
32
37
  continue;
38
+ }
33
39
  for (const name of resolveDirectToolNames(config, cache, getToolPrefix(config.settings?.toolPrefix), mcpDirectTools)) {
34
40
  names.add(name);
35
41
  }
36
42
  }
37
- catch { /* An unavailable adapter does not hide the other adapter's tools. */ }
43
+ catch {
44
+ /* An unavailable adapter does not hide the other adapter's tools. */
45
+ }
38
46
  }
39
47
  return [...names];
40
48
  }
@@ -47,20 +55,15 @@ function loadMetadataCache(directory) {
47
55
  catch {
48
56
  return null;
49
57
  }
50
- if (!parsed || typeof parsed !== "object")
51
- return null;
52
- const raw = parsed;
53
- if (raw.version !== CACHE_VERSION || !raw.servers || typeof raw.servers !== "object" || Array.isArray(raw.servers)) {
54
- return null;
55
- }
56
- return raw;
58
+ return Check(CacheSchema, parsed) ? parsed : null;
57
59
  }
58
60
  function loadMcpConfig(cwd, directory) {
59
61
  let config = { mcpServers: {} };
60
62
  for (const sourcePath of getConfigPaths(cwd, directory)) {
61
63
  const loaded = readConfig(sourcePath);
62
- if (!loaded)
64
+ if (!loaded) {
63
65
  continue;
66
+ }
64
67
  config = mergeConfigs(config, expandImports(loaded, cwd));
65
68
  }
66
69
  return config;
@@ -70,13 +73,16 @@ function getConfigPaths(cwd, directory) {
70
73
  const projectPath = path.resolve(cwd, ".mcp.json");
71
74
  const projectPiPath = path.resolve(cwd, ".pi", directory, "mcp.json");
72
75
  const sources = [];
73
- if (GENERIC_GLOBAL_CONFIG_PATH !== piGlobalPath)
76
+ if (GENERIC_GLOBAL_CONFIG_PATH !== piGlobalPath) {
74
77
  sources.push(GENERIC_GLOBAL_CONFIG_PATH);
78
+ }
75
79
  sources.push(piGlobalPath);
76
- if (projectPath !== piGlobalPath)
80
+ if (projectPath !== piGlobalPath) {
77
81
  sources.push(projectPath);
78
- if (projectPiPath !== piGlobalPath && projectPiPath !== projectPath)
82
+ }
83
+ if (projectPiPath !== piGlobalPath && projectPiPath !== projectPath) {
79
84
  sources.push(projectPiPath);
85
+ }
80
86
  return sources;
81
87
  }
82
88
  function readConfig(configPath) {
@@ -89,35 +95,40 @@ function readConfig(configPath) {
89
95
  }
90
96
  return validateConfig(parsed);
91
97
  }
98
+ function validatedServers(value) {
99
+ return Check(ServersSchema, value) ? value : {};
100
+ }
92
101
  function validateConfig(raw) {
93
- if (!raw || typeof raw !== "object" || Array.isArray(raw))
102
+ if (!isRecord(raw)) {
94
103
  return { mcpServers: {} };
95
- const obj = raw;
96
- const servers = obj.mcpServers ?? obj["mcp-servers"] ?? {};
104
+ }
105
+ const settings = isRecord(raw.settings)
106
+ ? { toolPrefix: getToolPrefix(raw.settings.toolPrefix) }
107
+ : undefined;
97
108
  return {
98
- mcpServers: servers && typeof servers === "object" && !Array.isArray(servers) ? servers : {},
99
- imports: Array.isArray(obj.imports) ? obj.imports.filter((value) => isImportKind(value)) : undefined,
100
- settings: obj.settings && typeof obj.settings === "object" && !Array.isArray(obj.settings)
101
- ? obj.settings
102
- : undefined,
109
+ mcpServers: validatedServers(raw.mcpServers ?? raw["mcp-servers"] ?? {}),
110
+ imports: Array.isArray(raw.imports) ? raw.imports.filter(isImportKind) : undefined,
111
+ settings,
103
112
  };
104
113
  }
105
114
  function mergeConfigs(base, next) {
106
115
  const imports = [...(base.imports ?? []), ...(next.imports ?? [])];
107
116
  return {
108
117
  mcpServers: { ...base.mcpServers, ...next.mcpServers },
109
- imports: imports.length ? [...new Set(imports)] : undefined,
118
+ imports: imports.length > 0 ? [...new Set(imports)] : undefined,
110
119
  settings: next.settings ? { ...base.settings, ...next.settings } : base.settings,
111
120
  };
112
121
  }
113
122
  function expandImports(config, cwd) {
114
- if (!config.imports?.length)
123
+ if (config.imports === undefined || config.imports.length === 0) {
115
124
  return config;
116
- const importedServers = {};
125
+ }
126
+ const importedServers = new Map();
117
127
  for (const importKind of config.imports) {
118
128
  const importPath = resolveImportPath(importKind, cwd);
119
- if (!importPath)
129
+ if (importPath === null) {
120
130
  continue;
131
+ }
121
132
  let imported;
122
133
  try {
123
134
  imported = JSON.parse(fs.readFileSync(importPath, "utf-8"));
@@ -126,108 +137,125 @@ function expandImports(config, cwd) {
126
137
  continue;
127
138
  }
128
139
  for (const [name, definition] of Object.entries(extractServers(imported, importKind))) {
129
- if (!importedServers[name])
130
- importedServers[name] = definition;
140
+ if (!importedServers.has(name)) {
141
+ importedServers.set(name, definition);
142
+ }
131
143
  }
132
144
  }
133
145
  return {
134
146
  imports: config.imports,
135
147
  settings: config.settings,
136
- mcpServers: { ...importedServers, ...config.mcpServers },
148
+ mcpServers: { ...Object.fromEntries(importedServers), ...config.mcpServers },
137
149
  };
138
150
  }
139
151
  function resolveImportPath(importKind, cwd) {
140
152
  for (const candidate of IMPORT_PATHS[importKind]) {
141
153
  const fullPath = candidate.startsWith(".") ? path.resolve(cwd, candidate) : candidate;
142
- if (fs.existsSync(fullPath))
154
+ if (fs.existsSync(fullPath)) {
143
155
  return fullPath;
156
+ }
144
157
  }
145
158
  return null;
146
159
  }
147
160
  function extractServers(config, kind) {
148
- if (!config || typeof config !== "object" || Array.isArray(config))
161
+ if (!isRecord(config)) {
149
162
  return {};
150
- const obj = config;
163
+ }
151
164
  const servers = kind === "cursor" || kind === "windsurf" || kind === "vscode"
152
- ? obj.mcpServers ?? obj["mcp-servers"]
153
- : obj.mcpServers;
154
- return servers && typeof servers === "object" && !Array.isArray(servers) ? servers : {};
165
+ ? (config.mcpServers ?? config["mcp-servers"])
166
+ : config.mcpServers;
167
+ return validatedServers(servers);
168
+ }
169
+ function cachedNames(cache, exposeResources) {
170
+ const tools = (cache.tools ?? []).flatMap((tool) => tool.name !== undefined && tool.name !== "" ? [tool.name] : []);
171
+ if (!exposeResources) {
172
+ return tools;
173
+ }
174
+ const resources = (cache.resources ?? []).flatMap((resource) => {
175
+ if (resource.name === undefined ||
176
+ resource.name === "" ||
177
+ resource.uri === undefined ||
178
+ resource.uri === "") {
179
+ return [];
180
+ }
181
+ return [`read_${resourceNameToToolName(resource.name)}`];
182
+ });
183
+ return [...tools, ...resources];
184
+ }
185
+ function serverDirectNames(input) {
186
+ const names = [];
187
+ for (const name of cachedNames(input.cache, input.definition.exposeResources !== false)) {
188
+ if (input.selection !== true && !input.selection.has(name)) {
189
+ continue;
190
+ }
191
+ if (isToolExcluded(name, input.serverName, input.prefix, input.definition.excludeTools)) {
192
+ continue;
193
+ }
194
+ const prefixed = formatToolName(name, input.serverName, input.prefix);
195
+ if (!BUILTIN_TOOL_NAMES.has(prefixed)) {
196
+ names.push(prefixed);
197
+ }
198
+ }
199
+ return names;
155
200
  }
156
201
  function resolveDirectToolNames(config, cache, defaultPrefix, envOverride) {
157
202
  const names = [];
158
- const seenNames = new Set();
159
- const { servers: selectedServers, tools: selectedTools } = parseSelections(envOverride);
203
+ const { servers, tools } = parseSelections(envOverride);
160
204
  for (const [serverName, definition] of Object.entries(config.mcpServers)) {
161
- if (definition.disabled)
162
- continue;
163
205
  const serverCache = cache.servers[serverName];
164
- if (!isServerCacheValid(serverCache, definition))
165
- continue;
166
- const prefix = definition.toolPrefix ?? defaultPrefix;
167
- const toolFilter = selectedServers.has(serverName)
168
- ? true
169
- : selectedTools.get(serverName);
170
- if (!toolFilter)
206
+ if (definition.disabled === true || !isServerCacheValid(serverCache, definition)) {
171
207
  continue;
172
- for (const tool of Array.isArray(serverCache.tools) ? serverCache.tools : []) {
173
- if (typeof tool?.name !== "string" || !tool.name)
174
- continue;
175
- if (toolFilter !== true && !toolFilter.has(tool.name))
176
- continue;
177
- if (isToolExcluded(tool.name, serverName, prefix, definition.excludeTools))
178
- continue;
179
- const prefixedName = formatToolName(tool.name, serverName, prefix);
180
- if (BUILTIN_TOOL_NAMES.has(prefixedName) || seenNames.has(prefixedName))
181
- continue;
182
- seenNames.add(prefixedName);
183
- names.push(prefixedName);
184
208
  }
185
- if (definition.exposeResources === false)
209
+ const selection = servers.has(serverName) ? true : tools.get(serverName);
210
+ if (selection === undefined) {
186
211
  continue;
187
- for (const resource of Array.isArray(serverCache.resources) ? serverCache.resources : []) {
188
- if (typeof resource?.name !== "string" || !resource.name || typeof resource.uri !== "string" || !resource.uri)
189
- continue;
190
- const baseName = `read_${resourceNameToToolName(resource.name)}`;
191
- if (toolFilter !== true && !toolFilter.has(baseName))
192
- continue;
193
- if (isToolExcluded(baseName, serverName, prefix, definition.excludeTools))
194
- continue;
195
- const prefixedName = formatToolName(baseName, serverName, prefix);
196
- if (BUILTIN_TOOL_NAMES.has(prefixedName) || seenNames.has(prefixedName))
197
- continue;
198
- seenNames.add(prefixedName);
199
- names.push(prefixedName);
200
212
  }
213
+ names.push(...serverDirectNames({
214
+ serverName,
215
+ definition,
216
+ cache: serverCache,
217
+ prefix: definition.toolPrefix ?? defaultPrefix,
218
+ selection,
219
+ }));
201
220
  }
202
- return names;
221
+ return [...new Set(names)];
222
+ }
223
+ function parseSelection(item) {
224
+ const normalized = item.replace(/\/+$/, "");
225
+ if (!normalized.includes("/")) {
226
+ return normalized === "" ? undefined : { server: normalized };
227
+ }
228
+ const [server = "", tool = ""] = normalized.split("/", 2);
229
+ if (server === "") {
230
+ return;
231
+ }
232
+ return tool === "" ? { server } : { server, tool };
203
233
  }
204
234
  function parseSelections(selections) {
205
235
  const servers = new Set();
206
236
  const tools = new Map();
207
- for (let item of selections) {
208
- item = item.replace(/\/+$/, "");
209
- if (item.includes("/")) {
210
- const [server, tool] = item.split("/", 2);
211
- if (server && tool) {
212
- if (!tools.has(server))
213
- tools.set(server, new Set());
214
- tools.get(server).add(tool);
215
- }
216
- else if (server) {
217
- servers.add(server);
218
- }
237
+ for (const item of selections) {
238
+ const selected = parseSelection(item);
239
+ if (!selected) {
240
+ continue;
219
241
  }
220
- else if (item) {
221
- servers.add(item);
242
+ if (selected.tool === undefined) {
243
+ servers.add(selected.server);
244
+ continue;
222
245
  }
246
+ const names = tools.get(selected.server) ?? new Set();
247
+ names.add(selected.tool);
248
+ tools.set(selected.server, names);
223
249
  }
224
250
  return { servers, tools };
225
251
  }
226
252
  function isServerCacheValid(entry, definition) {
227
- if (!entry || entry.configHash !== computeMcpServerHash(definition))
253
+ if (!entry || entry.configHash !== computeMcpServerHash(definition)) {
228
254
  return false;
229
- if (!entry.cachedAt || typeof entry.cachedAt !== "number")
255
+ }
256
+ if (entry.cachedAt === undefined || entry.cachedAt === 0) {
230
257
  return false;
258
+ }
231
259
  return Date.now() - entry.cachedAt <= CACHE_MAX_AGE_MS;
232
260
  }
233
261
  function computeMcpServerHash(definition) {
@@ -237,7 +265,9 @@ function computeMcpServerHash(definition) {
237
265
  socket: resolveConfigPath(definition.socket),
238
266
  env: interpolateEnvRecord(definition.env),
239
267
  cwd: resolveConfigPath(definition.cwd),
240
- url: definition.url ? interpolateEnvVars(definition.url) : definition.url,
268
+ url: definition.url !== undefined && definition.url !== ""
269
+ ? interpolateEnvVars(definition.url)
270
+ : definition.url,
241
271
  headers: interpolateEnvRecord(definition.headers),
242
272
  auth: definition.auth,
243
273
  bearerToken: resolveBearerToken(definition),
@@ -255,21 +285,23 @@ function isImportKind(value) {
255
285
  return typeof value === "string" && Object.hasOwn(IMPORT_PATHS, value);
256
286
  }
257
287
  function getServerPrefix(serverName, mode) {
258
- if (mode === "none")
288
+ if (mode === "none") {
259
289
  return "";
290
+ }
260
291
  if (mode === "short") {
261
292
  const short = serverName.replace(/-?mcp$/i, "").replace(/-/g, "_");
262
- return short || "mcp";
293
+ return short === "" ? "mcp" : short;
263
294
  }
264
295
  return serverName.replace(/-/g, "_");
265
296
  }
266
297
  function formatToolName(toolName, serverName, prefix) {
267
298
  const serverPrefix = getServerPrefix(serverName, prefix);
268
- return serverPrefix ? `${serverPrefix}_${toolName}` : toolName;
299
+ return serverPrefix !== "" ? `${serverPrefix}_${toolName}` : toolName;
269
300
  }
270
301
  function isToolExcluded(toolName, serverName, prefix, excludeTools) {
271
- if (!Array.isArray(excludeTools) || excludeTools.length === 0)
302
+ if (!Array.isArray(excludeTools) || excludeTools.length === 0) {
272
303
  return false;
304
+ }
273
305
  const candidates = new Set([
274
306
  normalizeToolName(toolName),
275
307
  normalizeToolName(formatToolName(toolName, serverName, prefix)),
@@ -288,17 +320,20 @@ function resourceNameToToolName(name) {
288
320
  .replace(/^_+/, "")
289
321
  .replace(/_+$/, "")
290
322
  .toLowerCase();
291
- if (!result || /^\d/.test(result))
292
- result = `resource${result ? `_${result}` : ""}`;
323
+ if (result === "" || /^\d/.test(result)) {
324
+ result = `resource${result !== "" ? `_${result}` : ""}`;
325
+ }
293
326
  return result;
294
327
  }
295
328
  function interpolateEnvRecord(values) {
296
- if (!values || typeof values !== "object" || Array.isArray(values))
329
+ if (!values || typeof values !== "object" || Array.isArray(values)) {
297
330
  return undefined;
331
+ }
298
332
  const resolved = {};
299
333
  for (const [key, value] of Object.entries(values)) {
300
- if (typeof value === "string")
334
+ if (typeof value === "string") {
301
335
  resolved[key] = interpolateEnvVars(value);
336
+ }
302
337
  }
303
338
  return resolved;
304
339
  }
@@ -308,27 +343,23 @@ function interpolateEnvVars(value) {
308
343
  .replace(/\$env:(\w+)/g, (_, name) => process.env[name] ?? "");
309
344
  }
310
345
  function resolveConfigPath(value) {
311
- if (typeof value !== "string")
346
+ if (typeof value !== "string") {
312
347
  return undefined;
348
+ }
313
349
  const resolved = interpolateEnvVars(value);
314
- if (resolved === "~")
350
+ if (resolved === "~") {
315
351
  return os.homedir();
316
- if (resolved.startsWith("~/") || resolved.startsWith("~\\"))
352
+ }
353
+ if (resolved.startsWith("~/") || resolved.startsWith("~\\")) {
317
354
  return path.join(os.homedir(), resolved.slice(2));
355
+ }
318
356
  return resolved;
319
357
  }
320
358
  function resolveBearerToken(definition) {
321
- if (typeof definition.bearerToken === "string")
359
+ if (typeof definition.bearerToken === "string") {
322
360
  return interpolateEnvVars(definition.bearerToken);
323
- return typeof definition.bearerTokenEnv === "string" ? process.env[definition.bearerTokenEnv] : undefined;
324
- }
325
- function stableStringify(value) {
326
- if (value === null || value === undefined || typeof value !== "object") {
327
- const serialized = JSON.stringify(value);
328
- return serialized === undefined ? "undefined" : serialized;
329
- }
330
- if (Array.isArray(value))
331
- return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
332
- const obj = value;
333
- return `{${Object.keys(obj).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(obj[key])}`).join(",")}}`;
361
+ }
362
+ return typeof definition.bearerTokenEnv === "string"
363
+ ? process.env[definition.bearerTokenEnv]
364
+ : undefined;
334
365
  }
@@ -1,39 +1,51 @@
1
1
  export function splitThinkingSuffix(model) {
2
2
  const colonIdx = model.lastIndexOf(":");
3
- if (colonIdx === -1)
3
+ if (colonIdx === -1) {
4
4
  return { baseModel: model, thinkingSuffix: "" };
5
+ }
5
6
  return {
6
7
  baseModel: model.substring(0, colonIdx),
7
8
  thinkingSuffix: model.substring(colonIdx),
8
9
  };
9
10
  }
11
+ function preferredModel(matches, provider) {
12
+ return provider === undefined || provider.length === 0
13
+ ? undefined
14
+ : matches.find((entry) => entry.provider === provider);
15
+ }
10
16
  export function resolveModelCandidate(model, availableModels, preferredProvider) {
11
- if (!model)
17
+ if (model === undefined || model.length === 0) {
12
18
  return undefined;
13
- if (model.includes("/"))
19
+ }
20
+ if (model.includes("/")) {
14
21
  return model;
15
- if (!availableModels || availableModels.length === 0)
22
+ }
23
+ if (!availableModels || availableModels.length === 0) {
16
24
  return model;
25
+ }
17
26
  const { baseModel, thinkingSuffix } = splitThinkingSuffix(model);
18
27
  const matches = availableModels.filter((entry) => entry.id === baseModel);
19
- if (preferredProvider) {
20
- const preferredMatch = matches.find((entry) => entry.provider === preferredProvider);
21
- if (preferredMatch)
22
- return `${preferredMatch.fullId}${thinkingSuffix}`;
28
+ const preferredMatch = preferredModel(matches, preferredProvider);
29
+ if (preferredMatch) {
30
+ return `${preferredMatch.fullId}${thinkingSuffix}`;
23
31
  }
24
- if (matches.length !== 1)
32
+ if (matches.length !== 1) {
25
33
  return model;
26
- return `${matches[0].fullId}${thinkingSuffix}`;
34
+ }
35
+ const match = matches.at(0);
36
+ return match === undefined ? model : `${match.fullId}${thinkingSuffix}`;
27
37
  }
28
38
  export function buildModelCandidates(primaryModel, fallbackModels, availableModels, preferredProvider) {
29
39
  const seen = new Set();
30
40
  const candidates = [];
31
41
  for (const raw of [primaryModel, ...(fallbackModels ?? [])]) {
32
- if (!raw)
42
+ if (raw === undefined || raw.length === 0) {
33
43
  continue;
44
+ }
34
45
  const normalized = resolveModelCandidate(raw.trim(), availableModels, preferredProvider);
35
- if (!normalized || seen.has(normalized))
46
+ if (normalized === undefined || normalized.length === 0 || seen.has(normalized)) {
36
47
  continue;
48
+ }
37
49
  seen.add(normalized);
38
50
  candidates.push(normalized);
39
51
  }
@@ -75,8 +87,9 @@ const RETRYABLE_MODEL_FAILURE_PATTERNS = [
75
87
  /\b504\b/,
76
88
  ];
77
89
  export function isRetryableModelFailure(error) {
78
- if (!error)
90
+ if (error === undefined || error.length === 0) {
79
91
  return false;
92
+ }
80
93
  return RETRYABLE_MODEL_FAILURE_PATTERNS.some((pattern) => pattern.test(error));
81
94
  }
82
95
  const NON_RECOVERABLE_SAME_MODEL_PATTERNS = [
@@ -119,36 +132,87 @@ const SAME_MODEL_RECOVERY_PATTERNS = [
119
132
  /\b504\b/,
120
133
  ];
121
134
  export function isRecoverableSameModelFailure(error, exitCode) {
122
- if (exitCode === 143)
135
+ if (exitCode === 143) {
123
136
  return true;
124
- if (!error)
137
+ }
138
+ if (error === undefined || error.length === 0) {
125
139
  return false;
126
- if (NON_RECOVERABLE_SAME_MODEL_PATTERNS.some((pattern) => pattern.test(error)))
140
+ }
141
+ if (NON_RECOVERABLE_SAME_MODEL_PATTERNS.some((pattern) => pattern.test(error))) {
127
142
  return false;
143
+ }
128
144
  return SAME_MODEL_RECOVERY_PATTERNS.some((pattern) => pattern.test(error));
129
145
  }
130
146
  export function formatModelAttemptNote(attempt, nextModel) {
131
- const failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? 1}`;
132
- return nextModel
147
+ const failure = failureDescription(attempt);
148
+ return nextModel !== undefined && nextModel.length > 0
133
149
  ? `[fallback] ${attempt.model} failed: ${failure}. Retrying with ${nextModel}.`
134
150
  : `[fallback] ${attempt.model} failed: ${failure}.`;
135
151
  }
136
152
  export function formatModelRecoveryAttemptNote(attempt, retryNumber, maxRetries) {
137
- const failure = attempt.error?.trim() || `exit ${attempt.exitCode ?? 1}`;
153
+ const failure = failureDescription(attempt);
138
154
  return `[retry] ${attempt.model} failed: ${failure}. Retrying same model (${retryNumber}/${maxRetries}).`;
139
155
  }
140
156
  export function sumAttemptUsage(attempts) {
141
- const usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0, turns: 0 };
157
+ const usage = {
158
+ input: 0,
159
+ output: 0,
160
+ cacheRead: 0,
161
+ cacheWrite: 0,
162
+ cost: 0,
163
+ turns: 0,
164
+ };
142
165
  for (const attempt of attempts) {
143
- for (const key of ["input", "output", "cacheRead", "cacheWrite", "cost", "turns"])
166
+ for (const key of ["input", "output", "cacheRead", "cacheWrite", "cost", "turns"]) {
144
167
  usage[key] += attempt.usage?.[key] ?? 0;
145
- if (attempt.usage?.contributions?.length)
146
- (usage.contributions ??= []).push(...attempt.usage.contributions);
168
+ }
169
+ const contributions = attempt.usage?.contributions;
170
+ if (contributions !== undefined && contributions.length > 0) {
171
+ (usage.contributions ??= []).push(...contributions);
172
+ }
147
173
  }
148
174
  return usage;
149
175
  }
176
+ function failureDescription(attempt) {
177
+ const error = attempt.error?.trim();
178
+ return error !== undefined && error.length > 0 ? error : `exit ${attempt.exitCode ?? 1}`;
179
+ }
180
+ function successfulAttempt(result) {
181
+ return (result.exitCode === 0 &&
182
+ (result.error === undefined || result.error.length === 0) &&
183
+ result.interrupted !== true);
184
+ }
185
+ function terminalAttempt(result, signal) {
186
+ return (signal?.aborted === true ||
187
+ result.resourceLimitExceeded !== undefined ||
188
+ result.terminalFailure === true ||
189
+ result.interrupted === true ||
190
+ result.timedOut === true);
191
+ }
192
+ function summarizeAttempt(model, result) {
193
+ return {
194
+ model: model ?? result.model ?? "default",
195
+ success: successfulAttempt(result),
196
+ exitCode: result.exitCode,
197
+ error: result.error,
198
+ accounting: result.accounting,
199
+ usage: { ...result.usage },
200
+ };
201
+ }
202
+ function retryDecision(result, recovery, lastCandidate, signal) {
203
+ if (terminalAttempt(result, signal) || successfulAttempt(result)) {
204
+ return "stop";
205
+ }
206
+ const recoverable = isRecoverableSameModelFailure(result.error, result.exitCode);
207
+ if (recoverable && recovery === 0) {
208
+ return "recover";
209
+ }
210
+ return lastCandidate || (!recoverable && !isRetryableModelFailure(result.error))
211
+ ? "stop"
212
+ : "fallback";
213
+ }
150
214
  export async function runModelAttempts(input) {
151
- const candidates = input.candidates.length ? input.candidates : [undefined];
215
+ const candidates = input.candidates.length > 0 ? input.candidates : [undefined];
152
216
  const modelAttempts = [];
153
217
  const attemptedModels = [];
154
218
  const notes = [];
@@ -156,27 +220,22 @@ export async function runModelAttempts(input) {
156
220
  modelLoop: for (let index = 0; index < candidates.length; index++) {
157
221
  const model = candidates[index];
158
222
  for (let recovery = 0;; recovery++) {
223
+ // A recovery needs the previous finalized outcome and accumulated notes before it starts.
224
+ // oxlint-disable-next-line no-await-in-loop
159
225
  result = await input.runAttempt(model, notes);
160
- if (model)
226
+ if (model !== undefined && model.length > 0) {
161
227
  attemptedModels.push(model);
162
- const attempt = {
163
- model: model ?? result.model ?? "default",
164
- success: result.exitCode === 0 && !result.error && !result.interrupted,
165
- exitCode: result.exitCode,
166
- error: result.error,
167
- accounting: result.accounting,
168
- usage: { ...result.usage },
169
- };
228
+ }
229
+ const attempt = summarizeAttempt(model, result);
170
230
  modelAttempts.push(attempt);
171
- if (attempt.success || input.signal?.aborted || result.interrupted || result.timedOut || result.resourceLimitExceeded || result.terminalFailure)
231
+ const decision = retryDecision(result, recovery, index === candidates.length - 1, input.signal);
232
+ if (decision === "stop") {
172
233
  break modelLoop;
173
- const recoverable = isRecoverableSameModelFailure(result.error, result.exitCode);
174
- if (recoverable && recovery === 0) {
234
+ }
235
+ if (decision === "recover") {
175
236
  notes.push(formatModelRecoveryAttemptNote(attempt, 1, 1));
176
237
  continue;
177
238
  }
178
- if ((!recoverable && !isRetryableModelFailure(result.error)) || index === candidates.length - 1)
179
- break modelLoop;
180
239
  notes.push(formatModelAttemptNote(attempt, candidates[index + 1]));
181
240
  break;
182
241
  }