clawborrator-mcp 0.0.24 → 0.0.26
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 +90 -26
- package/dist/hook.js +117 -64
- package/dist/hook.js.map +1 -1
- package/dist/install-hooks.js +83 -41
- package/dist/install-hooks.js.map +1 -1
- package/dist/sidecar.js +11 -13
- package/dist/sidecar.js.map +1 -1
- package/dist/tools/index.d.ts +8 -7
- package/dist/tools/index.js +438 -371
- package/dist/tools/index.js.map +1 -1
- package/dist/transcript.js +43 -60
- package/dist/transcript.js.map +1 -1
- package/dist/ws-client.d.ts +13 -0
- package/dist/ws-client.js +87 -56
- package/dist/ws-client.js.map +1 -1
- package/dist-hook/clawborrator-tail.mjs +96 -87
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
MCP server that connects each running Claude Code instance to a
|
|
4
4
|
[`hub_v1`](https://github.com/clawborrator/hub_v1) over WebSocket.
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
Designed to be invoked by Claude Code via `.mcp.json`; runs as both
|
|
6
|
+
a long-lived stdio MCP server AND a short-lived hook spawn (selected
|
|
7
|
+
by the `--hook=<HookName>` CLI flag).
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
>
|
|
9
|
+
Published as [`clawborrator-mcp`](https://www.npmjs.com/package/clawborrator-mcp)
|
|
10
|
+
on npm.
|
|
11
|
+
|
|
12
|
+
> **Status: production hub at [`next.clawborrator.com`](https://next.clawborrator.com).**
|
|
13
|
+
> Local dev uses `ws://localhost:8787`. Both supported.
|
|
13
14
|
|
|
14
15
|
---
|
|
15
16
|
|
|
@@ -24,7 +25,7 @@ Set in your project's `.mcp.json`:
|
|
|
24
25
|
"command": "npx",
|
|
25
26
|
"args": ["-y", "clawborrator-mcp"],
|
|
26
27
|
"env": {
|
|
27
|
-
"CLAWBORRATOR_HUB_URL": "
|
|
28
|
+
"CLAWBORRATOR_HUB_URL": "wss://next.clawborrator.com",
|
|
28
29
|
"CLAWBORRATOR_TOKEN": "ck_live_…"
|
|
29
30
|
}
|
|
30
31
|
}
|
|
@@ -56,7 +57,8 @@ claw token mint --kind=channel --name=mbp --mcp-snippet
|
|
|
56
57
|
4. Writes `<cwd>/.claude/clawborrator.session.json` (mode 0600) so per-event hook spawns can find the active session.
|
|
57
58
|
5. Maintains the WS with heartbeat ping/pong; reconnects with exponential backoff (1s/2s/5s/15s/30s/60s).
|
|
58
59
|
6. Listens for hub-side messages: `prompt` (cross-session route), `permission_response`, `peers_update`, `bye`, `error`.
|
|
59
|
-
7.
|
|
60
|
+
7. Dispatches MCP tool calls (see below) over the same WS.
|
|
61
|
+
8. On clean shutdown (SIGINT/SIGTERM/exit), deletes the sidecar.
|
|
60
62
|
|
|
61
63
|
**Short-lived hook path** (`--hook=<HookName>` flag):
|
|
62
64
|
1. Reads JSON payload from stdin (Claude Code's hook protocol).
|
|
@@ -70,29 +72,79 @@ Hooks are installed with `claw session init` from inside a project — see hub_v
|
|
|
70
72
|
|
|
71
73
|
---
|
|
72
74
|
|
|
73
|
-
##
|
|
75
|
+
## MCP tools exposed to Claude
|
|
76
|
+
|
|
77
|
+
Routed: targets a peer (your own session or another operator's session you have a share on) by routingName.
|
|
78
|
+
|
|
79
|
+
| Tool | Purpose |
|
|
80
|
+
|---|---|
|
|
81
|
+
| `reply({ chat_id, text })` | Post a tagged final reply for a routed prompt (closes the round-trip when the source session is blocking on a reply). |
|
|
82
|
+
| `reply_chunk({ chat_id, text, done })` | Stream a reply progressively — the operator sees text growing live; close with `done:true`. Same correlation as `reply`. |
|
|
83
|
+
| `list_peers()` | Discover other CC sessions the operator has access to (own sessions + shared ones). Refused on agents published as `isolated`. |
|
|
84
|
+
| `route_to_peer({ peer, prompt, mode })` | Send one prompt to one peer. `mode: 'ask'` blocks for the reply; `mode: 'tell'` is fire-and-forget. |
|
|
85
|
+
| `probe_peers({ prompt, peers? })` | Fan out the same short question to many peers in parallel for discovery. |
|
|
86
|
+
| `await_routed_prompt({ maxWaitMs })` | Dequeue an inbound routed prompt for THIS session — used by agents that service requests from other sessions. |
|
|
87
|
+
|
|
88
|
+
Cross-tenant — public agents owned by other operators:
|
|
89
|
+
|
|
90
|
+
| Tool | Purpose |
|
|
91
|
+
|---|---|
|
|
92
|
+
| `list_agents()` | Discover public agents on the hub. Returns handle, name, tagline, online, mine, isolated flags. |
|
|
93
|
+
| `dispatch_to_agent({ handle, prompt, mode })` | Invoke a published agent by `<owner>/<slug>` handle. `ask` mode waits up to 15 min for the reply; `tell` mode is fire-and-forget. |
|
|
74
94
|
|
|
75
|
-
|
|
76
|
-
covers chat + tail event capture without any Claude-side tool calls.
|
|
95
|
+
File exchange:
|
|
77
96
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
97
|
+
| Tool | Purpose |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `attach_file({ path, targetSessionId? })` | Upload a file from disk to the session (or to a peer's session you have a share on). Returns `fileId`. |
|
|
100
|
+
| `read_file({ fileId })` | Fetch a session-attached file inline (text-mime; under 1 MB). Reply-clone makes peer-uploaded files visible to the recipient. |
|
|
101
|
+
| `download_to_path({ fileId, path })` | Fetch a larger or binary file to disk. Returns the absolute path written. |
|
|
83
102
|
|
|
84
|
-
|
|
103
|
+
The hub correlates `reply` / `reply_chunk` to their originating
|
|
104
|
+
`route_to_peer` / `dispatch_to_agent` by chatId; the source session's
|
|
105
|
+
CC unblocks when the matching reply lands. 15-minute timeout caps —
|
|
106
|
+
see `hub_v1/server/src/services/agents.ts` and `services/op-routes.ts`.
|
|
107
|
+
|
|
108
|
+
For `await_routed_prompt` to actually fire — i.e., for an agent to
|
|
109
|
+
service incoming requests — its CLAUDE.md needs a line telling Claude
|
|
110
|
+
to call it at the start of each turn. Without that note, Claude
|
|
111
|
+
won't know to consult the inbox. See
|
|
112
|
+
[`hub_v1/docs/3-AGENT-SETUP.md`](https://github.com/clawborrator/hub_v1/blob/main/docs/3-AGENT-SETUP.md)
|
|
113
|
+
for the dispatcher-pattern setup.
|
|
85
114
|
|
|
86
115
|
---
|
|
87
116
|
|
|
88
|
-
##
|
|
117
|
+
## Hook coverage
|
|
118
|
+
|
|
119
|
+
Maps each Claude Code hook to a hub event. The hook script is
|
|
120
|
+
`dist-hook/clawborrator-tail.mjs`; install via `claw session init`.
|
|
89
121
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
122
|
+
| Hook | Hub event | Notes |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `UserPromptSubmit` | `chat/prompt` (source='cli') | Operator typing into the local CC terminal. |
|
|
125
|
+
| `PreToolUse` | `tail/PreToolUse` (+ `chat/assistant_text` per text block from the transcript) | The tail captures pre-reply narration too. |
|
|
126
|
+
| `PostToolUse` | `tail/PostToolUse` | |
|
|
127
|
+
| `PostToolUseFailure` | `tail/PostToolUseFailure` | |
|
|
128
|
+
| `Stop` | `tail/Stop` (+ `chat/reply` if assistant_text present) | Turn-end signal. |
|
|
129
|
+
| `Notification` | `tail/Notification` | CC user notifications (idle / permission). |
|
|
130
|
+
| `SessionStart` / `SessionEnd` | `tail/SessionStart` / `tail/SessionEnd` | |
|
|
131
|
+
| `TaskCreated` / `TaskCompleted` | `tail/TaskCreated` / `tail/TaskCompleted` | Carries `task_id`, `task_subject`, `task_description`. |
|
|
132
|
+
| `SubagentStart` / `SubagentStop` | `tail/SubagentStart` / `tail/SubagentStop` | SubagentStop carries `last_assistant_message` recap. |
|
|
133
|
+
|
|
134
|
+
The tail reads the CC transcript file directly to enrich `PreToolUse`
|
|
135
|
+
with the assistant's pre-reply text (which CC doesn't put on the
|
|
136
|
+
hook payload directly). See `transcript.ts` for the walker.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## Phases (all shipped)
|
|
141
|
+
|
|
142
|
+
- **Phase A** ✓ — connect / register / heartbeat / reconnect
|
|
143
|
+
- **Phase B** ✓ — hooks + event forwarding via sidecar
|
|
144
|
+
- **Phase C** ✓ — bidirectional permission relay (channel → hub → operator → back)
|
|
145
|
+
- **Phase D** ✓ — MCP tools (above)
|
|
146
|
+
- **Phase E** ✓ — public-agent dispatch (`dispatch_to_agent`, `list_agents`); 15-min timeouts; cyclomatic-complexity refactor
|
|
147
|
+
- **Phase F** ✓ — streaming `reply_chunk` (incremental output), `read_file` / `download_to_path` for cross-session file exchange
|
|
96
148
|
|
|
97
149
|
---
|
|
98
150
|
|
|
@@ -107,4 +159,16 @@ npm link
|
|
|
107
159
|
clawborrator-mcp --hook=PreToolUse < /dev/null # exits cleanly with no sidecar
|
|
108
160
|
```
|
|
109
161
|
|
|
110
|
-
When `claude` runs in a folder whose `.mcp.json` references
|
|
162
|
+
When `claude` runs in a folder whose `.mcp.json` references
|
|
163
|
+
`clawborrator-mcp`, npm/npx resolves it to your linked build.
|
|
164
|
+
|
|
165
|
+
To publish a new release:
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npm version patch # bumps package.json + creates git tag
|
|
169
|
+
npm publish
|
|
170
|
+
git push --follow-tags
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
The CLI's `claw token mint --mcp-snippet` autogenerates an `.mcp.json`
|
|
174
|
+
snippet pointing at the published version.
|
package/dist/hook.js
CHANGED
|
@@ -80,6 +80,16 @@ async function postEvent(sidecar, body, timeoutMs) {
|
|
|
80
80
|
clearTimeout(timer);
|
|
81
81
|
}
|
|
82
82
|
}
|
|
83
|
+
// Returns true if payload already has a populated string-shaped
|
|
84
|
+
// alternative (`text` / `response`) — caller should bail out and let
|
|
85
|
+
// downstream use it instead of overwriting with assistant_text.
|
|
86
|
+
function hasStringShapedReply(payload) {
|
|
87
|
+
if (typeof payload.text === 'string' && payload.text.trim())
|
|
88
|
+
return true;
|
|
89
|
+
if (typeof payload.response === 'string' && payload.response.trim())
|
|
90
|
+
return true;
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
83
93
|
// Stop / SubagentStop: try to populate payload.assistant_text from
|
|
84
94
|
// (in order) last_assistant_message → existing payload fields →
|
|
85
95
|
// transcript tail. Mutates payload in place.
|
|
@@ -92,10 +102,8 @@ async function enrichStopAssistantText(payload, hookName) {
|
|
|
92
102
|
log.debug('stop: assistant_text from last_assistant_message', { chars: fromLAM.length });
|
|
93
103
|
return;
|
|
94
104
|
}
|
|
95
|
-
if (
|
|
96
|
-
|
|
97
|
-
return; // a string-shaped variant is already there; let downstream use it
|
|
98
|
-
}
|
|
105
|
+
if (hasStringShapedReply(payload))
|
|
106
|
+
return;
|
|
99
107
|
const transcriptPath = typeof payload.transcript_path === 'string' ? payload.transcript_path : '';
|
|
100
108
|
if (!transcriptPath) {
|
|
101
109
|
log.debug('stop: no transcript_path on payload, no assistant_text recoverable', { hookName });
|
|
@@ -115,23 +123,26 @@ async function enrichStopAssistantText(payload, hookName) {
|
|
|
115
123
|
log.debug('stop: transcript had no assistant-text block in tail window', { hookName, path: transcriptPath });
|
|
116
124
|
}
|
|
117
125
|
}
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
|
|
123
|
-
// thinking here" marker.
|
|
124
|
-
async function shipPreToolAssistantText(sidecar, payload) {
|
|
126
|
+
// Pull + normalize the PreToolUse-relevant fields off the hook
|
|
127
|
+
// payload. Returns null when essential identifiers are missing or
|
|
128
|
+
// the tool is on the skip-list (e.g. mcp__clawborrator__reply, where
|
|
129
|
+
// the WS path already routes the user-facing answer).
|
|
130
|
+
function parsePreToolPayload(payload) {
|
|
125
131
|
const transcriptPath = typeof payload.transcript_path === 'string' ? payload.transcript_path : '';
|
|
126
132
|
const toolUseId = String(payload.tool_use_id ?? payload.toolUseId ?? '');
|
|
127
133
|
const toolName = String(payload.tool_name ?? payload.toolName ?? '');
|
|
128
134
|
if (!transcriptPath || !toolUseId)
|
|
129
|
-
return;
|
|
135
|
+
return null;
|
|
130
136
|
if (TOOLS_SKIPPED_FOR_PRE_TEXT.has(toolName))
|
|
131
|
-
return;
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
137
|
+
return null;
|
|
138
|
+
return { transcriptPath, toolUseId };
|
|
139
|
+
}
|
|
140
|
+
// Race-retry: CC writes the assistant message that DECIDED the
|
|
141
|
+
// tool_use to the transcript ASYNC, so a fresh read right after the
|
|
142
|
+
// hook fires can miss it. Retry up to 4 times with 80ms delays.
|
|
143
|
+
// Returns the latest messages array + whether the target was ever
|
|
144
|
+
// found + retry count.
|
|
145
|
+
async function readTranscriptWithRetry(transcriptPath, toolUseId) {
|
|
135
146
|
let messages = readTranscriptMessages(transcriptPath, DEFAULT_TAIL_BYTES);
|
|
136
147
|
let foundTarget = messageContainsToolUse(messages, toolUseId);
|
|
137
148
|
let retries = 0;
|
|
@@ -141,19 +152,14 @@ async function shipPreToolAssistantText(sidecar, payload) {
|
|
|
141
152
|
foundTarget = messageContainsToolUse(messages, toolUseId);
|
|
142
153
|
retries++;
|
|
143
154
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
placeholder: hasThinking,
|
|
153
|
-
});
|
|
154
|
-
// Monotonic timestamps so events sort chronologically on the hub
|
|
155
|
-
// (chat_events orders by ts; ties broken by id, but ts ordering is
|
|
156
|
-
// the human signal). We use ms epoch then convert to ISO.
|
|
155
|
+
return { messages, foundTarget, retries };
|
|
156
|
+
}
|
|
157
|
+
// Build + dispatch the per-block AssistantText POSTs (or a single
|
|
158
|
+
// placeholder when only extended-thinking happened). Monotonic
|
|
159
|
+
// timestamps so events sort chronologically on the hub (chat_events
|
|
160
|
+
// orders by ts; ties broken by id, but ts ordering is the human
|
|
161
|
+
// signal).
|
|
162
|
+
async function postPreToolAssistantBlocks(sidecar, blocks, hasThinking, toolUseId) {
|
|
157
163
|
const baseMs = Date.now();
|
|
158
164
|
const tsAt = (i) => new Date(baseMs + i).toISOString();
|
|
159
165
|
if (blocks.length > 0) {
|
|
@@ -166,8 +172,9 @@ async function shipPreToolAssistantText(sidecar, payload) {
|
|
|
166
172
|
payload: { text, toolUseId },
|
|
167
173
|
ts: tsAt(i),
|
|
168
174
|
}, 800)));
|
|
175
|
+
return;
|
|
169
176
|
}
|
|
170
|
-
|
|
177
|
+
if (hasThinking) {
|
|
171
178
|
await postEvent(sidecar, {
|
|
172
179
|
sessionId: sidecar.sessionId,
|
|
173
180
|
kind: 'chat',
|
|
@@ -181,12 +188,34 @@ async function shipPreToolAssistantText(sidecar, payload) {
|
|
|
181
188
|
}, 800);
|
|
182
189
|
}
|
|
183
190
|
}
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
191
|
+
// PreToolUse: ship every text block Claude wrote in the same
|
|
192
|
+
// assistant message BEFORE this tool_use as its own chat/assistant_text
|
|
193
|
+
// event. If no text blocks but extended-thinking blocks were present
|
|
194
|
+
// (CC strips thinking plaintext on disk; only the signature survives),
|
|
195
|
+
// ship a single placeholder so the operator sees a "claude was
|
|
196
|
+
// thinking here" marker.
|
|
197
|
+
async function shipPreToolAssistantText(sidecar, payload) {
|
|
198
|
+
const parsed = parsePreToolPayload(payload);
|
|
199
|
+
if (!parsed)
|
|
200
|
+
return;
|
|
201
|
+
const { transcriptPath, toolUseId } = parsed;
|
|
202
|
+
const { messages, foundTarget, retries } = await readTranscriptWithRetry(transcriptPath, toolUseId);
|
|
203
|
+
const blocks = extractTextBlocksBeforeToolUse(messages, toolUseId);
|
|
204
|
+
const hasThinking = blocks.length === 0 ? hasThinkingBlocksBeforeToolUse(messages, toolUseId) : false;
|
|
205
|
+
log.debug('PreToolUse extract', {
|
|
206
|
+
toolUseId: toolUseId.slice(0, 24),
|
|
207
|
+
messages: messages.length,
|
|
208
|
+
targetFound: foundTarget,
|
|
209
|
+
retries,
|
|
210
|
+
blocks: blocks.length,
|
|
211
|
+
placeholder: hasThinking,
|
|
212
|
+
});
|
|
213
|
+
await postPreToolAssistantBlocks(sidecar, blocks, hasThinking, toolUseId);
|
|
214
|
+
}
|
|
215
|
+
// Read stdin → echo to stdout (preserve CC hook chain) → parse JSON.
|
|
216
|
+
// Falls back to a {rawStdin} record if the payload doesn't parse so
|
|
217
|
+
// the operator still sees something on the wire.
|
|
218
|
+
async function readAndEchoHookPayload() {
|
|
190
219
|
const stdinRaw = await readStdin();
|
|
191
220
|
// Always echo stdin so Claude's hook chain sees the original payload.
|
|
192
221
|
if (stdinRaw)
|
|
@@ -199,40 +228,64 @@ export async function runHook(hookName) {
|
|
|
199
228
|
catch {
|
|
200
229
|
payload = { rawStdin: stdinRaw.slice(0, 2000) };
|
|
201
230
|
}
|
|
231
|
+
return payload;
|
|
232
|
+
}
|
|
233
|
+
// Stop-specific pre-event handler: enrich + ship chat/reply if a real
|
|
234
|
+
// final-answer text was recovered. The tail Stop event posted by the
|
|
235
|
+
// caller marks the turn boundary independently.
|
|
236
|
+
async function runStop(sidecar, payload) {
|
|
237
|
+
await enrichStopAssistantText(payload, 'Stop');
|
|
238
|
+
const reply = typeof payload.assistant_text === 'string' ? payload.assistant_text.trim() : '';
|
|
239
|
+
if (!reply)
|
|
240
|
+
return;
|
|
241
|
+
await postEvent(sidecar, {
|
|
242
|
+
sessionId: sidecar.sessionId,
|
|
243
|
+
kind: 'chat',
|
|
244
|
+
type: 'reply',
|
|
245
|
+
payload: { text: reply },
|
|
246
|
+
ts: new Date().toISOString(),
|
|
247
|
+
}, 2000);
|
|
248
|
+
}
|
|
249
|
+
// Per-hook pre-enrichment dispatch. Mutates payload in place where
|
|
250
|
+
// the variant needs to (Stop's assistant_text path) and may emit
|
|
251
|
+
// chat-lane events. SubagentStop intentionally does NOTHING here —
|
|
252
|
+
// see comment below; we only record the tail event.
|
|
253
|
+
async function dispatchHookEnrichment(hookName, sidecar, payload) {
|
|
254
|
+
if (hookName === 'Stop') {
|
|
255
|
+
// Real turn end — extract final answer + ship chat/reply so
|
|
256
|
+
// attached operators see Claude's response in the chat lane.
|
|
257
|
+
// The tail Stop event below marks the boundary.
|
|
258
|
+
await runStop(sidecar, payload);
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
if (hookName === 'SubagentStop') {
|
|
262
|
+
// A Task-tool subagent finished. NOT a final-answer event — the
|
|
263
|
+
// parent agent is still running and will fire its own Stop later.
|
|
264
|
+
// Some CC versions populate `last_assistant_message` with the
|
|
265
|
+
// subagent's INPUT prompt rather than its reply, which previously
|
|
266
|
+
// surfaced as a misleading chat/reply row. We still record the
|
|
267
|
+
// tail event below for activity-lane visibility, but skip the
|
|
268
|
+
// chat/reply ship entirely.
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
if (hookName === 'PreToolUse') {
|
|
272
|
+
await shipPreToolAssistantText(sidecar, payload);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
export async function runHook(hookName) {
|
|
276
|
+
const map = HOOK_TO_EVENT[hookName];
|
|
277
|
+
if (!map) {
|
|
278
|
+
log.warn('unknown hook name; skipping', { hookName });
|
|
279
|
+
process.exit(0);
|
|
280
|
+
}
|
|
281
|
+
const payload = await readAndEchoHookPayload();
|
|
202
282
|
const sidecar = findSidecar(process.cwd());
|
|
203
283
|
if (!sidecar) {
|
|
204
284
|
log.warn('hook fired but no sidecar found — channel must not be running', { cwd: process.cwd() });
|
|
205
285
|
process.exit(0);
|
|
206
286
|
}
|
|
207
287
|
try {
|
|
208
|
-
|
|
209
|
-
// Real turn end — extract final answer + ship chat/reply so
|
|
210
|
-
// attached operators see Claude's response in the chat lane.
|
|
211
|
-
// The tail Stop event below marks the boundary.
|
|
212
|
-
await enrichStopAssistantText(payload, hookName);
|
|
213
|
-
const reply = typeof payload.assistant_text === 'string' ? payload.assistant_text.trim() : '';
|
|
214
|
-
if (reply) {
|
|
215
|
-
await postEvent(sidecar, {
|
|
216
|
-
sessionId: sidecar.sessionId,
|
|
217
|
-
kind: 'chat',
|
|
218
|
-
type: 'reply',
|
|
219
|
-
payload: { text: reply },
|
|
220
|
-
ts: new Date().toISOString(),
|
|
221
|
-
}, 2000);
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
else if (hookName === 'SubagentStop') {
|
|
225
|
-
// A Task-tool subagent finished. NOT a final-answer event — the
|
|
226
|
-
// parent agent is still running and will fire its own Stop later.
|
|
227
|
-
// Some CC versions populate `last_assistant_message` with the
|
|
228
|
-
// subagent's INPUT prompt rather than its reply, which previously
|
|
229
|
-
// surfaced as a misleading chat/reply row. We still record the
|
|
230
|
-
// tail event below for activity-lane visibility, but skip the
|
|
231
|
-
// chat/reply ship entirely.
|
|
232
|
-
}
|
|
233
|
-
else if (hookName === 'PreToolUse') {
|
|
234
|
-
await shipPreToolAssistantText(sidecar, payload);
|
|
235
|
-
}
|
|
288
|
+
await dispatchHookEnrichment(hookName, sidecar, payload);
|
|
236
289
|
}
|
|
237
290
|
catch (e) {
|
|
238
291
|
log.warn('pre-event enrichment threw', { error: e?.message ?? String(e), hookName });
|
package/dist/hook.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"hook.js","sourceRoot":"","sources":["../src/hook.ts"],"names":[],"mappings":"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"}
|
package/dist/install-hooks.js
CHANGED
|
@@ -65,6 +65,78 @@ function findBundledHookFile() {
|
|
|
65
65
|
}
|
|
66
66
|
return null;
|
|
67
67
|
}
|
|
68
|
+
// Read settings.json (tolerate missing/empty) and return the parsed
|
|
69
|
+
// SettingsShape + the original raw text (used later to skip the
|
|
70
|
+
// rewrite when nothing changed). Returns null on JSON parse failure
|
|
71
|
+
// — caller should leave the file alone in that case.
|
|
72
|
+
function loadOrInitHookSettings(settingsPath) {
|
|
73
|
+
if (!existsSync(settingsPath))
|
|
74
|
+
return { s: {}, originalText: '' };
|
|
75
|
+
try {
|
|
76
|
+
const originalText = readFileSync(settingsPath, 'utf8');
|
|
77
|
+
if (!originalText.trim())
|
|
78
|
+
return { s: {}, originalText };
|
|
79
|
+
return { s: JSON.parse(originalText), originalText };
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
log.warn('install-hooks: settings.json unparseable, leaving alone', { error: e?.message ?? String(e) });
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Mirror the bundled hook .mjs into `.claude/hooks/clawborrator-
|
|
87
|
+
// tail.mjs` if absent or byte-different. Returns whether we touched
|
|
88
|
+
// the file. Bundle bytes already in hand from `findBundledHookFile`.
|
|
89
|
+
function syncBundledHookFile(hookFile, bundleBytes) {
|
|
90
|
+
if (!existsSync(hookFile) || !readFileSync(hookFile).equals(bundleBytes)) {
|
|
91
|
+
writeFileSync(hookFile, bundleBytes);
|
|
92
|
+
try {
|
|
93
|
+
chmodSync(hookFile, 0o755);
|
|
94
|
+
}
|
|
95
|
+
catch { /* Windows */ }
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
// Decide what to do with our hook entry inside one event's `hooks[]`
|
|
101
|
+
// list. 'add' means no entry exists yet, 'refresh' means our entry's
|
|
102
|
+
// command is stale, 'noop' means it's already exactly right.
|
|
103
|
+
function decideHookAction(entry, desiredCmd) {
|
|
104
|
+
const existingIdx = entry.hooks.findIndex(isOurHook);
|
|
105
|
+
if (existingIdx < 0)
|
|
106
|
+
return 'add';
|
|
107
|
+
if (entry.hooks[existingIdx].command !== desiredCmd)
|
|
108
|
+
return 'refresh';
|
|
109
|
+
return 'noop';
|
|
110
|
+
}
|
|
111
|
+
// Apply the chosen action to the entry's hooks[] list, mutating in
|
|
112
|
+
// place. Idempotent on 'noop'; replaces for 'refresh'; appends for
|
|
113
|
+
// 'add'.
|
|
114
|
+
function materializeHookEntry(entry, desiredCmd, action) {
|
|
115
|
+
if (action === 'noop')
|
|
116
|
+
return;
|
|
117
|
+
if (action === 'refresh') {
|
|
118
|
+
const existingIdx = entry.hooks.findIndex(isOurHook);
|
|
119
|
+
entry.hooks[existingIdx] = { type: 'command', command: desiredCmd };
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// add
|
|
123
|
+
entry.hooks.push({ type: 'command', command: desiredCmd });
|
|
124
|
+
}
|
|
125
|
+
// Per-event update: ensures the catch-all `.* matcher` row exists,
|
|
126
|
+
// then resolves + applies the action. Returns the action so the
|
|
127
|
+
// caller can tally counts.
|
|
128
|
+
function reconcileHookEvent(s, name, hookFile) {
|
|
129
|
+
const arr = (s.hooks[name] ??= []);
|
|
130
|
+
let entry = arr.find((e) => (e.matcher ?? '.*') === '.*');
|
|
131
|
+
if (!entry) {
|
|
132
|
+
entry = { matcher: '.*', hooks: [] };
|
|
133
|
+
arr.push(entry);
|
|
134
|
+
}
|
|
135
|
+
const desiredCmd = hookCommand(name, hookFile);
|
|
136
|
+
const action = decideHookAction(entry, desiredCmd);
|
|
137
|
+
materializeHookEntry(entry, desiredCmd, action);
|
|
138
|
+
return action;
|
|
139
|
+
}
|
|
68
140
|
/**
|
|
69
141
|
* Install/maintain .claude/settings.json + .claude/hooks/clawborrator-
|
|
70
142
|
* tail.mjs for the project at `cwd`. Returns a summary describing what
|
|
@@ -88,54 +160,24 @@ export function installHooks(cwd) {
|
|
|
88
160
|
// already on disk. Compare exact bytes — cheaper than hashing
|
|
89
161
|
// and good enough for files this small.
|
|
90
162
|
const bundleBytes = readFileSync(bundleSource);
|
|
91
|
-
|
|
92
|
-
if (!existsSync(hookFile) || !readFileSync(hookFile).equals(bundleBytes)) {
|
|
93
|
-
writeFileSync(hookFile, bundleBytes);
|
|
94
|
-
try {
|
|
95
|
-
chmodSync(hookFile, 0o755);
|
|
96
|
-
}
|
|
97
|
-
catch { /* Windows */ }
|
|
98
|
-
hookFileWritten = true;
|
|
99
|
-
}
|
|
163
|
+
const hookFileWritten = syncBundledHookFile(hookFile, bundleBytes);
|
|
100
164
|
// 2) Read existing settings.json (tolerate missing/empty).
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
try {
|
|
105
|
-
originalText = readFileSync(settings, 'utf8');
|
|
106
|
-
if (originalText.trim())
|
|
107
|
-
s = JSON.parse(originalText);
|
|
108
|
-
}
|
|
109
|
-
catch (e) {
|
|
110
|
-
log.warn('install-hooks: settings.json unparseable, leaving alone', { error: e?.message ?? String(e) });
|
|
111
|
-
return { hookFileWritten, settingsWritten: false, added: 0, refreshed: 0, alreadyOk: 0, hookFilePath: hookFile };
|
|
112
|
-
}
|
|
165
|
+
const loaded = loadOrInitHookSettings(settings);
|
|
166
|
+
if (!loaded) {
|
|
167
|
+
return { hookFileWritten, settingsWritten: false, added: 0, refreshed: 0, alreadyOk: 0, hookFilePath: hookFile };
|
|
113
168
|
}
|
|
169
|
+
const { s, originalText } = loaded;
|
|
114
170
|
if (!s.hooks)
|
|
115
171
|
s.hooks = {};
|
|
116
172
|
let added = 0, refreshed = 0, alreadyOk = 0;
|
|
117
173
|
for (const name of HOOK_NAMES) {
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
if (!entry) {
|
|
121
|
-
entry = { matcher: '.*', hooks: [] };
|
|
122
|
-
arr.push(entry);
|
|
123
|
-
}
|
|
124
|
-
const desiredCmd = hookCommand(name, hookFile);
|
|
125
|
-
const existingIdx = entry.hooks.findIndex(isOurHook);
|
|
126
|
-
if (existingIdx >= 0) {
|
|
127
|
-
if (entry.hooks[existingIdx].command !== desiredCmd) {
|
|
128
|
-
entry.hooks[existingIdx] = { type: 'command', command: desiredCmd };
|
|
129
|
-
refreshed++;
|
|
130
|
-
}
|
|
131
|
-
else {
|
|
132
|
-
alreadyOk++;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
else {
|
|
136
|
-
entry.hooks.push({ type: 'command', command: desiredCmd });
|
|
174
|
+
const action = reconcileHookEvent(s, name, hookFile);
|
|
175
|
+
if (action === 'add')
|
|
137
176
|
added++;
|
|
138
|
-
|
|
177
|
+
else if (action === 'refresh')
|
|
178
|
+
refreshed++;
|
|
179
|
+
else
|
|
180
|
+
alreadyOk++;
|
|
139
181
|
}
|
|
140
182
|
// 3) Write only if the serialized form changed.
|
|
141
183
|
const newText = JSON.stringify(s, null, 2) + '\n';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../src/install-hooks.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,8DAA8D;AAC9D,mEAAmE;AACnE,wDAAwD;AACxD,EAAE;AACF,4BAA4B;AAC5B,oEAAoE;AACpE,qEAAqE;AACrE,gEAAgE;AAChE,uDAAuD;AACvD,8DAA8D;AAC9D,mEAAmE;AACnE,mEAAmE;AACnE,+DAA+D;AAC/D,yCAAyC;AAEzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,MAAM,UAAU,GAAG;IACjB,cAAc;IACd,YAAY;IACZ,kBAAkB;IAClB,YAAY;IACZ,aAAa;IACb,oBAAoB;IACpB,aAAa;IACb,eAAe;IACf,cAAc;IACd,eAAe;IACf,MAAM;IACN,cAAc;CACN,CAAC;AAEX,MAAM,GAAG,GAAG,mBAAmB,CAAC;AAWhC,SAAS,SAAS,CAAC,CAAuC;IACxD,OAAO,CAAC,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,WAAW,CAAC,IAAY,EAAE,YAAoB;IACrD,gEAAgE;IAChE,oEAAoE;IACpE,gEAAgE;IAChE,mEAAmE;IACnE,6DAA6D;IAC7D,8DAA8D;IAC9D,oEAAoE;IACpE,6DAA6D;IAC7D,4DAA4D;IAC5D,kEAAkE;IAClE,4BAA4B;IAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,SAAS,OAAO,KAAK,IAAI,KAAK,GAAG,EAAE,CAAC;AAC7C,CAAC;AAED,mEAAmE;AACnE,6DAA6D;AAC7D,mEAAmE;AACnE,+BAA+B;AAC/B,SAAS,mBAAmB;IAC1B,MAAM,UAAU,GAAG;QACjB,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,uBAAuB,CAAC;KAC/D,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"install-hooks.js","sourceRoot":"","sources":["../src/install-hooks.ts"],"names":[],"mappings":"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"}
|