@scotthuang/agent-knock-knock 0.12.13 → 0.12.15

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 (170) hide show
  1. package/CHANGELOG.md +44 -0
  2. package/README.md +13 -13
  3. package/dist/src/callback-cli-adapter.d.ts +9 -6
  4. package/dist/src/callback-cli-adapter.js +119 -30
  5. package/dist/src/callback-cli-adapter.js.map +1 -1
  6. package/dist/src/callback-outbox-policy.d.ts +39 -0
  7. package/dist/src/callback-outbox-policy.js +163 -6
  8. package/dist/src/callback-outbox-policy.js.map +1 -1
  9. package/dist/src/callback-outbox-service.d.ts +28 -1
  10. package/dist/src/callback-outbox-service.js +413 -82
  11. package/dist/src/callback-outbox-service.js.map +1 -1
  12. package/dist/src/callback-outbox-settlement.d.ts +14 -1
  13. package/dist/src/callback-outbox-settlement.js +151 -30
  14. package/dist/src/callback-outbox-settlement.js.map +1 -1
  15. package/dist/src/callback-route-authority.d.ts +59 -0
  16. package/dist/src/callback-route-authority.js +123 -0
  17. package/dist/src/callback-route-authority.js.map +1 -0
  18. package/dist/src/callback-transport.d.ts +134 -0
  19. package/dist/src/callback-transport.js +256 -0
  20. package/dist/src/callback-transport.js.map +1 -0
  21. package/dist/src/cli-core.js +56 -18
  22. package/dist/src/cli-core.js.map +1 -1
  23. package/dist/src/cli-runtime-context.d.ts +2 -0
  24. package/dist/src/cli-runtime-context.js.map +1 -1
  25. package/dist/src/codex-lifecycle-compatibility.js +2 -1
  26. package/dist/src/codex-lifecycle-compatibility.js.map +1 -1
  27. package/dist/src/deferred-foreground-application-service.d.ts +18 -0
  28. package/dist/src/deferred-foreground-application-service.js +72 -0
  29. package/dist/src/deferred-foreground-application-service.js.map +1 -1
  30. package/dist/src/deferred-foreground-authority-cli-adapter.js +10 -1
  31. package/dist/src/deferred-foreground-authority-cli-adapter.js.map +1 -1
  32. package/dist/src/deferred-foreground-recovery-cli-adapter.d.ts +1 -1
  33. package/dist/src/deferred-foreground-recovery-cli-adapter.js +108 -37
  34. package/dist/src/deferred-foreground-recovery-cli-adapter.js.map +1 -1
  35. package/dist/src/deferred-foreground-recovery-service.d.ts +1 -1
  36. package/dist/src/deferred-foreground-recovery-service.js +10 -3
  37. package/dist/src/deferred-foreground-recovery-service.js.map +1 -1
  38. package/dist/src/deferred-foreground-transfer-policy.d.ts +1 -1
  39. package/dist/src/deferred-foreground-transfer-policy.js +3 -2
  40. package/dist/src/deferred-foreground-transfer-policy.js.map +1 -1
  41. package/dist/src/deferred-foreground-transfer.d.ts +17 -1
  42. package/dist/src/deferred-foreground-transfer.js +244 -35
  43. package/dist/src/deferred-foreground-transfer.js.map +1 -1
  44. package/dist/src/deferred-foreground-user-close.d.ts +18 -0
  45. package/dist/src/deferred-foreground-user-close.js +180 -0
  46. package/dist/src/deferred-foreground-user-close.js.map +1 -0
  47. package/dist/src/install-doctor-command-adapter.js +1 -1
  48. package/dist/src/install-doctor-command-adapter.js.map +1 -1
  49. package/dist/src/openclaw-callback-transport.d.ts +4 -1
  50. package/dist/src/openclaw-callback-transport.js +403 -10
  51. package/dist/src/openclaw-callback-transport.js.map +1 -1
  52. package/dist/src/openclaw-doctor.js +16 -2
  53. package/dist/src/openclaw-doctor.js.map +1 -1
  54. package/dist/src/openclaw-managed-callback-cli-adapter.d.ts +23 -0
  55. package/dist/src/openclaw-managed-callback-cli-adapter.js +77 -0
  56. package/dist/src/openclaw-managed-callback-cli-adapter.js.map +1 -0
  57. package/dist/src/openclaw-plugin-command-adapter.js +93 -39
  58. package/dist/src/openclaw-plugin-command-adapter.js.map +1 -1
  59. package/dist/src/openclaw-plugin-helpers.d.ts +1 -0
  60. package/dist/src/openclaw-plugin-helpers.js +9 -1
  61. package/dist/src/openclaw-plugin-helpers.js.map +1 -1
  62. package/dist/src/openclaw-plugin-schemas.d.ts +20 -1
  63. package/dist/src/openclaw-plugin-schemas.js +27 -3
  64. package/dist/src/openclaw-plugin-schemas.js.map +1 -1
  65. package/dist/src/protocol.d.ts +3 -0
  66. package/dist/src/protocol.js +4 -0
  67. package/dist/src/protocol.js.map +1 -1
  68. package/dist/src/store.d.ts +12 -1
  69. package/dist/src/store.js +81 -3
  70. package/dist/src/store.js.map +1 -1
  71. package/dist/src/terminal-acceptance-cli-adapter.d.ts +2 -0
  72. package/dist/src/terminal-acceptance-cli-adapter.js +62 -12
  73. package/dist/src/terminal-acceptance-cli-adapter.js.map +1 -1
  74. package/dist/src/terminal-action-projection.d.ts +31 -3
  75. package/dist/src/terminal-action-projection.js +64 -9
  76. package/dist/src/terminal-action-projection.js.map +1 -1
  77. package/dist/src/terminal-agent-bridge.d.ts +82 -0
  78. package/dist/src/terminal-agent-bridge.js +553 -109
  79. package/dist/src/terminal-agent-bridge.js.map +1 -1
  80. package/dist/src/terminal-command-cli-adapter.d.ts +26 -2
  81. package/dist/src/terminal-command-cli-adapter.js +3162 -214
  82. package/dist/src/terminal-command-cli-adapter.js.map +1 -1
  83. package/dist/src/terminal-delegate-cli-adapter.d.ts +4 -22
  84. package/dist/src/terminal-delegate-cli-adapter.js +239 -192
  85. package/dist/src/terminal-delegate-cli-adapter.js.map +1 -1
  86. package/dist/src/terminal-delegate-send-binding.d.ts +63 -0
  87. package/dist/src/terminal-delegate-send-binding.js +360 -0
  88. package/dist/src/terminal-delegate-send-binding.js.map +1 -0
  89. package/dist/src/terminal-dispatch-application.d.ts +4 -1
  90. package/dist/src/terminal-dispatch-application.js +11 -2
  91. package/dist/src/terminal-dispatch-application.js.map +1 -1
  92. package/dist/src/terminal-dispatch-composition.d.ts +5 -0
  93. package/dist/src/terminal-dispatch-execution.js +3 -1
  94. package/dist/src/terminal-dispatch-execution.js.map +1 -1
  95. package/dist/src/terminal-dispatch-ledger-codec.d.ts +3 -0
  96. package/dist/src/terminal-dispatch-ledger-codec.js +46 -19
  97. package/dist/src/terminal-dispatch-ledger-codec.js.map +1 -1
  98. package/dist/src/terminal-dispatch-presenter.js +5 -3
  99. package/dist/src/terminal-dispatch-presenter.js.map +1 -1
  100. package/dist/src/terminal-dispatch-receipt.d.ts +3 -0
  101. package/dist/src/terminal-dispatch-receipt.js +15 -1
  102. package/dist/src/terminal-dispatch-receipt.js.map +1 -1
  103. package/dist/src/terminal-dispatch-recovery-cli-adapter.js +68 -7
  104. package/dist/src/terminal-dispatch-recovery-cli-adapter.js.map +1 -1
  105. package/dist/src/terminal-dispatch-recovery-service.d.ts +2 -0
  106. package/dist/src/terminal-dispatch-recovery-service.js +9 -0
  107. package/dist/src/terminal-dispatch-recovery-service.js.map +1 -1
  108. package/dist/src/terminal-dispatch-repository-cli-adapter.d.ts +4 -2
  109. package/dist/src/terminal-dispatch-repository-cli-adapter.js +10 -3
  110. package/dist/src/terminal-dispatch-repository-cli-adapter.js.map +1 -1
  111. package/dist/src/terminal-identity-authority-cli-adapter.d.ts +2 -0
  112. package/dist/src/terminal-identity-authority-cli-adapter.js +34 -27
  113. package/dist/src/terminal-identity-authority-cli-adapter.js.map +1 -1
  114. package/dist/src/terminal-list-cli-adapter.d.ts +6 -0
  115. package/dist/src/terminal-list-cli-adapter.js +391 -177
  116. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  117. package/dist/src/terminal-list-renderer.d.ts +9 -1
  118. package/dist/src/terminal-list-renderer.js +226 -104
  119. package/dist/src/terminal-list-renderer.js.map +1 -1
  120. package/dist/src/terminal-maintenance-cli-adapter.js +253 -326
  121. package/dist/src/terminal-maintenance-cli-adapter.js.map +1 -1
  122. package/dist/src/terminal-monitor-application-service.d.ts +5 -0
  123. package/dist/src/terminal-monitor-application-service.js +5 -0
  124. package/dist/src/terminal-monitor-application-service.js.map +1 -1
  125. package/dist/src/terminal-monitor-cli-adapter.d.ts +25 -1
  126. package/dist/src/terminal-monitor-cli-adapter.js +170 -27
  127. package/dist/src/terminal-monitor-cli-adapter.js.map +1 -1
  128. package/dist/src/terminal-monitor-reconciliation-eligibility.d.ts +1 -1
  129. package/dist/src/terminal-monitor-reconciliation-eligibility.js +220 -32
  130. package/dist/src/terminal-monitor-reconciliation-eligibility.js.map +1 -1
  131. package/dist/src/terminal-monitor-state-cli-adapter.d.ts +1 -1
  132. package/dist/src/terminal-monitor-state-cli-adapter.js +808 -147
  133. package/dist/src/terminal-monitor-state-cli-adapter.js.map +1 -1
  134. package/dist/src/terminal-monitor-state-reconciliation-service.d.ts +2 -1
  135. package/dist/src/terminal-monitor-state-reconciliation-service.js +12 -0
  136. package/dist/src/terminal-monitor-state-reconciliation-service.js.map +1 -1
  137. package/dist/src/terminal-monitor-supervision-cli-adapter.d.ts +2 -0
  138. package/dist/src/terminal-monitor-supervision-cli-adapter.js +31 -11
  139. package/dist/src/terminal-monitor-supervision-cli-adapter.js.map +1 -1
  140. package/dist/src/terminal-process-source.d.ts +13 -0
  141. package/dist/src/terminal-process-source.js +37 -0
  142. package/dist/src/terminal-process-source.js.map +1 -1
  143. package/dist/src/terminal-runtime-cli-adapter.js +14 -2
  144. package/dist/src/terminal-runtime-cli-adapter.js.map +1 -1
  145. package/dist/src/terminal-status-cli-adapter.d.ts +1 -0
  146. package/dist/src/terminal-status-cli-adapter.js +30 -28
  147. package/dist/src/terminal-status-cli-adapter.js.map +1 -1
  148. package/dist/src/terminal-submission-acceptance.js +78 -25
  149. package/dist/src/terminal-submission-acceptance.js.map +1 -1
  150. package/dist/src/terminal-submission-retry-service.d.ts +114 -0
  151. package/dist/src/terminal-submission-retry-service.js +589 -0
  152. package/dist/src/terminal-submission-retry-service.js.map +1 -0
  153. package/dist/src/terminal-user-send-intent.d.ts +65 -0
  154. package/dist/src/terminal-user-send-intent.js +317 -0
  155. package/dist/src/terminal-user-send-intent.js.map +1 -0
  156. package/dist/src/terminal-watch-callback-cli-adapter.d.ts +10 -2
  157. package/dist/src/terminal-watch-callback-cli-adapter.js +76 -37
  158. package/dist/src/terminal-watch-callback-cli-adapter.js.map +1 -1
  159. package/dist/src/terminal-watch-cli-adapter.js +41 -17
  160. package/dist/src/terminal-watch-cli-adapter.js.map +1 -1
  161. package/dist/src/terminal-watch-service.d.ts +11 -6
  162. package/dist/src/terminal-watch-service.js +210 -41
  163. package/dist/src/terminal-watch-service.js.map +1 -1
  164. package/dist/src/terminal-watch-store.d.ts +23 -0
  165. package/dist/src/terminal-watch-store.js +162 -4
  166. package/dist/src/terminal-watch-store.js.map +1 -1
  167. package/docs/quickstart-herdr.md +1 -1
  168. package/docs/quickstart-tmux.md +3 -3
  169. package/package.json +1 -1
  170. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +14 -11
@@ -0,0 +1,65 @@
1
+ import { atomicSaveJsonFile } from "./durable-json-file.js";
2
+ export declare const TERMINAL_USER_SEND_INTENT_SCHEMA = "agent-knock-knock/terminal-user-send-intent";
3
+ export declare const TERMINAL_USER_SEND_INTENT_VERSION = 1;
4
+ export declare const TERMINAL_USER_SEND_INTENTS_DIRECTORY = "terminal-user-send-intents";
5
+ export type TerminalUserSendIntentStage = "reserved" | "zero_input_cancelled" | "enter_dispatched";
6
+ export type TerminalUserSendDeliveryMode = "managed" | "unmanaged";
7
+ export declare class TerminalUserSendIntentBoundaryConflictError extends Error {
8
+ constructor(message: string);
9
+ }
10
+ export declare class TerminalUserSendIntentUncertainError extends Error {
11
+ constructor(message: string);
12
+ }
13
+ export interface TerminalUserSendIntentBoundary {
14
+ terminalRuntimeKey: string;
15
+ physicalToken: string;
16
+ messageId: string;
17
+ requestHash: string;
18
+ }
19
+ export interface TerminalUserSendIntent {
20
+ schema: typeof TERMINAL_USER_SEND_INTENT_SCHEMA;
21
+ version: typeof TERMINAL_USER_SEND_INTENT_VERSION;
22
+ terminal_runtime_key: string;
23
+ physical_token: string;
24
+ message_id: string;
25
+ request_hash: string;
26
+ stage: TerminalUserSendIntentStage;
27
+ reserved_at: string;
28
+ zero_input_cancelled_at?: string;
29
+ enter_dispatched_at?: string;
30
+ delivery_mode?: TerminalUserSendDeliveryMode;
31
+ }
32
+ export type TerminalUserSendIntentReserveResult = {
33
+ outcome: "reserved";
34
+ intent: TerminalUserSendIntent;
35
+ } | {
36
+ outcome: "replay" | "uncertain";
37
+ stage: TerminalUserSendIntentStage;
38
+ intent: TerminalUserSendIntent;
39
+ };
40
+ export interface TerminalUserSendIntentRepository {
41
+ pathFor(input: Pick<TerminalUserSendIntentBoundary, "messageId">): string;
42
+ load(input: TerminalUserSendIntentBoundary): TerminalUserSendIntent | undefined;
43
+ reserve(input: TerminalUserSendIntentBoundary): TerminalUserSendIntentReserveResult;
44
+ cancelProvenZeroInput(input: TerminalUserSendIntentBoundary): boolean;
45
+ complete(input: TerminalUserSendIntentBoundary, deliveryMode: TerminalUserSendDeliveryMode): TerminalUserSendIntent;
46
+ }
47
+ interface TerminalUserSendIntentRepositoryOptions {
48
+ runtimeDir: string;
49
+ now?: () => Date;
50
+ ensureDirectory?: (directoryPath: string) => void;
51
+ acquireLock?: (lockPath: string) => () => void;
52
+ saveJson?: typeof atomicSaveJsonFile;
53
+ }
54
+ /**
55
+ * Store-independent global idempotency for one explicit physical-terminal
56
+ * Send. The path is keyed only by host message id, so the same id cannot move
57
+ * between explicit, delegated, or differently targeted terminal entry points.
58
+ *
59
+ * The caller owns the physical-terminal lock. A reserved record means the
60
+ * previous managed or unmanaged attempt may have started input; only a
61
+ * completed record is safe to replay as success. The request body is never
62
+ * stored.
63
+ */
64
+ export declare function createTerminalUserSendIntentRepository(options: TerminalUserSendIntentRepositoryOptions): TerminalUserSendIntentRepository;
65
+ export {};
@@ -0,0 +1,317 @@
1
+ import { createHash } from "node:crypto";
2
+ import { lstatSync } from "node:fs";
3
+ import path from "node:path";
4
+ import process from "node:process";
5
+ import { atomicSaveJsonFile, isNodeError, readJsonFileNoFollow } from "./durable-json-file.js";
6
+ import { ensureDir } from "./store.js";
7
+ import { createFileLockCliAdapter } from "./file-lock-cli-adapter.js";
8
+ export const TERMINAL_USER_SEND_INTENT_SCHEMA = "agent-knock-knock/terminal-user-send-intent";
9
+ export const TERMINAL_USER_SEND_INTENT_VERSION = 1;
10
+ export const TERMINAL_USER_SEND_INTENTS_DIRECTORY = "terminal-user-send-intents";
11
+ export class TerminalUserSendIntentBoundaryConflictError extends Error {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "TerminalUserSendIntentBoundaryConflictError";
15
+ }
16
+ }
17
+ export class TerminalUserSendIntentUncertainError extends Error {
18
+ constructor(message) {
19
+ super(message);
20
+ this.name = "TerminalUserSendIntentUncertainError";
21
+ }
22
+ }
23
+ const ALLOWED_KEYS = new Set([
24
+ "schema",
25
+ "version",
26
+ "terminal_runtime_key",
27
+ "physical_token",
28
+ "message_id",
29
+ "request_hash",
30
+ "stage",
31
+ "reserved_at",
32
+ "zero_input_cancelled_at",
33
+ "enter_dispatched_at",
34
+ "delivery_mode"
35
+ ]);
36
+ function digest(value) {
37
+ return createHash("sha256").update(value, "utf8").digest("hex");
38
+ }
39
+ function requiredString(value, label) {
40
+ if (typeof value !== "string" || value.length === 0 || value.includes("\0")) {
41
+ throw new Error(`${label} must be a non-empty string without NUL bytes`);
42
+ }
43
+ return value;
44
+ }
45
+ function canonicalTimestamp(value, label) {
46
+ const timestamp = requiredString(value, label);
47
+ if (Number.isNaN(Date.parse(timestamp)) ||
48
+ new Date(timestamp).toISOString() !== timestamp) {
49
+ throw new Error(`${label} must be a canonical ISO timestamp`);
50
+ }
51
+ return timestamp;
52
+ }
53
+ function isRecord(value) {
54
+ return typeof value === "object" && value !== null && !Array.isArray(value);
55
+ }
56
+ function parseIntent(value) {
57
+ if (!isRecord(value)) {
58
+ throw new Error("terminal user-send intent must contain a JSON object");
59
+ }
60
+ for (const key of Object.keys(value)) {
61
+ if (!ALLOWED_KEYS.has(key)) {
62
+ throw new Error(`terminal user-send intent contains unsupported field ${key}`);
63
+ }
64
+ }
65
+ if (value.schema !== TERMINAL_USER_SEND_INTENT_SCHEMA ||
66
+ value.version !== TERMINAL_USER_SEND_INTENT_VERSION) {
67
+ throw new Error("terminal user-send intent has an unsupported schema");
68
+ }
69
+ const stage = value.stage;
70
+ if (stage !== "reserved" &&
71
+ stage !== "zero_input_cancelled" &&
72
+ stage !== "enter_dispatched") {
73
+ throw new Error("terminal user-send intent stage is invalid");
74
+ }
75
+ requiredString(value.terminal_runtime_key, "terminal_runtime_key");
76
+ requiredString(value.physical_token, "physical_token");
77
+ requiredString(value.message_id, "message_id");
78
+ requiredString(value.request_hash, "request_hash");
79
+ canonicalTimestamp(value.reserved_at, "reserved_at");
80
+ if (stage === "enter_dispatched") {
81
+ canonicalTimestamp(value.enter_dispatched_at, "enter_dispatched_at");
82
+ if (value.delivery_mode !== "managed" && value.delivery_mode !== "unmanaged") {
83
+ throw new Error("a completed terminal user-send intent needs a delivery mode");
84
+ }
85
+ if (value.zero_input_cancelled_at !== undefined) {
86
+ throw new Error("a completed terminal user-send intent cannot claim zero-input cancellation");
87
+ }
88
+ }
89
+ else if (stage === "zero_input_cancelled") {
90
+ canonicalTimestamp(value.zero_input_cancelled_at, "zero_input_cancelled_at");
91
+ if (value.enter_dispatched_at !== undefined ||
92
+ value.delivery_mode !== undefined) {
93
+ throw new Error("a zero-input terminal user-send intent cannot claim delivery");
94
+ }
95
+ }
96
+ else if (value.zero_input_cancelled_at !== undefined ||
97
+ value.enter_dispatched_at !== undefined ||
98
+ value.delivery_mode !== undefined) {
99
+ throw new Error("a reserved terminal user-send intent cannot claim delivery");
100
+ }
101
+ return value;
102
+ }
103
+ function assertBoundaryMatches(intent, input) {
104
+ if (intent.terminal_runtime_key !== input.terminalRuntimeKey ||
105
+ intent.message_id !== input.messageId) {
106
+ throw new TerminalUserSendIntentBoundaryConflictError("terminal user-send intent identity does not match");
107
+ }
108
+ if (intent.physical_token !== input.physicalToken) {
109
+ throw new TerminalUserSendIntentBoundaryConflictError("messageId is already reserved for a different physical terminal");
110
+ }
111
+ if (intent.request_hash !== input.requestHash) {
112
+ throw new TerminalUserSendIntentBoundaryConflictError("messageId is already reserved for a different request hash");
113
+ }
114
+ }
115
+ function nowTimestamp(now) {
116
+ const value = now();
117
+ if (!(value instanceof Date) || Number.isNaN(value.getTime())) {
118
+ throw new Error("now() must return a valid Date");
119
+ }
120
+ return value.toISOString();
121
+ }
122
+ function requiredDeliveryMode(value) {
123
+ if (value !== "managed" && value !== "unmanaged") {
124
+ throw new Error("terminal user-send delivery mode is invalid");
125
+ }
126
+ return value;
127
+ }
128
+ function syncSleep(milliseconds) {
129
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, milliseconds);
130
+ }
131
+ function finalIntentPathDefinitelyAbsent(filePath) {
132
+ try {
133
+ lstatSync(filePath);
134
+ return false;
135
+ }
136
+ catch (error) {
137
+ if (isNodeError(error, "ENOENT") || isNodeError(error, "ENOTDIR")) {
138
+ return true;
139
+ }
140
+ return undefined;
141
+ }
142
+ }
143
+ function classifyIntentStorageError(error, filePath) {
144
+ const definitelyAbsent = finalIntentPathDefinitelyAbsent(filePath);
145
+ if (definitelyAbsent === true)
146
+ return error;
147
+ return new TerminalUserSendIntentUncertainError(`${definitelyAbsent === false ? "existing" : "possibly existing"} ` +
148
+ `same-id terminal user-Send intent cannot be verified: ${error instanceof Error ? error.message : String(error)}`);
149
+ }
150
+ /**
151
+ * Store-independent global idempotency for one explicit physical-terminal
152
+ * Send. The path is keyed only by host message id, so the same id cannot move
153
+ * between explicit, delegated, or differently targeted terminal entry points.
154
+ *
155
+ * The caller owns the physical-terminal lock. A reserved record means the
156
+ * previous managed or unmanaged attempt may have started input; only a
157
+ * completed record is safe to replay as success. The request body is never
158
+ * stored.
159
+ */
160
+ export function createTerminalUserSendIntentRepository(options) {
161
+ const runtimeDir = path.resolve(options.runtimeDir);
162
+ const intentsDir = path.join(runtimeDir, TERMINAL_USER_SEND_INTENTS_DIRECTORY);
163
+ const now = options.now ?? (() => new Date());
164
+ const ensureDirectory = options.ensureDirectory ?? ensureDir;
165
+ const saveJson = options.saveJson ?? atomicSaveJsonFile;
166
+ const fileLock = createFileLockCliAdapter({
167
+ now: () => new Date(),
168
+ nowMs: Date.now,
169
+ pid: () => process.pid,
170
+ sleepSync: syncSleep
171
+ });
172
+ const acquireLock = options.acquireLock ?? ((lockPath) => fileLock.acquire(lockPath));
173
+ const heldMessages = new Set();
174
+ function pathFor(input) {
175
+ const messageId = requiredString(input.messageId, "messageId");
176
+ return path.join(intentsDir, `terminal-user-send-intent-${digest(messageId)}.json`);
177
+ }
178
+ function withMessageLock(messageId, operation) {
179
+ const messageKey = digest(requiredString(messageId, "messageId"));
180
+ if (heldMessages.has(messageKey)) {
181
+ throw new TerminalUserSendIntentUncertainError("terminal user-Send intent lock is already held");
182
+ }
183
+ const filePath = pathFor({ messageId });
184
+ let release;
185
+ let operationStarted = false;
186
+ try {
187
+ ensureDirectory(path.dirname(filePath));
188
+ release = acquireLock(`${filePath}.lock`);
189
+ heldMessages.add(messageKey);
190
+ operationStarted = true;
191
+ return operation();
192
+ }
193
+ catch (error) {
194
+ if (error instanceof TerminalUserSendIntentBoundaryConflictError ||
195
+ error instanceof TerminalUserSendIntentUncertainError) {
196
+ throw error;
197
+ }
198
+ if (isRecord(error) && error.code === "LOCK_TIMEOUT") {
199
+ throw new TerminalUserSendIntentUncertainError(`terminal user-Send intent lock is busy: ${error instanceof Error ? error.message : String(error)}`);
200
+ }
201
+ if (operationStarted)
202
+ throw error;
203
+ throw classifyIntentStorageError(error, filePath);
204
+ }
205
+ finally {
206
+ heldMessages.delete(messageKey);
207
+ try {
208
+ release?.();
209
+ }
210
+ catch {
211
+ // Releasing a completed lock is cleanup, not Send authority. A stale
212
+ // file is reclaimed by the normal owner/age protocol on a later call.
213
+ }
214
+ }
215
+ }
216
+ function load(input) {
217
+ const filePath = pathFor(input);
218
+ try {
219
+ const intent = parseIntent(readJsonFileNoFollow(filePath, "terminal user-send intent"));
220
+ assertBoundaryMatches(intent, input);
221
+ return intent;
222
+ }
223
+ catch (error) {
224
+ if (isNodeError(error, "ENOENT"))
225
+ return undefined;
226
+ if (error instanceof TerminalUserSendIntentBoundaryConflictError ||
227
+ error instanceof TerminalUserSendIntentUncertainError) {
228
+ throw error;
229
+ }
230
+ throw classifyIntentStorageError(error, filePath);
231
+ }
232
+ }
233
+ function save(intent) {
234
+ saveJson(pathFor({ messageId: intent.message_id }), intent, {
235
+ rootLabel: "terminal user-send intent root",
236
+ directoryLabel: "terminal user-send intent directory",
237
+ fileLabel: "terminal user-send intent",
238
+ ensureDirectory,
239
+ fsyncNewRootParent: true,
240
+ fsyncNewDirectoryParent: true
241
+ });
242
+ }
243
+ function reserve(input) {
244
+ return withMessageLock(input.messageId, () => {
245
+ const existing = load(input);
246
+ if (existing?.stage === "enter_dispatched") {
247
+ return {
248
+ outcome: "replay",
249
+ stage: existing.stage,
250
+ intent: existing
251
+ };
252
+ }
253
+ if (existing?.stage === "reserved") {
254
+ return {
255
+ outcome: "uncertain",
256
+ stage: existing.stage,
257
+ intent: existing
258
+ };
259
+ }
260
+ const intent = {
261
+ schema: TERMINAL_USER_SEND_INTENT_SCHEMA,
262
+ version: TERMINAL_USER_SEND_INTENT_VERSION,
263
+ terminal_runtime_key: requiredString(input.terminalRuntimeKey, "terminalRuntimeKey"),
264
+ physical_token: requiredString(input.physicalToken, "physicalToken"),
265
+ message_id: requiredString(input.messageId, "messageId"),
266
+ request_hash: requiredString(input.requestHash, "requestHash"),
267
+ stage: "reserved",
268
+ reserved_at: nowTimestamp(now)
269
+ };
270
+ save(intent);
271
+ return { outcome: "reserved", intent };
272
+ });
273
+ }
274
+ function complete(input, deliveryMode) {
275
+ return withMessageLock(input.messageId, () => {
276
+ const mode = requiredDeliveryMode(deliveryMode);
277
+ const existing = load(input);
278
+ if (!existing) {
279
+ throw new Error("terminal user-send intent must be reserved before completion");
280
+ }
281
+ if (existing.stage === "enter_dispatched") {
282
+ if (existing.delivery_mode !== mode) {
283
+ throw new Error("terminal user-send intent already completed in another mode");
284
+ }
285
+ return existing;
286
+ }
287
+ const completed = {
288
+ ...existing,
289
+ stage: "enter_dispatched",
290
+ enter_dispatched_at: nowTimestamp(now),
291
+ delivery_mode: mode
292
+ };
293
+ save(completed);
294
+ return completed;
295
+ });
296
+ }
297
+ function cancelProvenZeroInput(input) {
298
+ return withMessageLock(input.messageId, () => {
299
+ const existing = load(input);
300
+ if (!existing)
301
+ return false;
302
+ if (existing.stage === "zero_input_cancelled")
303
+ return false;
304
+ if (existing.stage === "enter_dispatched") {
305
+ throw new Error("a completed terminal user-send intent cannot be cancelled");
306
+ }
307
+ save({
308
+ ...existing,
309
+ stage: "zero_input_cancelled",
310
+ zero_input_cancelled_at: nowTimestamp(now)
311
+ });
312
+ return true;
313
+ });
314
+ }
315
+ return { pathFor, load, reserve, cancelProvenZeroInput, complete };
316
+ }
317
+ //# sourceMappingURL=terminal-user-send-intent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-user-send-intent.js","sourceRoot":"","sources":["../../src/terminal-user-send-intent.ts"],"names":[],"mappings":"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"}
@@ -1,20 +1,28 @@
1
1
  import type { CallbackSpawnSync } from "./openclaw-callback-transport.js";
2
- export type TerminalWatchCallbackEvent = "approval_required" | "completed" | "failed" | "timed_out" | "invalidated" | "cancelled";
2
+ import { type CallbackAttemptOutcome, type CallbackRouteV1, type CallbackTransportContextV1, type CallbackTransportDeliverInput } from "./callback-transport.js";
3
+ import { type TerminalWatchCallbackEvent as TerminalWatchCallbackEventType, type TerminalWatchCallbackResolution } from "./terminal-watch-service.js";
4
+ import type { TerminalWatch } from "./terminal-watch-store.js";
5
+ export type TerminalWatchCallbackEvent = TerminalWatchCallbackEventType;
3
6
  export interface TerminalWatchCallbackInput {
4
7
  watchId: string;
5
8
  idempotencyKey: string;
6
9
  event: TerminalWatchCallbackEvent;
7
10
  agent: "codex" | "claude";
8
11
  terminalId: string;
9
- openclawSession: string;
12
+ openclawSession?: string;
10
13
  openclawBin?: string;
11
14
  detail?: string;
12
15
  completionText?: string;
13
16
  }
17
+ export type TerminalWatchTransportDeliveryInput = CallbackTransportDeliverInput;
14
18
  export interface TerminalWatchCallbackCliAdapter {
15
19
  deliver(input: TerminalWatchCallbackInput): void;
20
+ deliverTransport?(input: TerminalWatchTransportDeliveryInput): CallbackAttemptOutcome;
16
21
  }
22
+ export declare function resolveTerminalWatchOpenClawCallback(watch: Pick<TerminalWatch, "openclaw_session" | "openclaw_bin">): TerminalWatchCallbackResolution;
23
+ export declare function resolveTerminalWatchOpenClawCallbackContext(watch: Pick<TerminalWatch, "openclaw_session" | "openclaw_bin">, _route?: CallbackRouteV1): CallbackTransportContextV1;
17
24
  export declare function createTerminalWatchCallbackCliAdapter(options?: {
18
25
  environment?: () => NodeJS.ProcessEnv;
26
+ now?: () => Date;
19
27
  spawnSync?: CallbackSpawnSync;
20
28
  }): TerminalWatchCallbackCliAdapter;
@@ -1,7 +1,32 @@
1
+ import { createLegacyOpenClawCallbackRoute } from "./callback-transport.js";
1
2
  import { createOpenClawCallbackTransport, parseChatSendAcknowledgement } from "./openclaw-callback-transport.js";
3
+ import { terminalWatchCallbackMessage } from "./terminal-watch-service.js";
4
+ export function resolveTerminalWatchOpenClawCallback(watch) {
5
+ return {
6
+ route: {
7
+ ...createLegacyOpenClawCallbackRoute({
8
+ controllerSessionId: watch.openclaw_session,
9
+ gatewayMethod: "chat.send",
10
+ openclawBin: watch.openclaw_bin
11
+ }),
12
+ capabilities: { wake: true, respond: false }
13
+ },
14
+ context: resolveTerminalWatchOpenClawCallbackContext(watch)
15
+ };
16
+ }
17
+ export function resolveTerminalWatchOpenClawCallbackContext(watch, _route) {
18
+ return {
19
+ legacyOptions: {
20
+ gatewayMethod: "chat.send",
21
+ gatewaySession: watch.openclaw_session,
22
+ openclawBin: watch.openclaw_bin
23
+ }
24
+ };
25
+ }
2
26
  export function createTerminalWatchCallbackCliAdapter(options = {}) {
27
+ const now = options.now ?? (() => new Date());
3
28
  const transport = createOpenClawCallbackTransport({
4
- now: () => new Date(),
29
+ now,
5
30
  environment: options.environment ?? (() => process.env),
6
31
  redactConversation: () => ({}),
7
32
  recordCallbackProcessDelivery: () => { },
@@ -9,47 +34,61 @@ export function createTerminalWatchCallbackCliAdapter(options = {}) {
9
34
  });
10
35
  return Object.freeze({
11
36
  deliver(input) {
12
- const delivery = transport.deliverChatSend({
37
+ const attempt = attemptOpenClawCallback({
13
38
  openclawBin: input.openclawBin,
14
- params: {
15
- sessionKey: input.openclawSession,
16
- message: terminalWatchCallbackMessage(input),
17
- idempotencyKey: input.idempotencyKey,
18
- deliver: true
19
- }
39
+ sessionKey: requiredString(input.openclawSession, "Terminal Watch OpenClaw session"),
40
+ message: terminalWatchCallbackMessage(input),
41
+ idempotencyKey: input.idempotencyKey
20
42
  });
21
- if (delivery.status !== 0) {
22
- throw new Error(delivery.stderr || delivery.stdout ||
23
- `Terminal Watch callback failed with status ${delivery.status}`);
24
- }
25
- const acknowledgement = parseChatSendAcknowledgement(delivery.stdout, input.idempotencyKey);
26
- if (acknowledgement.status === "error" ||
27
- acknowledgement.status === "timeout") {
28
- throw new Error(`Terminal Watch chat.send was not accepted: ${acknowledgement.status}`);
43
+ if (attempt.disposition !== "accepted") {
44
+ throw new Error(attempt.errorMessage);
29
45
  }
46
+ },
47
+ deliverTransport(input) {
48
+ return transport.deliver(input);
30
49
  }
31
50
  });
51
+ function attemptOpenClawCallback(input) {
52
+ const delivery = transport.deliverChatSend({
53
+ openclawBin: input.openclawBin,
54
+ params: {
55
+ sessionKey: input.sessionKey,
56
+ message: input.message,
57
+ idempotencyKey: input.idempotencyKey,
58
+ deliver: true
59
+ }
60
+ });
61
+ if (delivery.status !== 0) {
62
+ return {
63
+ disposition: "retryable_failure",
64
+ errorMessage: delivery.stderr || delivery.stdout ||
65
+ `Terminal Watch callback failed with status ${delivery.status}`
66
+ };
67
+ }
68
+ let acknowledgement;
69
+ try {
70
+ acknowledgement = parseChatSendAcknowledgement(delivery.stdout, input.idempotencyKey);
71
+ }
72
+ catch (error) {
73
+ return {
74
+ disposition: "uncertain",
75
+ errorMessage: error instanceof Error ? error.message : String(error)
76
+ };
77
+ }
78
+ if (acknowledgement.status === "error" ||
79
+ acknowledgement.status === "timeout") {
80
+ return {
81
+ disposition: "retryable_failure",
82
+ errorMessage: `Terminal Watch chat.send was not accepted: ${acknowledgement.status}`
83
+ };
84
+ }
85
+ return { disposition: "accepted", acknowledgement };
86
+ }
32
87
  }
33
- function terminalWatchCallbackMessage(input) {
34
- const eventInstruction = input.event === "approval_required"
35
- ? "Tell the user that the observed TUI task is waiting for approval and ask the human to inspect and decide in the named live TUI. Do not call any AKK approval tool or action, do not send approval keys, and do not use autoApprove."
36
- : input.event === "completed"
37
- ? "Tell the user that the human-started TUI task completed and summarize only the bounded completion text below."
38
- : "Tell the user that Terminal Watch stopped without a verified successful completion and explain the exact reason below.";
39
- return [
40
- "Continue this OpenClaw conversation from the Agent Knock Knock Terminal Watch event below.",
41
- "This is an observation of a task started by the human directly in Codex or Claude Code. It is not an AKK Turn and AKK did not send terminal input.",
42
- eventInstruction,
43
- "Do not poll files, processes, terminal panes, stdout, or stderr. Use only this structured event.",
44
- "",
45
- `[AKK Terminal Watch: ${input.event}]`,
46
- `Watch: ${input.watchId}`,
47
- `Terminal: ${input.terminalId}`,
48
- `Agent: ${input.agent}`,
49
- ...(input.detail ? [`Detail: ${input.detail}`] : []),
50
- ...(input.completionText
51
- ? ["", "Bounded completion text:", input.completionText]
52
- : [])
53
- ].join("\n");
88
+ function requiredString(value, label) {
89
+ if (typeof value !== "string" || value.trim().length === 0) {
90
+ throw new Error(`${label} is required`);
91
+ }
92
+ return value;
54
93
  }
55
94
  //# sourceMappingURL=terminal-watch-callback-cli-adapter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-watch-callback-cli-adapter.js","sourceRoot":"","sources":["../../src/terminal-watch-callback-cli-adapter.ts"],"names":[],"mappings":"AACA,OAAO,EACL,+BAA+B,EAC/B,4BAA4B,EAC7B,MAAM,kCAAkC,CAAC;AA0B1C,MAAM,UAAU,qCAAqC,CACnD,OAAO,GAGH,EAAE;IAEN,MAAM,SAAS,GAAG,+BAA+B,CAAC;QAChD,GAAG,EAAE,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE;QACrB,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;QACvD,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9B,6BAA6B,EAAE,GAAG,EAAE,GAAE,CAAC;QACvC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC/D,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,MAAM,CAAC;QACnB,OAAO,CAAC,KAAK;YACX,MAAM,QAAQ,GAAG,SAAS,CAAC,eAAe,CAAC;gBACzC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,MAAM,EAAE;oBACN,UAAU,EAAE,KAAK,CAAC,eAAe;oBACjC,OAAO,EAAE,4BAA4B,CAAC,KAAK,CAAC;oBAC5C,cAAc,EAAE,KAAK,CAAC,cAAc;oBACpC,OAAO,EAAE,IAAI;iBACd;aACF,CAAC,CAAC;YACH,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,KAAK,CACb,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,MAAM;oBAClC,8CAA8C,QAAQ,CAAC,MAAM,EAAE,CAChE,CAAC;YACJ,CAAC;YACD,MAAM,eAAe,GAAG,4BAA4B,CAClD,QAAQ,CAAC,MAAM,EACf,KAAK,CAAC,cAAc,CACrB,CAAC;YACF,IACE,eAAe,CAAC,MAAM,KAAK,OAAO;gBAClC,eAAe,CAAC,MAAM,KAAK,SAAS,EACpC,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,8CAA8C,eAAe,CAAC,MAAM,EAAE,CACvE,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,4BAA4B,CACnC,KAAiC;IAEjC,MAAM,gBAAgB,GAAG,KAAK,CAAC,KAAK,KAAK,mBAAmB;QAC1D,CAAC,CAAC,qOAAqO;QACvO,CAAC,CAAC,KAAK,CAAC,KAAK,KAAK,WAAW;YAC3B,CAAC,CAAC,+GAA+G;YACjH,CAAC,CAAC,wHAAwH,CAAC;IAC/H,OAAO;QACL,4FAA4F;QAC5F,oJAAoJ;QACpJ,gBAAgB;QAChB,kGAAkG;QAClG,EAAE;QACF,wBAAwB,KAAK,CAAC,KAAK,GAAG;QACtC,UAAU,KAAK,CAAC,OAAO,EAAE;QACzB,aAAa,KAAK,CAAC,UAAU,EAAE;QAC/B,UAAU,KAAK,CAAC,KAAK,EAAE;QACvB,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,GAAG,CAAC,KAAK,CAAC,cAAc;YACtB,CAAC,CAAC,CAAC,EAAE,EAAE,0BAA0B,EAAE,KAAK,CAAC,cAAc,CAAC;YACxD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"terminal-watch-callback-cli-adapter.js","sourceRoot":"","sources":["../../src/terminal-watch-callback-cli-adapter.ts"],"names":[],"mappings":"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"}