one-code-extension 0.1.4 → 0.3.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 (300) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +200 -172
  3. package/agents/explore.md +9 -6
  4. package/agents/general-purpose.md +1 -1
  5. package/agents/plan.md +6 -4
  6. package/docs/guide/README.md +52 -0
  7. package/docs/guide/bring-your-claude-code-setup.md +126 -0
  8. package/docs/guide/configuration.md +171 -0
  9. package/docs/guide/differences-from-claude-code.md +150 -0
  10. package/docs/guide/doctor.md +86 -0
  11. package/docs/guide/hooks.md +109 -0
  12. package/docs/guide/installation.md +124 -0
  13. package/docs/guide/permissions-modes-and-auto-mode.md +450 -0
  14. package/docs/guide/providers-and-models.md +194 -0
  15. package/docs/guide/reference.md +224 -0
  16. package/docs/guide/sessions-and-context.md +190 -0
  17. package/docs/guide/skills-plugins-and-mcp.md +176 -0
  18. package/docs/guide/subagents-and-workflows.md +193 -0
  19. package/docs/guide/tasks-and-background-work.md +111 -0
  20. package/docs/guide/terminal-interface.md +155 -0
  21. package/docs/guide/tools.md +175 -0
  22. package/docs/guide/troubleshooting.md +175 -0
  23. package/extensions/ask-user/index.ts +65 -71
  24. package/extensions/ask-user/questions.ts +15 -28
  25. package/extensions/ask-user/widget.ts +533 -0
  26. package/extensions/auto-mode/actions.ts +9 -26
  27. package/extensions/auto-mode/classifier-prompt.ts +127 -0
  28. package/extensions/auto-mode/classifier.ts +305 -227
  29. package/extensions/auto-mode/config.ts +279 -77
  30. package/extensions/auto-mode/defaults.ts +17 -60
  31. package/extensions/auto-mode/instructions.ts +2 -1
  32. package/extensions/auto-mode/model-picker.ts +53 -31
  33. package/extensions/auto-mode/model-select.ts +153 -82
  34. package/extensions/auto-mode/paths.ts +13 -1
  35. package/extensions/auto-mode/pause.ts +8 -0
  36. package/extensions/auto-mode/prompt.ts +205 -238
  37. package/extensions/auto-mode/recoverability.ts +229 -0
  38. package/extensions/auto-mode/rules.ts +92 -75
  39. package/extensions/auto-mode/safety-floor.ts +43 -12
  40. package/extensions/auto-mode/sensitive.ts +11 -0
  41. package/extensions/auto-mode/setup-run.ts +245 -0
  42. package/extensions/auto-mode/setup.ts +235 -0
  43. package/extensions/auto-mode/shell-analysis.ts +332 -26
  44. package/extensions/auto-mode/transcript.ts +102 -0
  45. package/extensions/background/index.ts +256 -43
  46. package/extensions/background/monitor-batch.ts +58 -0
  47. package/extensions/background/registry.ts +9 -0
  48. package/extensions/background/wakeup.ts +45 -0
  49. package/extensions/bash/background.ts +47 -22
  50. package/extensions/bash/guards.ts +229 -0
  51. package/extensions/bash/index.ts +81 -19
  52. package/extensions/branding/index.ts +44 -18
  53. package/extensions/branding/startup.ts +23 -8
  54. package/extensions/claude-compat/index.ts +17 -2
  55. package/extensions/claude-context/index.ts +41 -12
  56. package/extensions/clear/index.ts +27 -0
  57. package/extensions/compaction/fit.ts +121 -0
  58. package/extensions/compaction/index.ts +176 -71
  59. package/extensions/compaction/prompt.ts +21 -1
  60. package/extensions/context-budget/budget.ts +61 -0
  61. package/extensions/context-budget/index.ts +66 -0
  62. package/extensions/context-management/index.ts +40 -16
  63. package/extensions/doctor/build.ts +226 -0
  64. package/extensions/doctor/cli.ts +99 -0
  65. package/extensions/doctor/compat.ts +532 -0
  66. package/extensions/doctor/dependencies.ts +186 -0
  67. package/extensions/doctor/fix-prompt.ts +125 -0
  68. package/extensions/doctor/index.ts +308 -0
  69. package/extensions/doctor/models.ts +231 -0
  70. package/extensions/doctor/presets.ts +208 -0
  71. package/extensions/doctor/report.ts +189 -0
  72. package/extensions/doctor/update-lookup.ts +46 -0
  73. package/extensions/doctor/viewer.ts +124 -0
  74. package/extensions/effort/index.ts +41 -4
  75. package/extensions/effort/slider.ts +33 -2
  76. package/extensions/file-tracker/index.ts +143 -20
  77. package/extensions/file-tracker/replay.ts +46 -0
  78. package/extensions/file-tracker/tracker.ts +51 -4
  79. package/extensions/footer/footer-line.ts +207 -0
  80. package/extensions/footer/index.ts +152 -0
  81. package/extensions/footer/pr.ts +53 -0
  82. package/extensions/hooks/executor.ts +57 -20
  83. package/extensions/hooks/formatter-notice.ts +76 -0
  84. package/extensions/hooks/index.ts +314 -73
  85. package/extensions/hooks/matcher.ts +35 -1
  86. package/extensions/hooks/plugin-hooks.ts +3 -3
  87. package/extensions/hooks/protocol.ts +58 -0
  88. package/extensions/hooks/subagent-bridge.ts +77 -0
  89. package/extensions/hooks/trust.ts +15 -4
  90. package/extensions/init/index.ts +26 -0
  91. package/extensions/init/prompt.ts +40 -0
  92. package/extensions/interrupted/index.ts +35 -0
  93. package/extensions/interrupted/line.ts +9 -0
  94. package/extensions/lib/abort.ts +15 -0
  95. package/extensions/lib/agent-loader.ts +183 -0
  96. package/extensions/lib/anthropic-payload.ts +15 -0
  97. package/extensions/lib/atomic-write.ts +56 -0
  98. package/extensions/lib/bridge-watch.ts +20 -0
  99. package/extensions/lib/cache-retention.ts +60 -0
  100. package/extensions/lib/capability-index.ts +466 -0
  101. package/extensions/lib/claude-context.ts +318 -27
  102. package/extensions/lib/claude-settings.ts +64 -0
  103. package/extensions/lib/consent-preview.ts +30 -0
  104. package/extensions/lib/deferred.ts +144 -13
  105. package/extensions/lib/favorites.ts +43 -0
  106. package/extensions/lib/fetch-timeout.ts +15 -0
  107. package/extensions/lib/frontmatter.ts +31 -0
  108. package/extensions/lib/git.ts +44 -2
  109. package/extensions/lib/hook-gate.ts +90 -0
  110. package/extensions/lib/interrupt.ts +94 -0
  111. package/extensions/lib/mcp-overrides.ts +61 -0
  112. package/extensions/lib/mcp-share.ts +25 -0
  113. package/extensions/lib/mcp-status.ts +34 -0
  114. package/extensions/lib/memory.ts +41 -6
  115. package/extensions/lib/model-facts.generated.json +2480 -0
  116. package/extensions/lib/model-facts.ts +162 -0
  117. package/extensions/lib/model-policy.ts +145 -189
  118. package/extensions/lib/model-tier.ts +480 -64
  119. package/extensions/lib/model-unusable.ts +37 -0
  120. package/extensions/lib/notifications.ts +320 -1
  121. package/extensions/lib/one-code-settings.ts +63 -0
  122. package/extensions/lib/original-command.ts +71 -0
  123. package/extensions/lib/package-version.ts +31 -0
  124. package/extensions/lib/paths.ts +39 -4
  125. package/extensions/lib/permission-gate.ts +192 -0
  126. package/extensions/lib/persisted-output.ts +18 -0
  127. package/extensions/lib/pi-ai-estimate.ts +160 -0
  128. package/extensions/lib/pi-version.ts +1 -1
  129. package/extensions/lib/plan-mode-channels.ts +11 -0
  130. package/extensions/lib/plugin-overrides.ts +24 -0
  131. package/extensions/lib/plugin-root.ts +44 -0
  132. package/extensions/lib/plugins.ts +233 -54
  133. package/extensions/lib/prefix-warm-gate.ts +157 -0
  134. package/extensions/lib/process-tree.ts +56 -0
  135. package/extensions/lib/reminders.ts +321 -68
  136. package/extensions/lib/scratchpad.ts +11 -8
  137. package/extensions/lib/session-lifecycle.ts +28 -0
  138. package/extensions/lib/settings-channels.ts +14 -0
  139. package/extensions/lib/shell-tasks.ts +54 -0
  140. package/extensions/lib/skill-overrides.ts +86 -0
  141. package/extensions/lib/skill-scan.ts +110 -0
  142. package/extensions/lib/text-width.ts +267 -0
  143. package/extensions/lib/tui-render.ts +281 -54
  144. package/extensions/lib/usage-bus.ts +75 -0
  145. package/extensions/lib/usage-tracker.ts +67 -0
  146. package/extensions/lib/worktree-isolation.ts +170 -0
  147. package/extensions/lsp/client.ts +69 -12
  148. package/extensions/lsp/format.ts +12 -2
  149. package/extensions/lsp/index.ts +273 -84
  150. package/extensions/lsp/install-hints.ts +43 -0
  151. package/extensions/lsp/keep-alive.ts +19 -0
  152. package/extensions/lsp/plugin-servers.ts +331 -0
  153. package/extensions/lsp/watcher.ts +157 -0
  154. package/extensions/mcp/announce.ts +99 -0
  155. package/extensions/mcp/client.ts +181 -22
  156. package/extensions/mcp/config.ts +55 -24
  157. package/extensions/mcp/index.ts +586 -86
  158. package/extensions/mcp/oauth/browser.ts +26 -0
  159. package/extensions/mcp/oauth/callback.ts +104 -0
  160. package/extensions/mcp/oauth/flow.ts +68 -0
  161. package/extensions/mcp/oauth/provider.ts +147 -0
  162. package/extensions/mcp/oauth/store.ts +86 -0
  163. package/extensions/mcp/panel/keys.ts +34 -0
  164. package/extensions/mcp/panel/model.ts +62 -0
  165. package/extensions/mcp/panel/render.ts +141 -0
  166. package/extensions/mcp/panel/state.ts +108 -0
  167. package/extensions/mcp/schema.ts +83 -6
  168. package/extensions/mcp/trust.ts +340 -0
  169. package/extensions/memory/entries.ts +163 -0
  170. package/extensions/memory/index.ts +119 -2
  171. package/extensions/memory/open-external.ts +97 -0
  172. package/extensions/memory/panel.ts +124 -0
  173. package/extensions/model-default/index.ts +74 -0
  174. package/extensions/notebook/index.ts +36 -18
  175. package/extensions/notebook/notebook.ts +110 -17
  176. package/extensions/permissions/index.ts +1012 -247
  177. package/extensions/permissions/matcher.ts +488 -57
  178. package/extensions/permissions/modes.ts +55 -7
  179. package/extensions/permissions/project-trust.ts +81 -0
  180. package/extensions/permissions/protected-paths.ts +16 -3
  181. package/extensions/permissions/rule-prose.ts +79 -0
  182. package/extensions/permissions/session-grant.ts +91 -0
  183. package/extensions/permissions/settings.ts +112 -33
  184. package/extensions/permissions/subagent-gate.ts +57 -0
  185. package/extensions/plan-mode/index.ts +143 -33
  186. package/extensions/plan-mode/reminder.ts +16 -19
  187. package/extensions/plan-mode/viewer.ts +40 -31
  188. package/extensions/plugins/counts.ts +68 -0
  189. package/extensions/plugins/index.ts +496 -32
  190. package/extensions/plugins/install/install.ts +167 -0
  191. package/extensions/plugins/install/paths.ts +23 -0
  192. package/extensions/plugins/install/registry.ts +72 -0
  193. package/extensions/plugins/marketplace/git.ts +103 -0
  194. package/extensions/plugins/marketplace/official.ts +36 -0
  195. package/extensions/plugins/marketplace/parse.ts +94 -0
  196. package/extensions/plugins/marketplace/registry.ts +60 -0
  197. package/extensions/plugins/marketplace/sync.ts +146 -0
  198. package/extensions/plugins/marketplace/types.ts +128 -0
  199. package/extensions/plugins/panel/keys.ts +52 -0
  200. package/extensions/plugins/panel/render.ts +315 -0
  201. package/extensions/plugins/panel/rows.ts +230 -0
  202. package/extensions/plugins/panel/state.ts +333 -0
  203. package/extensions/recap/index.ts +215 -0
  204. package/extensions/recap/prompt.ts +44 -0
  205. package/extensions/recap/scheduler.ts +87 -0
  206. package/extensions/search-tools/index.ts +0 -0
  207. package/extensions/search-tools/tools.ts +7 -5
  208. package/extensions/skill/index.ts +360 -34
  209. package/extensions/skill/invoke.ts +185 -0
  210. package/extensions/skill/listing.ts +21 -0
  211. package/extensions/skill/panel/keys.ts +41 -0
  212. package/extensions/skill/panel/render.ts +91 -0
  213. package/extensions/skill/panel/state.ts +115 -0
  214. package/extensions/spinner/index.ts +110 -0
  215. package/extensions/spinner/line.ts +51 -0
  216. package/extensions/spinner/verbs.ts +201 -0
  217. package/extensions/subagents/agents.ts +88 -44
  218. package/extensions/subagents/default-model.ts +62 -32
  219. package/extensions/subagents/delegation-steer.ts +23 -0
  220. package/extensions/subagents/hand-back-review.ts +67 -0
  221. package/extensions/subagents/index.ts +1545 -346
  222. package/extensions/subagents/live-runs.ts +293 -0
  223. package/extensions/subagents/model-select.ts +252 -82
  224. package/extensions/subagents/outcome.ts +90 -0
  225. package/extensions/subagents/panel-keys.ts +41 -0
  226. package/extensions/subagents/panel-render.ts +357 -0
  227. package/extensions/subagents/panel-widget.ts +330 -0
  228. package/extensions/subagents/pending-claim.ts +45 -0
  229. package/extensions/subagents/prose.ts +105 -0
  230. package/extensions/subagents/runner.ts +674 -0
  231. package/extensions/subagents/runs.ts +68 -1
  232. package/extensions/subagents/send-to-main-tool.ts +55 -0
  233. package/extensions/subagents/session-turns.ts +138 -0
  234. package/extensions/subagents/shell-panel.ts +198 -0
  235. package/extensions/subagents/usage.ts +16 -4
  236. package/extensions/subagents/worktree.ts +13 -0
  237. package/extensions/system-prompt/environment.ts +5 -3
  238. package/extensions/system-prompt/git-status.ts +93 -0
  239. package/extensions/system-prompt/index.ts +23 -1
  240. package/extensions/system-prompt/template.ts +34 -4
  241. package/extensions/system-prompt/tiers/common.ts +31 -6
  242. package/extensions/system-prompt/tiers/low.ts +13 -3
  243. package/extensions/system-prompt/tiers/mid.ts +21 -8
  244. package/extensions/system-reminder/index.ts +53 -9
  245. package/extensions/tasks/index.ts +65 -16
  246. package/extensions/tasks/store.ts +76 -3
  247. package/extensions/tool-search/announce.ts +42 -0
  248. package/extensions/tool-search/index.ts +136 -13
  249. package/extensions/turn-duration/index.ts +60 -0
  250. package/extensions/turn-duration/line.ts +22 -0
  251. package/extensions/turn-duration/span.ts +41 -0
  252. package/extensions/turn-duration/verbs.ts +24 -0
  253. package/extensions/web/backends.ts +421 -0
  254. package/extensions/web/index.ts +178 -21
  255. package/extensions/web-fetch/index.ts +74 -18
  256. package/extensions/web-fetch/summarize.ts +1 -1
  257. package/extensions/workflow/agent-session.ts +182 -112
  258. package/extensions/workflow/globals.ts +129 -106
  259. package/extensions/workflow/index.ts +343 -28
  260. package/extensions/workflow/records.ts +118 -0
  261. package/extensions/workflow/run-manager.ts +80 -31
  262. package/extensions/workflow/saved-workflows.ts +2 -1
  263. package/extensions/workflow/script-worker.mjs +110 -0
  264. package/extensions/workflow/types.ts +74 -8
  265. package/extensions/workflow/viewer.ts +562 -0
  266. package/extensions/workflow/vm-runtime.ts +118 -22
  267. package/extensions/workflow/widget.ts +126 -18
  268. package/extensions/worktree/guards.ts +240 -0
  269. package/extensions/worktree/index.ts +30 -5
  270. package/extensions/worktree/rewrite.ts +32 -16
  271. package/package.json +20 -10
  272. package/skills/code-review/SKILL.md +165 -0
  273. package/skills/fewer-permission-prompts/SKILL.md +61 -0
  274. package/skills/security-review/SKILL.md +178 -0
  275. package/skills/simplify/SKILL.md +70 -0
  276. package/themes/{one-code-light.json → onecode-light.json} +6 -1
  277. package/themes/{one-code.json → onecode.json} +6 -1
  278. package/types/app.d.ts +8 -1
  279. package/types/community-packages.d.ts +45 -2
  280. package/docs/decisions/auto-mode.md +0 -526
  281. package/docs/decisions/branding.md +0 -127
  282. package/docs/decisions/code-review-remediation.md +0 -106
  283. package/docs/decisions/compaction.md +0 -140
  284. package/docs/decisions/distribution.md +0 -168
  285. package/docs/decisions/hooks.md +0 -64
  286. package/docs/decisions/lsp.md +0 -58
  287. package/docs/decisions/mcp.md +0 -104
  288. package/docs/decisions/memory-state.md +0 -170
  289. package/docs/decisions/model-policy.md +0 -126
  290. package/docs/decisions/modes.md +0 -178
  291. package/docs/decisions/skills-plugins.md +0 -56
  292. package/docs/decisions/subagents-workflows.md +0 -225
  293. package/docs/decisions/system-prompt.md +0 -98
  294. package/docs/decisions/tools.md +0 -407
  295. package/docs/decisions/tui.md +0 -217
  296. package/docs/decisions.md +0 -148
  297. package/extensions/subagents/child.ts +0 -414
  298. package/extensions/subagents/rpc-turns.ts +0 -123
  299. package/extensions/todo/index.ts +0 -133
  300. package/extensions/workflow/permission-gate.ts +0 -71
@@ -0,0 +1,175 @@
1
+ # Tools
2
+
3
+ The model works by calling tools. You do not type tool names; you describe
4
+ the task and the model chooses. This page lists every tool One Code gives
5
+ the model, what each does, what you see when it runs, and how Claude Code's
6
+ tool names map onto them.
7
+
8
+ Every tool call passes through the permission gate. See
9
+ [Permissions, modes, and auto mode](permissions-modes-and-auto-mode.md).
10
+
11
+ ## Eager and deferred tools
12
+
13
+ Tools come in two kinds:
14
+
15
+ - **Eager tools** are in every request. These are the tools the model uses
16
+ constantly: `read`, `write`, `edit`, `bash`, `Agent`, `skill`,
17
+ `ask_user_question`, `workflow`, and `tool_search`.
18
+ - **Deferred tools** are listed by name only. When the model needs one, it
19
+ calls `tool_search` to load the full definition, and the tool stays
20
+ available for the rest of the session. This keeps the prompt small and
21
+ works the same way on every model tier and provider.
22
+
23
+ Run `/tools-deferred` to see which deferred tools are loaded and which are
24
+ still waiting. The list is fixed once the first request has gone out, so a
25
+ tool that appears later (an MCP server that connects slowly, for example)
26
+ is announced to the model separately.
27
+
28
+ ## Files and code
29
+
30
+ | Tool | What it does |
31
+ |---|---|
32
+ | `read` | Reads a file. Shown as `● Read(path)` in the transcript. |
33
+ | `write` | Creates or overwrites a file. The model must have read an existing file in this conversation before writing it. |
34
+ | `edit` | Replaces an exact string in a file. Shown as `● Update(path)`. The same read-before-write rule applies, and the edit is refused if the file changed on disk since the model last read it. |
35
+ | `notebook_edit` | Edits a Jupyter notebook cell: replace, insert, append, or delete. Editing a code cell clears its outputs. Deferred. |
36
+ | `grep`, `find`, `ls` | pi's search tools. Active only for the smallest model tier; on other tiers, searching goes through `bash`, as in Claude Code. |
37
+
38
+ The read-before-write and stale-edit guards track file **content**, not tool
39
+ calls, so a file the model changed through a shell command is tracked too.
40
+ When a file changes outside the model's view (you edited it, a formatter
41
+ ran, a `git checkout` happened) the model is told, with the changed lines,
42
+ and must re-read the file before editing it. A file that disappears is
43
+ reported as deleted or moved.
44
+
45
+ ## Shell
46
+
47
+ `bash` runs a shell command. Its `run_in_background` option starts the
48
+ command detached and returns a task id; output spools to a log file under
49
+ the session directory, and completion is reported to the model as a
50
+ notification. A background shell shows up in the shells section of the
51
+ panel below the editor. See
52
+ [Tasks and background work](tasks-and-background-work.md).
53
+
54
+ Some command shapes are refused before they run, with a message that steers
55
+ the model to a better route:
56
+
57
+ - A foreground command that starts with `sleep`, or a polling loop that
58
+ sleeps, when the wait is not provably short. The model is told to use
59
+ `run_in_background` or `monitor` instead.
60
+ - A command that would orphan a process (`nohup`, `setsid`, or a trailing
61
+ `&` with no `wait`).
62
+ - An interactive program that would stop responding without a terminal:
63
+ `vim`, `git rebase -i`, `git add -p`, `watch`, and similar.
64
+ - Inside a worktree session, a git command aimed at a different checkout.
65
+
66
+ ## Web
67
+
68
+ | Tool | What it does |
69
+ |---|---|
70
+ | `web_search` | Searches the web. Uses your provider's own search when it has one (Anthropic, OpenAI, Gemini, xAI); otherwise falls back to Brave, then Tavily, then Exa's free keyless endpoint. Results from the keyless endpoint are labelled, and the first use in a session shows a warning. See [Web search](providers-and-models.md#web-search-on-providers-without-a-search-api). Deferred. |
71
+ | `web_fetch` | Fetches a URL and converts it to readable Markdown. Follows same-host redirects; reports cross-host redirects instead of following them. Responses are cached for 15 minutes. With a `prompt`, a small reader model on your provider answers the question against the page, so the page itself stays out of your context; if the reader fails, the raw page is returned with a note. Deferred. |
72
+ | `url_context` | Gemini's page-context tool, available only when a Gemini model is in use. Deferred. |
73
+
74
+ ## Delegation
75
+
76
+ | Tool | What it does |
77
+ |---|---|
78
+ | `Agent` | Starts a subagent with its own context window. Runs in the background and returns a task id; the result arrives as a notification. Supports forking the current conversation and isolating the agent in a git worktree. |
79
+ | `SendMessage` | Sends a message to an agent that was started earlier: a running one receives it live, a finished one is resumed from its saved session. Deferred. |
80
+ | `list_agents` | Lists the agents started in this session and their status. Deferred. |
81
+ | `workflow` | Runs a JavaScript script that coordinates many agents. This is the `ultracode` mechanism. |
82
+
83
+ See [Subagents and workflows](subagents-and-workflows.md).
84
+
85
+ ## Planning and asking
86
+
87
+ | Tool | What it does |
88
+ |---|---|
89
+ | `enter_plan_mode`, `exit_plan_mode` | Switch into plan mode and ask you to approve the plan file. Deferred. See [Plan mode](permissions-modes-and-auto-mode.md#plan-mode). |
90
+ | `ask_user_question` | Asks you up to four structured questions in a tabbed dialog. See [The terminal interface](terminal-interface.md#the-question-dialog). |
91
+ | `skill` | Runs a skill by name. See [Skills](skills-plugins-and-mcp.md#skills). |
92
+
93
+ ## Tasks and background work
94
+
95
+ | Tool | What it does |
96
+ |---|---|
97
+ | `task_create`, `task_get`, `task_list`, `task_update` | Maintain the structured task list shown in the pinned widget. Deferred. |
98
+ | `monitor` | Watches a long-running command or a WebSocket and reports each output line as an event. Deferred. |
99
+ | `task_output`, `task_stop` | Read the output of a background task or stop it. Deferred. |
100
+ | `schedule_wakeup` | Schedules a prompt for later; the mechanism behind self-paced `/loop`. Deferred. |
101
+
102
+ See [Tasks and background work](tasks-and-background-work.md).
103
+
104
+ ## Worktrees
105
+
106
+ `enter_worktree` creates a git worktree under `.claude/worktrees/`, branched
107
+ from the current `HEAD`, and moves the session into it: every shell command
108
+ and relative path then resolves there, and your main working tree is
109
+ untouched. `exit_worktree` leaves it, either keeping the worktree or
110
+ removing it; removal is refused while the worktree has uncommitted or
111
+ unmerged work unless the model passes `discard_changes`. The worktrees
112
+ directory ignores itself in git. Both tools are deferred.
113
+
114
+ ## Diagnostics
115
+
116
+ `lsp_diagnostics` asks a language server for the diagnostics of one file.
117
+ Separately, after every round of edits, new diagnostics from every running
118
+ server are attached to the last tool result as a `<new-diagnostics>` block,
119
+ including diagnostics in other files that the edit broke. See
120
+ [Language-server diagnostics](configuration.md#language-server-diagnostics).
121
+ Deferred.
122
+
123
+ ## MCP
124
+
125
+ Every tool an MCP server provides appears as `mcp__<server>__<tool>`,
126
+ deferred until needed. `list_mcp_resources`, `read_mcp_resource`, and
127
+ `read_mcp_resource_dir` read the resources servers expose. See
128
+ [MCP servers](skills-plugins-and-mcp.md#mcp-servers).
129
+
130
+ ## Tool discovery
131
+
132
+ `tool_search` loads deferred tools. The model passes exact names
133
+ (`select:monitor,task_output`), a required term (`+notebook`), or free
134
+ keywords. If the model calls a tool it has not loaded yet, the call fails
135
+ and the model is steered to `tool_search`.
136
+
137
+ ## Behavior in non-interactive runs
138
+
139
+ In `-p` and `--mode json` runs the process exits when the turn settles, so
140
+ nothing can run in the background. Tools that would detach work run to
141
+ completion instead and return the output in their result: `bash` with
142
+ `run_in_background`, `Agent`, `monitor`, and `workflow`. Timers such as
143
+ `schedule_wakeup` and `/loop` never fire in these modes.
144
+
145
+ ## Claude Code tool names
146
+
147
+ Claude Code's tool names are accepted in permission rules and hook
148
+ matchers, and mapped to One Code's names. Case is ignored.
149
+
150
+ | Claude Code | One Code |
151
+ |---|---|
152
+ | `Bash` | `bash` |
153
+ | `Read`, `Write`, `Edit` | `read`, `write`, `edit` |
154
+ | `Grep`, `Glob`, `LS` | `grep`, `find`, `ls` |
155
+ | `NotebookEdit` | `notebook_edit` |
156
+ | `WebFetch`, `WebSearch` | `web_fetch`, `web_search` |
157
+ | `Task`, `Agent` | `Agent` |
158
+ | `SendMessage` | `SendMessage` |
159
+ | `ListAgents` | `list_agents` |
160
+ | `Skill` | `skill` |
161
+ | `ToolSearch` | `tool_search` |
162
+ | `AskUserQuestion` | `ask_user_question` |
163
+ | `Workflow` | `workflow` |
164
+ | `TaskCreate`, `TaskGet`, `TaskList`, `TaskUpdate` | `task_create`, `task_get`, `task_list`, `task_update` |
165
+ | `TodoWrite` | `task_create` |
166
+ | `TaskOutput`, `TaskStop` | `task_output`, `task_stop` |
167
+ | `Monitor` | `monitor` |
168
+ | `ScheduleWakeup` | `schedule_wakeup` |
169
+ | `EnterWorktree`, `ExitWorktree` | `enter_worktree`, `exit_worktree` |
170
+ | `LSP` | `lsp_diagnostics` |
171
+ | `ListMcpResourcesTool`, `ReadMcpResourceTool`, `ReadMcpResourceDirTool` | `list_mcp_resources`, `read_mcp_resource`, `read_mcp_resource_dir` |
172
+ | `mcp__<server>__<tool>` | Unchanged |
173
+
174
+ Claude Code tools that have no One Code equivalent are listed in
175
+ [Differences from Claude Code](differences-from-claude-code.md#tools-that-are-not-provided).
@@ -0,0 +1,175 @@
1
+ # Troubleshooting
2
+
3
+ Symptoms you might hit, what causes them, and what to do.
4
+
5
+ ## Start with the doctor
6
+
7
+ Most setup problems show up in the report:
8
+
9
+ ```bash
10
+ onecode doctor
11
+ ```
12
+
13
+ Inside a session, `/doctor report` shows the same report and `/doctor` has
14
+ the model fix what it finds. See [Check your setup with doctor](doctor.md).
15
+
16
+ ## Installation and startup
17
+
18
+ **`onecode requires Node >= 22.19`.** The bundled app refuses to start on
19
+ older Node, because pi crashes at import time there. Install Node 22.19 or
20
+ later, or use the Homebrew formula, which installs Node for you.
21
+
22
+ **`brew install` says no matching version was found.** Homebrew refuses
23
+ npm packages published less than a day ago. Wait a day after a release, or
24
+ install with `npm install -g @one-ai/one-code` in the meantime.
25
+
26
+ **The banner shows `model none`.** No provider has credentials. Run
27
+ `/login`, or set a provider key such as `ANTHROPIC_API_KEY` before
28
+ launching. Two providers offer free models; see
29
+ [Connect your first provider](providers-and-models.md#connect-your-first-provider).
30
+
31
+ **A warning says the pi version is outside the tested range.** This appears
32
+ on the extension installation when your pi is newer or older than the
33
+ versions One Code was tested against. Most things keep working; if
34
+ something breaks, pin pi to a tested version or use the bundled app, which
35
+ pins pi itself.
36
+
37
+ **`Failed to load extension` on startup.** The extension package and the
38
+ pi it runs on are out of step. On the bundled app, reinstall it. On your own
39
+ pi, run `pi update --extensions`.
40
+
41
+ **The stock pi first-run wizard did not appear.** The bundled app seeds
42
+ pi's settings with the One Code theme, quiet startup, and full-screen mode
43
+ on first run, so there is nothing to ask.
44
+
45
+ ## Permissions
46
+
47
+ **Auto mode is missing from the ctrl+q cycle.** Auto mode needs a model to
48
+ run its classifier. Connect a provider.
49
+
50
+ **ctrl+q does something else.** On Windows and WSL, pi's default
51
+ keybindings also bind ctrl+q, to queue a follow-up message. Rebind one of
52
+ them in pi's keybindings file.
53
+
54
+ **Everything prompts, even in auto mode.** Auto mode pauses after several
55
+ blocked actions in a row and prompts you once; approving resumes it. Also
56
+ check `/permissions`: an `ask` rule prompts in every mode.
57
+
58
+ **An allow rule I wrote has no effect in auto mode.** Broad execution rules
59
+ (`Bash(*)`, wildcarded interpreters, delegation rules) are suspended in
60
+ auto mode so they cannot bypass the classifier. Session grants from the
61
+ approval prompt are also ignored there. Narrow the rule or switch to
62
+ accept-edits or manual mode.
63
+
64
+ **A project's `defaultMode: "auto"` is ignored.** Project-scope settings
65
+ may not select auto or bypass mode. Set it in `~/.claude/settings.json`
66
+ or pass `--permission-mode auto`.
67
+
68
+ **`defaultMode` in `~/.onecode/settings.json` does nothing.** The
69
+ permission loader does not read that key from One Code's file. Use a Claude
70
+ Code settings file or the flag.
71
+
72
+ **The model is denied a write to `.claude/settings.json`.** The auto-mode
73
+ safety floor never lets the model change the gate's own configuration
74
+ unattended. Approve the prompt, or make the edit yourself.
75
+
76
+ **Every action is denied in a `-p` run.** Nothing can prompt in a
77
+ non-interactive run, so anything that would have prompted is denied. Add
78
+ allow rules, or use auto mode with a provider that can run the classifier.
79
+
80
+ ## Auto-mode classifier
81
+
82
+ **Actions are blocked with a message about the classifier being
83
+ unavailable.** The classifier model could not be reached or returned
84
+ nothing usable; the gate fails closed. Check `/auto-mode config` for the
85
+ model in use, and `/doctor report` for provider credentials. Set
86
+ `CC_AUTO_MODE_DEBUG=1` to see each verdict on stderr.
87
+
88
+ **The classifier approves or blocks something it should not.** Choose a
89
+ stronger classifier with `/auto-mode model <provider/model-id>`. A
90
+ Haiku-class classifier is a measurably weaker boundary than a Sonnet-class
91
+ one.
92
+
93
+ ## Models and providers
94
+
95
+ **The subagent model is stale after switching providers.** A saved
96
+ `/subagent` choice from another provider no longer applies. Run
97
+ `/subagent status`, then `/subagent clear` or pick a model on the current
98
+ provider.
99
+
100
+ **Cache-hit in the footer is low.** Changing the model or the effort level
101
+ re-caches the conversation once. A `-p` run and every subagent use the
102
+ provider's short cache lifetime. A persistent low rate on an interactive
103
+ session is worth reporting.
104
+
105
+ **A side call failed on a Gemini or OpenAI model with a message about
106
+ reasoning or temperature.** Some models reject an option others accept.
107
+ One Code avoids these options in its side calls; if you still see this,
108
+ choose a different classifier or reader model and report the model.
109
+
110
+ ## Web search
111
+
112
+ **A warning about Exa's free keyless endpoint.** Your provider has no
113
+ search of its own and you set no Brave or Tavily key, so search fell back
114
+ to a rate-limited endpoint. Set `BRAVE_SEARCH_API_KEY` or
115
+ `TAVILY_API_KEY`, or add the key to `~/.onecode/settings.json`. See
116
+ [Web search](providers-and-models.md#web-search-on-providers-without-a-search-api).
117
+
118
+ ## Language servers
119
+
120
+ **No diagnostics appear after edits.** The language server must be on the
121
+ `PATH` One Code was launched with. Run `/lsp` for each server's status and
122
+ `/doctor report` for install hints.
123
+
124
+ **TypeScript diagnostics fail with a message about `lib/tsserver.js`.**
125
+ TypeScript 7's native compiler does not ship that file, and
126
+ `typescript-language-server` needs it. Install a TypeScript 5.x development
127
+ dependency in the project.
128
+
129
+ ## MCP servers
130
+
131
+ **A server from `.mcp.json` is disabled.** Project servers run only after
132
+ you approve them. Open `/mcp`, select the server, and choose Enable.
133
+
134
+ **A server asks for approval again.** Its command or URL changed since you
135
+ approved it. Approvals are tied to the configuration.
136
+
137
+ **A server needs sign-in.** Open `/mcp`, select the server, and choose
138
+ Authenticate. Tokens are stored under `~/.onecode/mcp-auth/`.
139
+
140
+ ## Hooks
141
+
142
+ **A project's hooks do not run.** They need one-time approval at startup.
143
+ Restart the session and accept, or check
144
+ `~/.onecode/hooks/project-approvals.json`.
145
+
146
+ **A hook blocks a call with no message.** A `PreToolUse` or
147
+ `UserPromptSubmit` hook that times out blocks by design. Set
148
+ `CC_HOOKS_DEBUG=1` to see each dispatch and outcome.
149
+
150
+ ## Sessions
151
+
152
+ **My background shells are gone after `/clear`.** Background work ends
153
+ with the session. The new session lists what was stopped.
154
+
155
+ **A resumed session is in a different permission mode.** Modes are not
156
+ saved with the session. Pass `--permission-mode` or set a default.
157
+
158
+ **The `/effort` level reset after a restart.** `/effort` does not save the
159
+ level. Open pi's `/thinking` picker and press **ctrl+s** to save a startup
160
+ default, or pass `--thinking <level>` at launch.
161
+
162
+ ## Interface
163
+
164
+ **PgUp and PgDn do nothing in a panel.** In full-screen mode pi uses them
165
+ for its scrollback. Use the keys the panel's footer names (**Space** and
166
+ **b** page in the doctor report, for example).
167
+
168
+ **I want pi's own banner, footer, or spinner back.** Set `CC_NO_BANNER=1`,
169
+ `CC_FOOTER=0`, or the other toggles listed in
170
+ [Environment variables](reference.md#environment-variables).
171
+
172
+ ## Getting help
173
+
174
+ Report problems at the project's GitHub repository. Include the output of
175
+ `onecode doctor`, your platform, and the model and provider in use.
@@ -1,64 +1,25 @@
1
1
  /**
2
2
  * ask-user extension — Claude Code's AskUserQuestion.
3
3
  *
4
- * Asks the user up to four multiple-choice questions, each optionally
5
- * multi-select, always with a free-text escape hatch. Questions are presented
6
- * one dialog at a time (pi's UI has no native multi-question widget), and the
7
- * collected answers come back as one tool result.
4
+ * Asks the user up to four multiple-choice questions in one tabbed dialog
5
+ * (widget.ts): a tab per question plus Submit, option previews rendered
6
+ * beside the list, per-question notes, multi-select checkboxes, an inline
7
+ * free-text row, and "Chat about this" to decline and discuss in chat
8
+ * instead. The collected answers come back as one tool result.
8
9
  *
9
10
  * Replaces the community `pi-ask-user`, which asked one question per call and
10
11
  * pulled in a second, conflicting TypeBox.
11
12
  */
12
13
 
13
- import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
14
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
14
15
  import { Type } from "typebox";
15
- import { ccToolRenderers } from "../lib/tui-render.ts";
16
- import {
17
- type Answer,
18
- buildChoices,
19
- DONE_LABEL,
20
- formatAnswers,
21
- OTHER_LABEL,
22
- type Question,
23
- resolveSelection,
24
- stripMark,
25
- } from "./questions.ts";
16
+ import { ccToolRenderers, safeThemeBold, safeThemeInverse, safeThemePaint } from "../lib/tui-render.ts";
17
+ import { type Answer, formatAnswers, formatDecline, type Question } from "./questions.ts";
18
+ import { applyWidgetKey, createWidgetState, decodeWidgetKey, renderWidget, type WidgetResult } from "./widget.ts";
26
19
 
27
20
  const NON_INTERACTIVE =
28
21
  "This session has no interactive UI, so the user cannot be shown a dialog. Ask your question in your reply instead and stop, or proceed under a stated assumption.";
29
22
 
30
- async function askOne(question: Question, ctx: ExtensionContext): Promise<Answer | undefined> {
31
- const selected: string[] = [];
32
- const title = `${question.header}\n\n${question.question}`;
33
-
34
- // Multi-select loops until the user is done; single-select runs once.
35
- for (let round = 0; round < question.options.length + 1; round++) {
36
- const choice = await ctx.ui.select(title, buildChoices(question, selected));
37
- if (choice === undefined) return undefined; // cancelled
38
-
39
- if (choice === DONE_LABEL) break;
40
-
41
- if (choice === OTHER_LABEL) {
42
- const typed = await ctx.ui.input(question.question, "Type your answer");
43
- if (typed === undefined) return undefined;
44
- return { question: question.question, header: question.header, selected: [typed], freeform: true };
45
- }
46
-
47
- const label = resolveSelection(stripMark(choice), question.options);
48
- if (!label) break;
49
-
50
- if (!question.multiSelect) {
51
- return { question: question.question, header: question.header, selected: [label], freeform: false };
52
- }
53
-
54
- const existing = selected.indexOf(label);
55
- if (existing >= 0) selected.splice(existing, 1);
56
- else selected.push(label);
57
- }
58
-
59
- return { question: question.question, header: question.header, selected, freeform: false };
60
- }
61
-
62
23
  export default function askUserExtension(pi: ExtensionAPI) {
63
24
  pi.registerTool({
64
25
  name: "ask_user_question",
@@ -67,7 +28,7 @@ export default function askUserExtension(pi: ExtensionAPI) {
67
28
  title: (a) => a?.questions?.[0]?.question,
68
29
  }),
69
30
  description:
70
- "Ask the user to choose between options when you are blocked on a decision that is genuinely theirs — one you cannot resolve from the request, the code, or a sensible default. Ask up to four questions in one call; each gets a free-text 'Other' choice automatically. Do not use it for choices with an obvious default or for facts you can verify yourself.",
31
+ "Ask the user to choose between options when you are blocked on a decision that is genuinely theirs — one you cannot resolve from the request, the code, or a sensible default. Ask up to four questions in one call; the user answers them in one tabbed dialog and can decline into a chat discussion instead. Options on single-select questions may carry a `preview` — an ASCII mockup, diagram, or code snippet rendered beside the list while the user compares choices; use previews when seeing the alternatives helps (UI layouts, code style variants), never for plain preference questions. Non-preview questions get a free-text 'Other' row automatically, so never add an 'Other' option yourself. If you recommend a specific option, make it the first in the list and end its label with '(Recommended)'. To switch into plan mode use enter_plan_mode (not this tool); once in plan mode, use this tool only to clarify requirements or choose between approaches before finalizing the plan. Do not use this tool for choices with an obvious default or for facts you can verify yourself.",
71
32
  promptSnippet: "Ask the user to decide between options when genuinely blocked",
72
33
  parameters: Type.Object({
73
34
  questions: Type.Array(
@@ -81,6 +42,12 @@ export default function askUserExtension(pi: ExtensionAPI) {
81
42
  Type.Object({
82
43
  label: Type.String({ description: "Short choice text" }),
83
44
  description: Type.Optional(Type.String({ description: "What choosing this means" })),
45
+ preview: Type.Optional(
46
+ Type.String({
47
+ description:
48
+ "Preview shown beside the options while this option is focused: an ASCII mockup, diagram, or code snippet that helps the user compare choices. Single-select questions only.",
49
+ }),
50
+ ),
84
51
  }),
85
52
  { minItems: 2, maxItems: 4 },
86
53
  ),
@@ -93,31 +60,58 @@ export default function askUserExtension(pi: ExtensionAPI) {
93
60
  return { content: [{ type: "text", text: NON_INTERACTIVE }], details: {}, isError: true };
94
61
  }
95
62
 
96
- const answers: Answer[] = [];
97
- for (const question of params.questions as Question[]) {
98
- const answer = await askOne(question, ctx);
99
- if (!answer) {
100
- // Cancelling one question cancels the batch: the remaining answers
101
- // would be meaningless without it.
102
- return {
103
- content: [
104
- {
105
- type: "text",
106
- text:
107
- answers.length > 0
108
- ? `The user cancelled before finishing. Answers so far:\n\n${formatAnswers(answers)}`
109
- : "The user cancelled without answering.",
110
- },
111
- ],
112
- details: { answers, cancelled: true },
113
- };
114
- }
115
- answers.push(answer);
63
+ const questions = params.questions as Question[];
64
+ const outcome = await ctx.ui.custom<WidgetResult>((tui, theme, _keybindings, done) => {
65
+ const style = {
66
+ paint: safeThemePaint(theme),
67
+ bold: safeThemeBold(theme),
68
+ inverse: safeThemeInverse(theme),
69
+ };
70
+ const state = createWidgetState(questions);
71
+ // The output only changes on input or resize, but pi-tui calls
72
+ // render every frame — cache by width, drop the cache per keypress.
73
+ let cache: { width: number; lines: string[] } | undefined;
74
+ return {
75
+ render: (width: number) => {
76
+ if (cache?.width !== width) cache = { width, lines: renderWidget(state, style, width) };
77
+ return cache.lines;
78
+ },
79
+ handleInput: (data: string) => {
80
+ const key = decodeWidgetKey(data);
81
+ if (!key) return;
82
+ const resolved = applyWidgetKey(state, key);
83
+ if (resolved) return done(resolved);
84
+ cache = undefined;
85
+ tui.requestRender();
86
+ },
87
+ invalidate: () => {
88
+ cache = undefined;
89
+ },
90
+ };
91
+ });
92
+
93
+ if (!outcome || outcome.kind === "cancel") {
94
+ const partial = outcome?.kind === "cancel" ? outcome.answers : [];
95
+ const text =
96
+ partial.length > 0
97
+ ? `The user cancelled without submitting. They had made these selections before cancelling (NOT submitted — do not treat them as final answers):\n\n${formatAnswers(partial)}`
98
+ : "The user cancelled without answering.";
99
+ return {
100
+ content: [{ type: "text", text }],
101
+ details: { answers: partial, cancelled: true },
102
+ };
103
+ }
104
+
105
+ if (outcome.kind === "chat") {
106
+ return {
107
+ content: [{ type: "text", text: formatDecline(questions) }],
108
+ details: { answers: [] as Answer[], declined: true },
109
+ };
116
110
  }
117
111
 
118
112
  return {
119
- content: [{ type: "text", text: formatAnswers(answers) }],
120
- details: { answers },
113
+ content: [{ type: "text", text: formatAnswers(outcome.answers) }],
114
+ details: { answers: outcome.answers },
121
115
  };
122
116
  },
123
117
  });
@@ -5,6 +5,8 @@
5
5
  export interface QuestionOption {
6
6
  label: string;
7
7
  description?: string;
8
+ /** Rendered beside the options while this option is focused (single-select only). */
9
+ preview?: string;
8
10
  }
9
11
 
10
12
  export interface Question {
@@ -20,33 +22,8 @@ export interface Answer {
20
22
  selected: string[];
21
23
  /** True when the user typed their own answer instead of picking. */
22
24
  freeform: boolean;
23
- }
24
-
25
- export const OTHER_LABEL = "Other (type your own answer)";
26
- export const DONE_LABEL = "Done selecting";
27
-
28
- /** `label — description`, so the description is visible in a plain select list. */
29
- export function formatOptionLabel(option: QuestionOption): string {
30
- return option.description ? `${option.label} — ${option.description}` : option.label;
31
- }
32
-
33
- /** Maps a chosen display string back to the option label it came from. */
34
- export function resolveSelection(display: string, options: QuestionOption[]): string | undefined {
35
- return options.find((option) => formatOptionLabel(option) === display)?.label;
36
- }
37
-
38
- export function buildChoices(question: Question, alreadySelected: string[] = []): string[] {
39
- const marked = question.options.map((option) => {
40
- const label = formatOptionLabel(option);
41
- return question.multiSelect && alreadySelected.includes(option.label) ? `✓ ${label}` : label;
42
- });
43
- const extras = question.multiSelect ? [DONE_LABEL, OTHER_LABEL] : [OTHER_LABEL];
44
- return [...marked, ...extras];
45
- }
46
-
47
- /** Strips the multi-select tick so the choice can be matched against options. */
48
- export function stripMark(display: string): string {
49
- return display.startsWith("✓ ") ? display.slice(2) : display;
25
+ /** Free-text notes the user attached to this answer. */
26
+ notes?: string;
50
27
  }
51
28
 
52
29
  export function formatAnswers(answers: Answer[]): string {
@@ -54,7 +31,17 @@ export function formatAnswers(answers: Answer[]): string {
54
31
  return answers
55
32
  .map((answer) => {
56
33
  const value = answer.selected.length > 0 ? answer.selected.join(", ") : "(no answer)";
57
- return `${answer.question}\n→ ${value}${answer.freeform ? " (typed by the user)" : ""}`;
34
+ const typed = answer.freeform ? " (typed by the user)" : "";
35
+ const notes = answer.notes ? `\n→ notes: ${answer.notes}` : "";
36
+ return `${answer.question}\n→ ${value}${typed}${notes}`;
58
37
  })
59
38
  .join("\n\n");
60
39
  }
40
+
41
+ /** Tool result when the user picks "Chat about this" instead of answering. */
42
+ export function formatDecline(questions: Question[]): string {
43
+ const list = questions
44
+ .map((q) => `· ${q.question} (${q.options.map((o) => o.label).join(" / ")})`)
45
+ .join("\n");
46
+ return `The user declined to answer and wants to chat about these questions instead:\n\n${list}\n\nAsk them in your reply what they'd like to clarify; don't call ask_user_question again until the discussion resolves it.`;
47
+ }