@scotthuang/agent-knock-knock 0.2.51 → 0.3.0-beta.2

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.
@@ -0,0 +1,330 @@
1
+ import { createHash } from "node:crypto";
2
+ import { isExecutorKind } from "./executors.js";
3
+ const SHORT_REF_DOMAIN = "agent-knock-knock/session-ref/v1\0";
4
+ export const DEFAULT_SESSION_SHORT_REF_LENGTH = 10;
5
+ export class SessionSelectorError extends Error {
6
+ code;
7
+ selector;
8
+ candidates;
9
+ constructor(options) {
10
+ super(options.message);
11
+ this.name = "SessionSelectorError";
12
+ this.code = options.code;
13
+ this.selector = options.selector;
14
+ this.candidates = Object.freeze([...(options.candidates ?? [])]);
15
+ }
16
+ }
17
+ /**
18
+ * Produce a stable, opaque reference that does not depend on list order or on
19
+ * the other currently visible sessions.
20
+ */
21
+ export function sessionShortRef(id, length = DEFAULT_SESSION_SHORT_REF_LENGTH) {
22
+ const normalizedId = requireNonEmptyString(id, "session id");
23
+ if (!Number.isInteger(length) || length < 6 || length > 64) {
24
+ throw new TypeError("short reference length must be an integer between 6 and 64");
25
+ }
26
+ const digest = createHash("sha256")
27
+ .update(SHORT_REF_DOMAIN, "utf8")
28
+ .update(normalizedId, "utf8")
29
+ .digest("hex");
30
+ return `@${digest.slice(0, length)}`;
31
+ }
32
+ /**
33
+ * Return display-ready candidate details in a deterministic order.
34
+ */
35
+ export function sessionSelectorCandidateDetails(candidates, options = {}) {
36
+ const normalized = normalizeCandidates(candidates);
37
+ const shortRefLength = normalizedShortRefLength(options.shortRefLength);
38
+ return [...normalized]
39
+ .sort(compareCandidates)
40
+ .map((candidate) => detailFor(candidate, shortRefLength));
41
+ }
42
+ /**
43
+ * Resolve a user-facing selector to one authoritative id.
44
+ *
45
+ * This function only resolves identity. The caller must still revalidate any
46
+ * PID, tmux pane/socket, native session id, or process identity immediately
47
+ * before performing a side effect.
48
+ */
49
+ export function resolveSessionSelector(selector, candidates, options = {}) {
50
+ const normalizedCandidates = normalizeCandidates(candidates);
51
+ const shortRefLength = normalizedShortRefLength(options.shortRefLength);
52
+ const operation = normalizedOperation(options.operation);
53
+ const trimmedSelector = typeof selector === "string" ? selector.trim() : "";
54
+ const selectorForError = trimmedSelector || undefined;
55
+ // Complete ids are authoritative and case-sensitive. Check them before
56
+ // reserved selector words so even an unusual id such as "latest" remains
57
+ // addressable by its complete id.
58
+ if (trimmedSelector) {
59
+ const fullIdMatches = normalizedCandidates.filter((candidate) => candidate.id === trimmedSelector);
60
+ if (fullIdMatches.length > 0) {
61
+ return resolveExactMatches({
62
+ matches: fullIdMatches,
63
+ selector: trimmedSelector,
64
+ matchedBy: "full_id",
65
+ operation,
66
+ shortRefLength
67
+ });
68
+ }
69
+ }
70
+ const actionable = normalizedCandidates.filter((candidate) => candidate.actionable);
71
+ if (!trimmedSelector || trimmedSelector.toLowerCase() === "only") {
72
+ const matchedBy = trimmedSelector ? "only" : "implicit_only";
73
+ return resolveOnly({
74
+ matches: actionable,
75
+ allCandidates: normalizedCandidates,
76
+ selector: selectorForError,
77
+ matchedBy,
78
+ operation,
79
+ shortRefLength
80
+ });
81
+ }
82
+ const normalizedSelector = trimmedSelector.toLowerCase();
83
+ if (normalizedSelector === "latest") {
84
+ return resolveLatest({
85
+ matches: actionable,
86
+ allCandidates: normalizedCandidates,
87
+ selector: trimmedSelector,
88
+ matchedBy: "latest",
89
+ operation,
90
+ shortRefLength
91
+ });
92
+ }
93
+ if (isExecutorKind(normalizedSelector)) {
94
+ const allAgentMatches = normalizedCandidates.filter((candidate) => candidate.agent === normalizedSelector);
95
+ return resolveOnly({
96
+ matches: allAgentMatches.filter((candidate) => candidate.actionable),
97
+ allCandidates: allAgentMatches,
98
+ selector: trimmedSelector,
99
+ matchedBy: "agent",
100
+ operation,
101
+ shortRefLength
102
+ });
103
+ }
104
+ const agentLatestMatch = /^(codex|claude|cursor):latest$/u.exec(normalizedSelector);
105
+ if (agentLatestMatch) {
106
+ const agent = agentLatestMatch[1];
107
+ const allAgentMatches = normalizedCandidates.filter((candidate) => candidate.agent === agent);
108
+ return resolveLatest({
109
+ matches: allAgentMatches.filter((candidate) => candidate.actionable),
110
+ allCandidates: allAgentMatches,
111
+ selector: trimmedSelector,
112
+ matchedBy: "agent_latest",
113
+ operation,
114
+ shortRefLength
115
+ });
116
+ }
117
+ if (/^@[0-9a-f]+$/iu.test(trimmedSelector)) {
118
+ const shortRefMatches = normalizedCandidates.filter((candidate) => sessionShortRef(candidate.id, shortRefLength).toLowerCase() === normalizedSelector);
119
+ if (shortRefMatches.length > 0) {
120
+ return resolveExactMatches({
121
+ matches: shortRefMatches,
122
+ selector: trimmedSelector,
123
+ matchedBy: "short_ref",
124
+ operation,
125
+ shortRefLength
126
+ });
127
+ }
128
+ }
129
+ const details = candidateDetails(actionable, shortRefLength);
130
+ throw new SessionSelectorError({
131
+ code: "not_found",
132
+ selector: trimmedSelector,
133
+ candidates: details,
134
+ message: [
135
+ `Session selector ${quote(trimmedSelector)} did not match an actionable target${operationSuffix(operation)}.`,
136
+ candidateHint(details)
137
+ ].filter(Boolean).join(" ")
138
+ });
139
+ }
140
+ function resolveExactMatches(options) {
141
+ if (options.matches.length > 1) {
142
+ const details = candidateDetails(options.matches, options.shortRefLength);
143
+ throw new SessionSelectorError({
144
+ code: "ambiguous",
145
+ selector: options.selector,
146
+ candidates: details,
147
+ message: [
148
+ `Session selector ${quote(options.selector)} is ambiguous.`,
149
+ candidateHint(details)
150
+ ].join(" ")
151
+ });
152
+ }
153
+ const candidate = options.matches[0];
154
+ if (!candidate.actionable) {
155
+ const details = candidateDetails(options.matches, options.shortRefLength);
156
+ throw new SessionSelectorError({
157
+ code: "not_actionable",
158
+ selector: options.selector,
159
+ candidates: details,
160
+ message: `Session ${quote(candidate.id)} is not actionable${operationSuffix(options.operation)}.`
161
+ });
162
+ }
163
+ return resolution(candidate, options.selector, options.matchedBy, options.shortRefLength);
164
+ }
165
+ function resolveOnly(options) {
166
+ if (options.matches.length === 1) {
167
+ return resolution(options.matches[0], options.selector, options.matchedBy, options.shortRefLength);
168
+ }
169
+ if (options.matches.length === 0) {
170
+ throwNoActionable(options);
171
+ }
172
+ throwAmbiguous(options);
173
+ }
174
+ function resolveLatest(options) {
175
+ if (options.matches.length === 0) {
176
+ throwNoActionable(options);
177
+ }
178
+ if (options.matches.length === 1) {
179
+ return resolution(options.matches[0], options.selector, options.matchedBy, options.shortRefLength);
180
+ }
181
+ // If any candidate lacks recency, choosing another candidate as "latest"
182
+ // would be a guess. Equal newest timestamps are also intentionally ambiguous.
183
+ if (options.matches.some((candidate) => candidate.updatedAtMs === undefined)) {
184
+ throwAmbiguous(options, "latest cannot be determined because recency is missing");
185
+ }
186
+ const newestTimestamp = Math.max(...options.matches.map((candidate) => candidate.updatedAtMs));
187
+ const newest = options.matches.filter((candidate) => candidate.updatedAtMs === newestTimestamp);
188
+ if (newest.length !== 1) {
189
+ throwAmbiguous({ ...options, matches: newest }, "latest is tied between multiple targets");
190
+ }
191
+ return resolution(newest[0], options.selector, options.matchedBy, options.shortRefLength);
192
+ }
193
+ function throwNoActionable(options) {
194
+ const details = candidateDetails(options.allCandidates, options.shortRefLength);
195
+ const hasCandidates = options.allCandidates.length > 0;
196
+ throw new SessionSelectorError({
197
+ code: hasCandidates ? "not_actionable" : "no_actionable_targets",
198
+ selector: options.selector,
199
+ candidates: details,
200
+ message: hasCandidates
201
+ ? `No matching session is actionable${operationSuffix(options.operation)}. ${candidateHint(details)}`
202
+ : `There are no actionable sessions${operationSuffix(options.operation)}.`
203
+ });
204
+ }
205
+ function throwAmbiguous(options, reason = "multiple actionable targets match") {
206
+ const details = candidateDetails(options.matches, options.shortRefLength);
207
+ const subject = options.selector
208
+ ? `Session selector ${quote(options.selector)}`
209
+ : "The omitted session selector";
210
+ throw new SessionSelectorError({
211
+ code: "ambiguous",
212
+ selector: options.selector,
213
+ candidates: details,
214
+ message: `${subject} is ambiguous: ${reason}. ${candidateHint(details)}`
215
+ });
216
+ }
217
+ function resolution(candidate, selector, matchedBy, shortRefLength) {
218
+ return {
219
+ candidate,
220
+ id: candidate.id,
221
+ shortRef: sessionShortRef(candidate.id, shortRefLength),
222
+ selector,
223
+ matchedBy
224
+ };
225
+ }
226
+ function normalizeCandidates(candidates) {
227
+ if (!Array.isArray(candidates)) {
228
+ throw new TypeError("session selector candidates must be an array");
229
+ }
230
+ return candidates.map((candidate, index) => {
231
+ if (!candidate || typeof candidate !== "object") {
232
+ throw new TypeError(`session selector candidate ${index} must be an object`);
233
+ }
234
+ requireNonEmptyString(candidate.id, `session selector candidate ${index} id`);
235
+ if (!isExecutorKind(candidate.agent)) {
236
+ throw new TypeError(`session selector candidate ${index} has unsupported agent ${quote(String(candidate.agent))}`);
237
+ }
238
+ if (typeof candidate.actionable !== "boolean") {
239
+ throw new TypeError(`session selector candidate ${index} actionable must be a boolean`);
240
+ }
241
+ if (candidate.updatedAtMs !== undefined &&
242
+ !Number.isFinite(candidate.updatedAtMs)) {
243
+ throw new TypeError(`session selector candidate ${index} updatedAtMs must be finite when provided`);
244
+ }
245
+ return candidate;
246
+ });
247
+ }
248
+ function candidateDetails(candidates, shortRefLength) {
249
+ return [...candidates]
250
+ .sort(compareCandidates)
251
+ .map((candidate) => detailFor(candidate, shortRefLength));
252
+ }
253
+ function detailFor(candidate, shortRefLength) {
254
+ return {
255
+ id: candidate.id,
256
+ shortRef: sessionShortRef(candidate.id, shortRefLength),
257
+ agent: candidate.agent,
258
+ actionable: candidate.actionable,
259
+ updatedAtMs: candidate.updatedAtMs,
260
+ source: candidate.source,
261
+ status: candidate.status,
262
+ workspace: candidate.workspace,
263
+ label: candidate.label
264
+ };
265
+ }
266
+ function compareCandidates(left, right) {
267
+ const leftHasTime = left.updatedAtMs !== undefined;
268
+ const rightHasTime = right.updatedAtMs !== undefined;
269
+ if (leftHasTime && rightHasTime && left.updatedAtMs !== right.updatedAtMs) {
270
+ return right.updatedAtMs - left.updatedAtMs;
271
+ }
272
+ if (leftHasTime !== rightHasTime) {
273
+ return leftHasTime ? -1 : 1;
274
+ }
275
+ const agentOrder = compareStrings(left.agent, right.agent);
276
+ return agentOrder || compareStrings(left.id, right.id);
277
+ }
278
+ function compareStrings(left, right) {
279
+ return left < right ? -1 : left > right ? 1 : 0;
280
+ }
281
+ function candidateHint(details) {
282
+ if (details.length === 0) {
283
+ return "";
284
+ }
285
+ return `Candidates: ${details.map((detail) => {
286
+ const context = [
287
+ detail.shortRef,
288
+ detail.agent,
289
+ detail.status,
290
+ detail.source,
291
+ detail.workspace,
292
+ detail.label ? bounded(detail.label, 80) : undefined,
293
+ detail.id
294
+ ].filter((value) => Boolean(value));
295
+ return `[${context.join(" | ")}]`;
296
+ }).join(", ")}`;
297
+ }
298
+ function normalizedShortRefLength(value) {
299
+ const length = value ?? DEFAULT_SESSION_SHORT_REF_LENGTH;
300
+ // Reuse the public validation without making a meaningless hash allocation.
301
+ if (!Number.isInteger(length) || length < 6 || length > 64) {
302
+ throw new TypeError("short reference length must be an integer between 6 and 64");
303
+ }
304
+ return length;
305
+ }
306
+ function normalizedOperation(value) {
307
+ if (value === undefined) {
308
+ return undefined;
309
+ }
310
+ return requireNonEmptyString(value, "session selector operation");
311
+ }
312
+ function requireNonEmptyString(value, label) {
313
+ if (typeof value !== "string" || value.trim().length === 0) {
314
+ throw new TypeError(`${label} must be a non-empty string`);
315
+ }
316
+ return value;
317
+ }
318
+ function operationSuffix(operation) {
319
+ return operation ? ` for ${operation}` : "";
320
+ }
321
+ function bounded(value, maximum) {
322
+ const normalized = value.replace(/\s+/gu, " ").trim();
323
+ return normalized.length <= maximum
324
+ ? normalized
325
+ : `${normalized.slice(0, maximum - 1)}…`;
326
+ }
327
+ function quote(value) {
328
+ return JSON.stringify(value);
329
+ }
330
+ //# sourceMappingURL=session-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-selector.js","sourceRoot":"","sources":["../../src/session-selector.ts"],"names":[],"mappings":"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"}
@@ -30,5 +30,9 @@ export declare class SystemTerminalProcessSource implements TerminalProcessSourc
30
30
  }): Promise<TerminalProcessSnapshot[]>;
31
31
  }
32
32
  export declare function parsePsProcessSnapshots(output: string): TerminalProcessSnapshot[];
33
+ /**
34
+ * Parse `ps etime` (`[[DD-]HH:]MM:SS`) into elapsed seconds.
35
+ */
36
+ export declare function parseProcessElapsedSeconds(value: unknown): number | undefined;
33
37
  export declare function parseLsofCwdMap(output: string): Map<number, string>;
34
38
  export declare function runProcessCommand(command: string, args: string[]): ProcessCommandResult;
@@ -83,6 +83,26 @@ export function parsePsProcessSnapshots(output) {
83
83
  command: match[4]
84
84
  }));
85
85
  }
86
+ /**
87
+ * Parse `ps etime` (`[[DD-]HH:]MM:SS`) into elapsed seconds.
88
+ */
89
+ export function parseProcessElapsedSeconds(value) {
90
+ const match = /^(?:(\d+)-)?(?:(\d{1,2}):)?(\d{1,2}):(\d{2})$/u.exec(String(value ?? "").trim());
91
+ if (!match) {
92
+ return undefined;
93
+ }
94
+ const days = Number(match[1] ?? 0);
95
+ const hours = Number(match[2] ?? 0);
96
+ const minutes = Number(match[3]);
97
+ const seconds = Number(match[4]);
98
+ if (![days, hours, minutes, seconds].every(Number.isSafeInteger) ||
99
+ hours > 23 ||
100
+ minutes > 59 ||
101
+ seconds > 59) {
102
+ return undefined;
103
+ }
104
+ return (((days * 24 + hours) * 60 + minutes) * 60) + seconds;
105
+ }
86
106
  export function parseLsofCwdMap(output) {
87
107
  const cwdByPid = new Map();
88
108
  for (const line of output.split(/\r?\n/).slice(1)) {
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-process-source.js","sourceRoot":"","sources":["../../src/terminal-process-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiB/C,MAAM,OAAO,2BAA2B;IACT,SAAS;IAAtC,YAA6B,SAA6C;yBAA7C,SAAS;IAAuC,CAAC;IAE9E,KAAK,CAAC,oBAAoB,CACxB,WAAW,GAAmD,GAAG,EAAE,CAAC,IAAI,EACxE,OAAO,GAAyD,EAAE;QAElE,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACtD,OAAO,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,OAAO,CAAC,gBAAgB,KAAK,IAAI,CAAC;aACpF,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;CACF;AAED,MAAM,OAAO,2BAA2B;IACrB,UAAU,CAA4D;IAEvF,YAAY,OAAO,GAEf,EAAE;QACJ,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,iBAAiB,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,oBAAoB,CACxB,WAAW,GAAmD,GAAG,EAAE,CAAC,IAAI,EACxE,OAAO,GAAyD,EAAE;QAElE,MAAM,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACrE,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,EAAE,CAAC,MAAM,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,IAAI,WAAW,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,SAAS,GAAG,uBAAuB,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAG,iBAAiB,CAChC,SAAS,EACT,UAAU,EACV,OAAO,CAAC,gBAAgB,KAAK,IAAI,CAClC,CAAC;QACF,IAAI,OAAO,CAAC,UAAU,KAAK,KAAK,EAAE,CAAC;YACjC,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YACnC,IAAI;YACJ,IAAI;YACJ,KAAK;YACL,IAAI;YACJ,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;SAC7D,CAAC,CAAC;QACH,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC9C,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACjC,GAAG,QAAQ;YACX,GAAG,EAAE,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;SAChD,CAAC,CAAC,CAAC;IACN,CAAC;CACF;AAED,SAAS,iBAAiB,CACxB,SAA6C,EAC7C,UAA8C,EAC9C,gBAAyB;IAEzB,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7E,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACzE,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC;QAC/B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,OACE,OAAO,SAAS,KAAK,QAAQ;YAC7B,MAAM,CAAC,SAAS,CAAC,SAAS,CAAC;YAC3B,SAAS,GAAG,CAAC;YACb,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EACvB,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACvB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,MAAM;YACR,CAAC;YACD,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC7B,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,MAAc;IACpD,OAAO,MAAM;SACV,KAAK,CAAC,OAAO,CAAC;SACd,KAAK,CAAC,CAAC,CAAC;SACR,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,wCAAwC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SAClE,MAAM,CAAC,CAAC,KAAK,EAA4B,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;SAC3D,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;QACjB,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;KAClB,CAAC,CAAC,CAAC;AACR,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,+DAA+D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzF,IAAI,KAAK,EAAE,CAAC;YACV,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAe,EAAE,IAAc;IAC/D,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE;QACtC,QAAQ,EAAE,MAAM;QAChB,SAAS,EAAE,IAAI,GAAG,IAAI,GAAG,EAAE;KAC5B,CAAC,CAAC;IACH,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"terminal-process-source.js","sourceRoot":"","sources":["../../src/terminal-process-source.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ # Managed ACPX in 5 Minutes
2
+
3
+ Use this path for managed background Codex, Claude Code, or Cursor tasks with durable AKK state and callbacks. You need Node.js 24.15+ on the 24.x line, OpenClaw `2026.7.1-2`+, and an authenticated coding-agent CLI.
4
+
5
+ ## 1. Install and configure
6
+
7
+ From the project the agent may edit:
8
+
9
+ ```bash
10
+ npm install -g acpx@latest @scotthuang/agent-knock-knock@next && agent-knock-knock install-openclaw --workspace "$PWD" --default-agent codex --mode acpx --verify
11
+ ```
12
+
13
+ Use `--default-agent claude` or `cursor` when preferred. Existing AKK approval policy remains intact, and the Gateway restarts at most once.
14
+
15
+ ## 2. Run doctor
16
+
17
+ ```bash
18
+ agent-knock-knock doctor --mode acpx
19
+ ```
20
+
21
+ Success means `readiness` is `ready`, ACPX and the selected agent CLI can return versions, the AKK runtime and skill are loaded, the workspace is canonical, and the Gateway is healthy. Doctor does not make a credentialed model call.
22
+
23
+ ## 3. Start one managed task
24
+
25
+ From any configured OpenClaw channel:
26
+
27
+ ```text
28
+ /akk codex inspect this repository and summarize it
29
+ ```
30
+
31
+ Use `/akk claude ...` or `/akk cursor ...` to override the configured default.
32
+
33
+ ## 4. Continue it without copying an ID
34
+
35
+ ```text
36
+ /akk send only: run the tests and explain any failures
37
+ ```
38
+
39
+ `only` succeeds only when exactly one session is actionable. Otherwise AKK stops and lists stable short references instead of choosing a session.
40
+
41
+ ## Boundary and recovery
42
+
43
+ Managed ACPX runs separately from the shared-terminal permission policy; tmux prompt inspection and AKK's exact-command `autoApprove` rules do not apply. Keep work inside the configured workspace. Use `/akk status only`, `/akk cancel only`, or `/akk recover only` when the task needs intervention.
@@ -0,0 +1,43 @@
1
+ # tmux Bridge in 5 Minutes
2
+
3
+ Use this path when you want OpenClaw and a human to share the same live Codex or Claude Code terminal. You need Node.js 24.15+ on the 24.x line, OpenClaw `2026.7.1-2`+, tmux, and an authenticated `codex` or `claude` CLI, all running as the same OS user.
4
+
5
+ ## 1. Install and configure
6
+
7
+ From the project the agent may edit:
8
+
9
+ ```bash
10
+ npm install -g @scotthuang/agent-knock-knock@next && agent-knock-knock install-openclaw --workspace "$PWD" --default-agent codex --mode tmux --verify
11
+ ```
12
+
13
+ The installer updates only AKK's enabled flag, workspace, default agent, and mode. Existing plugin settings—including `autoApprove` rules—remain intact, and the Gateway restarts at most once.
14
+
15
+ ## 2. Run doctor
16
+
17
+ ```bash
18
+ agent-knock-knock doctor --mode tmux
19
+ ```
20
+
21
+ Success means `readiness` is `ready`, the selected CLI can return a version, the AKK runtime and skill are loaded, the workspace is canonical, and the Gateway is healthy. Doctor does not make a credentialed model call.
22
+
23
+ ## 3. Start the shared terminal
24
+
25
+ ```bash
26
+ tmux new-session -s akk-work -c "$PWD" codex
27
+ ```
28
+
29
+ Use `claude` instead of `codex` if that is your configured agent. Detach with `Ctrl-b`, then `d`.
30
+
31
+ ## 4. Send one chat command
32
+
33
+ From any configured OpenClaw channel:
34
+
35
+ ```text
36
+ /akk send codex: inspect this repository and summarize it
37
+ ```
38
+
39
+ AKK must find exactly one actionable Codex target; otherwise it stops and shows candidate short references instead of guessing. Success returns a managed conversation while the same tmux pane remains available for takeover.
40
+
41
+ ## Boundary and recovery
42
+
43
+ AKK keeps the coding agent's own permission mode. Trusted, exact `autoApprove` rules may approve a supported prompt; everything else remains manual. Reattach with `tmux attach -t akk-work`, inspect the terminal, and use `/akk status only` or `/akk recover only` if the managed turn needs recovery.
@@ -1,14 +1,19 @@
1
1
  {
2
2
  "id": "agent-knock-knock",
3
3
  "name": "Agent Knock Knock",
4
- "description": "Agent Knock Knock (AKK/akk) delegates OpenClaw coding work to local Codex, Claude, or Cursor agents. Use this plugin when the user says AKK, akk, Agent Knock Knock, asks to hand work to Codex, Claude, or Cursor, asks what agent tasks are running, asks what an AKK, Codex, or Claude session is about, sends a follow-up to an agent task, renews monitoring for a stalled terminal task, recovers an unavailable agent session, cancels a running agent task, or closes an agent task. Default delegation target comes from plugin config defaultAgent and falls back to Codex when unset; explicit user agent requests override it.",
4
+ "description": "Delegate OpenClaw coding tasks to local Codex, Claude Code, or Cursor agents, then take over the same live terminal session.",
5
+ "icon": "https://raw.githubusercontent.com/scotthuang/agent-knock-knock/main/docs/assets/agent-knock-knock-icon.png",
5
6
  "activation": {
6
- "onStartup": true
7
+ "onStartup": true,
8
+ "onCommands": ["akk"]
7
9
  },
10
+ "commandAliases": [
11
+ {
12
+ "name": "akk",
13
+ "kind": "runtime-slash"
14
+ }
15
+ ],
8
16
  "contracts": {
9
- "commands": [
10
- "akk"
11
- ],
12
17
  "tools": [
13
18
  "agent_knock_knock_delegate",
14
19
  "agent_knock_knock_list",
@@ -21,7 +26,6 @@
21
26
  "agent_knock_knock_recover",
22
27
  "agent_knock_knock_close",
23
28
  "agent_knock_knock_approve",
24
- "agent_knock_knock_agent_discover",
25
29
  "agent_knock_knock_agent_takeover"
26
30
  ]
27
31
  },
@@ -59,13 +63,13 @@
59
63
  "agent_knock_knock_approve": {
60
64
  "optional": true
61
65
  },
62
- "agent_knock_knock_agent_discover": {
63
- "optional": true
64
- },
65
66
  "agent_knock_knock_agent_takeover": {
66
67
  "optional": true
67
68
  }
68
69
  },
70
+ "skills": [
71
+ "templates/openclaw-skills/agent-knock-knock"
72
+ ],
69
73
  "configSchema": {
70
74
  "type": "object",
71
75
  "additionalProperties": false,
@@ -99,6 +103,11 @@
99
103
  "enum": ["claude", "codex", "cursor"],
100
104
  "description": "Default coding agent for unspecified AKK delegations. If unset, Agent Knock Knock falls back to codex."
101
105
  },
106
+ "mode": {
107
+ "type": "string",
108
+ "enum": ["tmux", "acpx", "all"],
109
+ "description": "Execution mode checked by /akk doctor. tmux shares live Codex or Claude terminals; acpx runs managed Codex, Claude, or Cursor tasks."
110
+ },
102
111
  "defaultClaudeSession": {
103
112
  "type": "string",
104
113
  "description": "Default Claude Code session name. claudeSession remains supported as a compatibility alias."
@@ -151,6 +160,10 @@
151
160
  "type": "string",
152
161
  "description": "Path to the OpenClaw CLI used by callback delivery. Defaults to PATH plus common user install locations."
153
162
  },
163
+ "codexHome": {
164
+ "type": "string",
165
+ "description": "Optional CODEX_HOME path used when resolving native Codex sessions for agent takeover."
166
+ },
154
167
  "callbackCommand": {
155
168
  "type": "string",
156
169
  "description": "Optional callback command template. {statePath} and {state_path} are replaced with the shell-quoted state path."
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@scotthuang/agent-knock-knock",
3
- "version": "0.2.51",
4
- "description": "Local-first OpenClaw orchestration for coding agents through shared tmux sessions or ACPX/ACP.",
3
+ "version": "0.3.0-beta.2",
4
+ "description": "Control local Codex and Claude Code from OpenClaw, take over the same live tmux session, and run managed ACP tasks through ACPX with Cursor support.",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "homepage": "https://github.com/scotthuang/agent-knock-knock#readme",
@@ -29,9 +29,26 @@
29
29
  "extensions": [
30
30
  "./dist/src/openclaw-plugin.js"
31
31
  ],
32
+ "runtimeExtensions": [
33
+ "./dist/src/openclaw-plugin.js"
34
+ ],
35
+ "install": {
36
+ "clawhubSpec": "clawhub:@scotthuang/agent-knock-knock",
37
+ "npmSpec": "@scotthuang/agent-knock-knock",
38
+ "defaultChoice": "clawhub",
39
+ "minHostVersion": ">=2026.7.1-2"
40
+ },
32
41
  "compat": {
33
- "pluginApi": ">=2026.3.24-beta.2",
34
- "minGatewayVersion": "2026.3.24-beta.2"
42
+ "pluginApi": ">=2026.7.1-2",
43
+ "minGatewayVersion": "2026.7.1-2"
44
+ },
45
+ "build": {
46
+ "openclawVersion": "2026.7.1-2",
47
+ "pluginSdkVersion": "2026.7.1-2"
48
+ },
49
+ "release": {
50
+ "publishToClawHub": true,
51
+ "publishToNpm": true
35
52
  }
36
53
  },
37
54
  "bin": {
@@ -41,6 +58,11 @@
41
58
  "dist/src",
42
59
  "templates",
43
60
  "docs/assets/agent-knock-knock-cover.jpg",
61
+ "docs/assets/agent-knock-knock-icon.png",
62
+ "docs/quickstart-managed-acpx.md",
63
+ "docs/quickstart-tmux.md",
64
+ "scripts/smoke-acpx.js",
65
+ "scripts/smoke-tmux.js",
44
66
  "openclaw.plugin.json",
45
67
  "README.md",
46
68
  "LICENSE",
@@ -55,6 +77,10 @@
55
77
  "prepack": "npm run build",
56
78
  "typecheck": "tsc -p tsconfig.json --noEmit",
57
79
  "test": "npm run build && node --test dist/test/*.test.js",
80
+ "clawhub:validate": "npm run build && clawhub package validate . --out .clawhub-validation --openclaw node_modules/openclaw --runtime --allow-execute --no-mock-sdk",
81
+ "clawhub:dry-run": "npm run build && clawhub package publish . --family code-plugin --owner scotthuang --tags beta --dry-run",
82
+ "smoke:acpx": "npm run build && node scripts/smoke-acpx.js",
83
+ "smoke:tmux": "npm run build && node scripts/smoke-tmux.js",
58
84
  "simulate:architecture": "node scripts/two-claude-weather-test.js --scenario architecture-questions",
59
85
  "simulate:weather": "node scripts/two-claude-weather-test.js --scenario weather",
60
86
  "transcript": "node dist/src/cli.js transcript"
@@ -62,8 +88,18 @@
62
88
  "engines": {
63
89
  "node": ">=22.14.0"
64
90
  },
91
+ "peerDependencies": {
92
+ "openclaw": ">=2026.7.1-2"
93
+ },
94
+ "peerDependenciesMeta": {
95
+ "openclaw": {
96
+ "optional": true
97
+ }
98
+ },
65
99
  "devDependencies": {
66
100
  "@types/node": "^22.20.1",
101
+ "clawhub": "0.23.1",
102
+ "openclaw": "2026.7.1-2",
67
103
  "typescript": "^7.0.2"
68
104
  }
69
105
  }