@fitchmultz/pi-subagents 0.44.7 → 0.46.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 (955) hide show
  1. package/CHANGELOG.md +264 -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 +89 -0
  111. package/dist/pi-intercom/bridge-http.js +86 -0
  112. package/dist/pi-intercom/bridge-launch-policy.js +88 -0
  113. package/dist/pi-intercom/bridge-launch.js +217 -0
  114. package/dist/pi-intercom/bridge-protocol.js +106 -0
  115. package/dist/pi-intercom/bridge-routes.js +72 -0
  116. package/dist/pi-intercom/bridge-rpc-process.js +264 -0
  117. package/dist/pi-intercom/bridge-session.js +420 -0
  118. package/dist/pi-intercom/bridge.js +221 -606
  119. package/dist/pi-intercom/broker/broker.js +236 -244
  120. package/dist/pi-intercom/broker/client.js +189 -304
  121. package/dist/pi-intercom/broker/connection.js +165 -0
  122. package/dist/pi-intercom/broker/framing.js +5 -3
  123. package/dist/pi-intercom/broker/paths.js +4 -1
  124. package/dist/pi-intercom/broker/pid.js +53 -25
  125. package/dist/pi-intercom/broker/snapshot-reader.js +78 -0
  126. package/dist/pi-intercom/broker/snapshots.js +188 -0
  127. package/dist/pi-intercom/broker/spawn.js +36 -25
  128. package/dist/pi-intercom/config.js +85 -71
  129. package/dist/pi-intercom/connection.js +297 -0
  130. package/dist/pi-intercom/identity.js +58 -0
  131. package/dist/pi-intercom/inbound-delivery.js +356 -0
  132. package/dist/pi-intercom/inbound-journal.js +303 -0
  133. package/dist/pi-intercom/inbound-record.js +113 -0
  134. package/dist/pi-intercom/inbound.js +179 -0
  135. package/dist/pi-intercom/index.js +79 -2933
  136. package/dist/pi-intercom/inspection.js +62 -0
  137. package/dist/pi-intercom/interview.js +236 -0
  138. package/dist/pi-intercom/lifecycle.js +168 -0
  139. package/dist/pi-intercom/message-format.js +69 -0
  140. package/dist/pi-intercom/outbound.js +304 -0
  141. package/dist/pi-intercom/peer-awareness.js +66 -0
  142. package/dist/pi-intercom/reply-tracker.js +62 -43
  143. package/dist/pi-intercom/reply-wait.js +201 -0
  144. package/dist/pi-intercom/runtime-types.js +3 -0
  145. package/dist/pi-intercom/session-events.js +180 -0
  146. package/dist/pi-intercom/session-targets.js +42 -34
  147. package/dist/pi-intercom/subagent-events.js +238 -0
  148. package/dist/pi-intercom/subagent-live-events.js +129 -86
  149. package/dist/pi-intercom/supervisor.js +282 -0
  150. package/dist/pi-intercom/tool-arguments.js +74 -0
  151. package/dist/pi-intercom/tool-registration.js +95 -0
  152. package/dist/pi-intercom/tool-results.js +38 -0
  153. package/dist/pi-intercom/tool-schemas.js +82 -0
  154. package/dist/pi-intercom/tools.js +51 -0
  155. package/dist/pi-intercom/topic-actions.js +177 -0
  156. package/dist/pi-intercom/topics.js +177 -92
  157. package/dist/pi-intercom/transport.js +1 -0
  158. package/dist/pi-intercom/types.js +151 -114
  159. package/dist/pi-intercom/ui/compose-paste.js +93 -0
  160. package/dist/pi-intercom/ui/compose.js +121 -143
  161. package/dist/pi-intercom/ui/inline-message.js +59 -59
  162. package/dist/pi-intercom/ui/message-renderers.js +147 -0
  163. package/dist/pi-intercom/ui/overlay.js +181 -0
  164. package/dist/pi-intercom/ui/session-format.js +124 -0
  165. package/dist/pi-intercom/ui/session-list.js +76 -43
  166. package/dist/pi-intercom/ui/tool-renderers.js +110 -0
  167. package/dist/pi-intercom/ui/topic-view.js +88 -0
  168. package/dist/pi-intercom/validation.js +59 -0
  169. package/dist/runs/background/async-chain-plan.js +265 -0
  170. package/dist/runs/background/async-control.js +134 -58
  171. package/dist/runs/background/async-execution.js +136 -633
  172. package/dist/runs/background/async-job-admission.js +40 -0
  173. package/dist/runs/background/async-job-projection.js +169 -0
  174. package/dist/runs/background/async-job-tracker.js +297 -327
  175. package/dist/runs/background/async-launch.js +216 -0
  176. package/dist/runs/background/async-plan.js +116 -0
  177. package/dist/runs/background/async-result-file.js +47 -23
  178. package/dist/runs/background/async-resume.js +195 -253
  179. package/dist/runs/background/async-run-discovery.js +213 -0
  180. package/dist/runs/background/async-run-location.js +135 -0
  181. package/dist/runs/background/async-run-record.js +1 -0
  182. package/dist/runs/background/async-run-repair.js +223 -0
  183. package/dist/runs/background/async-run-summary.js +1 -0
  184. package/dist/runs/background/async-single-plan.js +105 -0
  185. package/dist/runs/background/async-status-projection.js +155 -0
  186. package/dist/runs/background/async-status-render.js +117 -0
  187. package/dist/runs/background/async-status-validation.js +181 -0
  188. package/dist/runs/background/async-status.js +3 -442
  189. package/dist/runs/background/async-value.js +21 -0
  190. package/dist/runs/background/completion-dedupe.js +36 -12
  191. package/dist/runs/background/completion-delivery.js +211 -205
  192. package/dist/runs/background/completion-receipts.js +237 -0
  193. package/dist/runs/background/legacy-status-acceptance.js +34 -0
  194. package/dist/runs/background/notify.js +96 -48
  195. package/dist/runs/background/parallel-groups.js +36 -19
  196. package/dist/runs/background/result-payload.js +178 -0
  197. package/dist/runs/background/result-watcher.js +348 -339
  198. package/dist/runs/background/run-id-resolver.js +53 -33
  199. package/dist/runs/background/run-schemas.js +189 -0
  200. package/dist/runs/background/run-status-contracts.js +14 -0
  201. package/dist/runs/background/run-status-render.js +270 -0
  202. package/dist/runs/background/run-status.js +231 -339
  203. package/dist/runs/background/runner-attempt-output.js +155 -0
  204. package/dist/runs/background/runner-attempt.js +263 -0
  205. package/dist/runs/background/runner-child-executor.js +166 -0
  206. package/dist/runs/background/runner-child-observer.js +192 -0
  207. package/dist/runs/background/runner-completion-summary.js +71 -0
  208. package/dist/runs/background/runner-completion.js +211 -0
  209. package/dist/runs/background/runner-config.js +1 -0
  210. package/dist/runs/background/runner-contract.js +1 -0
  211. package/dist/runs/background/runner-dynamic.js +121 -0
  212. package/dist/runs/background/runner-finalization.js +149 -0
  213. package/dist/runs/background/runner-graph.js +68 -0
  214. package/dist/runs/background/runner-initial-status.js +60 -0
  215. package/dist/runs/background/runner-lifecycle.js +142 -0
  216. package/dist/runs/background/runner-monitor.js +309 -0
  217. package/dist/runs/background/runner-parallel.js +204 -0
  218. package/dist/runs/background/runner-prepare-step.js +86 -0
  219. package/dist/runs/background/runner-reporting.js +153 -0
  220. package/dist/runs/background/runner-status.js +148 -0
  221. package/dist/runs/background/runner-step-output.js +92 -0
  222. package/dist/runs/background/runner-step-record.js +45 -0
  223. package/dist/runs/background/runner-step.js +112 -0
  224. package/dist/runs/background/runner-streaming.js +173 -0
  225. package/dist/runs/background/runner-workflow.js +213 -0
  226. package/dist/runs/background/stale-run-reconciler.js +155 -292
  227. package/dist/runs/background/subagent-runner-launcher.js +33 -13
  228. package/dist/runs/background/subagent-runner.js +51 -1842
  229. package/dist/runs/background/top-level-async.js +2 -1
  230. package/dist/runs/foreground/chain-clarify.js +293 -1017
  231. package/dist/runs/foreground/clarification-draft.js +87 -0
  232. package/dist/runs/foreground/clarify-contracts.js +1 -0
  233. package/dist/runs/foreground/clarify-invocation.js +129 -38
  234. package/dist/runs/foreground/clarify-text-editor.js +210 -0
  235. package/dist/runs/foreground/clarify-view.js +167 -0
  236. package/dist/runs/foreground/execution-input.js +226 -353
  237. package/dist/runs/foreground/execution-routing.js +33 -0
  238. package/dist/runs/foreground/execution-timeout.js +81 -0
  239. package/dist/runs/foreground/foreground-control.js +222 -763
  240. package/dist/runs/foreground/foreground-memory.js +99 -0
  241. package/dist/runs/foreground/invocation-context.js +55 -0
  242. package/dist/runs/foreground/invocation-execution.js +331 -0
  243. package/dist/runs/foreground/invocation-expansion.js +48 -0
  244. package/dist/runs/foreground/management-actions.js +295 -0
  245. package/dist/runs/foreground/nested-control.js +179 -0
  246. package/dist/runs/foreground/question-continuation.js +78 -0
  247. package/dist/runs/foreground/question-control.js +155 -50
  248. package/dist/runs/foreground/resume-target.js +221 -0
  249. package/dist/runs/foreground/revival-launch-policy.js +58 -0
  250. package/dist/runs/foreground/run-async-path.js +190 -178
  251. package/dist/runs/foreground/run-interrupt.js +164 -0
  252. package/dist/runs/foreground/run-nudge.js +278 -0
  253. package/dist/runs/foreground/saved-revival.js +251 -0
  254. package/dist/runs/foreground/subagent-executor.js +135 -424
  255. package/dist/runs/foreground/subagent-params.js +67 -30
  256. package/dist/runs/foreground/wait-observation.js +104 -0
  257. package/dist/runs/foreground/wait-registration.js +17 -0
  258. package/dist/runs/foreground/wait-run.js +283 -123
  259. package/dist/runs/shared/acceptance-contract.js +193 -99
  260. package/dist/runs/shared/acceptance-defaults.js +1 -0
  261. package/dist/runs/shared/acceptance-evaluation.js +201 -181
  262. package/dist/runs/shared/acceptance-finalization.js +256 -180
  263. package/dist/runs/shared/acceptance-outcome.js +53 -0
  264. package/dist/runs/shared/acceptance-reports.js +137 -72
  265. package/dist/runs/shared/acceptance-submission.js +167 -0
  266. package/dist/runs/shared/acceptance-verification.js +100 -0
  267. package/dist/runs/shared/chain-outputs.js +80 -52
  268. package/dist/runs/shared/child-attempt-types.js +1 -0
  269. package/dist/runs/shared/child-attempt.js +314 -667
  270. package/dist/runs/shared/child-boundaries.js +173 -0
  271. package/dist/runs/shared/child-context-filter.js +44 -0
  272. package/dist/runs/shared/child-event-observer.js +390 -0
  273. package/dist/runs/shared/child-execution-cwd.js +73 -43
  274. package/dist/runs/shared/child-execution-outcome.js +72 -0
  275. package/dist/runs/shared/child-invocation.js +54 -0
  276. package/dist/runs/shared/child-message-validation.js +215 -0
  277. package/dist/runs/shared/child-native-accounting.js +106 -0
  278. package/dist/runs/shared/child-native-observation.js +69 -0
  279. package/dist/runs/shared/child-observation-spool.js +164 -0
  280. package/dist/runs/shared/child-observations.js +157 -76
  281. package/dist/runs/shared/child-presence.js +3 -0
  282. package/dist/runs/shared/child-route-env.js +119 -0
  283. package/dist/runs/shared/child-stream-observer.js +221 -0
  284. package/dist/runs/shared/child-stream-projection.js +137 -0
  285. package/dist/runs/shared/child-structured-tool.js +27 -0
  286. package/dist/runs/shared/claude-code.js +121 -158
  287. package/dist/runs/shared/claude-model.js +42 -0
  288. package/dist/runs/shared/claude-session.js +83 -0
  289. package/dist/runs/shared/claude-types.js +1 -0
  290. package/dist/runs/shared/completion-guard.js +18 -18
  291. package/dist/runs/shared/control-event-policy.js +8 -0
  292. package/dist/runs/shared/control-notification-owner.js +13 -0
  293. package/dist/runs/shared/dynamic-fanout.js +188 -173
  294. package/dist/runs/shared/dynamic-item.js +102 -0
  295. package/dist/runs/shared/history-index.js +62 -36
  296. package/dist/runs/shared/legacy-async-recovery.js +114 -0
  297. package/dist/runs/shared/legacy-output-recovery.js +148 -0
  298. package/dist/runs/shared/mcp-config-schema.js +36 -0
  299. package/dist/runs/shared/mcp-direct-tool-allowlist.js +147 -116
  300. package/dist/runs/shared/model-fallback.js +97 -38
  301. package/dist/runs/shared/mutating-tool-guard.js +128 -88
  302. package/dist/runs/shared/native-finalization-types.js +1 -0
  303. package/dist/runs/shared/native-finalization.js +155 -76
  304. package/dist/runs/shared/native-usage.js +238 -98
  305. package/dist/runs/shared/nested-control-records.js +128 -0
  306. package/dist/runs/shared/nested-events.js +8 -700
  307. package/dist/runs/shared/nested-path.js +32 -28
  308. package/dist/runs/shared/nested-projection.js +155 -0
  309. package/dist/runs/shared/nested-protocol.js +18 -0
  310. package/dist/runs/shared/nested-registry.js +191 -0
  311. package/dist/runs/shared/nested-render.js +106 -58
  312. package/dist/runs/shared/nested-route.js +220 -0
  313. package/dist/runs/shared/nested-validation.js +216 -0
  314. package/dist/runs/shared/owned-child-evidence.js +125 -0
  315. package/dist/runs/shared/owned-run-list.js +146 -0
  316. package/dist/runs/shared/owned-run-observation.js +267 -0
  317. package/dist/runs/shared/owned-run-progress.js +109 -0
  318. package/dist/runs/shared/owned-run-read-state.js +1 -0
  319. package/dist/runs/shared/owned-run-results.js +202 -0
  320. package/dist/runs/shared/owned-run-status.js +180 -0
  321. package/dist/runs/shared/owned-run-view.js +51 -0
  322. package/dist/runs/shared/owned-workflow-details.js +17 -0
  323. package/dist/runs/shared/owner-output.js +43 -0
  324. package/dist/runs/shared/parallel-utils.js +36 -28
  325. package/dist/runs/shared/parent-receipts.js +90 -32
  326. package/dist/runs/shared/parent-usage.js +169 -57
  327. package/dist/runs/shared/pi-args.js +108 -201
  328. package/dist/runs/shared/pi-launch-input.js +1 -0
  329. package/dist/runs/shared/pi-session-launch.js +86 -0
  330. package/dist/runs/shared/pi-spawn.js +35 -21
  331. package/dist/runs/shared/run-history-queries.js +126 -35
  332. package/dist/runs/shared/run-history.js +101 -35
  333. package/dist/runs/shared/run-metadata-paths.js +14 -0
  334. package/dist/runs/shared/run-metadata.js +158 -0
  335. package/dist/runs/shared/run-persistence.js +131 -0
  336. package/dist/runs/shared/run-records.js +9 -679
  337. package/dist/runs/shared/run-restoration.js +338 -0
  338. package/dist/runs/shared/run-state-owner.js +26 -0
  339. package/dist/runs/shared/session-cwd-preload.js +27 -18
  340. package/dist/runs/shared/single-output.js +148 -70
  341. package/dist/runs/shared/stable-value.js +15 -0
  342. package/dist/runs/shared/streaming-text.js +23 -12
  343. package/dist/runs/shared/structured-output.js +25 -13
  344. package/dist/runs/shared/subagent-control.js +167 -100
  345. package/dist/runs/shared/subagent-prompt-runtime.js +27 -130
  346. package/dist/runs/shared/subagent-tool-loop-guard.js +81 -52
  347. package/dist/runs/shared/supervisor-question-state.js +145 -0
  348. package/dist/runs/shared/supervisor-questions.js +185 -254
  349. package/dist/runs/shared/workflow-graph.js +259 -167
  350. package/dist/runs/shared/workflow-policy.js +120 -48
  351. package/dist/runs/shared/worktree-contract.js +1 -0
  352. package/dist/runs/shared/worktree-hook.js +138 -0
  353. package/dist/runs/shared/worktree-location.js +47 -0
  354. package/dist/runs/shared/worktree-preservation.js +8 -0
  355. package/dist/runs/shared/worktree-process.js +107 -0
  356. package/dist/runs/shared/worktree.js +183 -322
  357. package/dist/shared/agent-context-policy.js +34 -44
  358. package/dist/shared/agent-dir.js +14 -0
  359. package/dist/shared/artifacts.js +30 -12
  360. package/dist/shared/atomic-json.js +4 -1
  361. package/dist/shared/chain-files.js +72 -0
  362. package/dist/shared/concurrency.js +18 -0
  363. package/dist/shared/content-preview.js +115 -0
  364. package/dist/shared/cooperative.js +5 -2
  365. package/dist/shared/execution-cwd.js +13 -5
  366. package/dist/shared/file-coalescer.js +2 -1
  367. package/dist/shared/fork-context.js +10 -12
  368. package/dist/shared/formatters.js +45 -19
  369. package/dist/shared/journal-frames.js +164 -0
  370. package/dist/shared/journal-projections.js +121 -0
  371. package/dist/shared/journal-reader.js +6 -407
  372. package/dist/shared/json-projection.js +191 -0
  373. package/dist/shared/lazy-tools.js +19 -8
  374. package/dist/shared/message-output.js +116 -0
  375. package/dist/shared/model-info.js +31 -14
  376. package/dist/shared/native-import.js +20 -0
  377. package/dist/shared/native-journal.js +140 -0
  378. package/dist/shared/native-session-loader.js +17 -0
  379. package/dist/shared/native-session.js +2 -13
  380. package/dist/shared/native-tui.js +7 -2
  381. package/dist/shared/native-typebox.js +15 -3
  382. package/dist/shared/output-page.js +63 -0
  383. package/dist/shared/post-exit-stdio-guard.js +128 -88
  384. package/dist/shared/prompt-sections.js +2 -0
  385. package/dist/shared/session-entries.js +70 -35
  386. package/dist/shared/session-identity.js +5 -3
  387. package/dist/shared/settings.js +62 -192
  388. package/dist/shared/status-format.js +97 -37
  389. package/dist/shared/task-file-policy.js +24 -0
  390. package/dist/shared/temp-root.js +44 -15
  391. package/dist/shared/types/acceptance.js +1 -0
  392. package/dist/shared/types/async.js +1 -0
  393. package/dist/shared/types/config.js +1 -0
  394. package/dist/shared/types/details.js +1 -0
  395. package/dist/shared/types/history.js +1 -0
  396. package/dist/shared/types/inputs.js +1 -0
  397. package/dist/shared/types/intercom.js +1 -0
  398. package/dist/shared/types/launch.js +1 -0
  399. package/dist/shared/types/messages.js +1 -0
  400. package/dist/shared/types/nested.js +1 -0
  401. package/dist/shared/types/owned-runs.js +1 -0
  402. package/dist/shared/types/progress.js +1 -0
  403. package/dist/shared/types/questions.js +1 -0
  404. package/dist/shared/types/results.js +1 -0
  405. package/dist/shared/types/state.js +1 -0
  406. package/dist/shared/types/usage.js +1 -0
  407. package/dist/shared/types/workflow.js +1 -0
  408. package/dist/shared/types.js +75 -30
  409. package/dist/shared/unknown.js +52 -0
  410. package/dist/shared/utils.js +54 -260
  411. package/dist/slash/command-discovery.js +82 -0
  412. package/dist/slash/command-input.js +190 -0
  413. package/dist/slash/prompt-template-bridge.js +94 -270
  414. package/dist/slash/prompt-template-contract.js +77 -0
  415. package/dist/slash/prompt-template-results.js +125 -0
  416. package/dist/slash/request-protocol.js +68 -0
  417. package/dist/slash/result-delivery.js +237 -0
  418. package/dist/slash/saved-chain.js +78 -0
  419. package/dist/slash/slash-bridge.js +123 -89
  420. package/dist/slash/slash-commands.js +101 -572
  421. package/dist/slash/slash-live-state.js +68 -47
  422. package/dist/tui/action-hints.js +50 -22
  423. package/dist/tui/activity-lines.js +32 -0
  424. package/dist/tui/agent-browser.js +290 -0
  425. package/dist/tui/agent-controls.js +289 -0
  426. package/dist/tui/agent-conversation.js +444 -0
  427. package/dist/tui/agent-dock.js +171 -0
  428. package/dist/tui/agent-history.js +50 -183
  429. package/dist/tui/agent-model.js +62 -0
  430. package/dist/tui/agent-picker.js +262 -0
  431. package/dist/tui/agent-view.js +232 -1564
  432. package/dist/tui/compact-results.js +193 -0
  433. package/dist/tui/conversation-details.js +190 -0
  434. package/dist/tui/conversation-frame.js +135 -0
  435. package/dist/tui/conversation-history.js +201 -0
  436. package/dist/tui/conversation-menu.js +78 -0
  437. package/dist/tui/conversation-notices.js +79 -0
  438. package/dist/tui/conversation-selection.js +58 -0
  439. package/dist/tui/conversation-viewport.js +129 -0
  440. package/dist/tui/direction-message.js +27 -0
  441. package/dist/tui/display.js +282 -0
  442. package/dist/tui/editor-viewport.js +18 -0
  443. package/dist/tui/expanded-content.js +87 -0
  444. package/dist/tui/expanded-multi.js +170 -0
  445. package/dist/tui/expanded-single.js +65 -0
  446. package/dist/tui/history-cards.js +216 -0
  447. package/dist/tui/history-display.js +238 -0
  448. package/dist/tui/history-json.js +16 -0
  449. package/dist/tui/history-metadata.js +152 -0
  450. package/dist/tui/history-record.js +251 -0
  451. package/dist/tui/history-text.js +34 -0
  452. package/dist/tui/indexed-history.js +116 -0
  453. package/dist/tui/nested-widget.js +120 -0
  454. package/dist/tui/picker-page.js +59 -0
  455. package/dist/tui/render.js +58 -1501
  456. package/dist/tui/result-facts.js +64 -0
  457. package/dist/tui/task-observation.js +59 -0
  458. package/dist/tui/task-store.js +366 -0
  459. package/dist/tui/text-values.js +16 -0
  460. package/dist/tui/view-connections.js +47 -0
  461. package/dist/tui/view-model.js +94 -0
  462. package/dist/tui/view-persistence.js +51 -0
  463. package/dist/tui/view-ports.js +1 -0
  464. package/dist/tui/view-session.js +37 -0
  465. package/dist/tui/widget-details.js +144 -0
  466. package/dist/tui/widget-status.js +245 -0
  467. package/dist/tui/widget.js +145 -0
  468. package/dist/tui/workflow-labels.js +223 -0
  469. package/dist/tui/workflow-outcomes.js +124 -0
  470. package/docs/code-quality.md +38 -0
  471. package/docs/development.md +99 -0
  472. package/docs/intercom-bridge.md +77 -22
  473. package/docs/intercom.md +132 -106
  474. package/docs/performance.md +19 -17
  475. package/docs/reference.md +1472 -0
  476. package/generated/RunValidators.d.ts +28 -0
  477. package/generated/RunValidators.js +2 -0
  478. package/package.json +27 -6
  479. package/prompts/parallel-cleanup.md +3 -0
  480. package/prompts/parallel-context-build.md +3 -0
  481. package/prompts/parallel-handoff-plan.md +6 -0
  482. package/prompts/parallel-research.md +4 -0
  483. package/prompts/parallel-review.md +2 -0
  484. package/prompts/review-loop.md +2 -0
  485. package/scripts/build.mjs +129 -85
  486. package/scripts/check-compat.mjs +48 -11
  487. package/scripts/compat-host.mjs +35 -7
  488. package/scripts/generate-run-schemas.mjs +210 -0
  489. package/scripts/intercom-bridge-credentials.mjs +158 -29
  490. package/scripts/intercom-remote.mjs +213 -52
  491. package/scripts/local-install-smoke.mjs +47 -37
  492. package/scripts/native-package-smoke.mjs +135 -25
  493. package/scripts/package-smoke.mjs +360 -140
  494. package/scripts/prepare.mjs +54 -34
  495. package/scripts/real-pi-processes.mjs +261 -0
  496. package/scripts/real-pi-smoke.mjs +432 -351
  497. package/scripts/run-tests.mjs +29 -15
  498. package/skills/pi-intercom/SKILL.md +11 -11
  499. package/skills/pi-intercom/references/peer-sessions.md +7 -2
  500. package/skills/pi-subagents/SKILL.md +1 -1
  501. package/skills/pi-subagents/references/full-orchestration-guide.md +254 -112
  502. package/src/agents/agent-defaults.ts +13 -0
  503. package/src/agents/agent-definition.ts +253 -0
  504. package/src/agents/agent-management.ts +111 -808
  505. package/src/agents/agent-scope.ts +7 -3
  506. package/src/agents/agent-selection.ts +26 -16
  507. package/src/agents/agent-serializer.ts +84 -93
  508. package/src/agents/agents.ts +199 -906
  509. package/src/agents/builtin-overrides.ts +297 -0
  510. package/src/agents/chain-serializer.ts +3 -329
  511. package/src/agents/config-values.ts +57 -0
  512. package/src/agents/discovery-paths.ts +134 -0
  513. package/src/agents/frontmatter.ts +35 -17
  514. package/src/agents/identity.ts +49 -18
  515. package/src/agents/json-chain.ts +305 -0
  516. package/src/agents/management-config.ts +342 -0
  517. package/src/agents/management-format.ts +243 -0
  518. package/src/agents/management-persistence.ts +408 -0
  519. package/src/agents/management-targets.ts +260 -0
  520. package/src/agents/management-warnings.ts +115 -0
  521. package/src/agents/markdown-chain.ts +237 -0
  522. package/src/agents/package-agents.ts +231 -0
  523. package/src/agents/skill-files.ts +182 -0
  524. package/src/agents/skill-search-paths.ts +289 -0
  525. package/src/agents/skill-types.ts +31 -0
  526. package/src/agents/skills.ts +152 -610
  527. package/src/extension/acceptance-schema.ts +88 -0
  528. package/src/extension/chain-schema.ts +276 -0
  529. package/src/extension/child-runtime.ts +302 -0
  530. package/src/extension/compact-tools.ts +259 -102
  531. package/src/extension/config-schema.ts +59 -0
  532. package/src/extension/config.ts +39 -17
  533. package/src/extension/control-notice-schema.ts +55 -0
  534. package/src/extension/control-notices.ts +57 -33
  535. package/src/extension/delegation-bridges.ts +59 -0
  536. package/src/extension/doctor.ts +171 -135
  537. package/src/extension/everyday-schemas.ts +252 -0
  538. package/src/extension/fanout-child.ts +29 -308
  539. package/src/extension/index.ts +17 -642
  540. package/src/extension/message-renderers.ts +334 -0
  541. package/src/extension/nested-control-inbox.ts +196 -0
  542. package/src/extension/parent-runtime.ts +405 -0
  543. package/src/extension/primary-tool.ts +130 -0
  544. package/src/extension/result-snapshot.ts +35 -0
  545. package/src/extension/runtime-reload.ts +72 -0
  546. package/src/extension/runtime-storage.ts +49 -0
  547. package/src/extension/schema-overrides.ts +114 -0
  548. package/src/extension/schemas.ts +451 -418
  549. package/src/extension/tool-input.ts +40 -13
  550. package/src/extension/tool-result.ts +45 -14
  551. package/src/history/answer-texts.ts +74 -0
  552. package/src/history/canonical-result.ts +127 -51
  553. package/src/history/canonical-selection.ts +54 -0
  554. package/src/history/database-generation.ts +86 -0
  555. package/src/history/database.ts +86 -48
  556. package/src/history/entry-ingestion.ts +129 -0
  557. package/src/history/index.ts +426 -148
  558. package/src/history/ingest.ts +372 -342
  559. package/src/history/output-digests.ts +41 -0
  560. package/src/history/preview.ts +235 -0
  561. package/src/history/prune.ts +48 -0
  562. package/src/history/queries.ts +122 -256
  563. package/src/history/query-scope.ts +278 -0
  564. package/src/history/rows.ts +118 -0
  565. package/src/history/run-projection.ts +164 -0
  566. package/src/history/run-queries.ts +199 -0
  567. package/src/history/schema.ts +34 -0
  568. package/src/history/search-queries.ts +216 -0
  569. package/src/history/selected-record.ts +140 -0
  570. package/src/history/source-file.ts +51 -0
  571. package/src/history/source-watches.ts +156 -0
  572. package/src/history/store.ts +310 -197
  573. package/src/history/text-chunks.ts +181 -0
  574. package/src/history/text.ts +43 -0
  575. package/src/history/transcript-queries.ts +251 -0
  576. package/src/history/types.ts +27 -164
  577. package/src/history/values.ts +36 -0
  578. package/src/history/wire-inputs.ts +141 -0
  579. package/src/history/wire-models.ts +51 -0
  580. package/src/history/worker-runtime.ts +502 -0
  581. package/src/history/worker.ts +94 -336
  582. package/src/intercom/intercom-bridge.ts +136 -69
  583. package/src/intercom/live-intercom.ts +197 -92
  584. package/src/intercom/nested-result-tree.ts +213 -0
  585. package/src/intercom/result-delivery.ts +56 -0
  586. package/src/intercom/result-intercom.ts +364 -382
  587. package/src/pi-intercom/agent-dir.ts +9 -3
  588. package/src/pi-intercom/async.ts +33 -0
  589. package/src/pi-intercom/bridge-ask.ts +64 -0
  590. package/src/pi-intercom/bridge-config.ts +120 -0
  591. package/src/pi-intercom/bridge-http.ts +97 -0
  592. package/src/pi-intercom/bridge-launch-policy.ts +109 -0
  593. package/src/pi-intercom/bridge-launch.ts +317 -0
  594. package/src/pi-intercom/bridge-protocol.ts +123 -0
  595. package/src/pi-intercom/bridge-routes.ts +105 -0
  596. package/src/pi-intercom/bridge-rpc-process.ts +293 -0
  597. package/src/pi-intercom/bridge-session.ts +510 -0
  598. package/src/pi-intercom/bridge.ts +305 -549
  599. package/src/pi-intercom/broker/broker.ts +326 -263
  600. package/src/pi-intercom/broker/client.ts +273 -354
  601. package/src/pi-intercom/broker/connection.ts +192 -0
  602. package/src/pi-intercom/broker/framing.ts +11 -6
  603. package/src/pi-intercom/broker/paths.ts +28 -25
  604. package/src/pi-intercom/broker/pid.ts +68 -24
  605. package/src/pi-intercom/broker/snapshot-reader.ts +91 -0
  606. package/src/pi-intercom/broker/snapshots.ts +241 -0
  607. package/src/pi-intercom/broker/spawn.ts +58 -34
  608. package/src/pi-intercom/config.ts +113 -108
  609. package/src/pi-intercom/connection.ts +346 -0
  610. package/src/pi-intercom/identity.ts +71 -0
  611. package/src/pi-intercom/inbound-delivery.ts +450 -0
  612. package/src/pi-intercom/inbound-journal.ts +350 -0
  613. package/src/pi-intercom/inbound-record.ts +141 -0
  614. package/src/pi-intercom/inbound.ts +237 -0
  615. package/src/pi-intercom/index.ts +86 -2923
  616. package/src/pi-intercom/inspection.ts +82 -0
  617. package/src/pi-intercom/interview.ts +295 -0
  618. package/src/pi-intercom/lifecycle.ts +183 -0
  619. package/src/pi-intercom/message-format.ts +77 -0
  620. package/src/pi-intercom/outbound.ts +418 -0
  621. package/src/pi-intercom/peer-awareness.ts +84 -0
  622. package/src/pi-intercom/reply-tracker.ts +121 -59
  623. package/src/pi-intercom/reply-wait.ts +247 -0
  624. package/src/pi-intercom/runtime-types.ts +97 -0
  625. package/src/pi-intercom/session-events.ts +247 -0
  626. package/src/pi-intercom/session-targets.ts +124 -72
  627. package/src/pi-intercom/subagent-events.ts +299 -0
  628. package/src/pi-intercom/subagent-live-events.ts +212 -109
  629. package/src/pi-intercom/supervisor.ts +362 -0
  630. package/src/pi-intercom/tool-arguments.ts +120 -0
  631. package/src/pi-intercom/tool-registration.ts +121 -0
  632. package/src/pi-intercom/tool-results.ts +54 -0
  633. package/src/pi-intercom/tool-schemas.ts +134 -0
  634. package/src/pi-intercom/tools.ts +80 -0
  635. package/src/pi-intercom/topic-actions.ts +243 -0
  636. package/src/pi-intercom/topics.ts +267 -121
  637. package/src/pi-intercom/transport.ts +14 -0
  638. package/src/pi-intercom/types.ts +288 -190
  639. package/src/pi-intercom/ui/compose-paste.ts +109 -0
  640. package/src/pi-intercom/ui/compose.ts +173 -157
  641. package/src/pi-intercom/ui/inline-message.ts +80 -62
  642. package/src/pi-intercom/ui/message-renderers.ts +182 -0
  643. package/src/pi-intercom/ui/overlay.ts +238 -0
  644. package/src/pi-intercom/ui/session-format.ts +146 -0
  645. package/src/pi-intercom/ui/session-list.ts +145 -62
  646. package/src/pi-intercom/ui/tool-renderers.ts +148 -0
  647. package/src/pi-intercom/ui/topic-view.ts +107 -0
  648. package/src/pi-intercom/validation.ts +69 -0
  649. package/src/runs/background/async-chain-plan.ts +451 -0
  650. package/src/runs/background/async-control.ts +201 -71
  651. package/src/runs/background/async-execution.ts +206 -829
  652. package/src/runs/background/async-job-admission.ts +54 -0
  653. package/src/runs/background/async-job-projection.ts +225 -0
  654. package/src/runs/background/async-job-tracker.ts +416 -360
  655. package/src/runs/background/async-launch.ts +319 -0
  656. package/src/runs/background/async-plan.ts +285 -0
  657. package/src/runs/background/async-result-file.ts +79 -37
  658. package/src/runs/background/async-resume.ts +338 -285
  659. package/src/runs/background/async-run-discovery.ts +270 -0
  660. package/src/runs/background/async-run-location.ts +194 -0
  661. package/src/runs/background/async-run-record.ts +14 -0
  662. package/src/runs/background/async-run-repair.ts +307 -0
  663. package/src/runs/background/async-run-summary.ts +71 -0
  664. package/src/runs/background/async-single-plan.ts +168 -0
  665. package/src/runs/background/async-status-projection.ts +188 -0
  666. package/src/runs/background/async-status-render.ts +164 -0
  667. package/src/runs/background/async-status-validation.ts +238 -0
  668. package/src/runs/background/async-status.ts +9 -481
  669. package/src/runs/background/async-value.ts +29 -0
  670. package/src/runs/background/completion-dedupe.ts +103 -54
  671. package/src/runs/background/completion-delivery.ts +313 -187
  672. package/src/runs/background/completion-receipts.ts +309 -0
  673. package/src/runs/background/legacy-status-acceptance.ts +38 -0
  674. package/src/runs/background/notify.ts +167 -106
  675. package/src/runs/background/parallel-groups.ts +95 -46
  676. package/src/runs/background/result-payload.ts +268 -0
  677. package/src/runs/background/result-watcher.ts +484 -387
  678. package/src/runs/background/run-id-resolver.ts +126 -57
  679. package/src/runs/background/run-schemas.ts +240 -0
  680. package/src/runs/background/run-status-contracts.ts +46 -0
  681. package/src/runs/background/run-status-render.ts +364 -0
  682. package/src/runs/background/run-status.ts +338 -356
  683. package/src/runs/background/runner-attempt-output.ts +281 -0
  684. package/src/runs/background/runner-attempt.ts +354 -0
  685. package/src/runs/background/runner-child-executor.ts +232 -0
  686. package/src/runs/background/runner-child-observer.ts +270 -0
  687. package/src/runs/background/runner-completion-summary.ts +106 -0
  688. package/src/runs/background/runner-completion.ts +274 -0
  689. package/src/runs/background/runner-config.ts +52 -0
  690. package/src/runs/background/runner-contract.ts +51 -0
  691. package/src/runs/background/runner-dynamic.ts +185 -0
  692. package/src/runs/background/runner-finalization.ts +203 -0
  693. package/src/runs/background/runner-graph.ts +91 -0
  694. package/src/runs/background/runner-initial-status.ts +72 -0
  695. package/src/runs/background/runner-lifecycle.ts +159 -0
  696. package/src/runs/background/runner-monitor.ts +399 -0
  697. package/src/runs/background/runner-parallel.ts +280 -0
  698. package/src/runs/background/runner-prepare-step.ts +128 -0
  699. package/src/runs/background/runner-reporting.ts +192 -0
  700. package/src/runs/background/runner-status.ts +220 -0
  701. package/src/runs/background/runner-step-output.ts +158 -0
  702. package/src/runs/background/runner-step-record.ts +76 -0
  703. package/src/runs/background/runner-step.ts +150 -0
  704. package/src/runs/background/runner-streaming.ts +220 -0
  705. package/src/runs/background/runner-workflow.ts +284 -0
  706. package/src/runs/background/stale-run-reconciler.ts +279 -336
  707. package/src/runs/background/subagent-runner-launcher.ts +67 -35
  708. package/src/runs/background/subagent-runner.ts +80 -2048
  709. package/src/runs/background/top-level-async.ts +9 -7
  710. package/src/runs/foreground/chain-clarify.ts +499 -1334
  711. package/src/runs/foreground/clarification-draft.ts +92 -0
  712. package/src/runs/foreground/clarify-contracts.ts +33 -0
  713. package/src/runs/foreground/clarify-invocation.ts +192 -65
  714. package/src/runs/foreground/clarify-text-editor.ts +229 -0
  715. package/src/runs/foreground/clarify-view.ts +222 -0
  716. package/src/runs/foreground/execution-input.ts +358 -424
  717. package/src/runs/foreground/execution-routing.ts +41 -0
  718. package/src/runs/foreground/execution-timeout.ts +92 -0
  719. package/src/runs/foreground/foreground-control.ts +333 -812
  720. package/src/runs/foreground/foreground-memory.ts +132 -0
  721. package/src/runs/foreground/invocation-context.ts +88 -0
  722. package/src/runs/foreground/invocation-execution.ts +465 -0
  723. package/src/runs/foreground/invocation-expansion.ts +58 -0
  724. package/src/runs/foreground/management-actions.ts +360 -0
  725. package/src/runs/foreground/nested-control.ts +248 -0
  726. package/src/runs/foreground/question-continuation.ts +112 -0
  727. package/src/runs/foreground/question-control.ts +297 -70
  728. package/src/runs/foreground/resume-target.ts +330 -0
  729. package/src/runs/foreground/revival-launch-policy.ts +112 -0
  730. package/src/runs/foreground/run-async-path.ts +307 -223
  731. package/src/runs/foreground/run-interrupt.ts +202 -0
  732. package/src/runs/foreground/run-nudge.ts +355 -0
  733. package/src/runs/foreground/saved-revival.ts +356 -0
  734. package/src/runs/foreground/subagent-executor.ts +195 -493
  735. package/src/runs/foreground/subagent-params.ts +314 -242
  736. package/src/runs/foreground/wait-observation.ts +160 -0
  737. package/src/runs/foreground/wait-registration.ts +18 -0
  738. package/src/runs/foreground/wait-run.ts +361 -119
  739. package/src/runs/shared/acceptance-contract.ts +410 -209
  740. package/src/runs/shared/acceptance-defaults.ts +1 -0
  741. package/src/runs/shared/acceptance-evaluation.ts +314 -240
  742. package/src/runs/shared/acceptance-finalization.ts +447 -305
  743. package/src/runs/shared/acceptance-outcome.ts +69 -0
  744. package/src/runs/shared/acceptance-reports.ts +220 -126
  745. package/src/runs/shared/acceptance-submission.ts +251 -0
  746. package/src/runs/shared/acceptance-verification.ts +118 -0
  747. package/src/runs/shared/acceptance.ts +25 -25
  748. package/src/runs/shared/chain-outputs.ts +190 -98
  749. package/src/runs/shared/child-attempt-types.ts +118 -0
  750. package/src/runs/shared/child-attempt.ts +372 -608
  751. package/src/runs/shared/child-boundaries.ts +217 -0
  752. package/src/runs/shared/child-context-filter.ts +53 -0
  753. package/src/runs/shared/child-event-observer.ts +496 -0
  754. package/src/runs/shared/child-execution-cwd.ts +139 -68
  755. package/src/runs/shared/child-execution-outcome.ts +103 -0
  756. package/src/runs/shared/child-invocation.ts +74 -0
  757. package/src/runs/shared/child-message-validation.ts +233 -0
  758. package/src/runs/shared/child-native-accounting.ts +154 -0
  759. package/src/runs/shared/child-native-observation.ts +79 -0
  760. package/src/runs/shared/child-observation-spool.ts +188 -0
  761. package/src/runs/shared/child-observations.ts +219 -89
  762. package/src/runs/shared/child-presence.ts +6 -0
  763. package/src/runs/shared/child-route-env.ts +142 -0
  764. package/src/runs/shared/child-stream-observer.ts +302 -0
  765. package/src/runs/shared/child-stream-projection.ts +160 -0
  766. package/src/runs/shared/child-structured-tool.ts +38 -0
  767. package/src/runs/shared/claude-code.ts +201 -228
  768. package/src/runs/shared/claude-model.ts +67 -0
  769. package/src/runs/shared/claude-session.ts +124 -0
  770. package/src/runs/shared/claude-types.ts +31 -0
  771. package/src/runs/shared/completion-guard.ts +35 -26
  772. package/src/runs/shared/control-event-policy.ts +15 -0
  773. package/src/runs/shared/control-notification-owner.ts +20 -0
  774. package/src/runs/shared/dynamic-fanout.ts +402 -238
  775. package/src/runs/shared/dynamic-item.ts +114 -0
  776. package/src/runs/shared/history-index.ts +112 -51
  777. package/src/runs/shared/legacy-async-recovery.ts +153 -0
  778. package/src/runs/shared/legacy-output-recovery.ts +214 -0
  779. package/src/runs/shared/mcp-config-schema.ts +46 -0
  780. package/src/runs/shared/mcp-direct-tool-allowlist.ts +396 -307
  781. package/src/runs/shared/model-fallback.ts +302 -180
  782. package/src/runs/shared/mutating-tool-guard.ts +259 -158
  783. package/src/runs/shared/native-finalization-types.ts +29 -0
  784. package/src/runs/shared/native-finalization.ts +233 -109
  785. package/src/runs/shared/native-usage.ts +379 -96
  786. package/src/runs/shared/nested-control-records.ts +178 -0
  787. package/src/runs/shared/nested-events.ts +45 -752
  788. package/src/runs/shared/nested-path.ts +47 -34
  789. package/src/runs/shared/nested-projection.ts +230 -0
  790. package/src/runs/shared/nested-protocol.ts +67 -0
  791. package/src/runs/shared/nested-registry.ts +273 -0
  792. package/src/runs/shared/nested-render.ts +198 -100
  793. package/src/runs/shared/nested-route.ts +292 -0
  794. package/src/runs/shared/nested-validation.ts +291 -0
  795. package/src/runs/shared/owned-child-evidence.ts +184 -0
  796. package/src/runs/shared/owned-run-list.ts +187 -0
  797. package/src/runs/shared/owned-run-observation.ts +368 -0
  798. package/src/runs/shared/owned-run-progress.ts +172 -0
  799. package/src/runs/shared/owned-run-read-state.ts +7 -0
  800. package/src/runs/shared/owned-run-results.ts +289 -0
  801. package/src/runs/shared/owned-run-status.ts +239 -0
  802. package/src/runs/shared/owned-run-view.ts +65 -0
  803. package/src/runs/shared/owned-workflow-details.ts +24 -0
  804. package/src/runs/shared/owner-output.ts +73 -0
  805. package/src/runs/shared/parallel-utils.ts +93 -129
  806. package/src/runs/shared/parent-receipts.ts +177 -50
  807. package/src/runs/shared/parent-usage.ts +314 -91
  808. package/src/runs/shared/pi-args.ts +241 -311
  809. package/src/runs/shared/pi-launch-input.ts +48 -0
  810. package/src/runs/shared/pi-session-launch.ts +94 -0
  811. package/src/runs/shared/pi-spawn.ts +57 -33
  812. package/src/runs/shared/run-history-queries.ts +189 -38
  813. package/src/runs/shared/run-history.ts +197 -76
  814. package/src/runs/shared/run-id-ambiguity.ts +7 -3
  815. package/src/runs/shared/run-metadata-paths.ts +17 -0
  816. package/src/runs/shared/run-metadata.ts +240 -0
  817. package/src/runs/shared/run-persistence.ts +181 -0
  818. package/src/runs/shared/run-records.ts +19 -607
  819. package/src/runs/shared/run-restoration.ts +455 -0
  820. package/src/runs/shared/run-state-owner.ts +31 -0
  821. package/src/runs/shared/session-cwd-preload.ts +39 -19
  822. package/src/runs/shared/single-output.ts +358 -205
  823. package/src/runs/shared/stable-value.ts +15 -0
  824. package/src/runs/shared/streaming-text.ts +39 -12
  825. package/src/runs/shared/structured-output.ts +76 -46
  826. package/src/runs/shared/subagent-control.ts +330 -197
  827. package/src/runs/shared/subagent-prompt-runtime.ts +92 -174
  828. package/src/runs/shared/subagent-tool-loop-guard.ts +118 -68
  829. package/src/runs/shared/supervisor-question-state.ts +221 -0
  830. package/src/runs/shared/supervisor-questions.ts +396 -401
  831. package/src/runs/shared/workflow-graph.ts +400 -198
  832. package/src/runs/shared/workflow-policy.ts +245 -110
  833. package/src/runs/shared/worktree-contract.ts +29 -0
  834. package/src/runs/shared/worktree-hook.ts +181 -0
  835. package/src/runs/shared/worktree-location.ts +61 -0
  836. package/src/runs/shared/worktree-preservation.ts +10 -0
  837. package/src/runs/shared/worktree-process.ts +132 -0
  838. package/src/runs/shared/worktree.ts +459 -587
  839. package/src/shared/agent-context-policy.ts +176 -145
  840. package/src/shared/agent-dir.ts +15 -0
  841. package/src/shared/artifacts.ts +99 -68
  842. package/src/shared/atomic-json.ts +14 -11
  843. package/src/shared/chain-files.ts +72 -0
  844. package/src/shared/concurrency.ts +27 -0
  845. package/src/shared/content-preview.ts +117 -0
  846. package/src/shared/cooperative.ts +17 -13
  847. package/src/shared/execution-cwd.ts +34 -9
  848. package/src/shared/file-coalescer.ts +24 -22
  849. package/src/shared/fork-context.ts +52 -48
  850. package/src/shared/formatters.ts +88 -47
  851. package/src/shared/journal-frames.ts +197 -0
  852. package/src/shared/journal-projections.ts +133 -0
  853. package/src/shared/journal-reader.ts +18 -333
  854. package/src/shared/json-projection.ts +224 -0
  855. package/src/shared/lazy-tools.ts +76 -27
  856. package/src/shared/message-output.ts +146 -0
  857. package/src/shared/model-info.ts +94 -58
  858. package/src/shared/native-import.ts +25 -0
  859. package/src/shared/native-journal.ts +172 -0
  860. package/src/shared/native-session-loader.ts +13 -0
  861. package/src/shared/native-session.ts +3 -5
  862. package/src/shared/native-tui.ts +13 -3
  863. package/src/shared/native-typebox.ts +18 -3
  864. package/src/shared/output-page.ts +76 -0
  865. package/src/shared/post-exit-stdio-guard.ts +232 -172
  866. package/src/shared/prompt-sections.ts +13 -7
  867. package/src/shared/session-entries.ts +103 -44
  868. package/src/shared/session-identity.ts +17 -10
  869. package/src/shared/settings.ts +182 -367
  870. package/src/shared/status-format.ts +207 -98
  871. package/src/shared/stream-json.d.ts +10 -0
  872. package/src/shared/task-file-policy.ts +35 -0
  873. package/src/shared/temp-root.ts +122 -71
  874. package/src/shared/types/acceptance.ts +149 -0
  875. package/src/shared/types/async.ts +247 -0
  876. package/src/shared/types/config.ts +139 -0
  877. package/src/shared/types/details.ts +104 -0
  878. package/src/shared/types/history.ts +217 -0
  879. package/src/shared/types/inputs.ts +4 -0
  880. package/src/shared/types/intercom.ts +57 -0
  881. package/src/shared/types/launch.ts +39 -0
  882. package/src/shared/types/messages.ts +104 -0
  883. package/src/shared/types/nested.ts +153 -0
  884. package/src/shared/types/owned-runs.ts +148 -0
  885. package/src/shared/types/progress.ts +106 -0
  886. package/src/shared/types/questions.ts +103 -0
  887. package/src/shared/types/results.ts +119 -0
  888. package/src/shared/types/state.ts +56 -0
  889. package/src/shared/types/usage.ts +36 -0
  890. package/src/shared/types/workflow.ts +187 -0
  891. package/src/shared/types.ts +222 -1161
  892. package/src/shared/ui-mode.ts +1 -1
  893. package/src/shared/unknown.ts +59 -0
  894. package/src/shared/utils.ts +111 -305
  895. package/src/slash/command-discovery.ts +109 -0
  896. package/src/slash/command-input.ts +232 -0
  897. package/src/slash/prompt-template-bridge.ts +153 -400
  898. package/src/slash/prompt-template-contract.ts +152 -0
  899. package/src/slash/prompt-template-results.ts +189 -0
  900. package/src/slash/request-protocol.ts +87 -0
  901. package/src/slash/result-delivery.ts +312 -0
  902. package/src/slash/saved-chain.ts +115 -0
  903. package/src/slash/slash-bridge.ts +202 -156
  904. package/src/slash/slash-commands.ts +176 -598
  905. package/src/slash/slash-live-state.ts +287 -229
  906. package/src/tui/action-hints.ts +147 -61
  907. package/src/tui/activity-lines.ts +40 -0
  908. package/src/tui/agent-browser.ts +354 -0
  909. package/src/tui/agent-controls.ts +355 -0
  910. package/src/tui/agent-conversation.ts +514 -0
  911. package/src/tui/agent-dock.ts +250 -0
  912. package/src/tui/agent-history.ts +78 -203
  913. package/src/tui/agent-model.ts +78 -0
  914. package/src/tui/agent-picker.ts +325 -0
  915. package/src/tui/agent-view.ts +391 -1333
  916. package/src/tui/compact-results.ts +342 -0
  917. package/src/tui/conversation-details.ts +206 -0
  918. package/src/tui/conversation-frame.ts +184 -0
  919. package/src/tui/conversation-history.ts +246 -0
  920. package/src/tui/conversation-menu.ts +119 -0
  921. package/src/tui/conversation-notices.ts +116 -0
  922. package/src/tui/conversation-selection.ts +66 -0
  923. package/src/tui/conversation-viewport.ts +169 -0
  924. package/src/tui/direction-message.ts +35 -0
  925. package/src/tui/display.ts +409 -0
  926. package/src/tui/editor-viewport.ts +19 -0
  927. package/src/tui/expanded-content.ts +134 -0
  928. package/src/tui/expanded-multi.ts +264 -0
  929. package/src/tui/expanded-single.ts +92 -0
  930. package/src/tui/history-cards.ts +316 -0
  931. package/src/tui/history-display.ts +334 -0
  932. package/src/tui/history-json.ts +17 -0
  933. package/src/tui/history-metadata.ts +177 -0
  934. package/src/tui/history-record.ts +321 -0
  935. package/src/tui/history-text.ts +34 -0
  936. package/src/tui/indexed-history.ts +149 -0
  937. package/src/tui/nested-widget.ts +192 -0
  938. package/src/tui/picker-page.ts +80 -0
  939. package/src/tui/render.ts +100 -1546
  940. package/src/tui/result-facts.ts +99 -0
  941. package/src/tui/task-observation.ts +96 -0
  942. package/src/tui/task-store.ts +432 -0
  943. package/src/tui/text-values.ts +20 -0
  944. package/src/tui/view-connections.ts +64 -0
  945. package/src/tui/view-model.ts +181 -0
  946. package/src/tui/view-persistence.ts +57 -0
  947. package/src/tui/view-ports.ts +55 -0
  948. package/src/tui/view-session.ts +42 -0
  949. package/src/tui/widget-details.ts +220 -0
  950. package/src/tui/widget-status.ts +331 -0
  951. package/src/tui/widget.ts +208 -0
  952. package/src/tui/workflow-labels.ts +340 -0
  953. package/src/tui/workflow-outcomes.ts +150 -0
  954. package/tsconfig.build.json +11 -10
  955. 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
  }