one-code-extension 0.4.1 → 0.6.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 (439) hide show
  1. package/README.md +16 -5
  2. package/agents/general-purpose.md +2 -2
  3. package/docs/guide/README.md +2 -1
  4. package/docs/guide/bring-your-claude-code-setup.md +60 -9
  5. package/docs/guide/configuration.md +48 -14
  6. package/docs/guide/differences-from-claude-code.md +40 -28
  7. package/docs/guide/doctor.md +20 -13
  8. package/docs/guide/hooks.md +18 -3
  9. package/docs/guide/installation.md +26 -4
  10. package/docs/guide/permissions-modes-and-auto-mode.md +225 -49
  11. package/docs/guide/providers-and-models.md +137 -54
  12. package/docs/guide/reference.md +27 -15
  13. package/docs/guide/sessions-and-context.md +69 -16
  14. package/docs/guide/skills-plugins-and-mcp.md +57 -20
  15. package/docs/guide/subagents-and-workflows.md +95 -29
  16. package/docs/guide/tasks-and-background-work.md +101 -26
  17. package/docs/guide/terminal-interface.md +24 -12
  18. package/docs/guide/tools.md +46 -5
  19. package/docs/guide/troubleshooting.md +13 -9
  20. package/docs/guide/windows.md +58 -31
  21. package/extensions/artifacts/gallery.ts +227 -0
  22. package/extensions/artifacts/index.ts +288 -0
  23. package/extensions/artifacts/store.ts +570 -0
  24. package/extensions/artifacts/viewer.ts +199 -0
  25. package/extensions/ask-user/description.ts +67 -0
  26. package/extensions/ask-user/dialogs.ts +80 -0
  27. package/extensions/ask-user/index.ts +37 -33
  28. package/extensions/ask-user/questions.ts +32 -7
  29. package/extensions/ask-user/widget.ts +45 -25
  30. package/extensions/auto-mode/actions.ts +6 -0
  31. package/extensions/auto-mode/cache.ts +88 -0
  32. package/extensions/auto-mode/classifier-prompt.ts +5 -4
  33. package/extensions/auto-mode/classifier.ts +290 -65
  34. package/extensions/auto-mode/config.ts +72 -20
  35. package/extensions/auto-mode/decision-log.ts +2 -0
  36. package/extensions/auto-mode/defaults.ts +1 -1
  37. package/extensions/auto-mode/denials.ts +124 -0
  38. package/extensions/auto-mode/git-checkout-programs.ts +187 -0
  39. package/extensions/auto-mode/git-status-meta.ts +159 -0
  40. package/extensions/auto-mode/history.ts +189 -0
  41. package/extensions/auto-mode/instructions.ts +58 -52
  42. package/extensions/auto-mode/model-select.ts +159 -134
  43. package/extensions/auto-mode/paths.ts +57 -5
  44. package/extensions/auto-mode/pause.ts +57 -2
  45. package/extensions/auto-mode/prompt.ts +37 -21
  46. package/extensions/auto-mode/read-only-options.ts +724 -0
  47. package/extensions/auto-mode/resolved-paths-meta.ts +133 -0
  48. package/extensions/auto-mode/rules.ts +18 -1
  49. package/extensions/auto-mode/safety-floor.ts +361 -18
  50. package/extensions/auto-mode/setup-run.ts +20 -14
  51. package/extensions/auto-mode/shell-analysis.ts +764 -490
  52. package/extensions/auto-mode/shell-parse.ts +885 -0
  53. package/extensions/auto-mode/system-note.ts +33 -0
  54. package/extensions/auto-mode/transcript.ts +80 -51
  55. package/extensions/background/cron.ts +642 -0
  56. package/extensions/background/index.ts +614 -248
  57. package/extensions/background/loop-fire.ts +173 -0
  58. package/extensions/background/loop-preamble.ts +59 -0
  59. package/extensions/background/loop-skill.ts +163 -0
  60. package/extensions/background/monitor-batch.ts +53 -0
  61. package/extensions/background/noop-fold.ts +128 -0
  62. package/extensions/background/switch-guard.ts +56 -0
  63. package/extensions/background/wakeup.ts +178 -55
  64. package/extensions/bash/background.ts +53 -17
  65. package/extensions/bash/child.ts +7 -0
  66. package/extensions/bash/description.ts +188 -0
  67. package/extensions/bash/guards.ts +15 -67
  68. package/extensions/bash/index.ts +66 -35
  69. package/extensions/branding/compaction-keep.ts +63 -0
  70. package/extensions/branding/declined.ts +22 -0
  71. package/extensions/branding/index.ts +133 -9
  72. package/extensions/branding/prompt-editor.ts +53 -6
  73. package/extensions/branding/queued-edit.ts +31 -0
  74. package/extensions/branding/replaced-builtins.ts +68 -0
  75. package/extensions/branding/startup.ts +33 -71
  76. package/extensions/btw/index.ts +250 -78
  77. package/extensions/btw/panel.ts +228 -100
  78. package/extensions/btw/prompt.ts +41 -4
  79. package/extensions/cache-marks/index.ts +42 -0
  80. package/extensions/claude-compat/index.ts +7 -11
  81. package/extensions/claude-context/index.ts +436 -63
  82. package/extensions/compaction/cut.ts +157 -0
  83. package/extensions/compaction/index.ts +219 -75
  84. package/extensions/compaction/kept-thinking.ts +62 -0
  85. package/extensions/compaction/prompt.ts +15 -12
  86. package/extensions/context-budget/budget.ts +16 -2
  87. package/extensions/context-budget/index.ts +35 -15
  88. package/extensions/context-management/index.ts +36 -28
  89. package/extensions/doctor/build.ts +59 -8
  90. package/extensions/doctor/builtins.ts +84 -0
  91. package/extensions/doctor/cli.ts +7 -1
  92. package/extensions/doctor/compat.ts +88 -23
  93. package/extensions/doctor/dependencies.ts +41 -5
  94. package/extensions/doctor/fix-prompt.ts +9 -2
  95. package/extensions/doctor/index.ts +102 -58
  96. package/extensions/doctor/models.ts +102 -63
  97. package/extensions/doctor/presets.ts +42 -27
  98. package/extensions/doctor/report.ts +19 -2
  99. package/extensions/doctor/viewer.ts +49 -27
  100. package/extensions/effort/index.ts +141 -25
  101. package/extensions/effort/settings.ts +21 -0
  102. package/extensions/effort/slider.ts +24 -20
  103. package/extensions/exit/index.ts +32 -1
  104. package/extensions/file-tracker/index.ts +420 -42
  105. package/extensions/file-tracker/replay.ts +137 -24
  106. package/extensions/file-tracker/restore.ts +66 -0
  107. package/extensions/file-tracker/results.ts +66 -0
  108. package/extensions/file-tracker/shell-reads.ts +211 -0
  109. package/extensions/file-tracker/tracker.ts +45 -15
  110. package/extensions/footer/footer-line.ts +45 -24
  111. package/extensions/footer/index.ts +47 -2
  112. package/extensions/footer/pr.ts +34 -5
  113. package/extensions/hooks/compaction.ts +7 -0
  114. package/extensions/hooks/executor.ts +32 -30
  115. package/extensions/hooks/index.ts +209 -58
  116. package/extensions/hooks/matcher.ts +3 -0
  117. package/extensions/hooks/prompt-context.ts +59 -0
  118. package/extensions/hooks/protocol.ts +41 -3
  119. package/extensions/hooks/settings.ts +50 -19
  120. package/extensions/hooks/subagent-bridge.ts +2 -0
  121. package/extensions/hooks/trust.ts +26 -12
  122. package/extensions/idle-compact/index.ts +119 -0
  123. package/extensions/idle-compact/policy.ts +143 -0
  124. package/extensions/init/index.ts +11 -10
  125. package/extensions/init/prompt.ts +25 -32
  126. package/extensions/interrupted/index.ts +13 -1
  127. package/extensions/kept-thinking/index.ts +27 -0
  128. package/extensions/ledger/index.ts +46 -0
  129. package/extensions/ledger/wire.ts +154 -0
  130. package/extensions/lib/agent-cron.ts +146 -0
  131. package/extensions/lib/agent-loader.ts +18 -3
  132. package/extensions/lib/agent-view.ts +85 -0
  133. package/extensions/lib/anthropic-auth.ts +98 -0
  134. package/extensions/lib/anthropic-payload.ts +82 -1
  135. package/extensions/lib/anthropic-server-call.ts +230 -0
  136. package/extensions/lib/anthropic-server-tools.ts +485 -0
  137. package/extensions/lib/app-launch.mjs +94 -0
  138. package/extensions/lib/argument-hints.ts +190 -0
  139. package/extensions/lib/atomic-write.ts +6 -2
  140. package/extensions/lib/auto-memory.ts +75 -0
  141. package/extensions/lib/bash-parser.ts +84 -0
  142. package/extensions/lib/btw-fork.ts +93 -0
  143. package/extensions/lib/child-extensions.ts +52 -0
  144. package/extensions/lib/child-writes.ts +45 -0
  145. package/extensions/lib/claude-context.ts +515 -100
  146. package/extensions/lib/claude-external-includes.ts +68 -0
  147. package/extensions/lib/claude-id.ts +22 -0
  148. package/extensions/lib/claude-rules.ts +323 -0
  149. package/extensions/lib/claude-settings.ts +76 -4
  150. package/extensions/lib/compaction-boundary.ts +36 -0
  151. package/extensions/lib/compaction-keep.mjs +83 -0
  152. package/extensions/lib/config-mode.ts +112 -0
  153. package/extensions/lib/consent-dialogs.ts +63 -0
  154. package/extensions/lib/consent-preview.ts +5 -1
  155. package/extensions/lib/consent-stores.ts +48 -0
  156. package/extensions/lib/context-facts.ts +97 -0
  157. package/extensions/lib/covered-messages.ts +23 -0
  158. package/extensions/lib/deferred.ts +359 -25
  159. package/extensions/lib/dock-rows.ts +60 -0
  160. package/extensions/lib/empty-tool-result.ts +27 -0
  161. package/extensions/lib/environment-block.ts +76 -0
  162. package/extensions/lib/fetch-timeout.ts +24 -6
  163. package/extensions/{system-prompt → lib}/git-status.ts +51 -13
  164. package/extensions/lib/git.ts +75 -13
  165. package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
  166. package/extensions/lib/grammars/README.md +2 -0
  167. package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
  168. package/extensions/lib/guide-docs.ts +45 -0
  169. package/extensions/lib/headless-output.ts +46 -0
  170. package/extensions/lib/hook-gate.ts +7 -7
  171. package/extensions/lib/interrupt.ts +20 -4
  172. package/extensions/lib/key-input.ts +455 -0
  173. package/extensions/lib/keys.ts +14 -1
  174. package/extensions/lib/ledger/fold-memo.ts +49 -0
  175. package/extensions/lib/ledger/fold.ts +265 -0
  176. package/extensions/lib/ledger/layout.ts +72 -0
  177. package/extensions/lib/ledger/plan.ts +102 -0
  178. package/extensions/lib/ledger/records.ts +276 -0
  179. package/extensions/lib/ledger/state.ts +47 -0
  180. package/extensions/lib/ledger/validate.ts +141 -0
  181. package/extensions/lib/ledger/wire.ts +632 -0
  182. package/extensions/lib/local-command.ts +71 -19
  183. package/extensions/lib/mcp-overrides.ts +1 -1
  184. package/extensions/lib/mcp-share.ts +46 -0
  185. package/extensions/lib/memory-content.ts +146 -0
  186. package/extensions/lib/memory-index.ts +18 -0
  187. package/extensions/lib/memory.ts +134 -123
  188. package/extensions/lib/model-catalog/huggingface.json +178 -0
  189. package/extensions/lib/model-catalog/models-dev.json +18533 -0
  190. package/extensions/lib/model-catalog/openrouter.json +5050 -0
  191. package/extensions/lib/model-catalog-data.ts +513 -0
  192. package/extensions/lib/model-catalog.ts +462 -0
  193. package/extensions/lib/model-choice-warnings.ts +137 -0
  194. package/extensions/lib/model-pairings.ts +152 -0
  195. package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
  196. package/extensions/lib/model-policy.ts +112 -15
  197. package/extensions/lib/model-tier.ts +283 -355
  198. package/extensions/lib/model-unusable.ts +1 -1
  199. package/extensions/lib/newer-model.ts +100 -0
  200. package/extensions/lib/notices.ts +87 -0
  201. package/extensions/lib/notifications.ts +357 -73
  202. package/extensions/lib/one-code-settings.ts +74 -8
  203. package/extensions/lib/open-browser.ts +63 -0
  204. package/extensions/lib/openrouter-generation.ts +94 -0
  205. package/extensions/lib/operation-deadline.ts +30 -0
  206. package/extensions/lib/original-command.ts +4 -4
  207. package/extensions/lib/package-version.ts +1 -1
  208. package/extensions/lib/panel-focus.ts +134 -0
  209. package/extensions/lib/paths.ts +17 -2
  210. package/extensions/lib/permission-gate.ts +72 -6
  211. package/extensions/lib/persisted-output.ts +60 -8
  212. package/extensions/lib/pi-ai-estimate.ts +19 -3
  213. package/extensions/lib/pi-version.ts +38 -2
  214. package/extensions/lib/plan-mode-channels.ts +42 -5
  215. package/extensions/lib/plugins.ts +26 -17
  216. package/extensions/lib/powershell-parse-script.ts +208 -0
  217. package/extensions/lib/powershell-parser.ts +344 -0
  218. package/extensions/lib/previous-mark.ts +101 -0
  219. package/extensions/lib/process-state.ts +48 -0
  220. package/extensions/lib/process-tree.ts +132 -8
  221. package/extensions/lib/prompt-options.ts +82 -0
  222. package/extensions/lib/queued-delivery.ts +44 -0
  223. package/extensions/lib/reminders.ts +370 -358
  224. package/extensions/lib/replaced-builtins.mjs +199 -0
  225. package/extensions/lib/replay-call.ts +70 -0
  226. package/extensions/lib/request-replay.ts +547 -0
  227. package/extensions/lib/scratchpad.ts +81 -14
  228. package/extensions/lib/send-now-channel.ts +7 -0
  229. package/extensions/lib/session-model-tier.ts +51 -0
  230. package/extensions/lib/session-work.ts +64 -0
  231. package/extensions/lib/settings-channels.ts +4 -4
  232. package/extensions/lib/shell-exit-semantics.ts +170 -0
  233. package/extensions/lib/shell-quote.ts +11 -0
  234. package/extensions/lib/shell-result.ts +70 -0
  235. package/extensions/lib/shell-spawn.ts +70 -6
  236. package/extensions/lib/shell-tool.ts +75 -25
  237. package/extensions/lib/side-call-cache.ts +124 -0
  238. package/extensions/lib/side-call-run.ts +96 -0
  239. package/extensions/lib/side-call-usage.ts +38 -0
  240. package/extensions/lib/side-call.ts +24 -1
  241. package/extensions/lib/single-flight.ts +18 -0
  242. package/extensions/lib/skill-body.ts +42 -0
  243. package/extensions/lib/skill-scan.ts +63 -24
  244. package/extensions/lib/spill-file.ts +140 -0
  245. package/extensions/lib/subagent-handback.ts +112 -0
  246. package/extensions/lib/system-role.ts +156 -0
  247. package/extensions/lib/terminal-text.ts +114 -0
  248. package/extensions/lib/text-width.ts +47 -16
  249. package/extensions/lib/timer-ops.ts +20 -0
  250. package/extensions/lib/tool-additions.ts +129 -0
  251. package/extensions/lib/tool-call-corruption.ts +134 -0
  252. package/extensions/lib/tool-path.ts +66 -0
  253. package/extensions/lib/tool-variants.ts +69 -0
  254. package/extensions/lib/tui-render.ts +255 -27
  255. package/extensions/lib/turn-budget-layout.ts +159 -0
  256. package/extensions/lib/update-check.mjs +15 -2
  257. package/extensions/lib/usage-bus.ts +1 -1
  258. package/extensions/lib/user-denial.ts +38 -0
  259. package/extensions/lib/workspace-channel.ts +16 -0
  260. package/extensions/lib/worktree-channel.ts +31 -3
  261. package/extensions/lib/worktree-isolation.ts +40 -10
  262. package/extensions/lsp/client.ts +8 -9
  263. package/extensions/lsp/index.ts +76 -12
  264. package/extensions/lsp/keep-alive.ts +1 -1
  265. package/extensions/lsp/trust.ts +119 -0
  266. package/extensions/lsp/watcher.ts +1 -1
  267. package/extensions/mcp/announce.ts +90 -43
  268. package/extensions/mcp/client.ts +161 -48
  269. package/extensions/mcp/config.ts +132 -8
  270. package/extensions/mcp/discovery.ts +19 -0
  271. package/extensions/mcp/index.ts +220 -121
  272. package/extensions/mcp/oauth/browser.ts +38 -17
  273. package/extensions/mcp/oauth/flow.ts +25 -17
  274. package/extensions/mcp/oauth/provider.ts +14 -8
  275. package/extensions/mcp/oauth/store.ts +34 -16
  276. package/extensions/mcp/panel/keys.ts +12 -11
  277. package/extensions/mcp/panel/render.ts +9 -6
  278. package/extensions/mcp/schema.ts +104 -5
  279. package/extensions/mcp/trust.ts +164 -73
  280. package/extensions/memory/entries.ts +23 -14
  281. package/extensions/memory/index.ts +134 -28
  282. package/extensions/memory/open-external.ts +33 -18
  283. package/extensions/memory/panel.ts +135 -26
  284. package/extensions/model-default/index.ts +86 -19
  285. package/extensions/newer-model/index.ts +31 -0
  286. package/extensions/notebook/description.ts +18 -0
  287. package/extensions/notebook/index.ts +6 -5
  288. package/extensions/notebook/notebook.ts +1 -1
  289. package/extensions/permissions/index.ts +1426 -398
  290. package/extensions/permissions/matcher.ts +425 -74
  291. package/extensions/permissions/modes.ts +11 -4
  292. package/extensions/permissions/panel/host.ts +130 -0
  293. package/extensions/permissions/panel/keys.ts +48 -0
  294. package/extensions/permissions/panel/render.ts +450 -0
  295. package/extensions/permissions/panel/state.ts +550 -0
  296. package/extensions/permissions/powershell-cmdlets.ts +198 -0
  297. package/extensions/permissions/powershell-paths.ts +197 -0
  298. package/extensions/permissions/powershell-rules.ts +207 -280
  299. package/extensions/permissions/powershell-tree.ts +557 -0
  300. package/extensions/permissions/project-trust.ts +27 -11
  301. package/extensions/permissions/protected-paths.ts +14 -2
  302. package/extensions/permissions/session-grant.ts +6 -0
  303. package/extensions/permissions/settings.ts +166 -31
  304. package/extensions/permissions/subagent-gate.ts +25 -0
  305. package/extensions/permissions/workspace.ts +78 -0
  306. package/extensions/plan-mode/index.ts +276 -92
  307. package/extensions/plan-mode/reminder.ts +89 -21
  308. package/extensions/plan-mode/run-state.ts +26 -0
  309. package/extensions/plan-mode/texts.ts +177 -0
  310. package/extensions/plan-mode/viewer.ts +92 -27
  311. package/extensions/plugins/counts.ts +3 -3
  312. package/extensions/plugins/index.ts +64 -46
  313. package/extensions/plugins/install/install.ts +16 -0
  314. package/extensions/plugins/marketplace/sync.ts +9 -3
  315. package/extensions/plugins/marketplace/types.ts +3 -1
  316. package/extensions/plugins/panel/keys.ts +21 -24
  317. package/extensions/plugins/panel/render.ts +12 -6
  318. package/extensions/plugins/shell-expand.ts +107 -0
  319. package/extensions/plugins/template.ts +32 -15
  320. package/extensions/powershell/child.ts +7 -0
  321. package/extensions/powershell/description.ts +38 -6
  322. package/extensions/powershell/guards.ts +1 -1
  323. package/extensions/powershell/index.ts +14 -7
  324. package/extensions/recap/index.ts +73 -71
  325. package/extensions/recap/prompt.ts +2 -2
  326. package/extensions/recap/scheduler.ts +3 -5
  327. package/extensions/search-tools/grep-merge.ts +39 -0
  328. package/extensions/search-tools/index.ts +0 -0
  329. package/extensions/send-now/chord.ts +62 -0
  330. package/extensions/send-now/index.ts +133 -0
  331. package/extensions/session-title/index.ts +3 -0
  332. package/extensions/session-title/title.ts +4 -1
  333. package/extensions/skill/announce.ts +30 -0
  334. package/extensions/skill/code-review.ts +97 -0
  335. package/extensions/skill/index.ts +469 -132
  336. package/extensions/skill/invoke.ts +118 -75
  337. package/extensions/skill/listing.ts +133 -9
  338. package/extensions/skill/panel/keys.ts +15 -16
  339. package/extensions/skill/panel/render.ts +5 -2
  340. package/extensions/skill/panel/state.ts +12 -1
  341. package/extensions/subagents/agent-args.ts +39 -0
  342. package/extensions/subagents/agent-description.ts +132 -0
  343. package/extensions/subagents/agents.ts +146 -31
  344. package/extensions/subagents/default-model.ts +2 -3
  345. package/extensions/subagents/delegation-steer.ts +4 -4
  346. package/extensions/subagents/fork-cache.ts +82 -0
  347. package/extensions/subagents/guide-agent.ts +189 -0
  348. package/extensions/subagents/hand-back-review.ts +3 -0
  349. package/extensions/subagents/index.ts +1594 -852
  350. package/extensions/subagents/live-runs.ts +26 -6
  351. package/extensions/subagents/model-select.ts +38 -25
  352. package/extensions/subagents/outcome.ts +5 -2
  353. package/extensions/subagents/panel-keys.ts +73 -31
  354. package/extensions/subagents/panel-render.ts +120 -96
  355. package/extensions/subagents/panel-widget.ts +60 -89
  356. package/extensions/subagents/parent-mode.ts +50 -0
  357. package/extensions/subagents/pending-claim.ts +18 -1
  358. package/extensions/subagents/runner.ts +135 -80
  359. package/extensions/subagents/runs.ts +44 -5
  360. package/extensions/subagents/send-to-main-tool.ts +1 -1
  361. package/extensions/subagents/session-turns.ts +32 -8
  362. package/extensions/subagents/shell-panel.ts +36 -178
  363. package/extensions/subagents/tasks-dialog.ts +170 -0
  364. package/extensions/subagents/viewport-mirror.ts +95 -0
  365. package/extensions/subagents/worktree.ts +57 -13
  366. package/extensions/system-prompt/environment.ts +19 -19
  367. package/extensions/system-prompt/idle-turn.ts +65 -0
  368. package/extensions/system-prompt/index.ts +165 -47
  369. package/extensions/system-prompt/template.ts +34 -51
  370. package/extensions/system-prompt/tiers/common.ts +23 -64
  371. package/extensions/system-prompt/tiers/frontier.ts +32 -11
  372. package/extensions/system-prompt/tiers/low.ts +67 -45
  373. package/extensions/system-prompt/tiers/mid.ts +96 -38
  374. package/extensions/system-reminder/index.ts +204 -70
  375. package/extensions/tasks/descriptions.ts +190 -0
  376. package/extensions/tasks/index.ts +120 -41
  377. package/extensions/tasks/store.ts +83 -16
  378. package/extensions/tool-call-corruption/child.ts +7 -0
  379. package/extensions/tool-call-corruption/index.ts +237 -0
  380. package/extensions/tool-search/index.ts +366 -144
  381. package/extensions/tool-style/index.ts +68 -10
  382. package/extensions/tool-style/write-description.ts +40 -0
  383. package/extensions/tool-style/write-render.ts +237 -0
  384. package/extensions/turn-duration/index.ts +7 -3
  385. package/extensions/turn-duration/line.ts +47 -4
  386. package/extensions/web/backends.ts +6 -9
  387. package/extensions/web/description.ts +50 -0
  388. package/extensions/web/index.ts +118 -53
  389. package/extensions/web/native-call.ts +15 -0
  390. package/extensions/web/native-results.ts +41 -0
  391. package/extensions/web-fetch/description.ts +42 -0
  392. package/extensions/web-fetch/extract.ts +53 -6
  393. package/extensions/web-fetch/index.ts +125 -76
  394. package/extensions/web-fetch/page-content.ts +19 -0
  395. package/extensions/web-fetch/response.ts +49 -0
  396. package/extensions/web-fetch/summarize.ts +9 -10
  397. package/extensions/workflow/agent-session.ts +108 -18
  398. package/extensions/workflow/args.ts +24 -0
  399. package/extensions/workflow/description.ts +67 -0
  400. package/extensions/workflow/globals.ts +17 -3
  401. package/extensions/workflow/index.ts +157 -162
  402. package/extensions/workflow/records.ts +1 -0
  403. package/extensions/workflow/run-manager.ts +33 -6
  404. package/extensions/workflow/saved-workflows.ts +3 -2
  405. package/extensions/workflow/types.ts +22 -1
  406. package/extensions/workflow/viewer.ts +54 -24
  407. package/extensions/workflow/widget.ts +20 -0
  408. package/extensions/worktree/descriptions.ts +91 -0
  409. package/extensions/worktree/guards.ts +316 -54
  410. package/extensions/worktree/index.ts +162 -44
  411. package/extensions/worktree/powershell-guards.ts +167 -0
  412. package/extensions/worktree/rewrite.ts +14 -16
  413. package/package.json +21 -7
  414. package/skills/artifact-design/SKILL.md +85 -0
  415. package/skills/code-review/SKILL.md +20 -20
  416. package/skills/code-review/cells/arguments-and-flags.md +19 -0
  417. package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
  418. package/skills/code-review/cells/high-8-inline.md +122 -0
  419. package/skills/code-review/cells/low-1-pass-max4.md +27 -0
  420. package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
  421. package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
  422. package/skills/code-review/cells/medium-3x5-verify.md +132 -0
  423. package/skills/code-review/cells/minimal-prompt.md +32 -0
  424. package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
  425. package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
  426. package/skills/fewer-permission-prompts/SKILL.md +1 -1
  427. package/skills/loop/SKILL.md +11 -0
  428. package/skills/security-review/SKILL.md +2 -5
  429. package/skills/simplify/SKILL.md +7 -5
  430. package/skills/workflow-authoring/SKILL.md +143 -0
  431. package/themes/onecode-light.json +1 -1
  432. package/themes/onecode.json +1 -1
  433. package/types/app.d.ts +58 -0
  434. package/types/community-packages.d.ts +26 -1
  435. package/extensions/auto-mode/recoverability.ts +0 -229
  436. package/extensions/lib/capability-index.ts +0 -466
  437. package/extensions/lib/model-facts.generated.json +0 -2675
  438. package/extensions/lib/model-facts.ts +0 -162
  439. package/extensions/tool-search/announce.ts +0 -42
@@ -0,0 +1,276 @@
1
+ /**
2
+ * The ledger's session entries: what One Code records on the branch so every
3
+ * request is a pure function of it (working-docs/features/lifecycle-grid-hunt/design.md
4
+ * section 4). Each is a pi custom entry (`pi.appendEntry`), invisible to the
5
+ * model and to plain pi, carrying `v` (the record format) and `by` (the One
6
+ * Code version that wrote it). A record of any other `v` is ignored, never
7
+ * partly read: that part of the branch is rendered again once and recorded
8
+ * anew (design.md section 13 and the plan's record versioning).
9
+ *
10
+ * Pure: no pi imports.
11
+ */
12
+
13
+ export const LEDGER_VERSION = 1;
14
+
15
+ export const RECORD = {
16
+ /** One request as sent, as a delta against the previous one on the branch. */
17
+ request: "one-code:request",
18
+ /** What each injected block announced (tool names, skills, a mode switch, a delivered pending item). */
19
+ told: "one-code:told",
20
+ /** Durable session state, latest entry per key wins. */
21
+ state: "one-code:state",
22
+ /** Produced for the model, not yet sent. */
23
+ pending: "one-code:pending",
24
+ /**
25
+ * An epoch opens at the next request: written right before the record of a
26
+ * request that opened one, and by an owner that must change the history
27
+ * above the append point (the no-op loop fold) to make the next one open.
28
+ */
29
+ epoch: "one-code:epoch",
30
+ /** Written at every `/tree`: pi keeps the leaf move only in memory. */
31
+ branch: "one-code:branch",
32
+ } as const;
33
+
34
+ export type RecordKind = keyof typeof RECORD;
35
+
36
+ /** The fields every record carries. */
37
+ export interface RecordBase {
38
+ v: typeof LEDGER_VERSION;
39
+ by: string;
40
+ }
41
+
42
+ /** Who a request went to; a change opens an epoch. */
43
+ export interface RequestIdentity {
44
+ api: string;
45
+ provider: string;
46
+ model: string;
47
+ /** "key" | "oauth" | "chatgpt": OAuth renames tools, ChatGPT sign-in drops fields, so a change opens an epoch. */
48
+ auth: string;
49
+ /** Whether pi-ai puts its per-message effort markers in the list; absent on a model without them. */
50
+ effortMarkers?: boolean;
51
+ }
52
+
53
+ export const sameIdentity = (a: RequestIdentity, b: RequestIdentity): boolean =>
54
+ a.api === b.api && a.provider === b.provider && a.model === b.model && a.auth === b.auth && a.effortMarkers === b.effortMarkers;
55
+
56
+ /**
57
+ * Which of the session's context messages a request covers: the first `count`
58
+ * of pi's `context` messages, the last of them identified by role and
59
+ * timestamp. The next request in the epoch sends only the messages after them
60
+ * (the tail) through pi, and takes the rest from the record.
61
+ */
62
+ export interface Coverage {
63
+ count: number;
64
+ role: string;
65
+ timestamp: number;
66
+ }
67
+
68
+ export interface RequestRecordData extends RecordBase {
69
+ identity: RequestIdentity;
70
+ /** Absent on a record that cannot be extended (written without a context pass): the next request opens an epoch. */
71
+ covers?: Coverage;
72
+ /** Elements of the previous request's list reused unchanged. */
73
+ keep: number;
74
+ /** Content hashes of the elements appended after them. */
75
+ append: string[];
76
+ /** Content hash of the non-list body (system, tools, thinking, …). */
77
+ head: string;
78
+ /** Bodies for hashes not yet on the branch, by hash. */
79
+ blobs: Record<string, unknown>;
80
+ /** Pending ids this request carried, so the outbox drops them. */
81
+ consumed: string[];
82
+ /**
83
+ * The session whose cache host the request was routed to (pi-ai's
84
+ * session-affinity headers): the session that opened the epoch, so a /fork
85
+ * that extends its parent's request goes where the parent's cache lives.
86
+ */
87
+ routing?: string;
88
+ }
89
+
90
+ export type ToldFact =
91
+ /**
92
+ * `callable`: announced by a `tool_addition` the model may call at once, not
93
+ * only listed for tool_search. `removed`: announced gone, so the epoch no
94
+ * longer holds them told.
95
+ */
96
+ | { kind: "tools"; names: string[]; callable?: boolean; removed?: boolean }
97
+ | { kind: "skills"; names: string[] }
98
+ | { kind: "mode"; key: string; on: boolean }
99
+ /** A whole-text block (a menu, a catalog): the content hash of the text last told under `key`. */
100
+ | { kind: "block"; key: string; hash: string };
101
+
102
+ /** A whole-text block fact. */
103
+ export type BlockFact = Extract<ToldFact, { kind: "block" }>;
104
+
105
+ export interface ToldRecordData extends RecordBase {
106
+ facts: ToldFact[];
107
+ }
108
+
109
+ export interface StateRecordData extends RecordBase {
110
+ key: string;
111
+ value: unknown;
112
+ }
113
+
114
+ export interface PendingRecordData extends RecordBase {
115
+ id: string;
116
+ /** A later pending item with the same key replaces this one while both are undelivered. */
117
+ key?: string;
118
+ text: string;
119
+ /** Where it lands: the request's tail (default), or before the text of the prompt that opens a request. */
120
+ placement?: "last-append" | "user-prepend";
121
+ /** Sent bare instead of inside a `<system-reminder>` frame. */
122
+ raw?: boolean;
123
+ /** Rides this call's result when the request carries it. */
124
+ toolCallId?: string;
125
+ /** Rides the user message stamped at this time when the request carries it. */
126
+ promptTimestamp?: number;
127
+ /** `user-prepend` only: placed once per request, however many are pending (the shared caveat). */
128
+ once?: boolean;
129
+ /** `user-prepend` only: on a request that does not open with a prompt, it rides the tail instead of waiting for one. */
130
+ orTail?: boolean;
131
+ /** Dropped, undelivered, at a later compaction: it belongs to the epoch the compaction before it opened (a post-compaction restore). */
132
+ untilCompaction?: boolean;
133
+ /**
134
+ * Files whose whole content the item shows the model (a post-compaction
135
+ * restore), as they were when it was produced. The item and this record
136
+ * are one entry, so file-tracker's replay counts the files read exactly
137
+ * where the branch holds the item.
138
+ */
139
+ observations?: FileVersion[];
140
+ /** The changed versions of files the item names without showing them (a changed-on-disk notice): never a read. */
141
+ notified?: FileVersion[];
142
+ }
143
+
144
+ /** A file's version as a pending item or a tool result records it: the absolute path and content hash, with the size and modification time when known. */
145
+ export interface FileVersion {
146
+ /** Absolute, as the tool resolved it (worktree included). */
147
+ path: string;
148
+ sha256: string;
149
+ size?: number;
150
+ mtimeMs?: number;
151
+ }
152
+
153
+ const EPOCH_CAUSES = ["first", "compaction", "model", "auth", "effort", "fold", "coverage", "empty"] as const;
154
+
155
+ /** Why an epoch opened: no request yet, a compaction, a model or auth switch, thinking turned off or on where pi marks effort per message, a history fold, a base that cannot be extended, or nothing new since it. */
156
+ export type EpochCause = (typeof EPOCH_CAUSES)[number];
157
+
158
+ export interface EpochRecordData extends RecordBase {
159
+ cause: EpochCause;
160
+ }
161
+
162
+ export interface BranchRecordData extends RecordBase {
163
+ fromLeafId: string;
164
+ }
165
+
166
+ export interface RecordData {
167
+ request: RequestRecordData;
168
+ told: ToldRecordData;
169
+ state: StateRecordData;
170
+ pending: PendingRecordData;
171
+ epoch: EpochRecordData;
172
+ branch: BranchRecordData;
173
+ }
174
+
175
+ /** The slice of a pi session entry the ledger reads. */
176
+ export interface EntryLike {
177
+ type: string;
178
+ id: string;
179
+ parentId?: string | null;
180
+ customType?: string;
181
+ data?: unknown;
182
+ message?: { role?: string; stopReason?: string };
183
+ /** A `context_edit`: the entry it edits, and its replacement (null omits the entry from the model's view). */
184
+ targetId?: string;
185
+ replacement?: unknown;
186
+ }
187
+
188
+ export type ParsedRecord = { [K in RecordKind]: { kind: K; entryId: string; data: RecordData[K] } }[RecordKind];
189
+
190
+ const KIND_BY_TYPE = new Map<string, RecordKind>(Object.entries(RECORD).map(([kind, type]) => [type, kind as RecordKind]));
191
+
192
+ export const isObject = (value: unknown): value is Record<string, unknown> => typeof value === "object" && value !== null && !Array.isArray(value);
193
+ const isString = (value: unknown): value is string => typeof value === "string";
194
+ const isStrings = (value: unknown): value is string[] => Array.isArray(value) && value.every(isString);
195
+
196
+ export const isFileVersion = (file: unknown): file is FileVersion =>
197
+ isObject(file) && isString(file.path) && isString(file.sha256) && (file.size === undefined || typeof file.size === "number") && (file.mtimeMs === undefined || typeof file.mtimeMs === "number");
198
+ const isFileVersions = (value: unknown): boolean => Array.isArray(value) && value.every(isFileVersion);
199
+
200
+ const isCoverage = (value: unknown): boolean =>
201
+ isObject(value) && Number.isInteger(value.count) && (value.count as number) >= 0 && isString(value.role) && typeof value.timestamp === "number";
202
+
203
+ function isToldFact(fact: unknown): boolean {
204
+ if (!isObject(fact)) return false;
205
+ switch (fact.kind) {
206
+ case "tools":
207
+ return isStrings(fact.names) && (fact.callable === undefined || typeof fact.callable === "boolean") && (fact.removed === undefined || typeof fact.removed === "boolean");
208
+ case "skills":
209
+ return isStrings(fact.names);
210
+ case "mode":
211
+ return isString(fact.key) && typeof fact.on === "boolean";
212
+ case "block":
213
+ return isString(fact.key) && isString(fact.hash);
214
+ default:
215
+ return false;
216
+ }
217
+ }
218
+
219
+ /** Each kind's own fields, checked whole: a record that fails is ignored, never partly read. */
220
+ const SHAPE: { [K in RecordKind]: (data: Record<string, unknown>) => boolean } = {
221
+ request: (d) =>
222
+ (d.covers === undefined || isCoverage(d.covers)) &&
223
+ isObject(d.identity) &&
224
+ isString(d.identity.api) &&
225
+ isString(d.identity.provider) &&
226
+ isString(d.identity.model) &&
227
+ isString(d.identity.auth) &&
228
+ (d.identity.effortMarkers === undefined || typeof d.identity.effortMarkers === "boolean") &&
229
+ Number.isInteger(d.keep) &&
230
+ (d.keep as number) >= 0 &&
231
+ isStrings(d.append) &&
232
+ isString(d.head) &&
233
+ isObject(d.blobs) &&
234
+ isStrings(d.consumed) &&
235
+ (d.routing === undefined || isString(d.routing)),
236
+ told: (d) => Array.isArray(d.facts) && d.facts.every(isToldFact),
237
+ state: (d) => isString(d.key) && "value" in d,
238
+ pending: (d) =>
239
+ isString(d.id) &&
240
+ isString(d.text) &&
241
+ (d.key === undefined || isString(d.key)) &&
242
+ (d.placement === undefined || d.placement === "last-append" || d.placement === "user-prepend") &&
243
+ (d.raw === undefined || typeof d.raw === "boolean") &&
244
+ (d.toolCallId === undefined || isString(d.toolCallId)) &&
245
+ (d.promptTimestamp === undefined || typeof d.promptTimestamp === "number") &&
246
+ (d.once === undefined || typeof d.once === "boolean") &&
247
+ (d.orTail === undefined || typeof d.orTail === "boolean") &&
248
+ (d.untilCompaction === undefined || typeof d.untilCompaction === "boolean") &&
249
+ (d.observations === undefined || isFileVersions(d.observations)) &&
250
+ (d.notified === undefined || isFileVersions(d.notified)),
251
+ epoch: (d) => (EPOCH_CAUSES as readonly unknown[]).includes(d.cause),
252
+ branch: (d) => isString(d.fromLeafId),
253
+ };
254
+
255
+ /** The entry as a ledger record, or undefined when it is not one, has another `v`, or is malformed. */
256
+ export function readRecord(entry: EntryLike): ParsedRecord | undefined {
257
+ if (entry.type !== "custom" || entry.customType === undefined) return undefined;
258
+ const kind = KIND_BY_TYPE.get(entry.customType);
259
+ const data = entry.data;
260
+ if (!kind || !isObject(data) || data.v !== LEDGER_VERSION || !isString(data.by) || !SHAPE[kind](data)) return undefined;
261
+ return { kind, entryId: entry.id, data } as unknown as ParsedRecord;
262
+ }
263
+
264
+ /** A record's data with `v` and `by` filled in, ready for `pi.appendEntry(RECORD[kind], …)`. */
265
+ export function makeRecord<K extends RecordKind>(_kind: K, by: string, fields: Omit<RecordData[K], keyof RecordBase>): RecordData[K] {
266
+ return { v: LEDGER_VERSION, by, ...fields } as RecordData[K];
267
+ }
268
+
269
+ /** The latest value the branch's `one-code:state` entries hold for `key`, or undefined when none does (latest wins). */
270
+ export function stateOnBranch(branch: readonly EntryLike[], key: string): unknown {
271
+ for (let i = branch.length - 1; i >= 0; i--) {
272
+ const record = readRecord(branch[i]);
273
+ if (record?.kind === "state" && record.data.key === key) return record.data.value;
274
+ }
275
+ return undefined;
276
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Durable session state that follows the branch (design.md section 4.3): an
3
+ * owner records each change as a `one-code:state` entry and reads the
4
+ * branch's latest value back at a resume, `/reload`, a fork and a `/tree`
5
+ * switch.
6
+ *
7
+ * Pure: no pi imports (the session API is taken structurally).
8
+ */
9
+ import { latestCompaction } from "../compaction-boundary.ts";
10
+ import { extensionVersion } from "../package-version.ts";
11
+ import { type EntryLike, makeRecord, RECORD, stateOnBranch } from "./records.ts";
12
+
13
+ /** The slice of the extension API that appends an entry. */
14
+ export interface EntryAppender {
15
+ appendEntry(customType: string, data?: unknown): void;
16
+ }
17
+
18
+ /** The slice of an extension context that reads the branch. */
19
+ export interface BranchReader {
20
+ sessionManager: { getBranch(): readonly unknown[] };
21
+ }
22
+
23
+ /** Record `value` as the branch's state for `key`. */
24
+ export function recordState(pi: EntryAppender, key: string, value: unknown): void {
25
+ pi.appendEntry(RECORD.state, makeRecord("state", extensionVersion(), { key, value }));
26
+ }
27
+
28
+ /** The branch's latest state for `key`, or undefined when none is recorded. */
29
+ export function readState(ctx: BranchReader, key: string): unknown {
30
+ return stateOnBranch(ctx.sessionManager.getBranch() as EntryLike[], key);
31
+ }
32
+
33
+ /**
34
+ * The latest state for `key` on `branch` since its last compaction, or
35
+ * undefined when none is recorded after it. For state a compaction resets
36
+ * (design.md section 4.3 fold rules): what the summary replaced is out of the
37
+ * model's view, so what was told before it counts as untold.
38
+ */
39
+ export function stateSinceCompaction(branch: readonly unknown[], key: string): unknown {
40
+ return stateOnBranch(branch.slice((latestCompaction(branch)?.index ?? -1) + 1) as EntryLike[], key);
41
+ }
42
+
43
+ /** The branch's latest state for `key` as a list of strings (other items dropped), or an empty list. */
44
+ export function readStringsState(ctx: BranchReader, key: string): string[] {
45
+ const stored = readState(ctx, key);
46
+ return Array.isArray(stored) ? stored.filter((item): item is string => typeof item === "string") : [];
47
+ }
@@ -0,0 +1,141 @@
1
+ /**
2
+ * The last step before a request goes out (design.md section 5, step 6). Each
3
+ * returned problem is a bug: tests treat any as fatal; at runtime the caller
4
+ * drops the offending block (`repairRequest`) and logs it, so a bookkeeping
5
+ * bug costs one stale announcement, never a 400.
6
+ *
7
+ * Pure: no pi imports.
8
+ */
9
+ import { isObject, type ToldFact } from "./records.ts";
10
+ import { contentHash, declaredToolNames, listKey, type WirePayload } from "./wire.ts";
11
+
12
+ export type Problem =
13
+ /** A tool_reference, tool_addition or tool_removal names a tool `tools` does not declare. */
14
+ | { kind: "undeclared"; name: string; index: number }
15
+ /** Anthropic: a system message with content followed by something other than an assistant message (findings §52). */
16
+ | { kind: "stranded-system"; index: number };
17
+
18
+ /** The tool a `tool_reference` block names: `name` in a `tool_addition`, `tool_name` in a tool result. */
19
+ function referenceName(block: Record<string, unknown>): string | undefined {
20
+ if (block.type !== "tool_reference") return undefined;
21
+ const name = block.name ?? block.tool_name;
22
+ return typeof name === "string" ? name : undefined;
23
+ }
24
+
25
+ /** Every tool name a block references, at any depth: `tool_addition` and `tool_removal` wrap a `tool_reference`. */
26
+ function referencedNames(value: unknown, into: Set<string>): Set<string> {
27
+ if (Array.isArray(value)) for (const item of value) referencedNames(item, into);
28
+ else if (isObject(value)) {
29
+ const name = referenceName(value);
30
+ if (name !== undefined) into.add(name);
31
+ for (const item of Object.values(value)) referencedNames(item, into);
32
+ }
33
+ return into;
34
+ }
35
+
36
+ const roleOf = (element: unknown) => (isObject(element) ? element.role : undefined);
37
+
38
+ const hasContent = (element: unknown) => {
39
+ const content = isObject(element) ? element.content : undefined;
40
+ return Array.isArray(content) || typeof content === "string" ? content.length > 0 : content !== undefined;
41
+ };
42
+
43
+ /** Anthropic: each system message with content must reach an assistant message, or the end, through system messages only. */
44
+ function strandedSystems(list: readonly unknown[]): number[] {
45
+ const stranded: number[] = [];
46
+ list.forEach((element, index) => {
47
+ if (roleOf(element) !== "system" || !hasContent(element)) return;
48
+ let next = index + 1;
49
+ while (next < list.length && roleOf(list[next]) === "system") next++;
50
+ if (next < list.length && roleOf(list[next]) !== "assistant") stranded.push(index);
51
+ });
52
+ return stranded;
53
+ }
54
+
55
+ export function validateRequest(payload: WirePayload, api: string): Problem[] {
56
+ const problems: Problem[] = [];
57
+ const value = payload[listKey(api)];
58
+ const list: unknown[] = Array.isArray(value) ? value : [];
59
+
60
+ const declared = declaredToolNames(payload);
61
+ list.forEach((element, index) => {
62
+ for (const name of referencedNames(element, new Set())) if (!declared.has(name)) problems.push({ kind: "undeclared", name, index });
63
+ });
64
+
65
+ if (api === "anthropic-messages") for (const index of strandedSystems(list)) problems.push({ kind: "stranded-system", index });
66
+ return problems;
67
+ }
68
+
69
+ /** `value` without the `tool_reference` blocks naming `names` (and the `tool_addition` wrapping one); undefined when a container would empty. */
70
+ function withoutReferences(value: unknown, names: ReadonlySet<string>): unknown {
71
+ if (Array.isArray(value)) {
72
+ return value.flatMap((item) => {
73
+ if (isObject(item) && (item.type === "tool_addition" || item.type === "tool_removal") && referencedNames(item, new Set()).size > 0 && [...referencedNames(item, new Set())].every((name) => names.has(name))) return [];
74
+ if (isObject(item) && names.has(referenceName(item) ?? "")) return [];
75
+ return [withoutReferences(item, names)];
76
+ });
77
+ }
78
+ if (!isObject(value)) return value;
79
+ const out: Record<string, unknown> = {};
80
+ for (const [key, item] of Object.entries(value)) out[key] = withoutReferences(item, names);
81
+ return out;
82
+ }
83
+
84
+ /**
85
+ * The payload with every flagged problem removed, for a production request
86
+ * (a test treats any problem as fatal instead): references to undeclared
87
+ * tools are dropped, and so is a stranded system message.
88
+ */
89
+ export function repairRequest(payload: WirePayload, api: string, problems: readonly Problem[]): WirePayload {
90
+ const key = listKey(api);
91
+ const value = payload[key];
92
+ if (!Array.isArray(value) || problems.length === 0) return payload;
93
+ const undeclared = new Set(problems.flatMap((problem) => (problem.kind === "undeclared" ? [problem.name] : [])));
94
+ const stranded = new Set(problems.flatMap((problem) => (problem.kind === "stranded-system" ? [problem.index] : [])));
95
+ let list = value.filter((_, index) => !stranded.has(index));
96
+ if (undeclared.size > 0) {
97
+ list = (withoutReferences(list, undeclared) as unknown[]).filter(
98
+ (element) => !(isObject(element) && element.role === "system" && Array.isArray(element.content) && element.content.length === 0 && element.output_config === undefined),
99
+ );
100
+ }
101
+ return { ...payload, [key]: list };
102
+ }
103
+
104
+ /**
105
+ * What a repaired request still delivers, so its record does not count a
106
+ * dropped block as sent. Facts ride the text that carries them: the consumed
107
+ * pending items, and the facts of each `carried` block, count only while
108
+ * their text is still in the payload's new elements (not `prefix`, the
109
+ * recorded ones by hash, where an earlier copy of the same text may sit).
110
+ * The callable-tool facts also lose a tool whose `tool_addition` was dropped
111
+ * (a listing for tool_search names tools the request need not declare).
112
+ */
113
+ export function deliveredAfterRepair(
114
+ payload: WirePayload,
115
+ api: string,
116
+ delivered: { consumed: readonly string[]; facts: readonly ToldFact[] },
117
+ pending: readonly { id: string; text: string }[],
118
+ prefix: ReadonlySet<string> = new Set(),
119
+ carried: readonly { text: string; facts: readonly ToldFact[] }[] = [],
120
+ ): { consumed: string[]; facts: ToldFact[] } {
121
+ const list = payload[listKey(api)];
122
+ const sent = JSON.stringify(Array.isArray(list) ? list.filter((element) => !prefix.has(contentHash(element))) : []);
123
+ const onWire = (text: string) => sent.includes(JSON.stringify(text).slice(1, -1));
124
+ const texts = new Map(pending.map((item) => [item.id, item.text]));
125
+ const dropped = new Set(carried.filter((block) => !onWire(block.text)).flatMap((block) => block.facts));
126
+ // The repair left only references to declared tools.
127
+ const referenced = referencedNames(payload[listKey(api)], new Set());
128
+ const facts = delivered.facts.flatMap((fact): ToldFact[] => {
129
+ if (dropped.has(fact)) return [];
130
+ if (fact.kind !== "tools" || !fact.callable) return [fact];
131
+ const names = fact.names.filter((name) => referenced.has(name));
132
+ return names.length > 0 ? [{ ...fact, names }] : [];
133
+ });
134
+ return {
135
+ consumed: delivered.consumed.filter((id) => {
136
+ const text = texts.get(id);
137
+ return text === undefined || onWire(text);
138
+ }),
139
+ facts,
140
+ };
141
+ }