@scotthuang/agent-knock-knock 0.2.44 → 0.2.47

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +148 -242
  3. package/dist/src/approval-policy.d.ts +1 -0
  4. package/dist/src/approval-policy.js +6 -0
  5. package/dist/src/approval-policy.js.map +1 -1
  6. package/dist/src/claude-hook-installer.d.ts +65 -0
  7. package/dist/src/claude-hook-installer.js +410 -0
  8. package/dist/src/claude-hook-installer.js.map +1 -0
  9. package/dist/src/claude-hook-protocol.d.ts +89 -0
  10. package/dist/src/claude-hook-protocol.js +243 -0
  11. package/dist/src/claude-hook-protocol.js.map +1 -0
  12. package/dist/src/claude-hook-store.d.ts +247 -0
  13. package/dist/src/claude-hook-store.js +1064 -0
  14. package/dist/src/claude-hook-store.js.map +1 -0
  15. package/dist/src/claude-terminal-agent-adapter.d.ts +47 -0
  16. package/dist/src/claude-terminal-agent-adapter.js +920 -0
  17. package/dist/src/claude-terminal-agent-adapter.js.map +1 -0
  18. package/dist/src/cli.js +1565 -772
  19. package/dist/src/cli.js.map +1 -1
  20. package/dist/src/codex-session-provider.d.ts +6 -32
  21. package/dist/src/codex-session-provider.js +2 -1
  22. package/dist/src/codex-session-provider.js.map +1 -1
  23. package/dist/src/codex-store-adapter.d.ts +3 -9
  24. package/dist/src/codex-store-adapter.js +5 -55
  25. package/dist/src/codex-store-adapter.js.map +1 -1
  26. package/dist/src/codex-terminal-agent-adapter.d.ts +34 -0
  27. package/dist/src/codex-terminal-agent-adapter.js +386 -0
  28. package/dist/src/codex-terminal-agent-adapter.js.map +1 -0
  29. package/dist/src/openclaw-plugin.js +60 -11
  30. package/dist/src/openclaw-plugin.js.map +1 -1
  31. package/dist/src/protocol.d.ts +1 -1
  32. package/dist/src/terminal-agent-adapter.d.ts +158 -0
  33. package/dist/src/terminal-agent-adapter.js +109 -0
  34. package/dist/src/terminal-agent-adapter.js.map +1 -0
  35. package/dist/src/terminal-agent-bridge.d.ts +114 -0
  36. package/dist/src/terminal-agent-bridge.js +487 -0
  37. package/dist/src/terminal-agent-bridge.js.map +1 -0
  38. package/dist/src/terminal-agent-registry.d.ts +7 -0
  39. package/dist/src/terminal-agent-registry.js +24 -0
  40. package/dist/src/terminal-agent-registry.js.map +1 -0
  41. package/dist/src/terminal-control-provider.d.ts +8 -6
  42. package/dist/src/terminal-control-provider.js +5 -5
  43. package/dist/src/terminal-control-provider.js.map +1 -1
  44. package/dist/src/terminal-process-source.d.ts +25 -0
  45. package/dist/src/terminal-process-source.js +77 -0
  46. package/dist/src/terminal-process-source.js.map +1 -0
  47. package/openclaw.plugin.json +7 -3
  48. package/package.json +1 -1
  49. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +19 -16
@@ -0,0 +1,386 @@
1
+ import { createHash } from "node:crypto";
2
+ import { classifyCodexProcess } from "./codex-session-provider.js";
3
+ import { redactString } from "./runtime-log.js";
4
+ export function createCodexTerminalAgentAdapter(options = {}) {
5
+ return {
6
+ agent: "codex",
7
+ displayName: "Codex",
8
+ capabilities: {
9
+ processDiscovery: true,
10
+ screenStatus: true,
11
+ terminalApproval: true,
12
+ screenCompletion: true,
13
+ durableCompletion: true,
14
+ cancellation: true
15
+ },
16
+ cancelKeys: ["C-c"],
17
+ classifyProcess(snapshot) {
18
+ const process = classifyCodexProcess(snapshot);
19
+ return process?.kind === "codex_cli" ? process : undefined;
20
+ },
21
+ inspectScreen: inspectCodexScreen,
22
+ detectDurableCompletion: options.detectDurableCompletion ?? (async (request) => detectCodexDurableCompletion(request))
23
+ };
24
+ }
25
+ export const codexTerminalAgentAdapter = createCodexTerminalAgentAdapter();
26
+ export function inspectCodexScreen(options) {
27
+ const detectedApproval = detectCodexApprovalPrompt(options.screen);
28
+ const blocked = isCodexApprovalPromptVisible(options.screen);
29
+ const approval = detectedApproval.approvable
30
+ ? {
31
+ blocked: true,
32
+ approvable: true,
33
+ promptKind: detectedApproval.promptKind,
34
+ command: detectedApproval.command,
35
+ action: {
36
+ keys: detectedApproval.keys,
37
+ label: detectedApproval.label
38
+ }
39
+ }
40
+ : {
41
+ blocked,
42
+ approvable: false,
43
+ reason: detectedApproval.reason,
44
+ promptKind: detectedApproval.promptKind,
45
+ command: detectedApproval.command
46
+ };
47
+ const activity = detectCodexActivityState(options.screen, detectedApproval);
48
+ const screenExcerpt = codexScreenExcerpt(options.screen, options.maxExcerptLength ?? 4000);
49
+ const completion = activity.state === "idle"
50
+ ? detectCodexScreenCompletion({
51
+ screen: screenExcerpt,
52
+ requestText: options.requestText,
53
+ screenChangedSinceSend: options.screenChangedSinceSend
54
+ })
55
+ : undefined;
56
+ return {
57
+ activity,
58
+ approval,
59
+ screenExcerpt,
60
+ completion
61
+ };
62
+ }
63
+ export function detectCodexApprovalPrompt(screen) {
64
+ const prompt = codexApprovalPromptRegion(screen);
65
+ if (!prompt.visible) {
66
+ return {
67
+ approvable: false,
68
+ reason: prompt.reason
69
+ };
70
+ }
71
+ for (const line of prompt.region.split(/\r?\n/)) {
72
+ const match = /^[\s›]*1\.\s+(Yes,[^(]+)\(([^)]+)\)/u.exec(line.trim());
73
+ if (!match) {
74
+ continue;
75
+ }
76
+ const key = match[2].trim();
77
+ if (key !== "y") {
78
+ return {
79
+ approvable: false,
80
+ reason: `primary approval shortcut is ${key}, not y`,
81
+ ...approvalCandidateFromPrompt(prompt.marker, prompt.region)
82
+ };
83
+ }
84
+ return {
85
+ approvable: true,
86
+ key,
87
+ keys: [key],
88
+ label: match[1].trim(),
89
+ ...approvalCandidateFromPrompt(prompt.marker, prompt.region)
90
+ };
91
+ }
92
+ return {
93
+ approvable: false,
94
+ reason: "no primary approve option with a shortcut was detected",
95
+ ...approvalCandidateFromPrompt(prompt.marker, prompt.region)
96
+ };
97
+ }
98
+ export function isCodexApprovalPromptVisible(screen) {
99
+ return codexApprovalPromptRegion(screen).visible;
100
+ }
101
+ export function detectCodexActivityState(screen, approval = detectCodexApprovalPrompt(screen)) {
102
+ if (approval.approvable || isCodexApprovalPromptVisible(screen)) {
103
+ return {
104
+ state: "awaiting_approval",
105
+ reason: "current Codex approval prompt is visible"
106
+ };
107
+ }
108
+ const tailLines = screen.trimEnd().split(/\r?\n/).slice(-30);
109
+ const workingLine = tailLines.find((line) => isCodexWorkingLine(line));
110
+ if (workingLine) {
111
+ return {
112
+ state: "working",
113
+ reason: `Codex working marker detected: ${workingLine.trim()}`
114
+ };
115
+ }
116
+ const idleLine = tailLines
117
+ .slice(-6)
118
+ .map((line) => line.trim())
119
+ .find((line) => isCodexIdlePromptLine(line));
120
+ if (idleLine) {
121
+ return {
122
+ state: "idle",
123
+ reason: `Codex input prompt detected: ${idleLine}`
124
+ };
125
+ }
126
+ return {
127
+ state: "unknown",
128
+ reason: "no current Codex working, idle, or approval marker was detected in the terminal screen"
129
+ };
130
+ }
131
+ export function codexScreenExcerpt(screen, maxLength = 4000) {
132
+ const lines = screen.trimEnd().split(/\r?\n/);
133
+ const excerpt = lines.slice(Math.max(0, lines.length - 80)).join("\n");
134
+ return redactString(excerpt).slice(-maxLength);
135
+ }
136
+ export function detectCodexScreenCompletion({ screen, requestText, screenChangedSinceSend }) {
137
+ const request = requestText?.trim() ?? "";
138
+ const promptEnd = request ? whitespaceInsensitiveMatchEnd(screen, request) : undefined;
139
+ const afterPrompt = promptEnd === undefined ? undefined : screen.slice(promptEnd);
140
+ const completionBoundary = afterPrompt === undefined
141
+ ? undefined
142
+ : codexCompletionBoundary(afterPrompt);
143
+ const completionText = afterPrompt === undefined
144
+ ? screenChangedSinceSend
145
+ ? latestCompletedCodexSegment(screen)
146
+ : undefined
147
+ : completionBoundary === undefined
148
+ ? afterPrompt
149
+ : afterPrompt.slice(0, completionBoundary);
150
+ if (completionText === undefined) {
151
+ return undefined;
152
+ }
153
+ const cleaned = cleanCodexTerminalScreenText(completionText);
154
+ const hasCompletionEvidence = promptEnd === undefined || completionBoundary !== undefined || /[•└]/u.test(cleaned ?? "");
155
+ if (!cleaned || cleaned.length < 40 || !hasCompletionEvidence) {
156
+ return undefined;
157
+ }
158
+ return {
159
+ source: "screen",
160
+ text: truncateText(redactString(cleaned), 4000),
161
+ confidence: "screen_only"
162
+ };
163
+ }
164
+ export function detectCodexDurableCompletion(request) {
165
+ const context = asForkContextPackage(request.context);
166
+ const threshold = validTimestampMs(request.startedAt);
167
+ const expectedRequestHash = request.requestHash ?? requestFingerprint(request.requestText);
168
+ if (!context || threshold === undefined || !expectedRequestHash) {
169
+ return undefined;
170
+ }
171
+ const turn = [...context.turns]
172
+ .reverse()
173
+ .find((candidate) => {
174
+ const userTimestamp = validTimestampMs(candidate.userTimestamp);
175
+ const completedAt = validTimestampMs(candidate.completedAt);
176
+ return candidate.userTextHash === expectedRequestHash &&
177
+ userTimestamp !== undefined &&
178
+ completedAt !== undefined &&
179
+ userTimestamp >= threshold &&
180
+ completedAt >= userTimestamp &&
181
+ Boolean(candidate.lastAssistantMessage);
182
+ });
183
+ if (!turn?.lastAssistantMessage) {
184
+ return undefined;
185
+ }
186
+ return {
187
+ source: "durable",
188
+ text: turn.lastAssistantMessage,
189
+ timestamp: turn.completedAt,
190
+ id: turn.turnId,
191
+ confidence: "high",
192
+ metadata: {
193
+ match: "rollout_task_complete",
194
+ userTimestamp: turn.userTimestamp,
195
+ session: context.source
196
+ }
197
+ };
198
+ }
199
+ function codexApprovalPromptRegion(screen) {
200
+ const approvalMarkers = [
201
+ "Would you like to run the following command?",
202
+ "Would you like to make the following edits?",
203
+ "Would you like to grant these permissions?",
204
+ "needs your approval."
205
+ ];
206
+ const lines = screen.split(/\r?\n/);
207
+ let markerIndex = -1;
208
+ let matchedMarker = "";
209
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
210
+ const marker = approvalMarkers.find((candidate) => lines[index].includes(candidate));
211
+ if (marker) {
212
+ markerIndex = index;
213
+ matchedMarker = marker;
214
+ break;
215
+ }
216
+ }
217
+ if (markerIndex < 0) {
218
+ return {
219
+ visible: false,
220
+ reason: "no Codex approval prompt was detected in the terminal screen"
221
+ };
222
+ }
223
+ const regionLines = lines.slice(markerIndex);
224
+ const staleLine = regionLines.slice(1).find((line) => isPostApprovalActivityLine(line));
225
+ if (staleLine) {
226
+ return {
227
+ visible: false,
228
+ reason: `Codex approval prompt appears stale after later terminal activity: ${staleLine.trim()}`
229
+ };
230
+ }
231
+ return {
232
+ visible: true,
233
+ region: regionLines.join("\n"),
234
+ marker: matchedMarker
235
+ };
236
+ }
237
+ function approvalCandidateFromPrompt(marker, region) {
238
+ const promptKind = marker === "Would you like to run the following command?"
239
+ ? "run_command"
240
+ : marker === "Would you like to make the following edits?"
241
+ ? "file_edit"
242
+ : marker === "Would you like to grant these permissions?"
243
+ ? "grant_permissions"
244
+ : "unknown";
245
+ return {
246
+ promptKind,
247
+ command: promptKind === "run_command" ? commandFromApprovalRegion(region) : undefined
248
+ };
249
+ }
250
+ function commandFromApprovalRegion(region) {
251
+ const lines = region.split(/\r?\n/);
252
+ const commandStart = lines.findIndex((line) => /^\s*\$\s+/u.test(line));
253
+ if (commandStart < 0) {
254
+ return undefined;
255
+ }
256
+ const parts = [];
257
+ for (let index = commandStart; index < lines.length; index += 1) {
258
+ const line = lines[index];
259
+ if (index > commandStart && (!line.trim() || /^[\s›]*\d+\.\s+/u.test(line) || /Press enter to confirm/u.test(line))) {
260
+ break;
261
+ }
262
+ parts.push(index === commandStart ? line.replace(/^\s*\$\s+/u, "").trim() : line.trim());
263
+ }
264
+ const command = parts.filter(Boolean).join(" ").trim();
265
+ return command ? redactString(command) : undefined;
266
+ }
267
+ function isPostApprovalActivityLine(line) {
268
+ const trimmed = line.trim();
269
+ if (!trimmed) {
270
+ return false;
271
+ }
272
+ if (/^✔\s+You approved\b/u.test(trimmed)) {
273
+ return true;
274
+ }
275
+ if (/^›\s+(?!1\.)\S/u.test(trimmed)) {
276
+ return true;
277
+ }
278
+ if (/^•\s+(Working|Ran|Explored|Edited|Read|Called|Searching|Planning|Updated|Added|Deleted|Modified|Running|Thinking)\b/u.test(trimmed)) {
279
+ return true;
280
+ }
281
+ return /^─\s*Worked for\b/u.test(trimmed);
282
+ }
283
+ function isCodexWorkingLine(line) {
284
+ const trimmed = line.trim();
285
+ if (!trimmed) {
286
+ return false;
287
+ }
288
+ if (/^•\s+Working\b/u.test(trimmed) && (/\besc to interrupt\b/u.test(trimmed) || trimmed === "• Working")) {
289
+ return true;
290
+ }
291
+ if (/^•\s+Waiting for background terminals?\b(?:\s*·|$)/u.test(trimmed)) {
292
+ return true;
293
+ }
294
+ return /^\d+\s+background terminals? running\b/u.test(trimmed) && /\/(?:ps|stop)\b/u.test(trimmed);
295
+ }
296
+ function isCodexIdlePromptLine(line) {
297
+ const trimmed = line.trim();
298
+ return /^›(?:\s|$)/u.test(trimmed) && !/^›\s*1\./u.test(trimmed);
299
+ }
300
+ function whitespaceInsensitiveMatchEnd(text, expected) {
301
+ const normalizedExpected = expected.replace(/\s/gu, "");
302
+ if (!normalizedExpected) {
303
+ return undefined;
304
+ }
305
+ let normalizedText = "";
306
+ const sourceEnds = [];
307
+ for (let index = 0; index < text.length;) {
308
+ const codePoint = text.codePointAt(index);
309
+ if (codePoint === undefined) {
310
+ break;
311
+ }
312
+ const character = String.fromCodePoint(codePoint);
313
+ if (!/\s/u.test(character)) {
314
+ normalizedText += character;
315
+ for (let codeUnit = 0; codeUnit < character.length; codeUnit += 1) {
316
+ sourceEnds.push(index + character.length);
317
+ }
318
+ }
319
+ index += character.length;
320
+ }
321
+ const matchIndex = normalizedText.lastIndexOf(normalizedExpected);
322
+ if (matchIndex < 0) {
323
+ return undefined;
324
+ }
325
+ return sourceEnds[matchIndex + normalizedExpected.length - 1];
326
+ }
327
+ function latestCompletedCodexSegment(text) {
328
+ const matches = [...text.matchAll(/^[ \t]*[─━-]+\s+Worked for\b.*$/gmu)];
329
+ const completion = matches.at(-1);
330
+ if (completion?.index === undefined) {
331
+ return undefined;
332
+ }
333
+ const previousCompletion = matches.at(-2);
334
+ let start = previousCompletion?.index === undefined
335
+ ? 0
336
+ : previousCompletion.index + previousCompletion[0].length;
337
+ const beforeCompletion = text.slice(0, completion.index);
338
+ const prompts = [...beforeCompletion.matchAll(/^[ \t]*›(?:\s|$).*$/gmu)];
339
+ const latestPrompt = prompts.at(-1);
340
+ if (latestPrompt?.index !== undefined && latestPrompt.index >= start) {
341
+ start = latestPrompt.index + latestPrompt[0].length;
342
+ }
343
+ return text.slice(start, completion.index);
344
+ }
345
+ function codexCompletionBoundary(text) {
346
+ const matches = [...text.matchAll(/^[ \t]*[─━-]+\s+Worked for\b.*$/gmu)];
347
+ return matches.at(-1)?.index;
348
+ }
349
+ function cleanCodexTerminalScreenText(text) {
350
+ const lines = text
351
+ .split(/\r?\n/)
352
+ .map((line) => line.replace(/\s+$/u, ""))
353
+ .filter((line) => {
354
+ const trimmed = line.trim();
355
+ return trimmed &&
356
+ !trimmed.startsWith("› Use /skills") &&
357
+ !/^gpt-[\w.-]+/u.test(trimmed) &&
358
+ !/^[-\w.]+ default ·/u.test(trimmed);
359
+ });
360
+ const cleaned = lines.join("\n").trim();
361
+ return cleaned || undefined;
362
+ }
363
+ function asForkContextPackage(value) {
364
+ if (!value || typeof value !== "object") {
365
+ return undefined;
366
+ }
367
+ const context = value;
368
+ return context.source && Array.isArray(context.turns)
369
+ ? context
370
+ : undefined;
371
+ }
372
+ function validTimestampMs(value) {
373
+ const parsed = Date.parse(String(value ?? ""));
374
+ return Number.isFinite(parsed) ? parsed : undefined;
375
+ }
376
+ function requestFingerprint(value) {
377
+ const text = String(value ?? "").replace(/\s+/gu, " ").trim();
378
+ return text ? createHash("sha256").update(text).digest("hex") : undefined;
379
+ }
380
+ function truncateText(text, maxLength) {
381
+ if (text.length <= maxLength) {
382
+ return text;
383
+ }
384
+ return `${text.slice(0, Math.max(0, maxLength - 15)).trimEnd()}... [truncated]`;
385
+ }
386
+ //# sourceMappingURL=codex-terminal-agent-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-terminal-agent-adapter.js","sourceRoot":"","sources":["../../src/codex-terminal-agent-adapter.ts"],"names":[],"mappings":"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"}
@@ -144,6 +144,20 @@ const renewParameters = {
144
144
  }
145
145
  }
146
146
  };
147
+ const retryCallbackParameters = {
148
+ type: "object",
149
+ additionalProperties: false,
150
+ required: ["conversation_id"],
151
+ properties: {
152
+ conversation_id: {
153
+ type: "string",
154
+ description: "AKK-managed conversation whose persisted callback delivery is pending or failed."
155
+ },
156
+ storeDir: {
157
+ type: "string"
158
+ }
159
+ }
160
+ };
147
161
  const statusParameters = {
148
162
  type: "object",
149
163
  additionalProperties: false,
@@ -151,7 +165,7 @@ const statusParameters = {
151
165
  properties: {
152
166
  conversation_id: {
153
167
  type: "string",
154
- description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:tmux:codex-work:0.1:33389."
168
+ description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:v2:tmux:codex:codex-work:0.1:33389."
155
169
  },
156
170
  storeDir: {
157
171
  type: "string"
@@ -201,7 +215,7 @@ const sendParameters = {
201
215
  properties: {
202
216
  conversation_id: {
203
217
  type: "string",
204
- description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:tmux:codex-work:0.1:33389. When the user refers to a listed tmux target like my-work:0.1, resolve it to the terminal-controlled id from AKK list before sending."
218
+ description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:v2:tmux:codex:codex-work:0.1:33389. When the user refers to a listed tmux target like my-work:0.1, resolve it to the terminal-controlled id from AKK list before sending."
205
219
  },
206
220
  message: {
207
221
  type: "string"
@@ -240,7 +254,7 @@ const cancelParameters = {
240
254
  properties: {
241
255
  conversation_id: {
242
256
  type: "string",
243
- description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:tmux:codex-work:0.1:33389."
257
+ description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:v2:tmux:codex:codex-work:0.1:33389."
244
258
  },
245
259
  allProxy: {
246
260
  type: "string"
@@ -374,11 +388,15 @@ const agentTakeoverParameters = {
374
388
  const approveParameters = {
375
389
  type: "object",
376
390
  additionalProperties: false,
377
- required: ["conversation_id"],
391
+ required: ["conversation_id", "expected_approval_fingerprint"],
378
392
  properties: {
379
393
  conversation_id: {
380
394
  type: "string",
381
- description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:tmux:codex-work:0.1:33389."
395
+ description: "AKK-managed conversation id, or a terminal-controlled id from AKK list such as terminal:v2:tmux:codex:codex-work:0.1:33389."
396
+ },
397
+ expected_approval_fingerprint: {
398
+ type: "string",
399
+ description: "Exact approval fingerprint returned by the latest status or approval-required callback. The prompt is captured again and must still match before keys are sent."
382
400
  },
383
401
  storeDir: {
384
402
  type: "string"
@@ -435,7 +453,7 @@ export default definePluginEntry({
435
453
  }), { name: "agent_knock_knock_delegate", optional: true });
436
454
  registerCliTool(api, {
437
455
  name: "agent_knock_knock_list",
438
- description: "List Agent Knock Knock work and local active coding-agent sessions. Use this for AKK list, akk list, current AKK tasks, native Codex active work, terminal-controlled Codex work, or asking which Codex/Claude/Cursor sessions are open. The result separates delegated AKK tasks, native active processes, and terminal-controlled sessions; terminal-controlled entries include approval state when available.",
456
+ description: "List Agent Knock Knock work and local active coding-agent sessions. Use this for AKK list, current AKK tasks, native Codex work, terminal-controlled Codex or Claude Code work, or asking which coding-agent sessions are open. The result separates delegated tasks, native processes, and terminal-controlled sessions; terminal entries include approval state when available.",
439
457
  parameters: listParameters,
440
458
  buildArgs: (params) => {
441
459
  const args = ["list"];
@@ -474,7 +492,7 @@ export default definePluginEntry({
474
492
  });
475
493
  registerCliTool(api, {
476
494
  name: "agent_knock_knock_describe",
477
- description: "Describe what a listed Agent Knock Knock or local Codex session is about. Use this when the user asks what a session/task/drawing is doing, what the original work was, or wants a reminder of a session's content. It summarizes AKK history when available, otherwise Codex rollout history, cwd-based inferred history, or terminal screen fallback with confidence and limitations.",
495
+ description: "Describe what a listed Agent Knock Knock or local coding-agent session is about. It summarizes AKK history when available, otherwise uses supported durable agent context or a conservative terminal-screen fallback with confidence and limitations.",
478
496
  parameters: describeParameters,
479
497
  buildArgs: (params) => {
480
498
  const args = ["describe", "--conversation", requiredString(params.conversation_id, "conversation_id")];
@@ -488,7 +506,7 @@ export default definePluginEntry({
488
506
  });
489
507
  registerCliTool(api, {
490
508
  name: "agent_knock_knock_send",
491
- description: "Send a message, follow-up, or new task to an existing open Agent Knock Knock coding-agent session or terminal-controlled session from AKK list. Use this when the user says to send/tell/ask/forward/add/continue work in a listed session, a listed Codex terminal, a tmux target such as my-work:0.1, or the one from AKK list. Do not start a new delegate for those requests. This is an asynchronous handoff: after the message is accepted, end the OpenClaw turn and wait for an Agent Knock Knock callback or a later explicit status request. Do not poll terminal output or wait for the coding agent's final result in the same OpenClaw turn.",
509
+ description: "Send a message, follow-up, or new task to an existing open Agent Knock Knock or terminal-controlled coding-agent session from AKK list, including Codex or Claude Code in tmux. Do not start a new delegate for those requests. This is asynchronous: after acceptance, end the OpenClaw turn and wait for the AKK callback or a later explicit status request.",
492
510
  parameters: sendParameters,
493
511
  buildArgs: (params, toolContext) => {
494
512
  const config = isRecord(api.pluginConfig) ? api.pluginConfig : {};
@@ -524,17 +542,18 @@ export default definePluginEntry({
524
542
  });
525
543
  registerCliTool(api, {
526
544
  name: "agent_knock_knock_approve",
527
- description: "Approve the current visible terminal approval prompt for an AKK terminal-controlled session. Use only after showing the user the detected prompt and receiving explicit approval. This sends the primary approve shortcut to the controlled terminal pane.",
545
+ description: "Approve the current AKK terminal permission request after showing it to the user and receiving explicit approval. Claude Code uses a revalidated structured one-time Hook decision; supported screen fallbacks use the detected primary shortcut and are never eligible for Claude auto-approval.",
528
546
  parameters: approveParameters,
529
547
  buildArgs: (params) => {
530
548
  const args = ["approve", "--conversation", requiredString(params.conversation_id, "conversation_id")];
549
+ pushOptional(args, "--expected-approval-fingerprint", requiredString(params.expected_approval_fingerprint, "expected_approval_fingerprint"));
531
550
  pushOptional(args, "--store-dir", stringValue(params.storeDir) ?? stringValue(api.pluginConfig?.storeDir));
532
551
  return args;
533
552
  }
534
553
  });
535
554
  registerCliTool(api, {
536
555
  name: "agent_knock_knock_renew",
537
- description: "Renew monitoring for a stalled AKK-managed terminal bridge task without sending text or keys to Codex. Use this when the user wants a still-live long-running terminal task to keep monitoring after an inactivity stall.",
556
+ description: "Renew monitoring for a stalled AKK-managed terminal bridge task without sending text or keys to the coding agent. Use this when the user wants a still-live long-running terminal task to keep monitoring after an inactivity stall.",
538
557
  parameters: renewParameters,
539
558
  buildArgs: (params) => {
540
559
  const config = isRecord(api.pluginConfig) ? api.pluginConfig : {};
@@ -544,9 +563,20 @@ export default definePluginEntry({
544
563
  return args;
545
564
  }
546
565
  });
566
+ registerCliTool(api, {
567
+ name: "agent_knock_knock_retry_callback",
568
+ description: "Retry a persisted AKK callback that failed before reaching OpenClaw. The original callback message id is reused for idempotent delivery, and the task closes only after delivery succeeds.",
569
+ parameters: retryCallbackParameters,
570
+ buildArgs: (params) => {
571
+ const config = isRecord(api.pluginConfig) ? api.pluginConfig : {};
572
+ const args = ["retry-callback", "--conversation", requiredString(params.conversation_id, "conversation_id")];
573
+ pushOptional(args, "--store-dir", stringValue(params.storeDir) ?? stringValue(config.storeDir));
574
+ return args;
575
+ }
576
+ });
547
577
  registerCliTool(api, {
548
578
  name: "agent_knock_knock_cancel",
549
- description: "Request cancellation for an existing Agent Knock Knock Codex, Claude, or Cursor session. Delegated sessions use cooperative ACPX cancellation. Terminal-controlled sessions send Control-C to the controlled terminal pane. This does not close the AKK session; use close when the session should no longer be reused.",
579
+ description: "Cancel an existing Agent Knock Knock Codex, Claude, or Cursor task. Delegated sessions use cooperative ACPX cancellation. Terminal-controlled Claude denies a pending structured permission or sends Escape; other adapters use their declared interrupt keys. The underlying tmux pane remains open.",
550
580
  parameters: cancelParameters,
551
581
  buildArgs: (params) => {
552
582
  const args = ["cancel", "--conversation", requiredString(params.conversation_id, "conversation_id")];
@@ -682,6 +712,13 @@ async function handleAkkCommand(api, ctx) {
682
712
  const result = runCli(api, args);
683
713
  return { text: formatRenewCommandResult(result) };
684
714
  }
715
+ if (parsed.action === "retry-callback" || parsed.action === "retry") {
716
+ const config = isRecord(api.pluginConfig) ? api.pluginConfig : {};
717
+ const args = ["retry-callback", "--conversation", parsed.conversationId];
718
+ pushOptional(args, "--store-dir", stringValue(config.storeDir));
719
+ const result = runCli(api, args);
720
+ return { text: formatRetryCallbackCommandResult(result) };
721
+ }
685
722
  if (parsed.action === "cancel") {
686
723
  const args = [
687
724
  "cancel",
@@ -766,6 +803,10 @@ function parseAkkCommand(args) {
766
803
  }
767
804
  return { action: "renew", conversationId, minutes: minutes || undefined };
768
805
  }
806
+ if (action === "retry-callback" || action === "retry") {
807
+ const { token: conversationId } = takeRequiredToken(rest, "Usage: /akk retry-callback <conversation-id>");
808
+ return { action: "retry-callback", conversationId };
809
+ }
769
810
  if (action === "recover") {
770
811
  const { token: conversationId } = takeRequiredToken(rest, "Usage: /akk recover <conversation-id>");
771
812
  return { action: "recover", conversationId };
@@ -814,6 +855,7 @@ function akkUsageText() {
814
855
  "/akk send <conversation-id> <message>",
815
856
  "/akk cancel <conversation-id>",
816
857
  "/akk renew <conversation-id> [minutes]",
858
+ "/akk retry-callback <conversation-id>",
817
859
  "/akk recover <conversation-id>",
818
860
  "/akk close <conversation-id> [reason]"
819
861
  ].join("\n");
@@ -867,6 +909,13 @@ function formatRenewCommandResult(result) {
867
909
  "No message or key was sent to the coding agent."
868
910
  ].join("\n");
869
911
  }
912
+ function formatRetryCallbackCommandResult(result) {
913
+ return [
914
+ `AKK callback delivered: ${result.conversation?.conversation_id ?? "unknown"}`,
915
+ `status: ${result.conversation?.status ?? "unknown"}`,
916
+ `attempts: ${result.conversation?.callback_delivery?.attempts ?? "unknown"}`
917
+ ].join("\n");
918
+ }
870
919
  function formatDescribeCommandResult(result) {
871
920
  const lines = [
872
921
  `AKK description: ${result.conversation_id ?? "unknown"}`,