one-code-extension 0.4.0 → 0.5.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 (419) hide show
  1. package/README.md +219 -219
  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 +32 -23
  7. package/docs/guide/doctor.md +20 -13
  8. package/docs/guide/hooks.md +18 -3
  9. package/docs/guide/installation.md +27 -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 +66 -34
  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 +123 -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 +515 -0
  56. package/extensions/background/index.ts +514 -236
  57. package/extensions/background/loop-fire.ts +136 -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 +52 -0
  63. package/extensions/background/wakeup.ts +159 -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 +88 -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 +229 -71
  77. package/extensions/btw/panel.ts +228 -100
  78. package/extensions/btw/prompt.ts +41 -4
  79. package/extensions/claude-compat/index.ts +7 -11
  80. package/extensions/claude-context/index.ts +446 -58
  81. package/extensions/compaction/cut.ts +157 -0
  82. package/extensions/compaction/index.ts +216 -75
  83. package/extensions/compaction/kept-thinking.ts +62 -0
  84. package/extensions/compaction/prompt.ts +15 -12
  85. package/extensions/context-budget/index.ts +24 -5
  86. package/extensions/context-management/index.ts +25 -0
  87. package/extensions/doctor/build.ts +59 -8
  88. package/extensions/doctor/builtins.ts +84 -0
  89. package/extensions/doctor/cli.ts +7 -1
  90. package/extensions/doctor/compat.ts +88 -23
  91. package/extensions/doctor/dependencies.ts +41 -5
  92. package/extensions/doctor/fix-prompt.ts +9 -2
  93. package/extensions/doctor/index.ts +102 -58
  94. package/extensions/doctor/models.ts +102 -63
  95. package/extensions/doctor/presets.ts +42 -27
  96. package/extensions/doctor/report.ts +19 -2
  97. package/extensions/doctor/viewer.ts +49 -27
  98. package/extensions/effort/index.ts +72 -19
  99. package/extensions/effort/settings.ts +21 -0
  100. package/extensions/effort/slider.ts +24 -20
  101. package/extensions/exit/index.ts +32 -1
  102. package/extensions/file-tracker/index.ts +337 -26
  103. package/extensions/file-tracker/replay.ts +96 -10
  104. package/extensions/file-tracker/restore.ts +63 -0
  105. package/extensions/file-tracker/results.ts +66 -0
  106. package/extensions/file-tracker/shell-reads.ts +211 -0
  107. package/extensions/file-tracker/tracker.ts +32 -15
  108. package/extensions/footer/footer-line.ts +45 -24
  109. package/extensions/footer/index.ts +47 -2
  110. package/extensions/footer/pr.ts +34 -5
  111. package/extensions/hooks/compaction.ts +7 -0
  112. package/extensions/hooks/executor.ts +32 -30
  113. package/extensions/hooks/index.ts +198 -31
  114. package/extensions/hooks/matcher.ts +3 -0
  115. package/extensions/hooks/protocol.ts +41 -3
  116. package/extensions/hooks/settings.ts +50 -19
  117. package/extensions/hooks/subagent-bridge.ts +2 -0
  118. package/extensions/hooks/trust.ts +13 -5
  119. package/extensions/idle-compact/index.ts +119 -0
  120. package/extensions/idle-compact/policy.ts +143 -0
  121. package/extensions/init/index.ts +11 -10
  122. package/extensions/init/prompt.ts +25 -32
  123. package/extensions/interrupted/index.ts +13 -1
  124. package/extensions/kept-thinking/index.ts +27 -0
  125. package/extensions/lib/agent-cron.ts +130 -0
  126. package/extensions/lib/agent-loader.ts +15 -1
  127. package/extensions/lib/agent-view.ts +85 -0
  128. package/extensions/lib/anthropic-payload.ts +82 -1
  129. package/extensions/lib/anthropic-server-call.ts +230 -0
  130. package/extensions/lib/anthropic-server-tools.ts +485 -0
  131. package/extensions/lib/app-launch.mjs +94 -0
  132. package/extensions/lib/argument-hints.ts +190 -0
  133. package/extensions/lib/atomic-write.ts +6 -2
  134. package/extensions/lib/auto-memory.ts +75 -0
  135. package/extensions/lib/bash-parser.ts +84 -0
  136. package/extensions/lib/btw-fork.ts +93 -0
  137. package/extensions/lib/child-extensions.ts +42 -0
  138. package/extensions/lib/child-writes.ts +45 -0
  139. package/extensions/lib/claude-context.ts +515 -100
  140. package/extensions/lib/claude-external-includes.ts +68 -0
  141. package/extensions/lib/claude-id.ts +22 -0
  142. package/extensions/lib/claude-rules.ts +323 -0
  143. package/extensions/lib/claude-settings.ts +76 -4
  144. package/extensions/lib/compaction-boundary.ts +36 -0
  145. package/extensions/lib/compaction-keep.mjs +83 -0
  146. package/extensions/lib/config-mode.ts +112 -0
  147. package/extensions/lib/consent-dialogs.ts +63 -0
  148. package/extensions/lib/consent-preview.ts +5 -1
  149. package/extensions/lib/consent-stores.ts +48 -0
  150. package/extensions/lib/context-facts.ts +78 -0
  151. package/extensions/lib/context-stack.ts +81 -0
  152. package/extensions/lib/deferred.ts +219 -25
  153. package/extensions/lib/dock-rows.ts +60 -0
  154. package/extensions/lib/empty-tool-result.ts +27 -0
  155. package/extensions/lib/environment-block.ts +76 -0
  156. package/extensions/lib/fetch-timeout.ts +24 -6
  157. package/extensions/{system-prompt → lib}/git-status.ts +51 -13
  158. package/extensions/lib/git.ts +75 -13
  159. package/extensions/lib/grammars/LICENSE-tree-sitter-bash +21 -0
  160. package/extensions/lib/grammars/README.md +2 -0
  161. package/extensions/lib/grammars/tree-sitter-bash.wasm +0 -0
  162. package/extensions/lib/guide-docs.ts +45 -0
  163. package/extensions/lib/headless-output.ts +46 -0
  164. package/extensions/lib/hook-gate.ts +7 -7
  165. package/extensions/lib/interrupt.ts +20 -4
  166. package/extensions/lib/key-input.ts +455 -0
  167. package/extensions/lib/keys.ts +14 -1
  168. package/extensions/lib/local-command.ts +47 -13
  169. package/extensions/lib/mcp-overrides.ts +1 -1
  170. package/extensions/lib/mcp-share.ts +46 -0
  171. package/extensions/lib/memory-content.ts +146 -0
  172. package/extensions/lib/memory-index.ts +18 -0
  173. package/extensions/lib/memory.ts +134 -123
  174. package/extensions/lib/model-catalog/huggingface.json +174 -0
  175. package/extensions/lib/model-catalog/models-dev.json +18297 -0
  176. package/extensions/lib/model-catalog/openrouter.json +5252 -0
  177. package/extensions/lib/model-catalog-data.ts +513 -0
  178. package/extensions/lib/model-catalog.ts +462 -0
  179. package/extensions/lib/model-choice-warnings.ts +137 -0
  180. package/extensions/lib/model-pairings.ts +152 -0
  181. package/extensions/{auto-mode → lib}/model-picker.ts +26 -43
  182. package/extensions/lib/model-policy.ts +112 -15
  183. package/extensions/lib/model-tier.ts +283 -355
  184. package/extensions/lib/model-unusable.ts +1 -1
  185. package/extensions/lib/newer-model.ts +100 -0
  186. package/extensions/lib/notices.ts +87 -0
  187. package/extensions/lib/notifications.ts +308 -64
  188. package/extensions/lib/one-code-settings.ts +74 -8
  189. package/extensions/lib/open-browser.ts +63 -0
  190. package/extensions/lib/openrouter-generation.ts +94 -0
  191. package/extensions/lib/operation-deadline.ts +30 -0
  192. package/extensions/lib/original-command.ts +4 -4
  193. package/extensions/lib/package-version.ts +1 -1
  194. package/extensions/lib/panel-focus.ts +134 -0
  195. package/extensions/lib/paths.ts +17 -2
  196. package/extensions/lib/permission-gate.ts +72 -6
  197. package/extensions/lib/persisted-output.ts +60 -8
  198. package/extensions/lib/pi-ai-estimate.ts +19 -3
  199. package/extensions/lib/pi-version.ts +21 -2
  200. package/extensions/lib/plan-mode-channels.ts +20 -5
  201. package/extensions/lib/plugins.ts +26 -17
  202. package/extensions/lib/powershell-parse-script.ts +208 -0
  203. package/extensions/lib/powershell-parser.ts +344 -0
  204. package/extensions/lib/process-tree.ts +131 -8
  205. package/extensions/lib/prompt-options.ts +82 -0
  206. package/extensions/lib/queued-delivery.ts +44 -0
  207. package/extensions/lib/reminders.ts +364 -58
  208. package/extensions/lib/replaced-builtins.mjs +199 -0
  209. package/extensions/lib/replay-call.ts +70 -0
  210. package/extensions/lib/request-replay.ts +439 -0
  211. package/extensions/lib/scratchpad.ts +81 -14
  212. package/extensions/lib/send-now-channel.ts +7 -0
  213. package/extensions/lib/session-model-tier.ts +51 -0
  214. package/extensions/lib/session-work.ts +64 -0
  215. package/extensions/lib/settings-channels.ts +4 -4
  216. package/extensions/lib/shell-exit-semantics.ts +170 -0
  217. package/extensions/lib/shell-quote.ts +11 -0
  218. package/extensions/lib/shell-result.ts +70 -0
  219. package/extensions/lib/shell-spawn.ts +70 -6
  220. package/extensions/lib/shell-tool.ts +75 -25
  221. package/extensions/lib/side-call-cache.ts +124 -0
  222. package/extensions/lib/side-call-run.ts +96 -0
  223. package/extensions/lib/side-call-usage.ts +38 -0
  224. package/extensions/lib/side-call.ts +13 -1
  225. package/extensions/lib/single-flight.ts +18 -0
  226. package/extensions/lib/skill-body.ts +42 -0
  227. package/extensions/lib/skill-scan.ts +63 -24
  228. package/extensions/lib/spill-file.ts +140 -0
  229. package/extensions/lib/subagent-handback.ts +113 -0
  230. package/extensions/lib/system-role.ts +156 -0
  231. package/extensions/lib/terminal-text.ts +114 -0
  232. package/extensions/lib/text-width.ts +47 -16
  233. package/extensions/lib/timer-ops.ts +20 -0
  234. package/extensions/lib/tool-additions.ts +149 -0
  235. package/extensions/lib/tool-call-corruption.ts +134 -0
  236. package/extensions/lib/tool-path.ts +66 -0
  237. package/extensions/lib/tool-variants.ts +69 -0
  238. package/extensions/lib/tui-render.ts +255 -27
  239. package/extensions/lib/turn-budget-layout.ts +143 -0
  240. package/extensions/lib/update-check.mjs +15 -2
  241. package/extensions/lib/usage-bus.ts +1 -1
  242. package/extensions/lib/user-denial.ts +38 -0
  243. package/extensions/lib/workspace-channel.ts +16 -0
  244. package/extensions/lib/worktree-channel.ts +31 -3
  245. package/extensions/lib/worktree-isolation.ts +40 -10
  246. package/extensions/lsp/client.ts +8 -9
  247. package/extensions/lsp/index.ts +70 -4
  248. package/extensions/lsp/keep-alive.ts +1 -1
  249. package/extensions/lsp/trust.ts +119 -0
  250. package/extensions/lsp/watcher.ts +1 -1
  251. package/extensions/mcp/announce.ts +87 -5
  252. package/extensions/mcp/client.ts +161 -48
  253. package/extensions/mcp/config.ts +132 -8
  254. package/extensions/mcp/discovery.ts +19 -0
  255. package/extensions/mcp/index.ts +209 -71
  256. package/extensions/mcp/oauth/browser.ts +38 -17
  257. package/extensions/mcp/oauth/flow.ts +25 -17
  258. package/extensions/mcp/oauth/provider.ts +14 -8
  259. package/extensions/mcp/oauth/store.ts +34 -16
  260. package/extensions/mcp/panel/keys.ts +12 -11
  261. package/extensions/mcp/panel/render.ts +9 -6
  262. package/extensions/mcp/schema.ts +104 -5
  263. package/extensions/mcp/trust.ts +151 -67
  264. package/extensions/memory/entries.ts +23 -14
  265. package/extensions/memory/index.ts +134 -28
  266. package/extensions/memory/open-external.ts +33 -18
  267. package/extensions/memory/panel.ts +135 -26
  268. package/extensions/newer-model/index.ts +31 -0
  269. package/extensions/notebook/description.ts +18 -0
  270. package/extensions/notebook/index.ts +6 -5
  271. package/extensions/notebook/notebook.ts +1 -1
  272. package/extensions/permissions/index.ts +1300 -381
  273. package/extensions/permissions/matcher.ts +425 -74
  274. package/extensions/permissions/modes.ts +6 -4
  275. package/extensions/permissions/panel/host.ts +130 -0
  276. package/extensions/permissions/panel/keys.ts +48 -0
  277. package/extensions/permissions/panel/render.ts +450 -0
  278. package/extensions/permissions/panel/state.ts +550 -0
  279. package/extensions/permissions/powershell-cmdlets.ts +198 -0
  280. package/extensions/permissions/powershell-paths.ts +197 -0
  281. package/extensions/permissions/powershell-rules.ts +207 -280
  282. package/extensions/permissions/powershell-tree.ts +557 -0
  283. package/extensions/permissions/project-trust.ts +27 -11
  284. package/extensions/permissions/protected-paths.ts +14 -2
  285. package/extensions/permissions/session-grant.ts +6 -0
  286. package/extensions/permissions/settings.ts +166 -31
  287. package/extensions/permissions/subagent-gate.ts +25 -0
  288. package/extensions/permissions/workspace.ts +78 -0
  289. package/extensions/plan-mode/index.ts +156 -69
  290. package/extensions/plan-mode/reminder.ts +89 -21
  291. package/extensions/plan-mode/texts.ts +177 -0
  292. package/extensions/plan-mode/viewer.ts +92 -27
  293. package/extensions/plugins/counts.ts +3 -3
  294. package/extensions/plugins/index.ts +61 -46
  295. package/extensions/plugins/install/install.ts +16 -0
  296. package/extensions/plugins/marketplace/sync.ts +9 -3
  297. package/extensions/plugins/marketplace/types.ts +3 -1
  298. package/extensions/plugins/panel/keys.ts +21 -24
  299. package/extensions/plugins/panel/render.ts +12 -6
  300. package/extensions/plugins/shell-expand.ts +107 -0
  301. package/extensions/plugins/template.ts +32 -15
  302. package/extensions/powershell/child.ts +7 -0
  303. package/extensions/powershell/description.ts +38 -6
  304. package/extensions/powershell/guards.ts +1 -1
  305. package/extensions/powershell/index.ts +12 -7
  306. package/extensions/recap/index.ts +65 -60
  307. package/extensions/recap/prompt.ts +2 -2
  308. package/extensions/recap/scheduler.ts +3 -5
  309. package/extensions/search-tools/grep-merge.ts +39 -0
  310. package/extensions/search-tools/index.ts +0 -0
  311. package/extensions/send-now/chord.ts +62 -0
  312. package/extensions/send-now/index.ts +133 -0
  313. package/extensions/session-title/index.ts +3 -0
  314. package/extensions/session-title/title.ts +4 -1
  315. package/extensions/skill/code-review.ts +97 -0
  316. package/extensions/skill/index.ts +421 -101
  317. package/extensions/skill/invoke.ts +128 -18
  318. package/extensions/skill/listing.ts +133 -9
  319. package/extensions/skill/panel/keys.ts +15 -16
  320. package/extensions/skill/panel/render.ts +5 -2
  321. package/extensions/skill/panel/state.ts +12 -1
  322. package/extensions/subagents/agent-args.ts +39 -0
  323. package/extensions/subagents/agent-description.ts +132 -0
  324. package/extensions/subagents/agents.ts +116 -23
  325. package/extensions/subagents/announce.ts +69 -0
  326. package/extensions/subagents/default-model.ts +2 -3
  327. package/extensions/subagents/delegation-steer.ts +4 -4
  328. package/extensions/subagents/fork-cache.ts +76 -0
  329. package/extensions/subagents/guide-agent.ts +189 -0
  330. package/extensions/subagents/hand-back-review.ts +3 -0
  331. package/extensions/subagents/index.ts +1493 -824
  332. package/extensions/subagents/live-runs.ts +26 -6
  333. package/extensions/subagents/model-select.ts +38 -25
  334. package/extensions/subagents/outcome.ts +2 -2
  335. package/extensions/subagents/panel-keys.ts +73 -31
  336. package/extensions/subagents/panel-render.ts +120 -96
  337. package/extensions/subagents/panel-widget.ts +60 -89
  338. package/extensions/subagents/runner.ts +108 -80
  339. package/extensions/subagents/runs.ts +39 -5
  340. package/extensions/subagents/send-to-main-tool.ts +1 -1
  341. package/extensions/subagents/session-turns.ts +32 -8
  342. package/extensions/subagents/shell-panel.ts +36 -178
  343. package/extensions/subagents/tasks-dialog.ts +170 -0
  344. package/extensions/subagents/viewport-mirror.ts +95 -0
  345. package/extensions/subagents/worktree.ts +57 -13
  346. package/extensions/system-prompt/environment.ts +19 -19
  347. package/extensions/system-prompt/idle-turn.ts +65 -0
  348. package/extensions/system-prompt/index.ts +131 -47
  349. package/extensions/system-prompt/template.ts +24 -50
  350. package/extensions/system-prompt/tiers/common.ts +23 -64
  351. package/extensions/system-prompt/tiers/frontier.ts +32 -11
  352. package/extensions/system-prompt/tiers/low.ts +67 -45
  353. package/extensions/system-prompt/tiers/mid.ts +96 -38
  354. package/extensions/system-reminder/index.ts +175 -13
  355. package/extensions/tasks/descriptions.ts +190 -0
  356. package/extensions/tasks/index.ts +120 -41
  357. package/extensions/tasks/store.ts +83 -16
  358. package/extensions/tool-call-corruption/child.ts +7 -0
  359. package/extensions/tool-call-corruption/index.ts +237 -0
  360. package/extensions/tool-search/announce.ts +16 -0
  361. package/extensions/tool-search/index.ts +189 -41
  362. package/extensions/tool-style/index.ts +68 -10
  363. package/extensions/tool-style/write-description.ts +40 -0
  364. package/extensions/tool-style/write-render.ts +237 -0
  365. package/extensions/turn-duration/index.ts +7 -3
  366. package/extensions/turn-duration/line.ts +47 -4
  367. package/extensions/web/backends.ts +6 -9
  368. package/extensions/web/description.ts +50 -0
  369. package/extensions/web/index.ts +118 -53
  370. package/extensions/web/native-call.ts +15 -0
  371. package/extensions/web/native-results.ts +41 -0
  372. package/extensions/web-fetch/description.ts +42 -0
  373. package/extensions/web-fetch/extract.ts +53 -6
  374. package/extensions/web-fetch/index.ts +125 -76
  375. package/extensions/web-fetch/page-content.ts +19 -0
  376. package/extensions/web-fetch/response.ts +49 -0
  377. package/extensions/web-fetch/summarize.ts +9 -10
  378. package/extensions/workflow/agent-session.ts +105 -18
  379. package/extensions/workflow/args.ts +24 -0
  380. package/extensions/workflow/description.ts +67 -0
  381. package/extensions/workflow/globals.ts +17 -3
  382. package/extensions/workflow/index.ts +145 -162
  383. package/extensions/workflow/records.ts +1 -0
  384. package/extensions/workflow/run-manager.ts +29 -6
  385. package/extensions/workflow/saved-workflows.ts +3 -2
  386. package/extensions/workflow/types.ts +22 -1
  387. package/extensions/workflow/viewer.ts +54 -24
  388. package/extensions/workflow/widget.ts +20 -0
  389. package/extensions/worktree/descriptions.ts +91 -0
  390. package/extensions/worktree/guards.ts +316 -54
  391. package/extensions/worktree/index.ts +121 -39
  392. package/extensions/worktree/powershell-guards.ts +167 -0
  393. package/extensions/worktree/rewrite.ts +14 -16
  394. package/package.json +19 -7
  395. package/skills/artifact-design/SKILL.md +85 -0
  396. package/skills/code-review/SKILL.md +20 -20
  397. package/skills/code-review/cells/arguments-and-flags.md +19 -0
  398. package/skills/code-review/cells/high-3x5-recall-verify.md +137 -0
  399. package/skills/code-review/cells/high-8-inline.md +122 -0
  400. package/skills/code-review/cells/low-1-pass-max4.md +27 -0
  401. package/skills/code-review/cells/low-1-pass-min-files-4.md +28 -0
  402. package/skills/code-review/cells/max-5x5-verify-sweep.md +162 -0
  403. package/skills/code-review/cells/medium-3x5-verify.md +132 -0
  404. package/skills/code-review/cells/minimal-prompt.md +32 -0
  405. package/skills/code-review/cells/xhigh-10-inline-sweep.md +149 -0
  406. package/skills/code-review/cells/xhigh-5x5-verify-sweep.md +162 -0
  407. package/skills/fewer-permission-prompts/SKILL.md +1 -1
  408. package/skills/loop/SKILL.md +11 -0
  409. package/skills/security-review/SKILL.md +2 -5
  410. package/skills/simplify/SKILL.md +7 -5
  411. package/skills/workflow-authoring/SKILL.md +143 -0
  412. package/themes/onecode-light.json +1 -1
  413. package/themes/onecode.json +1 -1
  414. package/types/app.d.ts +58 -0
  415. package/types/community-packages.d.ts +26 -1
  416. package/extensions/auto-mode/recoverability.ts +0 -229
  417. package/extensions/lib/capability-index.ts +0 -466
  418. package/extensions/lib/model-facts.generated.json +0 -2675
  419. package/extensions/lib/model-facts.ts +0 -162
@@ -1,80 +1,184 @@
1
1
  /**
2
- * schedule_wakeup helpers (pure) — Claude Code's self-paced /loop timer.
2
+ * schedule_wakeup (pure): Claude Code's self-paced `/loop` timer, 2.1.282
3
+ * (findings §21). A wakeup is a one-shot job in the session's CronStore
4
+ * (source "wakeup"), so cron_list shows it and
5
+ * one timer fires everything. Its cron names the target minute
6
+ * (`M H * * *`); the fire itself is the exact target time.
3
7
  *
4
- * A fired wakeup or loop tick is a RE-INVOCATION, not a notification: Claude
5
- * Code enqueues the scheduled prompt verbatim as the next turn's input, behind
6
- * a dim "Running scheduled task" line in the TUI (findings §21), so the model
7
- * reads its own task back exactly as it wrote it. These builders therefore
8
- * return the prompt as-is; the TUI shows the line (`scheduledTaskComponent`).
8
+ * `DynamicLoop` is Claude Code's loop core: one pending wakeup (a new one
9
+ * supersedes the rest), a 7-day age per prompt, `stop` cancelling every
10
+ * wakeup, and the keepalive: a turn that ran a wakeup and ended without
11
+ * scheduling the next gets one 1200 s fallback, and a second miss ends the
12
+ * loop. Texts are Claude Code's with our tool names.
9
13
  */
10
14
 
15
+ import { type CronStore, RECURRING_MAX_AGE_MS } from "./cron.ts";
16
+
11
17
  export const MIN_DELAY_SECONDS = 60;
12
18
  export const MAX_DELAY_SECONDS = 3600;
19
+ /** Claude Code's keepalive fallback delay and budget. */
20
+ export const KEEPALIVE_DELAY_SECONDS = 1200;
21
+ export const KEEPALIVE_BUDGET = 1;
13
22
 
14
23
  export function clampDelaySeconds(delay: number): number {
15
24
  if (!Number.isFinite(delay)) return MIN_DELAY_SECONDS;
16
25
  return Math.min(MAX_DELAY_SECONDS, Math.max(MIN_DELAY_SECONDS, Math.round(delay)));
17
26
  }
18
27
 
19
- export interface WakeupRequest {
20
- delaySeconds: number;
21
- prompt: string;
22
- reason: string;
23
- /** Nothing changed this tick (matches CC's /loop noop flag). Recorded for callers; no effect on scheduling. */
24
- noop?: boolean;
28
+ /** An env flag as Claude Code reads a boolean: unset is `fallback`, a false-like value is off. */
29
+ export function envFlag(value: string | undefined, fallback: boolean): boolean {
30
+ if (value === undefined) return fallback;
31
+ return !["", "0", "false", "no", "off"].includes(value.trim().toLowerCase());
25
32
  }
26
33
 
27
- export interface ParsedLoop {
28
- /** undefined = dynamic (model self-paces via schedule_wakeup); set = fixed interval. */
29
- intervalSeconds?: number;
30
- task: string;
34
+ /** Keepalive is on unless `CLAUDE_CODE_LOOP_KEEPALIVE` turns it off. */
35
+ export function keepaliveEnabled(env: NodeJS.ProcessEnv = process.env): boolean {
36
+ return envFlag(env.CLAUDE_CODE_LOOP_KEEPALIVE, true);
31
37
  }
32
38
 
33
- /**
34
- * Parse `/loop` arguments: a leading duration token (`5m`, `30s`, `2h`) selects
35
- * fixed-interval mode and the rest is the task; no duration selects dynamic
36
- * (self-paced) mode. `stop` / `status` are handled by the caller, not here.
37
- */
38
- export function parseLoopArgs(raw: string): ParsedLoop {
39
- const m = raw.trim().match(/^(\d+)\s*(s|m|h)\b\s*([\s\S]*)$/i);
40
- if (m) {
41
- const n = Number(m[1]);
42
- const unit = m[2].toLowerCase();
43
- const seconds = unit === "h" ? n * 3600 : unit === "m" ? n * 60 : n;
44
- return { intervalSeconds: seconds, task: m[3].trim() };
45
- }
46
- return { task: raw.trim() };
39
+ export interface WakeupSchedule {
40
+ scheduledFor: number;
41
+ clampedDelaySeconds: number;
42
+ wasClamped: boolean;
47
43
  }
48
44
 
49
- /** The turn input a fixed-interval `/loop` tick delivers: the task, verbatim (CC's cron fire). */
50
- export function buildLoopMessage(task: string): string {
51
- return task;
45
+ interface PromptAge {
46
+ startedAt: number;
47
+ lastScheduledFor: number;
48
+ agedOut?: boolean;
52
49
  }
53
50
 
54
- /**
55
- * The opening turn of a dynamic (self-paced) `/loop`: the user's command, so it
56
- * reads as their instruction — drive schedule_wakeup, pass the task back each
57
- * time. Unframed: it is the user's `/loop`, not a harness event.
58
- */
59
- export function buildDynamicLoopPrompt(task: string): string {
60
- return [
61
- "Self-paced loop started. Work the task below now. When this iteration is done, call schedule_wakeup to schedule the next one — choose delaySeconds by what you're waiting for, and pass the same task back as `prompt`. End the loop with schedule_wakeup {stop: true} when the task is complete or the user says to stop.",
62
- "",
63
- task,
64
- ].join("\n");
51
+ export class DynamicLoop {
52
+ /** The wakeup prompt whose turn is running, for the keepalive (Claude Code's in-flight tick). */
53
+ inFlight: string | null = null;
54
+ private misses = 0;
55
+ private readonly ages = new Map<string, PromptAge>();
56
+
57
+ constructor(
58
+ private readonly store: CronStore,
59
+ private readonly maxAgeMs = RECURRING_MAX_AGE_MS,
60
+ ) {}
61
+
62
+ /** A pending wakeup exists. */
63
+ hasPending(): boolean {
64
+ return this.store.list().some((job) => job.source === "wakeup");
65
+ }
66
+
67
+ /**
68
+ * Claude Code's shared scheduling step: null when the loop for this prompt
69
+ * is past its maximum age, which ends it.
70
+ */
71
+ schedule(delaySeconds: number, prompt: string, now: number, viaKeepalive = false): WakeupSchedule | null {
72
+ if (!viaKeepalive) this.misses = 0;
73
+ this.store.deleteWhere((job) => job.source === "wakeup");
74
+ const age = this.ages.get(prompt);
75
+ const stale = age !== undefined && now > age.lastScheduledFor + MAX_DELAY_SECONDS * 1000;
76
+ const startedAt = age === undefined || stale ? now : age.startedAt;
77
+ if (this.maxAgeMs > 0 && now - startedAt >= this.maxAgeMs) {
78
+ if (!age?.agedOut) this.ages.set(prompt, { startedAt, lastScheduledFor: now - (MAX_DELAY_SECONDS - MIN_DELAY_SECONDS) * 1000, agedOut: true });
79
+ return null;
80
+ }
81
+ const clamped = clampDelaySeconds(delaySeconds);
82
+ const wasClamped = !(delaySeconds >= MIN_DELAY_SECONDS && delaySeconds <= MAX_DELAY_SECONDS);
83
+ const scheduledFor = now + clamped * 1000;
84
+ const target = new Date(scheduledFor);
85
+ this.store.create({ cron: `${target.getMinutes()} ${target.getHours()} * * *`, prompt, recurring: false, source: "wakeup", fireAt: scheduledFor }, now);
86
+ this.ages.set(prompt, { startedAt, lastScheduledFor: scheduledFor });
87
+ if (viaKeepalive) this.misses++;
88
+ return { scheduledFor, clampedDelaySeconds: clamped, wasClamped };
89
+ }
90
+
91
+ /**
92
+ * `stop: true`: cancel every pending wakeup; the count is the result's.
93
+ * The cancelled prompts and the one in flight forget their age, so a
94
+ * restarted loop gets a fresh 7 days (Claude Code's `forgetChainStart`).
95
+ */
96
+ stop(): number {
97
+ const cancelled = this.store.deleteWhere((job) => job.source === "wakeup");
98
+ for (const job of cancelled) this.ages.delete(job.prompt);
99
+ if (this.inFlight !== null) this.ages.delete(this.inFlight);
100
+ this.inFlight = null;
101
+ this.misses = 0;
102
+ return cancelled.length;
103
+ }
104
+
105
+ /**
106
+ * A turn ended. When it ran a wakeup and left none pending, re-arm once at
107
+ * the keepalive delay; past the budget the loop ends.
108
+ */
109
+ settle(now: number, keepalive = keepaliveEnabled()): "none" | "armed" | "ended" {
110
+ const prompt = this.inFlight;
111
+ this.inFlight = null;
112
+ if (prompt === null || !keepalive || this.hasPending()) return "none";
113
+ if (this.misses >= KEEPALIVE_BUDGET) return "ended";
114
+ return this.schedule(KEEPALIVE_DELAY_SECONDS, prompt, now, true) ? "armed" : "ended";
115
+ }
116
+
117
+ clear(): void {
118
+ this.inFlight = null;
119
+ this.misses = 0;
120
+ this.ages.clear();
121
+ }
65
122
  }
66
123
 
67
- /** The turn input a fired wakeup delivers: the scheduled prompt, verbatim (CC re-invokes with it). */
68
- export function buildWakeupMessage(request: WakeupRequest): string {
69
- return request.prompt;
124
+ // ── Model-facing text (Claude Code 2.1.282, our tool names) ────────────────
125
+
126
+ export function formatScheduled(result: WakeupSchedule, now: number): string {
127
+ const at = new Date(result.scheduledFor).toTimeString().slice(0, 8);
128
+ const inSeconds = Math.max(0, Math.round((result.scheduledFor - now) / 1000));
129
+ const clamped = result.wasClamped ? ` (clamped to ${result.clampedDelaySeconds}s from your requested value)` : "";
130
+ return `Next wakeup scheduled for ${at} (in ${inSeconds}s)${clamped}. Nothing more to do this turn — the harness re-invokes you when the wakeup fires or a task-notification arrives.`;
70
131
  }
71
132
 
72
- export function describeSchedule(request: WakeupRequest): string {
73
- const clamped = clampDelaySeconds(request.delaySeconds);
74
- const minutes = Math.round((clamped / 60) * 10) / 10;
75
- const adjusted =
76
- clamped !== request.delaySeconds
77
- ? ` (adjusted from ${request.delaySeconds}s — the allowed range is ${MIN_DELAY_SECONDS}-${MAX_DELAY_SECONDS}s)`
78
- : "";
79
- return `Wake-up scheduled in ${clamped}s (~${minutes}min)${adjusted}: ${request.reason}`;
133
+ export const AGED_OUT_RESULT = "Wakeup not scheduled. The loop reached its maximum duration — the loop has ended; do not re-issue.";
134
+
135
+ export function formatStopped(cancelled: number): string {
136
+ const monitor = "If you armed a monitor for this loop, task_stop it now; otherwise nothing more to do this turn.";
137
+ if (cancelled === 0) {
138
+ return `Loop stopped — any dynamic loop in this session is ended; there was no pending wakeup to cancel. If you are running a fixed-interval /loop (a recurring cron), it is NOT stopped by this call — cancel it with cron_delete. ${monitor}`;
139
+ }
140
+ return `Loop stopped — cancelled ${cancelled} pending wakeup(s); no further dynamic-loop wakeups scheduled. ${monitor}`;
80
141
  }
142
+
143
+ export const WAKEUP_ERRORS = {
144
+ delayAndReason: "`delaySeconds` and `reason` are required when `stop` is not true.",
145
+ prompt: "`prompt` is required when `stop` is not true.",
146
+ noop: "`noop` is required when `stop` is not true.",
147
+ } as const;
148
+
149
+ /**
150
+ * Claude Code's description for a session whose prompt-cache TTL it cannot
151
+ * name (its third branch): One Code runs on any provider, so the 1-hour and
152
+ * 5-minute branches, which assume Anthropic billing, never apply as such.
153
+ */
154
+ export const SCHEDULE_WAKEUP_DESCRIPTION = `Schedule when to resume work in /loop dynamic mode — the user invoked /loop without an interval, asking you to self-pace iterations of a specific task.
155
+
156
+ Do NOT schedule a short-interval wakeup to poll for background work you started — when harness-tracked work finishes, you are re-invoked automatically, so polling is wasted. Instead schedule a long fallback (1200s+) so the loop survives if the work hangs or never notifies. The exception is external work the harness cannot track (a CI run, a deploy, a remote queue) — there, pick a delay matched to how fast that state actually changes.
157
+
158
+ Pass the same /loop prompt back via \`prompt\` each turn so the next firing repeats the task. For an autonomous /loop (no user prompt), pass the literal sentinel \`<<autonomous-loop-dynamic>>\` as \`prompt\` instead — the runtime resolves it back to the autonomous-loop instructions at fire time. (There is a similar \`<<autonomous-loop>>\` sentinel for cron_create-based autonomous loops; do not confuse the two — schedule_wakeup always uses the \`-dynamic\` variant.) To end the loop, call this tool with \`stop: true\` (omit every other field) — the loop ends immediately and no further wakeups fire.
159
+
160
+ Set \`noop: true\` if nothing changed — you checked and there's nothing to report ("no change", "still waiting", "quiet hold"). Set \`noop: false\` if something happened worth keeping — you edited a file, posted a message, advanced state, or surfaced a finding. Consecutive \`noop: true\` ticks are collapsed in the user's terminal view and tracked as a streak, so long quiet holds stay legible to the user without scrolling. Omit \`noop\` when stopping (\`stop: true\`).
161
+
162
+ ## Picking delaySeconds
163
+
164
+ The Anthropic prompt cache decides how expensive a wake-up is: waking inside the cache TTL re-reads your conversation context cached (fast, cheap); waking past it re-reads everything uncached. The TTL depends on how the session is billed: Claude subscriber sessions get a 1-hour TTL (dropping to 5 minutes during usage overage), while API-key, Bedrock, and Vertex sessions default to 5 minutes.
165
+
166
+ In either regime: never schedule extra wakeups just to keep the cache warm — they cost more than the cache miss they avoid. Match the delay to what you're actually waiting for: when actively polling external state the harness can't notify you about (a CI run, a deploy, a remote queue), pick the delay from how fast that state actually changes; for idle ticks with no specific signal to watch, default to **1200s–1800s** (20–30 min) — the user can always interrupt if they need you sooner.
167
+
168
+ On a 5-minute TTL only, two refinements: under 300s (60s–270s) the cache stays warm, so prefer 270s over 300s when actively polling (300s is the worst-of-both — you pay the miss without amortizing it); and commit to 1200s+ rather than repeated ~300s waits, so one cache miss buys a long wait.
169
+
170
+ The runtime clamps to [60, 3600], so you don't need to clamp yourself.
171
+
172
+ ## The reason field
173
+
174
+ One short sentence on what you chose and why. Goes to telemetry and is shown back to the user. "watching CI run" beats "waiting." The user reads this to understand what you're doing without having to predict your cadence in advance — make it specific.
175
+ `;
176
+
177
+ export const SCHEDULE_WAKEUP_PARAMS = {
178
+ delaySeconds: "Seconds from now to wake up. Clamped to [60, 3600] by the runtime. Required unless `stop` is true.",
179
+ reason: "One short sentence explaining the chosen delay. Goes to telemetry and is shown to the user. Be specific. Required unless `stop` is true.",
180
+ prompt:
181
+ "The /loop input to fire on wake-up. Pass the same /loop input verbatim each turn so the next firing re-enters the skill and continues the loop. For autonomous /loop (no user prompt), pass the literal sentinel `<<autonomous-loop-dynamic>>` instead (the dynamic-pacing variant, not the cron_create-mode `<<autonomous-loop>>`). Required unless `stop` is true.",
182
+ stop: "Set to true to end the dynamic loop immediately instead of scheduling another wakeup. When true, all other fields are ignored and no further wakeups fire.",
183
+ noop: "true = nothing changed (you checked and there is nothing to report). false = something happened worth keeping (edited a file, posted a message, advanced state, surfaced a finding). Consecutive noop:true ticks are collapsed in the user's terminal view and tracked as a streak. Required unless `stop` is true.",
184
+ } as const;
@@ -5,7 +5,7 @@
5
5
  * A background command spawns detached in its own process group, spools
6
6
  * stdout+stderr to memory (tail-capped) and to a log file when one is given,
7
7
  * and satisfies the BackgroundTask contract so task_output/task_stop work
8
- * unchanged. Robustness rules from docs/features/tools/records/background-bash.md: `output()`
8
+ * unchanged. Robustness rules from working-docs/features/tools/records/background-bash.md: `output()`
9
9
  * never returns an empty body for a finished task (an explicitly-marked
10
10
  * "(no output)" beats an ambiguous blank a weak model reads as failure), and
11
11
  * the completion callback receives exactly what `output()` returns, so the
@@ -13,9 +13,10 @@
13
13
  */
14
14
 
15
15
  import { createWriteStream } from "node:fs";
16
+ import { StringDecoder } from "node:string_decoder";
16
17
  import type { BackgroundTask } from "../background/registry.ts";
17
18
  import { whenAborted } from "../lib/abort.ts";
18
- import { detachedSpawnOptions, KILL_GRACE_MS, stopProcessTree, waitForChildExit } from "../lib/process-tree.ts";
19
+ import { detachedSpawnOptions, KILL_GRACE_MS, rememberProcessGroup, stopProcessTree, waitForChildExit } from "../lib/process-tree.ts";
19
20
  import { bashSpawnOrThrow, type ShellSpawn, spawnShellCommand } from "../lib/shell-spawn.ts";
20
21
 
21
22
  export const STORED_OUTPUT_CAP = 200_000;
@@ -35,6 +36,8 @@ export interface BashFinishSummary {
35
36
  timedOut: boolean;
36
37
  /** Exactly what task.output() returns — never empty. */
37
38
  output: string;
39
+ /** The flushed spool, absent if writing it failed. */
40
+ logPath?: string;
38
41
  }
39
42
 
40
43
  export interface StartBackgroundBashOptions {
@@ -61,23 +64,33 @@ export function startBackgroundBash(options: StartBackgroundBashOptions): Backgr
61
64
  ...detachedSpawnOptions(),
62
65
  stdio: ["ignore", "pipe", "pipe"],
63
66
  });
67
+ rememberProcessGroup(child);
64
68
 
65
69
  let stored = "";
70
+ let overflowed = false;
71
+ let spoolFailed = false;
66
72
  let ended = false;
67
73
  let stopRequested = false;
68
74
  let timedOut = false;
69
75
  const log = options.logPath ? createWriteStream(options.logPath, { flags: "a" }) : undefined;
70
76
  log?.on("error", () => {
71
- // Spooling to disk is best-effort; the in-memory tail stays authoritative.
77
+ // Never name a missing or partial file as the full output.
78
+ spoolFailed = true;
79
+ task.logPath = undefined;
72
80
  });
73
81
 
74
- const append = (chunk: Buffer) => {
75
- const text = chunk.toString();
76
- stored = tailCap(stored + text, STORED_OUTPUT_CAP);
77
- log?.write(text);
82
+ // One streaming decoder per stream: a UTF-8 character split across two
83
+ // reads must not become two U+FFFD. The log gets the raw bytes.
84
+ const stdoutText = new StringDecoder("utf8");
85
+ const stderrText = new StringDecoder("utf8");
86
+ const appender = (decoder: StringDecoder) => (chunk: Buffer) => {
87
+ const text = stored + decoder.write(chunk);
88
+ overflowed ||= text.length > STORED_OUTPUT_CAP;
89
+ stored = tailCap(text, STORED_OUTPUT_CAP);
90
+ if (!spoolFailed) log?.write(chunk);
78
91
  };
79
- child.stdout?.on("data", append);
80
- child.stderr?.on("data", append);
92
+ child.stdout?.on("data", appender(stdoutText));
93
+ child.stderr?.on("data", appender(stderrText));
81
94
 
82
95
  let finish!: () => void;
83
96
  const finished = new Promise<void>((resolve) => {
@@ -94,7 +107,9 @@ export function startBackgroundBash(options: StartBackgroundBashOptions): Backgr
94
107
  startedAt: Date.now(),
95
108
  logPath: options.logPath,
96
109
  ownUI: true, // rendered live by the subagents panel's shell manager
97
- output: () => stored || (task.status === "running" ? "" : EMPTY_OUTPUT_MARKER),
110
+ output: () => overflowed && !task.logPath
111
+ ? `[The command's spool file could not be written, so only the last ${STORED_OUTPUT_CAP.toLocaleString("en-US")} characters of its output were kept.]\n${stored}`
112
+ : stored || (task.status === "running" ? "" : EMPTY_OUTPUT_MARKER),
98
113
  stop: () => {
99
114
  stopRequested = true;
100
115
  // SIGTERM the tree, SIGKILL after the grace: a command that traps TERM
@@ -117,18 +132,39 @@ export function startBackgroundBash(options: StartBackgroundBashOptions): Backgr
117
132
  if (ended) return;
118
133
  ended = true;
119
134
  if (timer) clearTimeout(timer);
120
- task.status = status;
121
- task.finishedAt = Date.now();
135
+ // An incomplete sequence at the very end decodes as U+FFFD, as it would have.
136
+ const rest = stdoutText.end() + stderrText.end();
137
+ if (rest) stored = tailCap(stored + rest, STORED_OUTPUT_CAP);
138
+ let completed = false;
122
139
  const complete = () => {
140
+ if (completed) return;
141
+ completed = true;
142
+ task.status = status;
143
+ task.finishedAt = Date.now();
123
144
  finish();
124
- options.onFinished(task, { exitCode, signal, stopped: stopRequested, timedOut, output: task.output() });
145
+ options.onFinished(task, { exitCode, signal, stopped: stopRequested, timedOut, output: task.output(), logPath: task.logPath });
125
146
  };
126
147
  // end() flushes asynchronously; `finished` must not resolve while the
127
148
  // log file is still short of what output() returns, or a reader sent to
128
- // logPath by the completion notification can see a truncated file. The
129
- // callback also fires if the stream errors, so this cannot hang.
130
- if (log) log.end(complete);
131
- else complete();
149
+ // logPath by the completion notification can see a truncated file.
150
+ // `close` follows a clean end and an error alike; a stuck stream (a
151
+ // write that never calls back) must not keep the task running, so after
152
+ // a second it is dropped and the partial file is no longer named.
153
+ if (log && !log.closed) {
154
+ const fallback = setTimeout(() => {
155
+ spoolFailed = true;
156
+ task.logPath = undefined;
157
+ log.destroy();
158
+ complete();
159
+ }, 1_000);
160
+ log.once("close", () => {
161
+ clearTimeout(fallback);
162
+ complete();
163
+ });
164
+ log.end();
165
+ } else {
166
+ complete();
167
+ }
132
168
  };
133
169
 
134
170
  // Exit plus a short stdio grace, not `close`: a descendant the stop missed
@@ -0,0 +1,7 @@
1
+ /** One Code's bash tool for an in-process child session (lib/child-extensions.ts): the same tool, prints nothing. */
2
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
+ import { bashTool } from "./index.ts";
4
+
5
+ export default function childBashExtension(pi: ExtensionAPI) {
6
+ bashTool(pi, { announce: false });
7
+ }
@@ -0,0 +1,188 @@
1
+ /**
2
+ * The bash tool's model-facing texts: Claude Code's Bash descriptions (pure).
3
+ *
4
+ * Claude Code has three: a short form for its current models, with one extra
5
+ * bullet ("IMPORTANT: Avoid using this tool to run `cat`…") when auto mode is
6
+ * off, and a long form for its weakest models that is the same in every mode.
7
+ * One Code picks the form by tier (lib/tool-variants.ts) and the extra bullet
8
+ * by the permission mode. Two kinds of change from Claude Code's text: tool
9
+ * names are One Code's (`read`, `edit`, `write`, `monitor`, `task_create`),
10
+ * and the working-directory sentence says what this tool does, since each
11
+ * command starts in the session's working directory and a `cd` does not carry
12
+ * over (lib/shell-tool.ts), where Claude Code tracks the directory between
13
+ * calls. The parameter texts are Claude Code's. On the tiny tier, the one
14
+ * with dedicated grep, find and ls tools (search-tools/tools.ts), the long
15
+ * form's two shell-`find` bullets give way to a pointer at those tools, as
16
+ * tiny's system prompt says (system-prompt/tiers/low.ts).
17
+ */
18
+
19
+ import type { DescriptionForm } from "../lib/tool-variants.ts";
20
+
21
+ /** The bullet Claude Code adds to the short form when auto mode is off. */
22
+ export const BASH_AVOID_SHELL_READS_LINE = "- IMPORTANT: Avoid using this tool to run `cat`, `head`, `tail`, `sed`, `awk`, or `echo` commands, unless explicitly instructed or after you have verified that a dedicated tool cannot accomplish your task. Instead, use the appropriate dedicated tool as this will provide a much better experience for the user.\n";
23
+
24
+ /** The short form outside auto mode. */
25
+ export const BASH_SHORT_DESCRIPTION = `Executes a bash command and returns its output.
26
+
27
+ - Each call starts in the session's working directory and a \`cd\` does not carry over, so prefer absolute paths — \`cd\` in a compound command can trigger a permission prompt. Shell state (env vars, functions) does not persist.
28
+ - IMPORTANT: Avoid using this tool to run \`cat\`, \`head\`, \`tail\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or after you have verified that a dedicated tool cannot accomplish your task. Instead, use the appropriate dedicated tool as this will provide a much better experience for the user.
29
+ - Command output is displayed to you, not reliably to the user.
30
+ - \`timeout\` is in milliseconds: default 120000, max 600000 for a foreground command.
31
+ - \`run_in_background\` runs the command detached: it keeps running across turns and re-invokes you when it exits. No \`&\` needed. Foreground \`sleep\` is blocked; use monitor with an until-loop to wait on a condition.
32
+
33
+ # Git
34
+ - Interactive flags (\`-i\`, e.g. \`git rebase -i\`, \`git add -i\`) are not supported in this environment.
35
+ - Use the \`gh\` CLI for GitHub operations (PRs, issues, API).
36
+ - Commit or push only when the user asks. If on the default branch, branch first.
37
+ - End git commit messages and PR bodies with the attribution lines given in the conversation's system-reminder, when one is present.`;
38
+
39
+ /** The long form (every permission mode). */
40
+ export const BASH_LONG_DESCRIPTION = `Executes a given bash command and returns its output.
41
+
42
+ Each command starts in the session's working directory; neither a directory change (\`cd\`) nor shell state (variables, functions) carries over to the next command.
43
+
44
+ IMPORTANT: Avoid using this tool to run \`cat\`, \`head\`, \`tail\`, \`sed\`, \`awk\`, or \`echo\` commands, unless explicitly instructed or after you have verified that a dedicated tool cannot accomplish your task. Instead, use the appropriate dedicated tool as this will provide a much better experience for the user:
45
+
46
+ - Read files: Use read (NOT cat/head/tail)
47
+ - Edit files: Use edit (NOT sed/awk)
48
+ - Write files: Use write (NOT echo >/cat <<EOF)
49
+ - Communication: Output text directly (NOT echo/printf)
50
+ While the bash tool can do similar things, it’s better to use the built-in tools as they provide a better user experience and make it easier to review tool calls and give permission.
51
+
52
+ # Instructions
53
+ - If your command will create new directories or files, first use this tool to run \`ls\` to verify the parent directory exists and is the correct location.
54
+ - Always quote file paths that contain spaces with double quotes in your command (e.g., cd "path with spaces/file.txt")
55
+ - Try to maintain your current working directory throughout the session by using absolute paths and avoiding usage of \`cd\`. You may use \`cd\` if the User explicitly requests it. In particular, never prepend \`cd <current-directory>\` to a \`git\` command — \`git\` already operates on the current working tree, and the compound triggers a permission prompt.
56
+ - You may specify an optional timeout in milliseconds (up to 600000ms / 10 minutes for a foreground command). By default, your command will timeout after 120000ms (2 minutes).
57
+ - You can use the \`run_in_background\` parameter to run the command in the background. Only use this if you don't need the result immediately and are OK being notified when the command completes later. You do not need to check the output right away - you'll be notified when it finishes. You do not need to use '&' at the end of the command when using this parameter.
58
+ - For git commands:
59
+ - Prefer to create a new commit rather than amending an existing commit.
60
+ - Before running destructive operations (e.g., git reset --hard, git push --force, git checkout --), consider whether there is a safer alternative that achieves the same goal. Only use destructive operations when they are truly the best approach.
61
+ - Never skip hooks (--no-verify) or bypass signing (--no-gpg-sign, -c commit.gpgsign=false) unless the user has explicitly asked for it. If a hook fails, investigate and fix the underlying issue.
62
+ - Avoid unnecessary \`sleep\` commands:
63
+ - Do not sleep between commands that can run immediately — just run them.
64
+ - Use the monitor tool to stream events from a background process (each stdout line is a notification). For one-shot "wait until done," use bash with run_in_background instead.
65
+ - If your command is long running and you would like to be notified when it finishes — use \`run_in_background\`. No sleep needed.
66
+ - Do not retry failing commands in a sleep loop — diagnose the root cause.
67
+ - If waiting for a background task you started with \`run_in_background\`, you will be notified when it completes — do not poll.
68
+ - Long leading \`sleep\` commands are blocked. To poll until a condition is met, use monitor with an until-loop (e.g. \`until <check>; do sleep 2; done\`) — you get a notification when the loop exits. Do not chain shorter sleeps to work around the block.
69
+ - When running \`find\`, search from \`.\` (or a specific path), not \`/\` — scanning the full filesystem can exhaust system resources on large trees.
70
+ - When using \`find -regex\` with alternation, put the longest alternative first. Example: use \`'.*\\.\\(tsx\\|ts\\)'\` not \`'.*\\.\\(ts\\|tsx\\)'\` — the second form silently skips \`.tsx\` files.
71
+
72
+
73
+ # Committing changes with git
74
+
75
+ Only create commits when requested by the user. If unclear, ask first. When the user asks you to create a new git commit, follow these steps carefully:
76
+
77
+ You can call multiple tools in a single response. When multiple independent pieces of information are requested and all commands are likely to succeed, run multiple tool calls in parallel for optimal performance. The numbered steps below indicate which commands should be batched in parallel.
78
+
79
+ Git Safety Protocol:
80
+ - NEVER update the git config
81
+ - NEVER run destructive git commands (push --force, reset --hard, checkout ., restore ., clean -f, branch -D) unless the user explicitly requests these actions. Taking unauthorized destructive actions is unhelpful and can result in lost work, so it's best to ONLY run these commands when given direct instructions
82
+ - NEVER skip hooks (--no-verify, --no-gpg-sign, etc) unless the user explicitly requests it
83
+ - NEVER run force push to main/master, warn the user if they request it
84
+ - CRITICAL: Always create NEW commits rather than amending, unless the user explicitly requests a git amend. When a pre-commit hook fails, the commit did NOT happen — so --amend would modify the PREVIOUS commit, which may result in destroying work or losing previous changes. Instead, after hook failure, fix the issue, re-stage, and create a NEW commit
85
+ - When staging files, prefer adding specific files by name rather than using "git add -A" or "git add .", which can accidentally include sensitive files (.env, credentials) or large binaries
86
+ - NEVER commit changes unless the user explicitly asks you to. It is VERY IMPORTANT to only commit when explicitly asked, otherwise the user will feel that you are being too proactive
87
+
88
+ 1. Run the following bash commands in parallel, each using the bash tool:
89
+ - Run a git status command to see all untracked files. IMPORTANT: Never use the -uall flag as it can cause memory issues on large repos.
90
+ - Run a git diff command to see both staged and unstaged changes that will be committed.
91
+ - Run a git log command to see recent commit messages, so that you can follow this repository's commit message style.
92
+ 2. Analyze all staged changes (both previously staged and newly added) and draft a commit message:
93
+ - Summarize the nature of the changes (eg. new feature, enhancement to an existing feature, bug fix, refactoring, test, docs, etc.). Ensure the message accurately reflects the changes and their purpose (i.e. "add" means a wholly new feature, "update" means an enhancement to an existing feature, "fix" means a bug fix, etc.).
94
+ - Do not commit files that likely contain secrets (.env, credentials.json, etc). Warn the user if they specifically request to commit those files
95
+ - Draft a concise (1-2 sentences) commit message that focuses on the "why" rather than the "what"
96
+ - Ensure it accurately reflects the changes and their purpose
97
+ 3. Run the following commands in parallel:
98
+ - Add relevant untracked files to the staging area.
99
+ - Create the commit with a message, ending with the attribution lines given in the conversation's system-reminder, when one is present.
100
+ - Run git status after the commit completes to verify success.
101
+ Note: git status depends on the commit completing, so run it sequentially after the commit.
102
+ 4. If the commit fails due to pre-commit hook: fix the issue and create a NEW commit
103
+
104
+ Important notes:
105
+ - NEVER run additional commands to read or explore code, besides git bash commands
106
+ - NEVER use the task_create or Agent tools
107
+ - DO NOT push to the remote repository unless the user explicitly asks you to do so
108
+ - IMPORTANT: Never use git commands with the -i flag (like git rebase -i or git add -i) since they require interactive input which is not supported.
109
+ - IMPORTANT: Do not use --no-edit with git rebase commands, as the --no-edit flag is not a valid option for git rebase.
110
+ - If there are no changes to commit (i.e., no untracked files and no modifications), do not create an empty commit
111
+ - In order to ensure good formatting, ALWAYS pass the commit message via a HEREDOC, a la this example:
112
+ <example>
113
+ git commit -m "$(cat <<'EOF'
114
+ Commit message here.
115
+ EOF
116
+ )"
117
+ </example>
118
+
119
+ # Creating pull requests
120
+ Use the gh command via the bash tool for ALL GitHub-related tasks including working with issues, pull requests, checks, and releases. If given a Github URL use the gh command to get the information needed.
121
+
122
+ IMPORTANT: When the user asks you to create a pull request, follow these steps carefully:
123
+
124
+ 1. Run the following bash commands in parallel using the bash tool, in order to understand the current state of the branch since it diverged from the main branch:
125
+ - Run a git status command to see all untracked files (never use -uall flag)
126
+ - Run a git diff command to see both staged and unstaged changes that will be committed
127
+ - Check if the current branch tracks a remote branch and is up to date with the remote, so you know if you need to push to the remote
128
+ - Run a git log command and \`git diff [base-branch]...HEAD\` to understand the full commit history for the current branch (from the time it diverged from the base branch)
129
+ 2. Analyze all changes that will be included in the pull request, making sure to look at all relevant commits (NOT just the latest commit, but ALL commits that will be included in the pull request!!!), and draft a pull request title and summary:
130
+ - Keep the PR title short (under 70 characters)
131
+ - Use the description/body for details, not the title
132
+ 3. Run the following commands in parallel:
133
+ - Create new branch if needed
134
+ - Push to remote with -u flag if needed
135
+ - Create PR using gh pr create with the format below. Use a HEREDOC to pass the body to ensure correct formatting. End the body with the attribution lines given in the conversation's system-reminder, when one is present.
136
+ <example>
137
+ gh pr create --title "the pr title" --body "$(cat <<'EOF'
138
+ ## Summary
139
+ <1-3 bullet points>
140
+
141
+ ## Test plan
142
+ [Bulleted markdown checklist of TODOs for testing the pull request...]
143
+ EOF
144
+ )"
145
+ </example>
146
+
147
+ Important:
148
+ - DO NOT use the task_create or Agent tools
149
+ - Return the PR URL when you're done, so the user can see it
150
+
151
+ # Other common operations
152
+ - View comments on a Github PR: gh api repos/foo/bar/pulls/123/comments`;
153
+
154
+ /** The long form's shell-`find` advice, which the tiny tier's search tools replace. */
155
+ const SHELL_FIND_LINES = ` - When running \`find\`, search from \`.\` (or a specific path), not \`/\` — scanning the full filesystem can exhaust system resources on large trees.
156
+ - When using \`find -regex\` with alternation, put the longest alternative first. Example: use \`'.*\\.\\(tsx\\|ts\\)'\` not \`'.*\\.\\(ts\\|tsx\\)'\` — the second form silently skips \`.tsx\` files.
157
+ `;
158
+ const SEARCH_TOOLS_LINE = ` - Search with the dedicated tools, not this shell: the find tool for files, the grep tool for content, the ls tool to list a directory.
159
+ `;
160
+
161
+ /** The long form on the tiny tier, whose grep, find and ls tools replace shell searches. */
162
+ export const BASH_LONG_SEARCH_TOOLS_DESCRIPTION = BASH_LONG_DESCRIPTION.replace(SHELL_FIND_LINES, SEARCH_TOOLS_LINE);
163
+
164
+ /** The description for a form and permission mode; `searchTools` when the session has the dedicated search tools. */
165
+ export function bashDescription(form: DescriptionForm, autoMode: boolean, searchTools = false): string {
166
+ if (form === "long") return searchTools ? BASH_LONG_SEARCH_TOOLS_DESCRIPTION : BASH_LONG_DESCRIPTION;
167
+ return autoMode ? BASH_SHORT_DESCRIPTION.replace(BASH_AVOID_SHELL_READS_LINE, "") : BASH_SHORT_DESCRIPTION;
168
+ }
169
+
170
+ /** Claude Code's parameter descriptions. */
171
+ export const BASH_PARAMS = {
172
+ command: `The command to execute`,
173
+ timeout: `Optional timeout in milliseconds (max 600000 for a foreground command)`,
174
+ description: `Clear, concise description of what this command does in active voice. Never use words like "complex" or "risk" in the description - just describe what it does.
175
+
176
+ Say what the command does in plain words: do not echo the command's text, its flags, or file paths - the user reads this description, often without seeing the command.
177
+
178
+ For simple commands (git, npm, standard CLI tools), keep it brief (5-10 words):
179
+ - ls → "List files in current directory"
180
+ - git status → "Show working tree status"
181
+ - npm install → "Install package dependencies"
182
+
183
+ For commands that are harder to parse at a glance (piped commands, obscure flags, etc.), add enough context to clarify what it does:
184
+ - find . -name "*.tmp" -exec rm {} \\; → "Find and delete all .tmp files recursively"
185
+ - git reset --hard origin/main → "Discard all local changes and match remote main"
186
+ - curl -s url | jq '.data[]' → "Fetch JSON from URL and extract data array elements"`,
187
+ run_in_background: `Set to true to run this command in the background.`,
188
+ } as const;