one-code-extension 0.3.1 → 0.4.1
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.
- package/README.md +214 -147
- package/docs/guide/README.md +1 -0
- package/docs/guide/configuration.md +2 -2
- package/docs/guide/differences-from-claude-code.md +13 -4
- package/docs/guide/hooks.md +14 -2
- package/docs/guide/installation.md +54 -6
- package/docs/guide/permissions-modes-and-auto-mode.md +23 -7
- package/docs/guide/reference.md +5 -2
- package/docs/guide/sessions-and-context.md +18 -0
- package/docs/guide/terminal-interface.md +1 -1
- package/docs/guide/tools.md +24 -2
- package/docs/guide/troubleshooting.md +14 -4
- package/docs/guide/windows.md +189 -0
- package/extensions/auto-mode/actions.ts +3 -1
- package/extensions/auto-mode/paths.ts +21 -23
- package/extensions/auto-mode/safety-floor.ts +44 -6
- package/extensions/auto-mode/shell-analysis.ts +25 -10
- package/extensions/auto-mode/transcript.ts +15 -5
- package/extensions/background/index.ts +83 -34
- package/extensions/background/monitor-batch.ts +7 -5
- package/extensions/background/wakeup.ts +18 -24
- package/extensions/bash/background.ts +19 -10
- package/extensions/bash/guards.ts +36 -16
- package/extensions/bash/index.ts +36 -166
- package/extensions/branding/index.ts +35 -4
- package/extensions/btw/index.ts +207 -0
- package/extensions/btw/panel.ts +179 -0
- package/extensions/btw/prompt.ts +45 -0
- package/extensions/clear/index.ts +15 -0
- package/extensions/compaction/fit.ts +9 -6
- package/extensions/doctor/build.ts +22 -2
- package/extensions/doctor/dependencies.ts +63 -31
- package/extensions/doctor/fix-prompt.ts +12 -4
- package/extensions/doctor/index.ts +1 -0
- package/extensions/doctor/models.ts +2 -1
- package/extensions/doctor/report.ts +2 -3
- package/extensions/doctor/update-lookup.ts +19 -11
- package/extensions/effort/index.ts +2 -1
- package/extensions/footer/footer-line.ts +19 -0
- package/extensions/footer/index.ts +25 -5
- package/extensions/hooks/executor.ts +84 -18
- package/extensions/hooks/index.ts +1 -0
- package/extensions/hooks/matcher.ts +23 -9
- package/extensions/hooks/settings.ts +15 -0
- package/extensions/lib/branch-restore.ts +12 -0
- package/extensions/lib/claude-context.ts +2 -3
- package/extensions/lib/claude-settings.ts +19 -0
- package/extensions/lib/command-launch.ts +71 -0
- package/extensions/lib/deferred.ts +173 -33
- package/extensions/lib/git.ts +16 -0
- package/extensions/lib/keys.ts +38 -0
- package/extensions/lib/local-command.ts +112 -0
- package/extensions/lib/model-facts.generated.json +263 -68
- package/extensions/lib/model-policy.ts +13 -0
- package/extensions/lib/model-tier.ts +16 -5
- package/extensions/lib/notifications.ts +547 -53
- package/extensions/lib/paths.ts +130 -2
- package/extensions/lib/pi-ai-estimate.ts +57 -26
- package/extensions/lib/pi-version.ts +1 -1
- package/extensions/lib/process-tree.ts +131 -5
- package/extensions/lib/reminders.ts +80 -27
- package/extensions/lib/scratchpad.ts +11 -10
- package/extensions/lib/shell-spawn.ts +298 -0
- package/extensions/lib/shell-tool.ts +252 -0
- package/extensions/lib/shell-tools.ts +13 -0
- package/extensions/lib/side-call.ts +76 -0
- package/extensions/lib/tui-render.ts +62 -11
- package/extensions/lib/update-check.mjs +155 -0
- package/extensions/lib/usage-bus.ts +1 -1
- package/extensions/lib/which.ts +62 -0
- package/extensions/lib/worktree-channel.ts +18 -0
- package/extensions/lib/worktree-isolation.ts +2 -1
- package/extensions/lsp/client.ts +14 -3
- package/extensions/lsp/index.ts +12 -5
- package/extensions/lsp/install-hints.ts +33 -3
- package/extensions/lsp/plugin-servers.ts +2 -2
- package/extensions/lsp/servers.ts +29 -7
- package/extensions/mcp/index.ts +3 -2
- package/extensions/memory/entries.ts +9 -6
- package/extensions/memory/index.ts +3 -2
- package/extensions/memory/open-external.ts +4 -1
- package/extensions/model-default/index.ts +21 -2
- package/extensions/permissions/index.ts +57 -28
- package/extensions/permissions/matcher.ts +120 -33
- package/extensions/permissions/modes.ts +14 -6
- package/extensions/permissions/powershell-rules.ts +549 -0
- package/extensions/permissions/session-grant.ts +9 -9
- package/extensions/plugins/index.ts +3 -2
- package/extensions/plugins/install/install.ts +1 -1
- package/extensions/powershell/description.ts +139 -0
- package/extensions/powershell/guards.ts +91 -0
- package/extensions/powershell/index.ts +89 -0
- package/extensions/powershell/policy.ts +91 -0
- package/extensions/recap/index.ts +10 -24
- package/extensions/recap/prompt.ts +3 -3
- package/extensions/session-title/index.ts +120 -0
- package/extensions/session-title/title.ts +111 -0
- package/extensions/skill/index.ts +40 -18
- package/extensions/skill/invoke.ts +1 -0
- package/extensions/subagents/hand-back-review.ts +10 -12
- package/extensions/subagents/index.ts +221 -78
- package/extensions/subagents/model-select.ts +75 -7
- package/extensions/system-prompt/environment.ts +14 -1
- package/extensions/system-reminder/index.ts +9 -0
- package/extensions/tasks/index.ts +2 -1
- package/extensions/tool-search/index.ts +41 -20
- package/extensions/workflow/agent-session.ts +6 -4
- package/extensions/workflow/index.ts +28 -5
- package/extensions/worktree/guards.ts +5 -4
- package/extensions/worktree/index.ts +15 -2
- package/extensions/worktree/rewrite.ts +17 -0
- package/package.json +9 -5
- package/types/app.d.ts +18 -2
|
@@ -8,14 +8,17 @@ fits how you already work.
|
|
|
8
8
|
| You | Install | What you get |
|
|
9
9
|
|---|---|---|
|
|
10
10
|
| New to this, or you want the simplest setup | `npm install -g @one-ai/one-code` | The bundled app: its own `onecode` command, a pinned version of the pi coding agent inside it, and its state kept in `~/.onecode`. It coexists with any `pi` you already have. |
|
|
11
|
+
| On Windows without Node.js | `powershell -c "irm https://raw.githubusercontent.com/IsuruMaduranga/one-code/master/install.ps1 \| iex"` | The bundled app, with Node.js fetched for you when the machine has none. See [Install on Windows](#install-on-windows). |
|
|
11
12
|
| Already running [pi](https://github.com/earendil-works/pi) | `pi install npm:one-code-extension` | The extensions only. They run on your existing pi. One Code's own state still goes to `~/.onecode`; pi's own files stay under your pi agent directory (`~/.pi/agent`). |
|
|
12
13
|
|
|
13
14
|
## Requirements
|
|
14
15
|
|
|
15
16
|
- Node.js 22.19 or later. The app refuses to start on older versions,
|
|
16
17
|
because pi crashes at import time there.
|
|
17
|
-
- macOS or
|
|
18
|
-
|
|
18
|
+
- macOS, Linux, or Windows. Windows Subsystem for Linux (WSL) works like
|
|
19
|
+
Linux. On native Windows, One Code takes Claude Code's shape: Git for
|
|
20
|
+
Windows is recommended but optional, and PowerShell is the primary shell
|
|
21
|
+
tool. See [Windows](windows.md) for what is verified and what isn't.
|
|
19
22
|
- `git`. Optional: `rg` (ripgrep) for faster search, the GitHub CLI for the
|
|
20
23
|
pull-request marker in the footer, and a language server for your
|
|
21
24
|
language (see
|
|
@@ -38,6 +41,46 @@ The first run also seeds pi's settings under `~/.onecode/agent/` with the
|
|
|
38
41
|
`onecode` theme, quiet startup, and full-screen mode. It never overrides a
|
|
39
42
|
value you change later.
|
|
40
43
|
|
|
44
|
+
## Install on Windows
|
|
45
|
+
|
|
46
|
+
Open Windows Terminal or PowerShell and run:
|
|
47
|
+
|
|
48
|
+
```powershell
|
|
49
|
+
powershell -c "irm https://raw.githubusercontent.com/IsuruMaduranga/one-code/master/install.ps1 | iex"
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The script looks for Node.js 22.19 or later on your PATH. When there is
|
|
53
|
+
none, it downloads the current Node LTS for your CPU from nodejs.org as a
|
|
54
|
+
zip, checks it against nodejs.org's published checksums, unpacks it under
|
|
55
|
+
`%LOCALAPPDATA%\onecode\node`, and adds that folder to your user PATH.
|
|
56
|
+
Nothing is installed system-wide and no Windows installer runs. It then
|
|
57
|
+
runs `npm install -g @one-ai/one-code` and makes sure the `onecode` command
|
|
58
|
+
is on your PATH. Open a new terminal afterwards so it sees the PATH change.
|
|
59
|
+
|
|
60
|
+
The script also tells you when `git` is missing. One Code runs without it,
|
|
61
|
+
but Git for Windows gives you the branch in the footer, `/init`, worktrees,
|
|
62
|
+
and a bash tool for the model next to PowerShell. Install it with
|
|
63
|
+
`winget install --id Git.Git -e`, or set `ONECODE_INSTALL_GIT=1` before
|
|
64
|
+
running the script to have it do that for you.
|
|
65
|
+
|
|
66
|
+
If you already have Node.js 22.19 or later, the plain npm command works the
|
|
67
|
+
same on Windows as anywhere else:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
npm install -g @one-ai/one-code
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The script's knobs are environment variables, because a piped script
|
|
74
|
+
cannot take parameters: `ONECODE_INSTALL_NODE=1` downloads the standalone
|
|
75
|
+
Node even when one exists, `ONECODE_NODE_VERSION` pins the version it
|
|
76
|
+
downloads, and `ONECODE_NO_PATH_UPDATE=1` leaves your PATH alone and prints
|
|
77
|
+
what to add. Read the script before running it if you like; it is the
|
|
78
|
+
`install.ps1` at the root of the repository.
|
|
79
|
+
|
|
80
|
+
Windows Subsystem for Linux (WSL) is Linux: use the npm or Homebrew route
|
|
81
|
+
inside the distribution. For what works on native Windows, see
|
|
82
|
+
[Windows](windows.md).
|
|
83
|
+
|
|
41
84
|
## Install with Homebrew
|
|
42
85
|
|
|
43
86
|
Homebrew installs Node for you, so this route has no separate Node step:
|
|
@@ -59,7 +102,7 @@ pi install npm:one-code-extension
|
|
|
59
102
|
```
|
|
60
103
|
|
|
61
104
|
Use `pi` in place of `onecode` for every command in this guide. The
|
|
62
|
-
extension is tested against pi 0.83 through 0.
|
|
105
|
+
extension is tested against pi 0.83 through 0.86 and warns at startup when
|
|
63
106
|
your pi is outside that range. Full-screen mode is opt-in on your own pi;
|
|
64
107
|
see [Full-screen mode and themes](configuration.md#full-screen-mode-and-themes).
|
|
65
108
|
|
|
@@ -102,7 +145,10 @@ npm install -g @one-ai/one-code # npm installs
|
|
|
102
145
|
brew upgrade onecode # Homebrew installs
|
|
103
146
|
```
|
|
104
147
|
|
|
105
|
-
|
|
148
|
+
A Homebrew install sees the notice a day after the npm release, because
|
|
149
|
+
Homebrew refuses packages younger than that and `brew upgrade` would find
|
|
150
|
+
nothing sooner. Set `ONECODE_NO_UPDATE_CHECK=1` to skip the check;
|
|
151
|
+
`--offline` skips it too.
|
|
106
152
|
On your own pi, update with `pi update --extensions`.
|
|
107
153
|
|
|
108
154
|
Both packages are released together with the same version number.
|
|
@@ -114,8 +160,10 @@ npm uninstall -g @one-ai/one-code # or: brew uninstall onecode
|
|
|
114
160
|
rm -rf ~/.onecode # One Code's state, including pi's under the app
|
|
115
161
|
```
|
|
116
162
|
|
|
117
|
-
|
|
118
|
-
|
|
163
|
+
If the Windows script fetched Node.js for you, delete `%LOCALAPPDATA%\onecode`
|
|
164
|
+
too and remove that folder from your user PATH. On your own pi, run
|
|
165
|
+
`pi remove one-code-extension` (or remove the package entry from pi's
|
|
166
|
+
settings). Removing `~/.onecode` deletes One Code's
|
|
119
167
|
settings, approvals, plan files, and, under the bundled app, pi's sessions
|
|
120
168
|
and credentials. Memory files stay in `~/.claude/projects/`, because they
|
|
121
169
|
are shared with Claude Code.
|
|
@@ -83,6 +83,18 @@ contains command substitution (`$(…)` or backticks), `eval`, `exec`, a pipe
|
|
|
83
83
|
into an interpreter, or a base64 decode is never covered by a prefix or
|
|
84
84
|
wildcard `allow` rule.
|
|
85
85
|
|
|
86
|
+
### PowerShell rule patterns
|
|
87
|
+
|
|
88
|
+
`PowerShell(...)` rules have the same shape and follow Claude Code's
|
|
89
|
+
PowerShell matching: aliases are canonicalized on both sides
|
|
90
|
+
(`PowerShell(Remove-Item:*)` catches `rm`, `del`, and `ri`), cmdlet names
|
|
91
|
+
are case-insensitive, a line is split on `|`, `;`, `&&`, `||`, and newlines
|
|
92
|
+
outside quotes and here-strings, an `allow` rule must cover every statement,
|
|
93
|
+
and a `deny` or `ask` rule fires on any statement. A `$(…)` subexpression, a
|
|
94
|
+
backtick escape, a script block, the `&`/`.` call operators,
|
|
95
|
+
`Invoke-Expression`, or an encoded command keeps a wildcard `allow` from
|
|
96
|
+
applying. Details in [Windows](windows.md#permission-rules).
|
|
97
|
+
|
|
86
98
|
### Add a rule during a session
|
|
87
99
|
|
|
88
100
|
To add an allow rule for the current repository, run:
|
|
@@ -120,10 +132,10 @@ stops risky ones, so you're not prompted for every step.
|
|
|
120
132
|
The current badge appears in the banner and is announced when the mode
|
|
121
133
|
changes.
|
|
122
134
|
|
|
123
|
-
### Cycle modes with ctrl+q
|
|
135
|
+
### Cycle modes with ctrl+q (alt+m on Windows and WSL)
|
|
124
136
|
|
|
125
|
-
Press **ctrl+q** to cycle through manual, accept edits, plan, and auto.
|
|
126
|
-
Two modes join the cycle only under certain conditions:
|
|
137
|
+
Press **ctrl+q** to cycle through manual, accept edits, plan, and auto. On
|
|
138
|
+
Windows and WSL the key is **alt+m**. Two modes join the cycle only under certain conditions:
|
|
127
139
|
|
|
128
140
|
- **Auto** appears only when a model that can run the classifier is
|
|
129
141
|
available. With no provider connected, the cycle skips it.
|
|
@@ -134,8 +146,9 @@ flag or a settings file.
|
|
|
134
146
|
|
|
135
147
|
Claude Code cycles modes with shift+tab. One Code can't use that key
|
|
136
148
|
because pi reserves it for the reasoning-effort dial. On Windows and WSL,
|
|
137
|
-
pi's own default keybindings
|
|
138
|
-
|
|
149
|
+
pi's own default keybindings use ctrl+q to queue a follow-up message, so
|
|
150
|
+
One Code cycles modes with alt+m there instead. The footer badge and the
|
|
151
|
+
startup hints name whichever key applies on your machine.
|
|
139
152
|
|
|
140
153
|
### Choose the starting mode
|
|
141
154
|
|
|
@@ -216,7 +229,10 @@ Reads and edits are confined to the working directory by default:
|
|
|
216
229
|
mode, and is denied in don't-ask mode.
|
|
217
230
|
- Accept-edits mode approves edits only inside the working directory.
|
|
218
231
|
- The harness's own session directories count as inside: the auto-memory
|
|
219
|
-
folder, the session scratchpad, persisted tool output,
|
|
232
|
+
folder, the session scratchpad, persisted tool output, the plan file, and
|
|
233
|
+
this project's own session transcripts (with auto mode's decision log next
|
|
234
|
+
to them), which is what `/doctor` reads. Other projects' transcripts are
|
|
235
|
+
outside, as they are for Claude Code.
|
|
220
236
|
|
|
221
237
|
Paths are compared after resolving symlinks, so a symlink inside the project
|
|
222
238
|
that points outside it counts as outside.
|
|
@@ -287,7 +303,7 @@ code. Only read-only tools and edits to one plan file are available.
|
|
|
287
303
|
`plan` agent, and then write the plan.
|
|
288
304
|
- You can read and edit the plan file yourself while the model works.
|
|
289
305
|
|
|
290
|
-
Enter plan mode by cycling to it with **ctrl+q
|
|
306
|
+
Enter plan mode by cycling to it with **ctrl+q** (**alt+m** on Windows and WSL), by starting with
|
|
291
307
|
`--permission-mode plan`, or by asking the model to plan first (it can call
|
|
292
308
|
`enter_plan_mode` itself).
|
|
293
309
|
|
package/docs/guide/reference.md
CHANGED
|
@@ -49,7 +49,7 @@ that explains it.
|
|
|
49
49
|
| `/loop status`, `/loop stop` | Report or end the loop. | |
|
|
50
50
|
| `/tools-deferred` | List deferred tools and whether each is loaded. | [Tools](tools.md#eager-and-deferred-tools) |
|
|
51
51
|
| `/init` | Have the model write a `CLAUDE.md` for the project. | [CLAUDE.md](bring-your-claude-code-setup.md#project-instructions-claudemd) |
|
|
52
|
-
| `/clear` | Start a new session (pi's `/new`). | [Sessions](sessions-and-context.md#start-over) |
|
|
52
|
+
| `/clear` | Start a new session (pi's `/new`); the model is told. | [Sessions](sessions-and-context.md#start-over) |
|
|
53
53
|
| `/exit` | Quit (pi's `/quit`). | |
|
|
54
54
|
|
|
55
55
|
### pi commands
|
|
@@ -85,7 +85,7 @@ These come from pi and are available in every One Code session.
|
|
|
85
85
|
|
|
86
86
|
| Shortcut | What it does |
|
|
87
87
|
|---|---|
|
|
88
|
-
| **ctrl+q** | Cycle the permission mode: manual, accept edits, plan, auto. |
|
|
88
|
+
| **ctrl+q** (**alt+m** on Windows and WSL) | Cycle the permission mode: manual, accept edits, plan, auto. |
|
|
89
89
|
| **↓** (empty editor) | Focus the panel below the editor: background shells, then subagents, then workflows. |
|
|
90
90
|
| **ctrl+x** then **ctrl+k** | Stop every running agent (in the subagent panel). |
|
|
91
91
|
| **x** | Stop the selected agent, shell, or workflow (in a panel). |
|
|
@@ -175,6 +175,7 @@ The `CC_` prefix is historical; `ONECODE_`-prefixed aliases are planned.
|
|
|
175
175
|
| `CC_FOOTER=0` | Keep pi's footer instead of One Code's status line. |
|
|
176
176
|
| `CC_TURN_DURATION=0` | Remove the post-turn timing line. |
|
|
177
177
|
| `CC_RECAP=0` | Turn off the "while you were away" recap. |
|
|
178
|
+
| `CC_SESSION_TITLE=0` | Turn off the automatic session title. |
|
|
178
179
|
| `CC_RECAP_IDLE_MS` | Idle time before a recap, in milliseconds (default 300000). |
|
|
179
180
|
| `CC_COMPACTION=0` | Use pi's compaction summary instead of Claude Code's. |
|
|
180
181
|
| `CC_CLEAR_THINKING=0`, `=1` | Force the thinking-preservation request off or on for Anthropic models. Default: on for `api.anthropic.com` only. |
|
|
@@ -194,6 +195,8 @@ The `CC_` prefix is historical; `ONECODE_`-prefixed aliases are planned.
|
|
|
194
195
|
| `PI_CACHE_RETENTION` | pi's prompt-cache lifetime. One Code sets `long` for interactive sessions unless you set it yourself. |
|
|
195
196
|
| `PI_OFFLINE=1` | Same as `--offline`. |
|
|
196
197
|
| `CLAUDE_CONFIG_DIR` | Where Claude Code's user configuration is read from. |
|
|
198
|
+
| `CLAUDE_CODE_USE_POWERSHELL_TOOL` | `1` turns the `powershell` tool on (the default on Windows), `0` turns it off. Off Windows it needs a `pwsh` on PATH. See [Windows](windows.md). |
|
|
199
|
+
| `CLAUDE_CODE_GIT_BASH_PATH` | The bash that drives the `bash` tool, hooks, and background shells. Also read from the `env` block of `~/.claude/settings.json`; a non-bash binary is ignored with a warning. |
|
|
197
200
|
| `CLAUDE_CODE_SUBAGENT_MODEL` | Default subagent model on a Claude session. |
|
|
198
201
|
| `EDITOR`, `VISUAL` | Editor used by `/memory` (and pi's **ctrl+g**). |
|
|
199
202
|
| `SHELL` | Shell used for commands (default `/bin/sh`). |
|
|
@@ -184,6 +184,24 @@ Not restored:
|
|
|
184
184
|
`/new`. Running background tasks are stopped and listed. The permission
|
|
185
185
|
mode you chose carries over.
|
|
186
186
|
|
|
187
|
+
### What the model learns about your commands
|
|
188
|
+
|
|
189
|
+
As in Claude Code, a slash command you run is recorded for the model: the
|
|
190
|
+
next message you send carries a short note that the command ran, wrapped in a
|
|
191
|
+
caveat telling the model not to act on it. `/clear` opens the new session
|
|
192
|
+
with that note, and a model switch records "Set model to …" the way Claude
|
|
193
|
+
Code does. Commands that One Code cannot observe (pi's own `/compact`,
|
|
194
|
+
`/settings`, `/name`) leave no note.
|
|
195
|
+
|
|
196
|
+
### The session title
|
|
197
|
+
|
|
198
|
+
After your first real message, One Code names the session the way Claude
|
|
199
|
+
Code does: a cheap model on your provider turns the message into a short
|
|
200
|
+
title (Claude Code's own naming prompt), which shows in the terminal tab as
|
|
201
|
+
`One Code - <title> - <folder>` and in the session picker. A name you set
|
|
202
|
+
with `/name` is never overwritten. The call's cost is included in the
|
|
203
|
+
footer's total. Set `CC_SESSION_TITLE=0` to turn it off.
|
|
204
|
+
|
|
187
205
|
## Turn timing
|
|
188
206
|
|
|
189
207
|
After each turn, a dim line such as `✻ Cooked for 5m 12s` reports how long
|
|
@@ -16,7 +16,7 @@ hint line lists the keys worth knowing:
|
|
|
16
16
|
|---|---|
|
|
17
17
|
| `/hotkeys` | pi's full key list. |
|
|
18
18
|
| `shift+tab` | Cycle reasoning effort. |
|
|
19
|
-
| `ctrl+q` | Cycle the permission mode. |
|
|
19
|
+
| `ctrl+q` (`alt+m` on Windows and WSL) | Cycle the permission mode. |
|
|
20
20
|
| `ctrl+t` | Show or hide thinking blocks. |
|
|
21
21
|
| `ctrl+o` | Expand a collapsed tool output. |
|
|
22
22
|
| `/` | List commands. |
|
package/docs/guide/tools.md
CHANGED
|
@@ -53,6 +53,15 @@ notification. A background shell shows up in the shells section of the
|
|
|
53
53
|
panel below the editor. See
|
|
54
54
|
[Tasks and background work](tasks-and-background-work.md).
|
|
55
55
|
|
|
56
|
+
`powershell` is Claude Code's PowerShell tool: on by default on Windows,
|
|
57
|
+
where it becomes the primary shell and `bash` (Git Bash) stays alongside
|
|
58
|
+
when Git for Windows is installed; off elsewhere unless
|
|
59
|
+
`CLAUDE_CODE_USE_POWERSHELL_TOOL=1` and a `pwsh` is on your PATH. It has the
|
|
60
|
+
same `run_in_background`, the same background panel, and its description is
|
|
61
|
+
Claude Code's own, with the edition section (PowerShell 7 or Windows
|
|
62
|
+
PowerShell 5.1) picked from the executable found. Permission rules use
|
|
63
|
+
Claude Code's `PowerShell(...)` form. See [Windows](windows.md).
|
|
64
|
+
|
|
56
65
|
Some command shapes are refused before they run, with a message that steers
|
|
57
66
|
the model to a better route:
|
|
58
67
|
|
|
@@ -140,10 +149,22 @@ and the model is steered to `tool_search`.
|
|
|
140
149
|
|
|
141
150
|
In `-p` and `--mode json` runs the process exits when the turn settles, so
|
|
142
151
|
nothing can run in the background. Tools that would detach work run to
|
|
143
|
-
completion instead and return the output in their result: `bash`
|
|
144
|
-
`run_in_background`, `Agent`, `monitor`, and `workflow`. Timers such as
|
|
152
|
+
completion instead and return the output in their result: `bash` and
|
|
153
|
+
`powershell` with `run_in_background`, `Agent`, `monitor`, and `workflow`. Timers such as
|
|
145
154
|
`schedule_wakeup` and `/loop` never fire in these modes.
|
|
146
155
|
|
|
156
|
+
Give a scripted run its own deadline. One Code has no idle timeout on a
|
|
157
|
+
provider response, so a stream that stalls mid-reply keeps the process
|
|
158
|
+
waiting indefinitely. Wrap the call in your script:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
timeout 180 onecode --mode json -p "…" </dev/null
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The `</dev/null` matters too: in `-p` mode piped standard input is read as
|
|
165
|
+
part of the prompt, so a run inside a shell script that reads its own body
|
|
166
|
+
from stdin would hand the rest of the script to the model.
|
|
167
|
+
|
|
147
168
|
## Claude Code tool names
|
|
148
169
|
|
|
149
170
|
Claude Code's tool names are accepted in permission rules and hook
|
|
@@ -152,6 +173,7 @@ matchers, and mapped to One Code's names. Case is ignored.
|
|
|
152
173
|
| Claude Code | One Code |
|
|
153
174
|
|---|---|
|
|
154
175
|
| `Bash` | `bash` |
|
|
176
|
+
| `PowerShell` | `powershell` |
|
|
155
177
|
| `Read`, `Write`, `Edit` | `read`, `write`, `edit` |
|
|
156
178
|
| `Grep`, `Glob`, `LS` | `grep`, `find`, `ls` |
|
|
157
179
|
| `NotebookEdit` | `notebook_edit` |
|
|
@@ -46,12 +46,12 @@ on first run, so there's nothing to ask.
|
|
|
46
46
|
|
|
47
47
|
## Permissions
|
|
48
48
|
|
|
49
|
-
**Auto mode is missing from the
|
|
49
|
+
**Auto mode is missing from the mode cycle.** Auto mode needs a model to
|
|
50
50
|
run its classifier. Connect a provider.
|
|
51
51
|
|
|
52
|
-
**ctrl+q
|
|
53
|
-
|
|
54
|
-
|
|
52
|
+
**ctrl+q queues a follow-up instead of changing the mode.** On Windows and
|
|
53
|
+
WSL that is pi's own binding for ctrl+q. The mode key there is alt+m; the
|
|
54
|
+
footer badge names it.
|
|
55
55
|
|
|
56
56
|
**Everything prompts, even in auto mode.** Auto mode pauses after several
|
|
57
57
|
blocked actions in a row and prompts you once; approving resumes it. Also
|
|
@@ -171,6 +171,16 @@ for its scrollback. Use the keys the panel's footer names (**Space** and
|
|
|
171
171
|
`CC_FOOTER=0`, or the other toggles listed in
|
|
172
172
|
[Environment variables](reference.md#environment-variables).
|
|
173
173
|
|
|
174
|
+
**On Windows the model has no shell tool, or the wrong one.** With Git for
|
|
175
|
+
Windows installed you get `bash` plus `powershell`; without it, `powershell`
|
|
176
|
+
alone. Set `CLAUDE_CODE_USE_POWERSHELL_TOOL=0` to hide the PowerShell tool
|
|
177
|
+
or `=1` to force it on (it also works on macOS and Linux with a `pwsh` on
|
|
178
|
+
PATH). A startup warning names a `CLAUDE_CODE_GIT_BASH_PATH` that was
|
|
179
|
+
ignored and why. If you report a Windows problem, include the shells on your
|
|
180
|
+
PATH (`where bash`, `where pwsh`, `where powershell`), the value of those two
|
|
181
|
+
variables, and whether the command came through `bash` or `powershell`.
|
|
182
|
+
See [Windows](windows.md).
|
|
183
|
+
|
|
174
184
|
## Getting help
|
|
175
185
|
|
|
176
186
|
Report problems at the project's GitHub repository. Include the output of
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
# Windows
|
|
2
|
+
|
|
3
|
+
[← One Code user guide](README.md)
|
|
4
|
+
|
|
5
|
+
One Code on native Windows works the way Claude Code does today: Git for
|
|
6
|
+
Windows is optional, PowerShell is the primary shell tool when it is
|
|
7
|
+
enabled, and the Windows-specific pieces of your Claude Code configuration
|
|
8
|
+
keep working. This page says what that means in practice and what has and
|
|
9
|
+
hasn't been verified.
|
|
10
|
+
|
|
11
|
+
## Install
|
|
12
|
+
|
|
13
|
+
```powershell
|
|
14
|
+
powershell -c "irm https://raw.githubusercontent.com/IsuruMaduranga/one-code/master/install.ps1 | iex"
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This fetches Node.js when the machine has none and installs the app; with
|
|
18
|
+
Node.js 22.19 or later already present, `npm install -g @one-ai/one-code`
|
|
19
|
+
does the same. Details, and the script's knobs, are in
|
|
20
|
+
[Install on Windows](installation.md#install-on-windows). Git for Windows is
|
|
21
|
+
optional; the section below says what it adds.
|
|
22
|
+
|
|
23
|
+
## Two shell tools
|
|
24
|
+
|
|
25
|
+
| Tool | When it is active | What runs it |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| `powershell` | On by default on Windows. Off elsewhere unless `CLAUDE_CODE_USE_POWERSHELL_TOOL=1`. | `pwsh.exe`, else `powershell.exe`, from your PATH. On macOS and Linux, a `pwsh` on PATH. |
|
|
28
|
+
| `bash` | Whenever a bash exists. | Git Bash (`Program Files\Git\bin\bash.exe`, then `bash.exe` on PATH), or the bash named by `CLAUDE_CODE_GIT_BASH_PATH`. |
|
|
29
|
+
|
|
30
|
+
When both are active, PowerShell is the primary shell: the system prompt says
|
|
31
|
+
so and the model reaches for it first, with bash alongside for POSIX scripts.
|
|
32
|
+
`CLAUDE_CODE_USE_POWERSHELL_TOOL=0` turns the PowerShell tool off and makes
|
|
33
|
+
bash primary again, which is the shape Claude Code had before 2.1.126.
|
|
34
|
+
|
|
35
|
+
A Windows machine with neither Git for Windows nor PowerShell has no shell
|
|
36
|
+
tool. One Code says so at startup, in Claude Code's words, and the fix is to
|
|
37
|
+
install one of them.
|
|
38
|
+
|
|
39
|
+
`CLAUDE_CODE_GIT_BASH_PATH` is read from your environment or from the `env`
|
|
40
|
+
block of `~/.claude/settings.json`. A value that isn't a `bash` or `sh`
|
|
41
|
+
binary is ignored with a warning, as Claude Code does since 2.1.219.
|
|
42
|
+
|
|
43
|
+
## The PowerShell tool
|
|
44
|
+
|
|
45
|
+
The tool the model sees is Claude Code's PowerShell tool: same parameters
|
|
46
|
+
(`command`, `timeout` in milliseconds, `description`, `run_in_background`)
|
|
47
|
+
and Claude Code's own description text, including the edition section. One
|
|
48
|
+
Code picks that section from the executable it found: PowerShell 7 guidance
|
|
49
|
+
for `pwsh`, Windows PowerShell 5.1 guidance for `powershell.exe`. Under the
|
|
50
|
+
hood it is pi's `powershell` tool, run with `-NoProfile -NonInteractive
|
|
51
|
+
-ExecutionPolicy Bypass -Command`, output forced to UTF-8.
|
|
52
|
+
|
|
53
|
+
`run_in_background` works like bash's: a task id comes back at once, output
|
|
54
|
+
spools to the session directory, completion arrives as a notification, and
|
|
55
|
+
the shell shows up in the panel below the editor. A foreground command that
|
|
56
|
+
starts with `Start-Sleep` is refused with a pointer to background runs and
|
|
57
|
+
the monitor tool, and `Read-Host`, `Get-Credential`, `Out-GridView`, `pause`
|
|
58
|
+
and interactive git are refused because the shell has no console to prompt
|
|
59
|
+
on.
|
|
60
|
+
|
|
61
|
+
Inside a worktree session, every PowerShell command is prefixed with a
|
|
62
|
+
`Set-Location` into the worktree, the way bash commands get a `cd`.
|
|
63
|
+
|
|
64
|
+
## Permission rules
|
|
65
|
+
|
|
66
|
+
`PowerShell(...)` rules use the same shape as `Bash(...)` rules and follow
|
|
67
|
+
Claude Code's PowerShell matching:
|
|
68
|
+
|
|
69
|
+
- Aliases are canonicalized on both sides, so `PowerShell(Remove-Item:*)`
|
|
70
|
+
catches `rm -Recurse build`, `del x`, and `ri y`, and
|
|
71
|
+
`PowerShell(Get-ChildItem:*)` allows `ls` and `dir`. Cmdlet names are
|
|
72
|
+
case-insensitive.
|
|
73
|
+
- A command line is split on `|`, `;`, `&&`, `||`, and newlines, outside
|
|
74
|
+
quotes and here-strings. An `allow` rule has to cover every statement; a
|
|
75
|
+
`deny` or `ask` rule fires on any statement, including inside a nested
|
|
76
|
+
`pwsh -Command '…'`.
|
|
77
|
+
- A line with a `$(…)` subexpression, a backtick escape, a script block, the
|
|
78
|
+
`&` or `.` call operators, `Invoke-Expression`, or an encoded command is
|
|
79
|
+
never covered by a wildcard or prefix allow rule. An exact rule for the
|
|
80
|
+
literal line still is.
|
|
81
|
+
- Unbalanced quoting is a parse failure: no allow rule applies and you are
|
|
82
|
+
asked.
|
|
83
|
+
|
|
84
|
+
Blanket rules (`PowerShell`, `PowerShell(*)`, `PowerShell(iex *)`,
|
|
85
|
+
`PowerShell(Start-Process *)`) are suspended in auto mode like their bash
|
|
86
|
+
counterparts. Hook matchers accept `PowerShell`, `Bash|PowerShell`, and
|
|
87
|
+
`Bash,PowerShell`.
|
|
88
|
+
|
|
89
|
+
## Auto mode and plan mode
|
|
90
|
+
|
|
91
|
+
Claude Code's read-only cmdlets run without a prompt or a classifier call:
|
|
92
|
+
`Get-ChildItem`, `Get-Content`, `Get-Item`, `Test-Path`, `Resolve-Path`,
|
|
93
|
+
`Select-String`, `Get-Location`, `Get-Process`, `Get-Service`,
|
|
94
|
+
`Get-FileHash`, `Get-Acl`, `Format-Hex`, `findstr`, `where.exe`, plus
|
|
95
|
+
`Write-Output` and `Write-Host`. One Code adds the pure pipeline cmdlets
|
|
96
|
+
those are usually piped through, `Select-Object`, `Sort-Object`,
|
|
97
|
+
`Measure-Object`, `Group-Object`, `ConvertFrom-Json`, `Out-String` and the
|
|
98
|
+
`Format-*` family, so `Select-String … | Measure-Object` counts as read-only
|
|
99
|
+
too; `Where-Object` and `ForEach-Object` do not, because they take script
|
|
100
|
+
blocks. The check is textual and strict: no
|
|
101
|
+
redirection, no variables, no script blocks, and every path inside the
|
|
102
|
+
project or one of the harness's own session directories (auto-memory, the
|
|
103
|
+
scratchpad, persisted tool output, this project's transcripts). A relative
|
|
104
|
+
path is inside by construction; an absolute or drive-lettered path is
|
|
105
|
+
resolved and checked, so `Select-String -Path C:\src\app\notes.md` runs
|
|
106
|
+
unprompted while `Get-Content C:\Users\you\.ssh\id_rsa` does not. A UNC
|
|
107
|
+
path, `~`, a registry or environment drive, or `..` always takes the
|
|
108
|
+
ordinary route.
|
|
109
|
+
|
|
110
|
+
Everything else goes to the auto-mode classifier. One Code has no PowerShell
|
|
111
|
+
command parser yet, so unlike bash there is no deterministic shortcut for
|
|
112
|
+
in-project deletes: a `Remove-Item` inside the repository is classified, not
|
|
113
|
+
auto-approved. The safety floor still applies. Any PowerShell line that
|
|
114
|
+
names a permission settings file (`.claude/settings.json`,
|
|
115
|
+
`~/.onecode/settings.json`, `.claude.json`, managed settings) stops for you,
|
|
116
|
+
whether it reads or writes.
|
|
117
|
+
|
|
118
|
+
Plan mode allows the read-only cmdlets above and refuses the rest, as it
|
|
119
|
+
does for bash.
|
|
120
|
+
|
|
121
|
+
## Hooks
|
|
122
|
+
|
|
123
|
+
Hooks run in bash where one exists and in PowerShell on a Windows machine
|
|
124
|
+
without Git for Windows. A hook can pick its interpreter with Claude Code's
|
|
125
|
+
`shell` field: `"shell": "powershell"` or `"shell": "bash"`. Timeouts kill
|
|
126
|
+
the whole process tree through `taskkill /T` on Windows. See
|
|
127
|
+
[Hooks](hooks.md#which-shell-runs-a-hook).
|
|
128
|
+
|
|
129
|
+
## Keys
|
|
130
|
+
|
|
131
|
+
pi binds a few of its own shortcuts differently on Windows and WSL, where
|
|
132
|
+
alt+enter and ctrl+shift+letter do not reach the terminal reliably: queue a
|
|
133
|
+
follow-up is ctrl+q instead of alt+enter, fork is ctrl+f, paste is alt+v,
|
|
134
|
+
model selection is alt+p. Because ctrl+q is taken there, One Code cycles
|
|
135
|
+
permission modes with **alt+m** on Windows and WSL (ctrl+q everywhere
|
|
136
|
+
else). The footer badge, the startup hints, and `/doctor` name the key that
|
|
137
|
+
applies on your machine. Everything else in the [terminal reference](reference.md)
|
|
138
|
+
is the same.
|
|
139
|
+
|
|
140
|
+
## Paths and state
|
|
141
|
+
|
|
142
|
+
- One Code's state lives in `%USERPROFILE%\.onecode`; Claude Code's
|
|
143
|
+
configuration is read from `%USERPROFILE%\.claude` (or
|
|
144
|
+
`CLAUDE_CONFIG_DIR`).
|
|
145
|
+
- The scratchpad directory is under `%TEMP%`.
|
|
146
|
+
- The `Shell:` line in the system prompt is the basename of `SHELL`, else
|
|
147
|
+
`COMSPEC`, with `.exe` stripped, the value Claude Code prints.
|
|
148
|
+
- Language servers installed with npm are `.cmd` shims on Windows
|
|
149
|
+
(`typescript-language-server.cmd`). One Code finds them on `PATH` and
|
|
150
|
+
starts them through `cmd.exe`, so a plugin's `.lsp.json` can name the
|
|
151
|
+
command the way it does elsewhere.
|
|
152
|
+
- Auto mode's shell pre-gate and the worktree guards understand Git Bash's
|
|
153
|
+
path spellings inside a command line: `/c/Users/…` is `C:\Users\…`, and
|
|
154
|
+
`/tmp/…` is your temp directory, which Git for Windows mounts there. A
|
|
155
|
+
path rule with a wildcard is spelled with forward slashes
|
|
156
|
+
(`Read(C:/notes/**)` or `Read(//c/notes/**)`), because a backslash before
|
|
157
|
+
`*` is the escape character.
|
|
158
|
+
|
|
159
|
+
## What is verified
|
|
160
|
+
|
|
161
|
+
- The unit suite, including live PowerShell runs, passes on the
|
|
162
|
+
`windows-latest`, `macos-latest`, and `ubuntu-latest` GitHub runners.
|
|
163
|
+
- A real model drives both shell tools on the `windows-latest` runner: the
|
|
164
|
+
bash tool under Git Bash and the PowerShell tool under PowerShell 7, each
|
|
165
|
+
running a command whose output has to come back in the tool result. This
|
|
166
|
+
runs as its own workflow whenever the shell-facing code changes.
|
|
167
|
+
- Drive-letter, backslash, `C:/` and `~` paths in `Read(...)`/`Edit(...)`
|
|
168
|
+
rules, Windows PowerShell 5.1 (edition text, UTF-8 output, no `&&`),
|
|
169
|
+
stopping background PowerShell commands and timed-out hooks, and
|
|
170
|
+
npm-installed language servers all have Windows-only unit tests that run
|
|
171
|
+
on that runner.
|
|
172
|
+
- The PowerShell tool has also been driven through a real model with a
|
|
173
|
+
`pwsh` on macOS, the same way Claude Code's own PowerShell tool was
|
|
174
|
+
captured for reference.
|
|
175
|
+
- An interactive session on a real Windows machine (a Windows Server 2025
|
|
176
|
+
VM, the same kernel as the CI runner): the interface in Windows Terminal,
|
|
177
|
+
`alt+m` mode cycling, a permission prompt, plan mode, the PowerShell tool's
|
|
178
|
+
rendering, a background PowerShell shell with its panel and notification,
|
|
179
|
+
diagnostics through an npm-installed language server, and both `/doctor`
|
|
180
|
+
surfaces, with Git for Windows present and with PowerShell alone. Windows
|
|
181
|
+
10 and 11 desktops have not had the same pass; if you hit something there,
|
|
182
|
+
[Troubleshooting](troubleshooting.md) says what to collect.
|
|
183
|
+
|
|
184
|
+
## Not provided
|
|
185
|
+
|
|
186
|
+
- No PowerShell command parser or pre-gate beyond the read-only list.
|
|
187
|
+
- No sandbox on Windows. Claude Code has none there either.
|
|
188
|
+
- `defaultShell` for the user's own `!` prefix is pi's to handle; One Code
|
|
189
|
+
does not read it.
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
* path auto mode exists to close.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
+
import type { HandBackVerdict } from "../lib/notifications.ts";
|
|
21
|
+
|
|
20
22
|
export const SUBAGENT_ACTIONS_CHANNEL = "one-code:subagent-actions";
|
|
21
23
|
|
|
22
24
|
export interface ChildAction {
|
|
@@ -45,7 +47,7 @@ export interface SubagentActionsPayload {
|
|
|
45
47
|
* synchronously when no review will run, so the emitter never waits for
|
|
46
48
|
* nothing.
|
|
47
49
|
*/
|
|
48
|
-
onReview?: (
|
|
50
|
+
onReview?: (verdict: HandBackVerdict | undefined) => void;
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
/** Per-action and total caps: a long-running child must not blow up the prompt. */
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
* and every caller treats that as "not provably contained".
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import { lstatSync, readlinkSync
|
|
18
|
+
import { lstatSync, readlinkSync } from "node:fs";
|
|
19
19
|
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
20
|
-
import { expandTilde } from "../lib/paths.ts";
|
|
20
|
+
import { comparablePath, expandTilde, gitBashPathToNative, isPathAtOrUnder, tryRealpath } from "../lib/paths.ts";
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Tools whose calls write to a path. Lives here — the lowest shared layer both
|
|
@@ -41,23 +41,8 @@ export function pathArgument(input: Record<string, unknown> | undefined): string
|
|
|
41
41
|
return typeof path === "string" ? path : undefined;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
/**
|
|
45
|
-
|
|
46
|
-
const normalized = resolve(target).replace(/\\/g, "/").replace(/\/+$/, "");
|
|
47
|
-
return process.platform === "linux" ? normalized : normalized.toLowerCase();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function tryRealpath(target: string): string | undefined {
|
|
51
|
-
try {
|
|
52
|
-
return realpathSync.native(target);
|
|
53
|
-
} catch {
|
|
54
|
-
try {
|
|
55
|
-
return realpathSync(target);
|
|
56
|
-
} catch {
|
|
57
|
-
return undefined;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
44
|
+
/** The shared comparison form (lib/paths.ts): `/` separators, case-folded on darwin/win32. */
|
|
45
|
+
const normalize = comparablePath;
|
|
61
46
|
|
|
62
47
|
/**
|
|
63
48
|
* Resolve a path for containment checks, following a symlink leaf that does not
|
|
@@ -99,11 +84,9 @@ export function resolveForContainment(target: string): string | undefined {
|
|
|
99
84
|
}
|
|
100
85
|
}
|
|
101
86
|
|
|
102
|
-
/** True only when `target` is provably at or under `base
|
|
87
|
+
/** True only when `target` is provably at or under `base` (lib/paths.ts `isPathAtOrUnder`, argument order kept for the callers here). */
|
|
103
88
|
export function isWithin(base: string, target: string): boolean {
|
|
104
|
-
|
|
105
|
-
const normalizedTarget = normalize(target);
|
|
106
|
-
return normalizedTarget === normalizedBase || normalizedTarget.startsWith(`${normalizedBase}/`);
|
|
89
|
+
return isPathAtOrUnder(target, base);
|
|
107
90
|
}
|
|
108
91
|
|
|
109
92
|
/**
|
|
@@ -119,3 +102,18 @@ export function toAbsolute(cwd: string, token: string, home: string): string {
|
|
|
119
102
|
if (isAbsolute(token)) return resolve(token);
|
|
120
103
|
return resolve(cwd, token);
|
|
121
104
|
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* {@link toAbsolute} for a token taken from a bash command line. On Windows the
|
|
108
|
+
* bash tool runs Git Bash, whose absolute paths are MSYS spellings — `/c/proj/f`
|
|
109
|
+
* is `C:\proj\f`, `/tmp/f` sits under the user's temp dir — so the token is
|
|
110
|
+
* converted first (lib/paths.ts gitBashPathToNative). `path.resolve` alone reads
|
|
111
|
+
* `/c/proj/f` as `<cwd drive>:\c\proj\f`, which no gate recognises as the
|
|
112
|
+
* project: the error fell towards escalate/prompt, never towards allow, but every
|
|
113
|
+
* in-project write spelled that way went to the classifier. File-tool paths keep
|
|
114
|
+
* `toAbsolute`: pi's read/edit/write resolve them natively, and a gate must
|
|
115
|
+
* judge the path the tool acts on, not the one Git Bash would reach.
|
|
116
|
+
*/
|
|
117
|
+
export function toAbsoluteBash(cwd: string, token: string, home: string): string {
|
|
118
|
+
return toAbsolute(cwd, gitBashPathToNative(token), home);
|
|
119
|
+
}
|