@agentdeck/hooks 0.2.3 → 1.0.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/dist/install.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,IAAI,qBAAqB,EACzC,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,IAAI,mBAAmB,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIrH,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,eAAO,MAAM,WAAW,kHAQd,CAAC;AAEX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,IAAI,qBAAqB,EACzC,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,cAAc,IAAI,mBAAmB,EAAE,aAAa,IAAI,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAIrH,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE3F,eAAO,MAAM,WAAW,kHAQd,CAAC;AAEX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAqC1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAe7D;AAGD,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM;;;EAgB/C;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAuB7C;AAED,+EAA+E;AAC/E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAwB9C;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,QAAQ,EAAE,GAAG,GAAG;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAyChF;AAED,4EAA4E;AAC5E,wBAAgB,YAAY,IAAI,IAAI,CAkBnC;AAED,8EAA8E;AAC9E,wBAAgB,cAAc,IAAI,IAAI,CASrC;AAED;iEACiE;AACjE,wBAAgB,oBAAoB,IAAI,IAAI,CA+B3C"}
|
package/dist/install.js
CHANGED
|
@@ -49,16 +49,27 @@ export function buildHookCommand(eventName) {
|
|
|
49
49
|
`PORT="\${PORT:-9120}"`,
|
|
50
50
|
];
|
|
51
51
|
// PreToolUse is request-response: the daemon may hold the connection open and
|
|
52
|
-
// return a permission decision (device approval)
|
|
53
|
-
// to stdout so Claude can gate the tool; empty output
|
|
54
|
-
// = Claude's normal permission flow. `--max-time 60`
|
|
55
|
-
//
|
|
52
|
+
// return a permission decision (device approval) or a soft-STOP deny. Capture
|
|
53
|
+
// the body and echo it to stdout so Claude can gate the tool; empty output
|
|
54
|
+
// (timeout/error/disabled) = Claude's normal permission flow. `--max-time 60`
|
|
55
|
+
// exceeds the daemon's internal hold timeout (default 25s) so the fallback
|
|
56
|
+
// reaches Claude before curl quits.
|
|
56
57
|
if (eventName === 'PreToolUse') {
|
|
57
58
|
return preamble.concat([
|
|
58
59
|
`RESP=$(curl -s -X POST "http://127.0.0.1:$PORT/hooks/PreToolUse" -H 'Content-Type: application/json' --max-time 60 -d @- 2>/dev/null)`,
|
|
59
60
|
`printf '%s' "\${RESP:-}"`,
|
|
60
61
|
]).join('\n');
|
|
61
62
|
}
|
|
63
|
+
// Stop is also request-response: the daemon answers instantly — either an
|
|
64
|
+
// empty body (turn ends normally) or `{decision:"block", reason}` delivering
|
|
65
|
+
// a deck-queued directive so Claude continues with it. Short --max-time:
|
|
66
|
+
// this runs on EVERY turn end, so a wedged daemon must never stall the TUI.
|
|
67
|
+
if (eventName === 'Stop') {
|
|
68
|
+
return preamble.concat([
|
|
69
|
+
`RESP=$(curl -s -X POST "http://127.0.0.1:$PORT/hooks/Stop" -H 'Content-Type: application/json' --max-time 10 -d @- 2>/dev/null)`,
|
|
70
|
+
`printf '%s' "\${RESP:-}"`,
|
|
71
|
+
]).join('\n');
|
|
72
|
+
}
|
|
62
73
|
return preamble.concat([
|
|
63
74
|
`curl -sf -X POST "http://127.0.0.1:$PORT/hooks/${eventName}" -H 'Content-Type: application/json' -d @- 2>/dev/null || true`,
|
|
64
75
|
]).join('\n');
|
|
@@ -238,6 +249,12 @@ export function migrateHooksIfNeeded() {
|
|
|
238
249
|
applyHooks(settings);
|
|
239
250
|
migrated = true;
|
|
240
251
|
}
|
|
252
|
+
// Migration 5: upgrade fire-and-forget Stop hooks to the request-response
|
|
253
|
+
// form (turn-end directive queue needs the response echoed to Claude).
|
|
254
|
+
if (raw.includes('/hooks/Stop') && !/RESP=\$\(curl[^\n]*\/hooks\/Stop/.test(raw)) {
|
|
255
|
+
applyHooks(settings);
|
|
256
|
+
migrated = true;
|
|
257
|
+
}
|
|
241
258
|
if (migrated) {
|
|
242
259
|
writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n');
|
|
243
260
|
}
|
package/dist/install.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAE7B,oEAAoE;AACpE,2EAA2E;AAC3E,OAAO,EACL,yBAAyB,EACzB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,IAAI,qBAAqB,EACzC,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,0EAA0E;AAC1E,0EAA0E;AAC1E,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,uBAAuB,CAAC;AAG/B,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,MAAM;IACN,cAAc;IACd,kBAAkB;CACV,CAAC;AAEX;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,QAAQ,GAAG;QACf,6BAA6B;QAC7B,yBAAyB;QACzB,8OAA8O;QAC9O,6BAA6B;QAC7B,oHAAoH;QACpH,kHAAkH;QAClH,QAAQ;QACR,IAAI;QACJ,uBAAuB;KACxB,CAAC;IACF,8EAA8E;IAC9E
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-install.d.ts","sourceRoot":"","sources":["../src/opencode-install.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"opencode-install.d.ts","sourceRoot":"","sources":["../src/opencode-install.ts"],"names":[],"mappings":"AA8BA,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAEvD;;wEAEwE;AACxE,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AAED,MAAM,WAAW,sBAAsB;IACrC,iEAAiE;IACjE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,OAAO,CAAC;IACnB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAUD;;0CAE0C;AAC1C,wBAAgB,oBAAoB,IAAI,MAAM,CA+P7C;AAeD;;6EAE6E;AAC7E,wBAAgB,4BAA4B,CAAC,IAAI,GAAE,sBAA2B,GAAG,qBAAqB,CAerG;AAED,4EAA4E;AAC5E,wBAAgB,sBAAsB,CAAC,IAAI,GAAE,sBAA2B,GAAG,IAAI,CAK9E"}
|
package/dist/opencode-install.js
CHANGED
|
@@ -20,8 +20,9 @@
|
|
|
20
20
|
// Counterpart consumers:
|
|
21
21
|
// - bridge/src/daemon-server.ts /hooks/ handler (opencode_* → shared
|
|
22
22
|
// observed-session pipeline: APME run/turn + chat_start/chat_response)
|
|
23
|
-
//
|
|
24
|
-
//
|
|
23
|
+
// + GET /opencode/commands steering long-poll (opencode-steering.ts)
|
|
24
|
+
// - apple .../DaemonServer.swift ingests opencode_* (2026-07-12) and
|
|
25
|
+
// serves the same /opencode/commands queue (OpenCodeCommandQueue).
|
|
25
26
|
import { readFileSync, writeFileSync, existsSync, mkdirSync, renameSync, unlinkSync } from 'fs';
|
|
26
27
|
import { dirname, join } from 'path';
|
|
27
28
|
import { homedir } from 'os';
|
|
@@ -39,7 +40,7 @@ export function opencodePluginPath() {
|
|
|
39
40
|
function envOptOut() {
|
|
40
41
|
return process.env.AGENTDECK_NO_OPENCODE_HOOKS === '1';
|
|
41
42
|
}
|
|
42
|
-
const PLUGIN_VERSION =
|
|
43
|
+
const PLUGIN_VERSION = 2;
|
|
43
44
|
/** Assemble the plugin source. Exported so tests can assert schema
|
|
44
45
|
* regressions (event names, payload fields, managed-session guard)
|
|
45
46
|
* without driving the file installer. */
|
|
@@ -100,7 +101,69 @@ function post(event, body) {
|
|
|
100
101
|
}).catch(() => { /* daemon down — observation is best-effort */ });
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
|
|
104
|
+
// ── Steering loop ──
|
|
105
|
+
// The daemon queues device commands per session (soft/hard interrupt, prompt
|
|
106
|
+
// injection); this loop long-polls GET /opencode/commands and executes them
|
|
107
|
+
// through the in-process SDK client — abort is immediate, prompts land even
|
|
108
|
+
// while the session is idle. One loop per observed session; stops on
|
|
109
|
+
// opencode_stop-less session death via the poll's own error backoff.
|
|
110
|
+
const steerLoops = new Set();
|
|
111
|
+
|
|
112
|
+
function startSteerLoop(client, sessionID) {
|
|
113
|
+
if (!client || steerLoops.has(sessionID)) return;
|
|
114
|
+
steerLoops.add(sessionID);
|
|
115
|
+
(async () => {
|
|
116
|
+
let failures = 0;
|
|
117
|
+
while (steerLoops.has(sessionID)) {
|
|
118
|
+
const port = await resolvePort();
|
|
119
|
+
if (!port) { await new Promise((r) => setTimeout(r, 30000)); continue; }
|
|
120
|
+
try {
|
|
121
|
+
const r = await fetch(
|
|
122
|
+
"http://127.0.0.1:" + port + "/opencode/commands?sid=" + encodeURIComponent(sessionID) + "&wait=25",
|
|
123
|
+
{ signal: AbortSignal.timeout(32000) },
|
|
124
|
+
);
|
|
125
|
+
if (!r.ok) throw new Error("poll " + r.status);
|
|
126
|
+
failures = 0;
|
|
127
|
+
const { commands } = await r.json();
|
|
128
|
+
for (const cmd of commands || []) {
|
|
129
|
+
try {
|
|
130
|
+
if (cmd.type === "interrupt") {
|
|
131
|
+
await client.session.abort({ path: { id: sessionID } });
|
|
132
|
+
} else if (cmd.type === "send_prompt" && cmd.text) {
|
|
133
|
+
const body = { parts: [{ type: "text", text: cmd.text }] };
|
|
134
|
+
// promptAsync (POST /session/{id}/prompt_async) returns
|
|
135
|
+
// immediately; session.prompt BLOCKS until the whole assistant
|
|
136
|
+
// turn completes, so the older fallback must not be awaited or
|
|
137
|
+
// it would stall this loop for the entire turn.
|
|
138
|
+
if (client.session.promptAsync) await client.session.promptAsync({ path: { id: sessionID }, body });
|
|
139
|
+
else if (client.session.prompt) client.session.prompt({ path: { id: sessionID }, body }).catch(() => {});
|
|
140
|
+
else if (client.session.chat) client.session.chat({ path: { id: sessionID }, body }).catch(() => {});
|
|
141
|
+
} else if (cmd.type === "permission_respond" && cmd.permissionId) {
|
|
142
|
+
// Resolve a pending OpenCode permission from the device.
|
|
143
|
+
// "once" (not "always") keeps device-approval one-shot.
|
|
144
|
+
if (client.postSessionIdPermissionsPermissionId) {
|
|
145
|
+
await client.postSessionIdPermissionsPermissionId({
|
|
146
|
+
path: { id: sessionID, permissionID: cmd.permissionId },
|
|
147
|
+
body: { response: cmd.response === "allow" ? "once" : "reject" },
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
} catch { /* one bad command must not kill the loop */ }
|
|
152
|
+
}
|
|
153
|
+
} catch {
|
|
154
|
+
failures += 1;
|
|
155
|
+
// Backoff on repeated failures so a dead daemon costs one probe/30s.
|
|
156
|
+
await new Promise((r) => setTimeout(r, Math.min(30000, 1000 * failures)));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
})();
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function stopSteerLoop(sessionID) {
|
|
163
|
+
steerLoops.delete(sessionID);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
export const AgentDeckObserver = async ({ directory, client }) => {
|
|
104
167
|
// Managed \`agentdeck opencode\` sessions already stream structured SSE
|
|
105
168
|
// events through their session bridge; posting hooks too would
|
|
106
169
|
// double-count every turn. AGENTDECK_PORT marks a managed PTY.
|
|
@@ -119,6 +182,10 @@ export const AgentDeckObserver = async ({ directory }) => {
|
|
|
119
182
|
if (!sessionID || announced.has(sessionID)) return;
|
|
120
183
|
announced.add(sessionID);
|
|
121
184
|
post("opencode_session_start", { session_id: sessionID, cwd });
|
|
185
|
+
// Steering: start draining device commands for this session (abort /
|
|
186
|
+
// prompt injection through the in-process client). Loop lives for the
|
|
187
|
+
// opencode process lifetime — sessions in one TUI are few and cheap.
|
|
188
|
+
startSteerLoop(client, sessionID);
|
|
122
189
|
}
|
|
123
190
|
|
|
124
191
|
function sendPrompt(messageID, sessionID, prompt) {
|
|
@@ -140,6 +207,11 @@ export const AgentDeckObserver = async ({ directory }) => {
|
|
|
140
207
|
const sessionID = info.sessionID;
|
|
141
208
|
announce(sessionID);
|
|
142
209
|
if (info.role === "user" && info.id) {
|
|
210
|
+
// userMsgs/promptSent are dedup memory keyed on user messageID and
|
|
211
|
+
// must outlive the turn (see the session.idle note), so cap them
|
|
212
|
+
// here instead of clearing per turn — same bound as toolPhase.
|
|
213
|
+
if (userMsgs.size > 512) userMsgs.clear();
|
|
214
|
+
if (promptSent.size > 512) promptSent.clear();
|
|
143
215
|
userMsgs.set(info.id, sessionID);
|
|
144
216
|
// Prompt text usually streams via message.part.updated moments
|
|
145
217
|
// later; flush immediately when the info carries it, otherwise
|
|
@@ -176,6 +248,32 @@ export const AgentDeckObserver = async ({ directory }) => {
|
|
|
176
248
|
}
|
|
177
249
|
if (toolPhase.size > 512) toolPhase.clear();
|
|
178
250
|
}
|
|
251
|
+
} else if (type === "permission.asked" || type === "permission.updated") {
|
|
252
|
+
// OpenCode emits this only when it is GENUINELY asking the user —
|
|
253
|
+
// no prediction needed, zero false-positive risk. Forward it so
|
|
254
|
+
// devices can render Allow/Deny; the daemon replies through the
|
|
255
|
+
// steering queue as a permission_respond command.
|
|
256
|
+
const perm = props.permission || props.info || props || {};
|
|
257
|
+
const psid = perm.sessionID;
|
|
258
|
+
if (psid && perm.id) {
|
|
259
|
+
announce(psid);
|
|
260
|
+
post("opencode_permission_asked", {
|
|
261
|
+
session_id: psid,
|
|
262
|
+
permission_id: perm.id,
|
|
263
|
+
title: typeof perm.title === "string" ? perm.title : "",
|
|
264
|
+
cwd,
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
} else if (type === "permission.replied") {
|
|
268
|
+
const perm = props.permission || props.info || props || {};
|
|
269
|
+
const psid = perm.sessionID;
|
|
270
|
+
if (psid) {
|
|
271
|
+
post("opencode_permission_replied", {
|
|
272
|
+
session_id: psid,
|
|
273
|
+
permission_id: perm.id || "",
|
|
274
|
+
cwd,
|
|
275
|
+
});
|
|
276
|
+
}
|
|
179
277
|
} else if (type === "session.idle") {
|
|
180
278
|
const sessionID = props.sessionID;
|
|
181
279
|
announce(sessionID);
|
|
@@ -186,9 +284,15 @@ export const AgentDeckObserver = async ({ directory }) => {
|
|
|
186
284
|
});
|
|
187
285
|
responses.delete(sessionID);
|
|
188
286
|
startedAt.delete(sessionID);
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
287
|
+
// Do NOT clear userMsgs/promptSent for this session. OpenCode
|
|
288
|
+
// re-emits message.updated for a user message after the turn
|
|
289
|
+
// settles; dropping its promptSent entry let that trailing update
|
|
290
|
+
// re-post opencode_user_prompt_submit, which flips the row back to
|
|
291
|
+
// processing and opens a phantom turn. The session is already idle
|
|
292
|
+
// by then, so no session.idle follows to close it and the row reads
|
|
293
|
+
// WORKING until the 30-min idle TTL evicts it. A messageID is never
|
|
294
|
+
// re-submitted, so these entries are pure dedup memory — bounded
|
|
295
|
+
// where they are added, not here.
|
|
192
296
|
}
|
|
193
297
|
} catch { /* never throw into OpenCode's event loop */ }
|
|
194
298
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"opencode-install.js","sourceRoot":"","sources":["../src/opencode-install.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,uEAAuE;AACvE,sEAAsE;AACtE,EAAE;AACF,qEAAqE;AACrE,uEAAuE;AACvE,sEAAsE;AACtE,sEAAsE;AACtE,wEAAwE;AACxE,yEAAyE;AACzE,kEAAkE;AAClE,EAAE;AACF,yEAAyE;AACzE,sEAAsE;AACtE,iEAAiE;AACjE,sEAAsE;AACtE,yEAAyE;AACzE,2BAA2B;AAC3B,EAAE;AACF,yBAAyB;AACzB,uEAAuE;AACvE,2EAA2E;AAC3E,uEAAuE;AACvE,
|
|
1
|
+
{"version":3,"file":"opencode-install.js","sourceRoot":"","sources":["../src/opencode-install.ts"],"names":[],"mappings":"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"}
|