claws-code 0.8.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.
- package/.claude/commands/claws-auto.md +90 -0
- package/.claude/commands/claws-bin.md +28 -0
- package/.claude/commands/claws-cleanup.md +28 -0
- package/.claude/commands/claws-do.md +82 -0
- package/.claude/commands/claws-fix.md +40 -0
- package/.claude/commands/claws-goal.md +111 -0
- package/.claude/commands/claws-help.md +54 -0
- package/.claude/commands/claws-plan.md +103 -0
- package/.claude/commands/claws-report.md +29 -0
- package/.claude/commands/claws-status.md +37 -0
- package/.claude/commands/claws-update.md +32 -0
- package/.claude/commands/claws.md +64 -0
- package/.claude/rules/claws-default-behavior.md +76 -0
- package/.claude/settings.json +112 -0
- package/.claude/settings.local.json +19 -0
- package/.claude/skills/claws-auto-engine/SKILL.md +97 -0
- package/.claude/skills/claws-goal-tracker/SKILL.md +106 -0
- package/.claude/skills/claws-prompt-templates/SKILL.md +203 -0
- package/.claude/skills/claws-wave-lead/SKILL.md +126 -0
- package/.claude/skills/claws-wave-subworker/SKILL.md +60 -0
- package/CHANGELOG.md +1949 -0
- package/LICENSE +21 -0
- package/README.md +420 -0
- package/bin/cli.js +84 -0
- package/cli.js +223 -0
- package/docs/ARCHITECTURE.md +511 -0
- package/docs/event-protocol.md +588 -0
- package/docs/features.md +562 -0
- package/docs/guide.md +891 -0
- package/docs/index.html +716 -0
- package/docs/protocol.md +323 -0
- package/extension/.vscodeignore +15 -0
- package/extension/CHANGELOG.md +1906 -0
- package/extension/LICENSE +21 -0
- package/extension/README.md +137 -0
- package/extension/docs/features.md +424 -0
- package/extension/docs/protocol.md +197 -0
- package/extension/esbuild.mjs +25 -0
- package/extension/icon.png +0 -0
- package/extension/native/.metadata.json +10 -0
- package/extension/native/node-pty/LICENSE +69 -0
- package/extension/native/node-pty/README.md +165 -0
- package/extension/native/node-pty/lib/conpty_console_list_agent.js +16 -0
- package/extension/native/node-pty/lib/conpty_console_list_agent.js.map +1 -0
- package/extension/native/node-pty/lib/eventEmitter2.js +47 -0
- package/extension/native/node-pty/lib/eventEmitter2.js.map +1 -0
- package/extension/native/node-pty/lib/index.js +52 -0
- package/extension/native/node-pty/lib/index.js.map +1 -0
- package/extension/native/node-pty/lib/interfaces.js +7 -0
- package/extension/native/node-pty/lib/interfaces.js.map +1 -0
- package/extension/native/node-pty/lib/shared/conout.js +11 -0
- package/extension/native/node-pty/lib/shared/conout.js.map +1 -0
- package/extension/native/node-pty/lib/terminal.js +190 -0
- package/extension/native/node-pty/lib/terminal.js.map +1 -0
- package/extension/native/node-pty/lib/types.js +7 -0
- package/extension/native/node-pty/lib/types.js.map +1 -0
- package/extension/native/node-pty/lib/unixTerminal.js +346 -0
- package/extension/native/node-pty/lib/unixTerminal.js.map +1 -0
- package/extension/native/node-pty/lib/utils.js +39 -0
- package/extension/native/node-pty/lib/utils.js.map +1 -0
- package/extension/native/node-pty/lib/windowsConoutConnection.js +125 -0
- package/extension/native/node-pty/lib/windowsConoutConnection.js.map +1 -0
- package/extension/native/node-pty/lib/windowsPtyAgent.js +320 -0
- package/extension/native/node-pty/lib/windowsPtyAgent.js.map +1 -0
- package/extension/native/node-pty/lib/windowsTerminal.js +199 -0
- package/extension/native/node-pty/lib/windowsTerminal.js.map +1 -0
- package/extension/native/node-pty/lib/worker/conoutSocketWorker.js +22 -0
- package/extension/native/node-pty/lib/worker/conoutSocketWorker.js.map +1 -0
- package/extension/native/node-pty/package.json +64 -0
- package/extension/native/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
- package/extension/native/node-pty/prebuilds/darwin-x64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty/OpenConsole.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty/conpty.dll +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/conpty_console_list.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/winpty-agent.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-arm64/winpty.dll +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty/OpenConsole.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty/conpty.dll +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/conpty_console_list.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/pty.node +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/winpty-agent.exe +0 -0
- package/extension/native/node-pty/prebuilds/win32-x64/winpty.dll +0 -0
- package/extension/package-lock.json +605 -0
- package/extension/package.json +343 -0
- package/extension/scripts/bundle-native.mjs +104 -0
- package/extension/scripts/deploy-dev.mjs +60 -0
- package/extension/src/ansi-strip.ts +52 -0
- package/extension/src/backends/vscode/claws-pty.ts +483 -0
- package/extension/src/backends/vscode/status-bar.ts +99 -0
- package/extension/src/backends/vscode/vscode-backend.ts +282 -0
- package/extension/src/capture-store.ts +125 -0
- package/extension/src/event-log.ts +629 -0
- package/extension/src/event-schemas.ts +478 -0
- package/extension/src/extension.js +492 -0
- package/extension/src/extension.ts +873 -0
- package/extension/src/lifecycle-engine.ts +60 -0
- package/extension/src/lifecycle-rules.ts +171 -0
- package/extension/src/lifecycle-store.ts +506 -0
- package/extension/src/peer-registry.ts +176 -0
- package/extension/src/pipeline-registry.ts +82 -0
- package/extension/src/platform.ts +64 -0
- package/extension/src/protocol.ts +532 -0
- package/extension/src/server-config.ts +98 -0
- package/extension/src/server.ts +2210 -0
- package/extension/src/task-registry.ts +51 -0
- package/extension/src/terminal-backend.ts +211 -0
- package/extension/src/terminal-manager.ts +395 -0
- package/extension/src/topic-registry.ts +70 -0
- package/extension/src/topic-utils.ts +46 -0
- package/extension/src/transport.ts +45 -0
- package/extension/src/uninstall-cleanup.ts +232 -0
- package/extension/src/wave-registry.ts +314 -0
- package/extension/src/websocket-transport.ts +153 -0
- package/extension/tsconfig.json +23 -0
- package/lib/capabilities.js +145 -0
- package/lib/dry-run.js +43 -0
- package/lib/install.js +1018 -0
- package/lib/mcp-setup.js +92 -0
- package/lib/platform.js +240 -0
- package/lib/preflight.js +152 -0
- package/lib/shell-hook.js +343 -0
- package/lib/uninstall.js +162 -0
- package/lib/verify.js +166 -0
- package/mcp_server.js +3529 -0
- package/package.json +48 -0
- package/rules/claws-default-behavior.md +72 -0
- package/scripts/_helpers/atomic-file.mjs +137 -0
- package/scripts/_helpers/fix-repair.js +64 -0
- package/scripts/_helpers/json-safe.mjs +218 -0
- package/scripts/bump-version.sh +84 -0
- package/scripts/codegen/gen-docs.mjs +61 -0
- package/scripts/codegen/gen-json-schema.mjs +62 -0
- package/scripts/codegen/gen-mcp-tools.mjs +358 -0
- package/scripts/codegen/gen-types.mjs +172 -0
- package/scripts/codegen/index.mjs +42 -0
- package/scripts/dev-hooks/check-extension-dirs.js +77 -0
- package/scripts/dev-hooks/check-open-claws-terminals.js +70 -0
- package/scripts/dev-hooks/check-stale-main.js +55 -0
- package/scripts/dev-hooks/check-tag-pushed.js +51 -0
- package/scripts/dev-hooks/check-tag-vs-main.js +56 -0
- package/scripts/dev-vsix-install.sh +60 -0
- package/scripts/fix.sh +702 -0
- package/scripts/gen-client-types.mjs +81 -0
- package/scripts/git-hooks/pre-commit +31 -0
- package/scripts/hooks/lifecycle-state.js +61 -0
- package/scripts/hooks/package.json +4 -0
- package/scripts/hooks/post-tool-use-claws.js +292 -0
- package/scripts/hooks/pre-bash-no-verify-block.js +72 -0
- package/scripts/hooks/pre-tool-use-claws.js +206 -0
- package/scripts/hooks/session-start-claws.js +97 -0
- package/scripts/hooks/stop-claws.js +88 -0
- package/scripts/inject-claude-md.js +205 -0
- package/scripts/inject-dev-hooks.js +96 -0
- package/scripts/inject-global-claude-md.js +140 -0
- package/scripts/inject-settings-hooks.js +370 -0
- package/scripts/install.ps1 +146 -0
- package/scripts/install.sh +1729 -0
- package/scripts/monitor-arm-watch.js +155 -0
- package/scripts/rebuild-node-pty.sh +245 -0
- package/scripts/report.sh +232 -0
- package/scripts/shell-hook.fish +164 -0
- package/scripts/shell-hook.ps1 +33 -0
- package/scripts/shell-hook.sh +232 -0
- package/scripts/stream-events.js +399 -0
- package/scripts/terminal-wrapper.sh +36 -0
- package/scripts/test-enforcement.sh +132 -0
- package/scripts/test-install.sh +174 -0
- package/scripts/test-installer-parity.sh +135 -0
- package/scripts/test-template-enforcement.sh +76 -0
- package/scripts/uninstall.sh +143 -0
- package/scripts/update.sh +337 -0
- package/scripts/verify-release.sh +323 -0
- package/scripts/verify-wrapped.sh +194 -0
- package/templates/CLAUDE.global.md +135 -0
- package/templates/CLAUDE.project.md +37 -0
package/docs/features.md
ADDED
|
@@ -0,0 +1,562 @@
|
|
|
1
|
+
# Claws — Complete Feature Reference
|
|
2
|
+
|
|
3
|
+
Everything the extension can do, in depth. For the quick overview, see the [README](../README.md).
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Table of Contents
|
|
8
|
+
|
|
9
|
+
- [Terminal Discovery](#terminal-discovery)
|
|
10
|
+
- [Terminal Creation](#terminal-creation)
|
|
11
|
+
- [Wrapped Terminals](#wrapped-terminals)
|
|
12
|
+
- [Text Injection (send)](#text-injection)
|
|
13
|
+
- [Command Execution (exec)](#command-execution)
|
|
14
|
+
- [Pty Log Reading (readLog)](#pty-log-reading)
|
|
15
|
+
- [Event Streaming (poll)](#event-streaming)
|
|
16
|
+
- [Introspection (introspect)](#introspection)
|
|
17
|
+
- [Terminal Profile — Dropdown Integration](#terminal-profile)
|
|
18
|
+
- [Safety Gate](#safety-gate)
|
|
19
|
+
- [Bracketed Paste](#bracketed-paste)
|
|
20
|
+
- [Command Palette](#command-palette)
|
|
21
|
+
- [Keybindings](#keybindings)
|
|
22
|
+
- [Status Bar Item](#status-bar-item)
|
|
23
|
+
- [Uninstall Cleanup](#uninstall-cleanup)
|
|
24
|
+
- [Configuration Reference](#configuration-reference)
|
|
25
|
+
- [Socket Server Internals](#socket-server-internals)
|
|
26
|
+
- [Cross-Device Control](#cross-device-control)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Terminal Discovery
|
|
31
|
+
|
|
32
|
+
**Command**: `list`
|
|
33
|
+
|
|
34
|
+
Returns every open VS Code terminal with full metadata:
|
|
35
|
+
|
|
36
|
+
| Field | Type | Description |
|
|
37
|
+
|---|---|---|
|
|
38
|
+
| `id` | string | Stable numeric ID, persists for the terminal's lifetime |
|
|
39
|
+
| `name` | string | Terminal display name (user-set or auto-assigned) |
|
|
40
|
+
| `pid` | number | Shell process ID |
|
|
41
|
+
| `hasShellIntegration` | boolean | Whether VS Code's shell integration is active |
|
|
42
|
+
| `active` | boolean | Whether this is the currently focused terminal |
|
|
43
|
+
| `logPath` | string or null | Absolute path to the pty log file (null if not wrapped) |
|
|
44
|
+
|
|
45
|
+
**Why stable IDs matter**: VS Code's terminal API identifies terminals by object reference internally. Claws assigns each terminal a monotonically increasing numeric ID at first sight and holds it in a `WeakMap`. The ID survives terminal renames, focus changes, and extension reloads within the same VS Code session. External clients use this ID for every subsequent command — no fragile name-matching.
|
|
46
|
+
|
|
47
|
+
**Example response**:
|
|
48
|
+
```json
|
|
49
|
+
{
|
|
50
|
+
"ok": true,
|
|
51
|
+
"terminals": [
|
|
52
|
+
{"id": "1", "name": "zsh", "pid": 45123, "hasShellIntegration": true, "active": false, "logPath": null},
|
|
53
|
+
{"id": "3", "name": "build-worker", "pid": 45890, "hasShellIntegration": false, "active": true, "logPath": "/project/.claws/terminals/claws-3.log"}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Terminal Creation
|
|
61
|
+
|
|
62
|
+
**Command**: `create`
|
|
63
|
+
|
|
64
|
+
Opens a new VS Code integrated terminal with full control over its configuration.
|
|
65
|
+
|
|
66
|
+
| Parameter | Type | Default | Description |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `name` | string | `"claws"` | Display name in the terminal panel |
|
|
69
|
+
| `cwd` | string | workspace root | Working directory |
|
|
70
|
+
| `wrapped` | boolean | `false` | Wrap in `script(1)` for pty logging |
|
|
71
|
+
| `show` | boolean | `true` | Show the terminal panel and focus it |
|
|
72
|
+
| `shellPath` | string | system default | Override the shell binary |
|
|
73
|
+
| `env` | object | `{}` | Additional environment variables |
|
|
74
|
+
|
|
75
|
+
**Returns**: `{ id, logPath }` — the new terminal's stable ID and (if wrapped) the absolute path to its pty log file.
|
|
76
|
+
|
|
77
|
+
**Terminal naming**: the `name` parameter sets the tab label in VS Code's terminal panel. Use descriptive names for orchestration (`"lint-worker"`, `"test-runner"`, `"ai-session-1"`) so you can identify terminals visually.
|
|
78
|
+
|
|
79
|
+
**Working directory**: defaults to the workspace root. Set `cwd` to any absolute path to start the terminal elsewhere — useful for monorepo setups where different workers operate in different packages.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Wrapped Terminals
|
|
84
|
+
|
|
85
|
+
The core innovation. A wrapped terminal runs your shell inside `script(1)`:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
VS Code Terminal Panel
|
|
89
|
+
└── script(1) process
|
|
90
|
+
└── /bin/zsh (your actual shell)
|
|
91
|
+
└── whatever you run (claude, npm, vim, etc.)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`script(1)` is a standard Unix utility (ships with macOS and Linux) that records everything that flows through a pseudo-terminal to a file. Claws sets the output file to `.claws/terminals/claws-<id>.log` and passes it via the `CLAWS_TERM_LOG` environment variable.
|
|
95
|
+
|
|
96
|
+
### What gets captured
|
|
97
|
+
|
|
98
|
+
Everything. Every byte that the terminal renders:
|
|
99
|
+
|
|
100
|
+
- Shell prompts and command echoes
|
|
101
|
+
- stdout and stderr from every command
|
|
102
|
+
- Interactive TUI rendering (Claude Code's Ink framework, vim's ncurses, htop's dashboard)
|
|
103
|
+
- ANSI escape sequences (colors, cursor movement, screen clearing)
|
|
104
|
+
- Control characters
|
|
105
|
+
|
|
106
|
+
### What you get back (after ANSI stripping)
|
|
107
|
+
|
|
108
|
+
Clean, readable text. Claws strips ANSI CSI sequences (`\e[...m`, `\e[...H`, etc.), OSC sequences (`\e]...BEL`), and control characters (`\x00-\x1f` except `\n` and `\t`). The result is what a human would read if they were watching the terminal.
|
|
109
|
+
|
|
110
|
+
### Visual impact
|
|
111
|
+
|
|
112
|
+
Zero. A wrapped terminal looks, feels, and behaves identically to a regular terminal. The `script(1)` layer adds no visible latency, no changed prompts, no extra processes in the shell's job table. The user cannot tell the difference unless they check for the `CLAWS_WRAPPED=1` environment variable.
|
|
113
|
+
|
|
114
|
+
### Log buffering
|
|
115
|
+
|
|
116
|
+
`script(1)` buffers output before writing to disk. On macOS with the default settings (no `-F` flag), there's a ~1-2 second delay before new content appears in the log file. This is intentional — aggressive flushing (`-F` flag) causes visual corruption in Ink-based TUI renderers (like Claude Code) by splitting their atomic frame updates across flush boundaries.
|
|
117
|
+
|
|
118
|
+
### Creating wrapped terminals
|
|
119
|
+
|
|
120
|
+
Three ways:
|
|
121
|
+
|
|
122
|
+
1. **From the dropdown**: Click the arrow next to `+` in the terminal panel → "Claws Wrapped Terminal"
|
|
123
|
+
2. **From code**: `client.create("name", wrapped=True)`
|
|
124
|
+
3. **From the socket**: `{"cmd": "create", "name": "name", "wrapped": true}`
|
|
125
|
+
|
|
126
|
+
### The wrapper script
|
|
127
|
+
|
|
128
|
+
Located at `scripts/terminal-wrapper.sh`. It:
|
|
129
|
+
|
|
130
|
+
1. Creates the log directory if missing
|
|
131
|
+
2. Truncates the log file (fresh start)
|
|
132
|
+
3. Sets `CLAWS_WRAPPED=1` in the environment
|
|
133
|
+
4. Exec-replaces itself with `script -q "$CLAWS_TERM_LOG" /bin/zsh -il`
|
|
134
|
+
|
|
135
|
+
The script is resolved at runtime: Claws checks for a workspace-local `scripts/terminal-wrapper.sh` first, then falls back to the extension-bundled copy.
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Text Injection
|
|
140
|
+
|
|
141
|
+
**Command**: `send`
|
|
142
|
+
|
|
143
|
+
Sends text into any terminal's input stream. This is equivalent to a human typing — the text appears at whatever input cursor is active (shell prompt, TUI input field, REPL prompt).
|
|
144
|
+
|
|
145
|
+
| Parameter | Type | Default | Description |
|
|
146
|
+
|---|---|---|---|
|
|
147
|
+
| `id` | string | required | Target terminal ID |
|
|
148
|
+
| `text` | string | required | Text to send |
|
|
149
|
+
| `newline` | boolean | `true` | Append Enter (newline) after the text |
|
|
150
|
+
|
|
151
|
+
**Single-line**: `{"cmd": "send", "id": "3", "text": "ls -la"}` — sends `ls -la\n` into the terminal.
|
|
152
|
+
|
|
153
|
+
**Raw keystrokes**: Set `newline: false` and send control characters directly:
|
|
154
|
+
- `\r` — Enter (carriage return, needed for some TUIs)
|
|
155
|
+
- `\x03` — Ctrl+C (interrupt)
|
|
156
|
+
- `\x04` — Ctrl+D (EOF)
|
|
157
|
+
- `\x1a` — Ctrl+Z (suspend)
|
|
158
|
+
- `\x1b` — Escape
|
|
159
|
+
|
|
160
|
+
**Sending to TUI sessions**: When the terminal is running Claude Code, vim, or any interactive program, `send` delivers text to that program's input handler. This is how AI orchestration works — you send a prompt as text into a Claude Code session, and Claude Code processes it as a user turn.
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Command Execution
|
|
165
|
+
|
|
166
|
+
**Command**: `exec`
|
|
167
|
+
|
|
168
|
+
Runs a shell command in a terminal and captures structured output. Unlike `send`, `exec` waits for the command to finish and returns the result.
|
|
169
|
+
|
|
170
|
+
| Parameter | Type | Default | Description |
|
|
171
|
+
|---|---|---|---|
|
|
172
|
+
| `id` | string | auto-created | Target terminal ID |
|
|
173
|
+
| `command` | string | required | Shell command to run |
|
|
174
|
+
| `timeoutMs` | number | `claws.execTimeoutMs` (default `180000`) | Max wait time in milliseconds. Falls back to the hot-reloadable config value when omitted. |
|
|
175
|
+
|
|
176
|
+
**Returns**:
|
|
177
|
+
```json
|
|
178
|
+
{
|
|
179
|
+
"ok": true,
|
|
180
|
+
"terminalId": "3",
|
|
181
|
+
"commandLine": "npm test",
|
|
182
|
+
"output": "PASS src/utils.test.ts\nTests: 5 passed\n",
|
|
183
|
+
"exitCode": 0
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### How file-based capture works
|
|
188
|
+
|
|
189
|
+
Shell integration (`onDidEndTerminalShellExecution`) is unreliable in many terminal configurations. Claws uses a robust alternative:
|
|
190
|
+
|
|
191
|
+
1. Wraps your command: `{ your_command; } > /tmp/claws-exec/abc123.out 2>&1; echo $? > /tmp/claws-exec/abc123.done`
|
|
192
|
+
2. Sends the wrapped command via `send`
|
|
193
|
+
3. Polls for the `.done` marker file
|
|
194
|
+
4. Reads the output file and exit code
|
|
195
|
+
5. Cleans up both temp files
|
|
196
|
+
|
|
197
|
+
This works in **every terminal type** — wrapped, unwrapped, with or without shell integration, bash, zsh, fish.
|
|
198
|
+
|
|
199
|
+
### Auto-created exec terminal
|
|
200
|
+
|
|
201
|
+
If you call `exec` without specifying a terminal `id`, Claws automatically creates (or reuses) a terminal named `claws-work` for execution. This is the simplest path for scripts that just need to run commands.
|
|
202
|
+
|
|
203
|
+
### Timeout handling
|
|
204
|
+
|
|
205
|
+
If the command doesn't produce a `.done` file within `timeoutMs`, `exec` returns an error with whatever partial output was captured. The command itself keeps running in the terminal — Claws doesn't kill it.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Pty Log Reading
|
|
210
|
+
|
|
211
|
+
**Command**: `readLog`
|
|
212
|
+
|
|
213
|
+
Reads a wrapped terminal's pty log file with optional ANSI stripping.
|
|
214
|
+
|
|
215
|
+
| Parameter | Type | Default | Description |
|
|
216
|
+
|---|---|---|---|
|
|
217
|
+
| `id` | string | required | Terminal ID (must be wrapped) |
|
|
218
|
+
| `offset` | number | tail of file | Byte offset to start reading from |
|
|
219
|
+
| `limit` | number | `524288` | Max bytes to read (512KB) |
|
|
220
|
+
| `strip` | boolean | `true` | Strip ANSI escape sequences |
|
|
221
|
+
|
|
222
|
+
**Returns**:
|
|
223
|
+
```json
|
|
224
|
+
{
|
|
225
|
+
"ok": true,
|
|
226
|
+
"bytes": "$ npm test\nPASS src/utils.test.ts\nTests: 5 passed\n$ ",
|
|
227
|
+
"offset": 4096,
|
|
228
|
+
"nextOffset": 4350,
|
|
229
|
+
"totalSize": 4350,
|
|
230
|
+
"truncated": false,
|
|
231
|
+
"logPath": "/project/.claws/terminals/claws-3.log"
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Incremental tailing
|
|
236
|
+
|
|
237
|
+
Use `offset` and `nextOffset` for efficient tailing without re-reading the entire file:
|
|
238
|
+
|
|
239
|
+
```python
|
|
240
|
+
cursor = 0
|
|
241
|
+
while True:
|
|
242
|
+
resp = client._send({"cmd": "readLog", "id": term_id, "offset": cursor})
|
|
243
|
+
if resp["nextOffset"] > cursor:
|
|
244
|
+
print(resp["bytes"]) # new content
|
|
245
|
+
cursor = resp["nextOffset"]
|
|
246
|
+
time.sleep(1)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### ANSI stripping
|
|
250
|
+
|
|
251
|
+
When `strip: true` (default), Claws removes:
|
|
252
|
+
- CSI sequences: `\e[0m`, `\e[31;1m`, `\e[2J`, `\e[H`, etc.
|
|
253
|
+
- OSC sequences: `\e]0;title\a`, `\e]133;...`, etc.
|
|
254
|
+
- Control characters: `\x00`-`\x08`, `\x0b`-`\x1a`, `\x1c`-`\x1f`, `\x7f`
|
|
255
|
+
|
|
256
|
+
Set `strip: false` to get the raw pty output with all escape sequences intact — useful for terminal replay or debugging rendering issues.
|
|
257
|
+
|
|
258
|
+
### Errors
|
|
259
|
+
|
|
260
|
+
- `"terminal X is not wrapped (no log path)"` — you called readLog on an unwrapped terminal. Create it with `wrapped: true`.
|
|
261
|
+
- `"read failed: ..."` — file I/O error (permissions, disk full, etc.)
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Event Streaming
|
|
266
|
+
|
|
267
|
+
**Command**: `poll`
|
|
268
|
+
|
|
269
|
+
Returns shell-integration command-completion events since a cursor position.
|
|
270
|
+
|
|
271
|
+
| Parameter | Type | Default | Description |
|
|
272
|
+
|---|---|---|---|
|
|
273
|
+
| `since` | number | `0` | Sequence cursor — return only events after this |
|
|
274
|
+
|
|
275
|
+
Each event contains:
|
|
276
|
+
|
|
277
|
+
| Field | Type | Description |
|
|
278
|
+
|---|---|---|
|
|
279
|
+
| `seq` | number | Monotonically increasing sequence number |
|
|
280
|
+
| `terminalId` | string | Which terminal this event came from |
|
|
281
|
+
| `terminalName` | string | Terminal display name at time of event |
|
|
282
|
+
| `commandLine` | string | The command that was executed |
|
|
283
|
+
| `output` | string | Captured stdout (up to `maxOutputBytes`) |
|
|
284
|
+
| `exitCode` | number | Process exit code |
|
|
285
|
+
| `startedAt` | number | Epoch ms when the command started |
|
|
286
|
+
| `endedAt` | number | Epoch ms when the command finished |
|
|
287
|
+
|
|
288
|
+
**Cursor-based pagination**: Save the `cursor` from each response and pass it as `since` in the next call. You'll only receive new events.
|
|
289
|
+
|
|
290
|
+
**Reliability note**: `poll` depends on VS Code's `onDidEndTerminalShellExecution` API, which requires shell integration to be active. It's unreliable in wrapped terminals (where shell integration often doesn't inject) and in TUI sessions. For those cases, use `readLog` instead.
|
|
291
|
+
|
|
292
|
+
**Ring buffer**: Claws stores the last `maxHistory` events (default 500). Older events are dropped. If you poll infrequently, you may miss events that were pushed out of the buffer.
|
|
293
|
+
|
|
294
|
+
**Response cap**: Each `poll` is also capped at `claws.pollLimit` (default 100). The response includes `limit` (the effective cap applied) and `truncated` (true when the pending queue exceeded it). Clients may pass their own `limit` on the request; it's clamped to `claws.pollLimit` as an upper bound.
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## Introspection
|
|
299
|
+
|
|
300
|
+
**Command**: `introspect`
|
|
301
|
+
|
|
302
|
+
Returns a single structured snapshot of the extension + host. Both the `/claws-introspect` slash command and the in-UI `Claws: Health Check` command are powered by the same provider, so the data is identical across paths.
|
|
303
|
+
|
|
304
|
+
**Request**: `{"cmd": "introspect"}`
|
|
305
|
+
|
|
306
|
+
**Response**:
|
|
307
|
+
```json
|
|
308
|
+
{
|
|
309
|
+
"ok": true,
|
|
310
|
+
"protocol": "claws/1",
|
|
311
|
+
"extensionVersion": "0.5.0",
|
|
312
|
+
"nodeVersion": "v20.11.1",
|
|
313
|
+
"electronAbi": 125,
|
|
314
|
+
"platform": "darwin-arm64",
|
|
315
|
+
"nodePty": {
|
|
316
|
+
"loaded": true,
|
|
317
|
+
"loadedFrom": "/absolute/path/to/extension/native/node-pty",
|
|
318
|
+
"error": null
|
|
319
|
+
},
|
|
320
|
+
"servers": [
|
|
321
|
+
{ "workspace": "/absolute/path", "socket": "/absolute/path/.claws/claws.sock" }
|
|
322
|
+
],
|
|
323
|
+
"terminals": 3,
|
|
324
|
+
"uptime_ms": 1234567
|
|
325
|
+
}
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
- `nodePty.loaded = false` → pipe-mode fallback is active; wrapped terminals still work but without real PTY semantics (no resize signals, limited TUI compatibility).
|
|
329
|
+
- `servers` is an array: multi-root workspaces run one server per folder, each with its own socket.
|
|
330
|
+
- `uptime_ms` is since the server bound its socket, not since VS Code launched.
|
|
331
|
+
|
|
332
|
+
Call `introspect` as the first thing after connecting to verify compatibility and confirm `node-pty` loaded cleanly.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## Terminal Profile
|
|
337
|
+
|
|
338
|
+
Claws registers a terminal profile so "Claws Wrapped Terminal" appears in the VS Code terminal dropdown (the arrow next to `+`).
|
|
339
|
+
|
|
340
|
+
When selected:
|
|
341
|
+
1. Claws reserves a terminal ID and computes a log path
|
|
342
|
+
2. A new terminal opens with `scripts/terminal-wrapper.sh` as the shell
|
|
343
|
+
3. The `CLAWS_TERM_LOG` environment variable points to the log file
|
|
344
|
+
4. `onDidOpenTerminal` fires, Claws associates the terminal with the reserved ID
|
|
345
|
+
|
|
346
|
+
The profile name includes the ID: "Claws Wrapped 5". This is used for internal matching and can be renamed by the user after creation without affecting Claws.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Safety Gate
|
|
351
|
+
|
|
352
|
+
Before `send` injects text, Claws inspects the terminal's process tree to detect the foreground process:
|
|
353
|
+
|
|
354
|
+
1. Reads the terminal's shell PID from VS Code's API
|
|
355
|
+
2. Runs `pgrep -P <pid>` to find child processes
|
|
356
|
+
3. Checks if the foreground child is a known shell (`bash`, `zsh`, `fish`, `sh`, `dash`, `ksh`)
|
|
357
|
+
4. If it's not a shell (e.g., `claude`, `vim`, `less`, `top`, `python3`), emits a warning
|
|
358
|
+
|
|
359
|
+
**Default behavior**: warn and proceed. The send goes through with a `[warning: foreground is 'vim' (not a shell)]` prefix in the response. The caller decides whether to continue.
|
|
360
|
+
|
|
361
|
+
**Strict mode**: Pass `strict: true` in the send request. Claws will refuse the send and return an error instead of a warning.
|
|
362
|
+
|
|
363
|
+
**Why warn instead of block**: The primary use case for Claws is AI pair programming, where you intentionally send prompts into Claude Code's TUI input. Blocking that would defeat the purpose. The warning exists to catch accidental sends (e.g., a script meant to run a shell command but the terminal is in vim).
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## Bracketed Paste
|
|
368
|
+
|
|
369
|
+
When `send` receives multi-line text (contains `\n`), it automatically wraps it in bracketed paste mode:
|
|
370
|
+
|
|
371
|
+
```
|
|
372
|
+
\x1b[200~your multi-line text here\x1b[201~
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
This tells the terminal to treat the entire block as a single paste operation. Without it, each `\n` in the text would be interpreted as a separate Enter keystroke, causing the shell to execute each line independently — breaking multi-line commands, heredocs, and prompt text.
|
|
376
|
+
|
|
377
|
+
After the bracketed paste block, Claws sends a separate `\r` (carriage return) to submit the pasted content.
|
|
378
|
+
|
|
379
|
+
**Disable with `paste: false`** if you want raw line-by-line behavior.
|
|
380
|
+
|
|
381
|
+
---
|
|
382
|
+
|
|
383
|
+
## Command Palette
|
|
384
|
+
|
|
385
|
+
Every contributed command is grouped under the `Claws:` category in the command palette (`Cmd/Ctrl+Shift+P`).
|
|
386
|
+
|
|
387
|
+
| Command | ID | What it does |
|
|
388
|
+
|---|---|---|
|
|
389
|
+
| Show Status | `claws.status` | Writes a markdown-formatted runtime block to the `Claws` Output channel (socket list, runtime, version). |
|
|
390
|
+
| Refresh Status Bar | `claws.statusBar` | Manually refresh + re-show the status bar item (useful after a theme swap or focus cycle). |
|
|
391
|
+
| List Terminals | `claws.listTerminals` | Opens a QuickPick with every Claws-known terminal (`id · name · wrapped/unwrapped · pid`). Selecting an item calls `terminal.show()`. |
|
|
392
|
+
| Health Check | `claws.healthCheck` | Renders a full introspection snapshot — extension version, Node / Electron ABI, platform, node-pty state, active sockets, MCP server version, uptime — to the Output channel. |
|
|
393
|
+
| Show Log | `claws.showLog` | Focuses the `Claws` Output channel. |
|
|
394
|
+
| Rebuild Native PTY | `claws.rebuildPty` | Runs `@electron/rebuild` against the bundled `node-pty`. Use after a VS Code major upgrade if pipe-mode fallback kicks in. |
|
|
395
|
+
| Uninstall Cleanup | `claws.uninstallCleanup` | Opt-in — scans workspace folders, inventories Claws-installed files, asks per folder, removes only what was installed. See below. |
|
|
396
|
+
|
|
397
|
+
All seven commands are also registered as activation events, so invoking any of them from a cold start activates the extension before executing.
|
|
398
|
+
|
|
399
|
+
---
|
|
400
|
+
|
|
401
|
+
## Keybindings
|
|
402
|
+
|
|
403
|
+
Chord bindings (`ctrl+alt+c` prefix on Windows/Linux, `cmd+alt+c` on macOS) for the three most-used diagnostic commands:
|
|
404
|
+
|
|
405
|
+
| Binding | Command |
|
|
406
|
+
|---|---|
|
|
407
|
+
| `cmd+alt+c h` / `ctrl+alt+c h` | Claws: Health Check |
|
|
408
|
+
| `cmd+alt+c l` / `ctrl+alt+c l` | Claws: Show Log |
|
|
409
|
+
| `cmd+alt+c s` / `ctrl+alt+c s` | Claws: Show Status |
|
|
410
|
+
|
|
411
|
+
Conflicts with other extensions surface in `Keyboard Shortcuts` (`Cmd/Ctrl+K Cmd/Ctrl+S`). The extension remains fully functional if you rebind or remove them.
|
|
412
|
+
|
|
413
|
+
---
|
|
414
|
+
|
|
415
|
+
## Status Bar Item
|
|
416
|
+
|
|
417
|
+
Right-aligned, priority 100. Shows `$(terminal) Claws (N)` where `N` is the live terminal count.
|
|
418
|
+
|
|
419
|
+
- **Tooltip**: Markdown-rendered block listing every active socket, node-pty load state, and extension version. Hovering for ~500ms reveals it.
|
|
420
|
+
- **Click**: runs `Claws: Health Check`.
|
|
421
|
+
- **Color**: default theme color when healthy; warning-yellow (`statusBarItem.warningBackground`) in pipe-mode fallback; error-red (`statusBarItem.errorBackground`) when no server is running.
|
|
422
|
+
- **Refresh cadence**: 30s interval (unref'd — never blocks shutdown). Manual refresh via `claws.statusBar`.
|
|
423
|
+
|
|
424
|
+
To hide: right-click the status bar and uncheck "Claws".
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Uninstall Cleanup
|
|
429
|
+
|
|
430
|
+
`claws.uninstallCleanup` is an opt-in, reversible-by-git, destructive-outside-git command that removes Claws's per-project footprint from one or more workspace folders.
|
|
431
|
+
|
|
432
|
+
**What it scans for**, per folder:
|
|
433
|
+
- `.mcp.json` — the `claws` entry only (other MCP entries are left untouched; file deleted only if that was the only entry)
|
|
434
|
+
- `.claws-bin/` — vendored MCP server + shell hook
|
|
435
|
+
- `.claude/commands/claws-*.md` — the 19 slash command files
|
|
436
|
+
- `.claude/rules/claws-default-behavior.md`
|
|
437
|
+
- `.claude/skills/claws-prompt-templates/`
|
|
438
|
+
- `.vscode/extensions.json` — removes `neunaha.claws` from `recommendations` only
|
|
439
|
+
- `CLAUDE.md` — removes just the fenced `<!-- CLAWS:BEGIN --> … <!-- CLAWS:END -->` block
|
|
440
|
+
|
|
441
|
+
**Flow**:
|
|
442
|
+
1. Inventories everything that's actually present.
|
|
443
|
+
2. Prompts with a modal per folder listing exactly what will be removed.
|
|
444
|
+
3. On confirm, deletes only what was inventoried — never reaches outside the scanned set.
|
|
445
|
+
4. Writes a summary to the `Claws` Output channel.
|
|
446
|
+
|
|
447
|
+
Machine-wide artifacts (`~/.claws-src/`, the extension symlink, the shell-hook line in your `rc` file) are **not** touched. Remove those manually as documented in the README's "Uninstall" section.
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Configuration Reference
|
|
452
|
+
|
|
453
|
+
All settings live under the `claws` namespace in VS Code's settings (`settings.json`).
|
|
454
|
+
|
|
455
|
+
### `claws.socketPath`
|
|
456
|
+
- **Type**: string
|
|
457
|
+
- **Default**: `.claws/claws.sock`
|
|
458
|
+
- **Description**: Path to the Unix domain socket, relative to the workspace root. Claws creates the parent directory if it doesn't exist. The socket is created with `chmod 600` (owner-only access).
|
|
459
|
+
|
|
460
|
+
### `claws.logDirectory`
|
|
461
|
+
- **Type**: string
|
|
462
|
+
- **Default**: `.claws/terminals`
|
|
463
|
+
- **Description**: Directory where wrapped terminal pty logs are stored. Each terminal gets its own file: `claws-<id>.log`. Add `.claws/` to your `.gitignore`.
|
|
464
|
+
|
|
465
|
+
### `claws.defaultWrapped`
|
|
466
|
+
- **Type**: boolean
|
|
467
|
+
- **Default**: `false`
|
|
468
|
+
- **Description**: When `true`, every terminal created via the Claws API (not via VS Code's `+` button) is automatically wrapped with pty logging. Useful for AI orchestration setups where you always want readable terminals.
|
|
469
|
+
|
|
470
|
+
### `claws.maxOutputBytes`
|
|
471
|
+
- **Type**: number
|
|
472
|
+
- **Default**: `262144` (256KB)
|
|
473
|
+
- **Description**: Maximum bytes of stdout captured per shell-integration command event. Larger outputs are truncated with a `[...truncated N bytes]` note. Does not affect `readLog` (which has its own `MAX_READLOG_BYTES` of 512KB).
|
|
474
|
+
|
|
475
|
+
### `claws.maxHistory`
|
|
476
|
+
- **Type**: number
|
|
477
|
+
- **Default**: `500`
|
|
478
|
+
- **Description**: Maximum number of command-completion events retained in the ring buffer for `poll`. Older events are dropped FIFO. Increase if you poll infrequently and don't want to miss events.
|
|
479
|
+
|
|
480
|
+
### `claws.maxCaptureBytes`
|
|
481
|
+
- **Type**: number
|
|
482
|
+
- **Default**: `1048576` (1 MB)
|
|
483
|
+
- **Description**: Per-terminal in-memory capture buffer for Pseudoterminal-backed wrapped terminals. `readLog` serves from this ring buffer. Bytes beyond the cap are dropped FIFO. Hot-reloadable.
|
|
484
|
+
|
|
485
|
+
### `claws.execTimeoutMs`
|
|
486
|
+
- **Type**: number
|
|
487
|
+
- **Default**: `180000` (180 s)
|
|
488
|
+
- **Description**: Default wall-clock timeout for an `exec` request before the server rejects with `exec timeout after Xms`. Individual requests may override via `timeoutMs` in the payload. Hot-reloadable — edits to `settings.json` take effect on the next request, no reload needed.
|
|
489
|
+
|
|
490
|
+
### `claws.pollLimit`
|
|
491
|
+
- **Type**: number
|
|
492
|
+
- **Default**: `100`
|
|
493
|
+
- **Description**: Maximum number of history events returned by a single `poll` request. Client-requested `limit` is clamped to this. Responses exceeding the cap return the tail slice with `truncated: true`. Hot-reloadable.
|
|
494
|
+
|
|
495
|
+
### `claws.enableWebSocket`
|
|
496
|
+
- **Type**: boolean
|
|
497
|
+
- **Default**: `false`
|
|
498
|
+
- **Description**: [Planned — v0.6] Enable a WebSocket server alongside the Unix socket for cross-device access. Currently a no-op.
|
|
499
|
+
|
|
500
|
+
### `claws.webSocketPort`
|
|
501
|
+
- **Type**: number
|
|
502
|
+
- **Default**: `9876`
|
|
503
|
+
- **Description**: [Planned — v0.6] Port for the WebSocket server. Honored only when `claws.enableWebSocket` is true.
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Socket Server Internals
|
|
508
|
+
|
|
509
|
+
### Lifecycle
|
|
510
|
+
|
|
511
|
+
1. **Activation**: Claws activates on `onStartupFinished`. It reads the workspace root, constructs the socket path, creates the directory, and starts a `net.createServer` listener.
|
|
512
|
+
2. **Connection**: Each client gets its own socket connection. Multiple clients can connect simultaneously. Requests are handled independently.
|
|
513
|
+
3. **Protocol**: Newline-delimited JSON. Each `\n`-terminated line is parsed as a JSON request, handled asynchronously, and the response is written back as a `\n`-terminated JSON line.
|
|
514
|
+
4. **Deactivation**: On VS Code shutdown or extension deactivation, the server is closed and the socket file is unlinked.
|
|
515
|
+
|
|
516
|
+
### Error handling
|
|
517
|
+
|
|
518
|
+
- Malformed JSON → `{"ok": false, "error": "bad json"}`
|
|
519
|
+
- Unknown command → `{"ok": false, "error": "unknown cmd: X"}`
|
|
520
|
+
- Missing terminal → `{"ok": false, "error": "unknown terminal id X"}`
|
|
521
|
+
- Handler exceptions → `{"ok": false, "error": "Error message"}`
|
|
522
|
+
|
|
523
|
+
### Security
|
|
524
|
+
|
|
525
|
+
- Socket created with `chmod 600` — only the current user can connect
|
|
526
|
+
- No authentication on Unix socket (same-user access is the trust boundary)
|
|
527
|
+
- WebSocket transport (planned) will add token-based auth + TLS
|
|
528
|
+
|
|
529
|
+
---
|
|
530
|
+
|
|
531
|
+
## Cross-Device Control
|
|
532
|
+
|
|
533
|
+
**Status**: Planned for v0.3
|
|
534
|
+
|
|
535
|
+
### Current workaround — SSH tunnel
|
|
536
|
+
|
|
537
|
+
You can control a remote VS Code instance today using an SSH tunnel:
|
|
538
|
+
|
|
539
|
+
```bash
|
|
540
|
+
# On your local machine:
|
|
541
|
+
ssh -L 9999:/remote/workspace/.claws/claws.sock user@remote-host
|
|
542
|
+
|
|
543
|
+
# Then connect locally:
|
|
544
|
+
from claws import ClawsClient
|
|
545
|
+
client = ClawsClient("/tmp/claws-remote.sock") # forwarded socket
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
### Planned architecture
|
|
549
|
+
|
|
550
|
+
```
|
|
551
|
+
Device A (controller) Device B (workspace)
|
|
552
|
+
┌──────────────┐ ┌──────────────────┐
|
|
553
|
+
│ Python/Node │◄── WebSocket ─►│ Claws Extension │
|
|
554
|
+
│ client │ + TLS │ (VS Code) │
|
|
555
|
+
└──────────────┘ + token └──────────────────┘
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
- **WebSocket transport**: opt-in alongside Unix socket
|
|
559
|
+
- **Token auth**: generated per-session, shown in the Claws output panel
|
|
560
|
+
- **TLS**: self-signed or ACME for encrypted connections
|
|
561
|
+
- **mDNS discovery**: auto-discover Claws-enabled VS Code instances on your LAN
|
|
562
|
+
- **Team config**: named devices with per-terminal read/write access control
|