@scotthuang/agent-knock-knock 0.13.17 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (291) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/CONTRIBUTING.md +212 -0
  3. package/README.md +105 -166
  4. package/connectors/deepseek-harness/LICENSE +21 -0
  5. package/connectors/deepseek-harness/README.md +406 -0
  6. package/connectors/pi/LICENSE +21 -0
  7. package/connectors/pi/README.md +446 -0
  8. package/dist/src/backend-recovery-semantic.d.ts +16 -0
  9. package/dist/src/backend-recovery-semantic.js +113 -0
  10. package/dist/src/backend-recovery-semantic.js.map +1 -0
  11. package/dist/src/backend-task-recovery.d.ts +103 -0
  12. package/dist/src/backend-task-recovery.js +142 -0
  13. package/dist/src/backend-task-recovery.js.map +1 -0
  14. package/dist/src/callback-transport.d.ts +8 -0
  15. package/dist/src/callback-transport.js +14 -0
  16. package/dist/src/callback-transport.js.map +1 -1
  17. package/dist/src/cli-core.js +18 -8
  18. package/dist/src/cli-core.js.map +1 -1
  19. package/dist/src/cli-runtime-context.d.ts +5 -0
  20. package/dist/src/cli-runtime-context.js.map +1 -1
  21. package/dist/src/codex-async-question-adapter.js +14 -4
  22. package/dist/src/codex-async-question-adapter.js.map +1 -1
  23. package/dist/src/codex-lifecycle-compatibility.d.ts +1 -1
  24. package/dist/src/codex-lifecycle-compatibility.js +9 -3
  25. package/dist/src/codex-lifecycle-compatibility.js.map +1 -1
  26. package/dist/src/codex-native-cli-adapter.d.ts +6 -0
  27. package/dist/src/codex-native-cli-adapter.js +273 -0
  28. package/dist/src/codex-native-cli-adapter.js.map +1 -0
  29. package/dist/src/codex-native-client-interactions.d.ts +6 -0
  30. package/dist/src/codex-native-client-interactions.js +124 -0
  31. package/dist/src/codex-native-client-interactions.js.map +1 -0
  32. package/dist/src/codex-native-client-rpc.d.ts +21 -0
  33. package/dist/src/codex-native-client-rpc.js +137 -0
  34. package/dist/src/codex-native-client-rpc.js.map +1 -0
  35. package/dist/src/codex-native-client.d.ts +42 -0
  36. package/dist/src/codex-native-client.js +326 -0
  37. package/dist/src/codex-native-client.js.map +1 -0
  38. package/dist/src/codex-native-identity.d.ts +6 -0
  39. package/dist/src/codex-native-identity.js +42 -0
  40. package/dist/src/codex-native-identity.js.map +1 -0
  41. package/dist/src/codex-native-monitor.d.ts +4 -0
  42. package/dist/src/codex-native-monitor.js +92 -0
  43. package/dist/src/codex-native-monitor.js.map +1 -0
  44. package/dist/src/codex-native-outbox.d.ts +16 -0
  45. package/dist/src/codex-native-outbox.js +120 -0
  46. package/dist/src/codex-native-outbox.js.map +1 -0
  47. package/dist/src/codex-native-public-projection.d.ts +545 -0
  48. package/dist/src/codex-native-public-projection.js +182 -0
  49. package/dist/src/codex-native-public-projection.js.map +1 -0
  50. package/dist/src/codex-native-record-store.d.ts +27 -0
  51. package/dist/src/codex-native-record-store.js +111 -0
  52. package/dist/src/codex-native-record-store.js.map +1 -0
  53. package/dist/src/codex-native-response-service.d.ts +69 -0
  54. package/dist/src/codex-native-response-service.js +244 -0
  55. package/dist/src/codex-native-response-service.js.map +1 -0
  56. package/dist/src/codex-native-runtime.d.ts +46 -0
  57. package/dist/src/codex-native-runtime.js +112 -0
  58. package/dist/src/codex-native-runtime.js.map +1 -0
  59. package/dist/src/codex-native-semantic.d.ts +17 -0
  60. package/dist/src/codex-native-semantic.js +175 -0
  61. package/dist/src/codex-native-semantic.js.map +1 -0
  62. package/dist/src/codex-native-snapshot.d.ts +19 -0
  63. package/dist/src/codex-native-snapshot.js +160 -0
  64. package/dist/src/codex-native-snapshot.js.map +1 -0
  65. package/dist/src/codex-native-state-store.d.ts +61 -0
  66. package/dist/src/codex-native-state-store.js +132 -0
  67. package/dist/src/codex-native-state-store.js.map +1 -0
  68. package/dist/src/codex-native-task-service.d.ts +71 -0
  69. package/dist/src/codex-native-task-service.js +502 -0
  70. package/dist/src/codex-native-task-service.js.map +1 -0
  71. package/dist/src/codex-native-types.d.ts +92 -0
  72. package/dist/src/codex-native-types.js +15 -0
  73. package/dist/src/codex-native-types.js.map +1 -0
  74. package/dist/src/codex-permission-surface.d.ts +1 -1
  75. package/dist/src/codex-permission-surface.js +1 -1
  76. package/dist/src/codex-permission-surface.js.map +1 -1
  77. package/dist/src/codex-terminal-agent-adapter.js +3 -1
  78. package/dist/src/codex-terminal-agent-adapter.js.map +1 -1
  79. package/dist/src/conversation-list.d.ts +12 -0
  80. package/dist/src/conversation-list.js +30 -0
  81. package/dist/src/conversation-list.js.map +1 -0
  82. package/dist/src/conversation-route-dispatch.d.ts +13 -0
  83. package/dist/src/conversation-route-dispatch.js +66 -0
  84. package/dist/src/conversation-route-dispatch.js.map +1 -0
  85. package/dist/src/conversation-route-legacy.d.ts +18 -0
  86. package/dist/src/conversation-route-legacy.js +54 -0
  87. package/dist/src/conversation-route-legacy.js.map +1 -0
  88. package/dist/src/conversation-route-store.d.ts +51 -0
  89. package/dist/src/conversation-route-store.js +126 -0
  90. package/dist/src/conversation-route-store.js.map +1 -0
  91. package/dist/src/conversation-routing-cli-adapter.d.ts +12 -0
  92. package/dist/src/conversation-routing-cli-adapter.js +211 -0
  93. package/dist/src/conversation-routing-cli-adapter.js.map +1 -0
  94. package/dist/src/conversation-routing-commands.d.ts +11 -0
  95. package/dist/src/conversation-routing-commands.js +85 -0
  96. package/dist/src/conversation-routing-commands.js.map +1 -0
  97. package/dist/src/conversation-routing-home.d.ts +26 -0
  98. package/dist/src/conversation-routing-home.js +105 -0
  99. package/dist/src/conversation-routing-home.js.map +1 -0
  100. package/dist/src/conversation-routing-identity.d.ts +40 -0
  101. package/dist/src/conversation-routing-identity.js +174 -0
  102. package/dist/src/conversation-routing-identity.js.map +1 -0
  103. package/dist/src/conversation-runtime-route-store.d.ts +11 -0
  104. package/dist/src/conversation-runtime-route-store.js +118 -0
  105. package/dist/src/conversation-runtime-route-store.js.map +1 -0
  106. package/dist/src/desktop-async-interactions.d.ts +15 -0
  107. package/dist/src/desktop-async-interactions.js +88 -0
  108. package/dist/src/desktop-async-interactions.js.map +1 -0
  109. package/dist/src/desktop-async-state.d.ts +5 -0
  110. package/dist/src/desktop-async-state.js +53 -0
  111. package/dist/src/desktop-async-state.js.map +1 -0
  112. package/dist/src/desktop-cli-adapter.d.ts +7 -0
  113. package/dist/src/desktop-cli-adapter.js +322 -0
  114. package/dist/src/desktop-cli-adapter.js.map +1 -0
  115. package/dist/src/desktop-cli-controls.d.ts +9 -0
  116. package/dist/src/desktop-cli-controls.js +45 -0
  117. package/dist/src/desktop-cli-controls.js.map +1 -0
  118. package/dist/src/desktop-command-presentation.d.ts +2 -0
  119. package/dist/src/desktop-command-presentation.js +31 -0
  120. package/dist/src/desktop-command-presentation.js.map +1 -0
  121. package/dist/src/desktop-control-semantic.d.ts +8 -0
  122. package/dist/src/desktop-control-semantic.js +68 -0
  123. package/dist/src/desktop-control-semantic.js.map +1 -0
  124. package/dist/src/desktop-identity.d.ts +5 -0
  125. package/dist/src/desktop-identity.js +40 -0
  126. package/dist/src/desktop-identity.js.map +1 -0
  127. package/dist/src/desktop-interaction-projection.d.ts +57 -0
  128. package/dist/src/desktop-interaction-projection.js +196 -0
  129. package/dist/src/desktop-interaction-projection.js.map +1 -0
  130. package/dist/src/desktop-interaction-state.d.ts +3 -0
  131. package/dist/src/desktop-interaction-state.js +48 -0
  132. package/dist/src/desktop-interaction-state.js.map +1 -0
  133. package/dist/src/desktop-ipc-async-answer.d.ts +9 -0
  134. package/dist/src/desktop-ipc-async-answer.js +71 -0
  135. package/dist/src/desktop-ipc-async-answer.js.map +1 -0
  136. package/dist/src/desktop-ipc-client.d.ts +47 -0
  137. package/dist/src/desktop-ipc-client.js +400 -0
  138. package/dist/src/desktop-ipc-client.js.map +1 -0
  139. package/dist/src/desktop-ipc-native-operations.d.ts +11 -0
  140. package/dist/src/desktop-ipc-native-operations.js +126 -0
  141. package/dist/src/desktop-ipc-native-operations.js.map +1 -0
  142. package/dist/src/desktop-ipc-transport.d.ts +13 -0
  143. package/dist/src/desktop-ipc-transport.js +123 -0
  144. package/dist/src/desktop-ipc-transport.js.map +1 -0
  145. package/dist/src/desktop-list.d.ts +25 -0
  146. package/dist/src/desktop-list.js +55 -0
  147. package/dist/src/desktop-list.js.map +1 -0
  148. package/dist/src/desktop-metadata-reader.d.ts +30 -0
  149. package/dist/src/desktop-metadata-reader.js +182 -0
  150. package/dist/src/desktop-metadata-reader.js.map +1 -0
  151. package/dist/src/desktop-monitor.d.ts +4 -0
  152. package/dist/src/desktop-monitor.js +101 -0
  153. package/dist/src/desktop-monitor.js.map +1 -0
  154. package/dist/src/desktop-public-projection.d.ts +6 -0
  155. package/dist/src/desktop-public-projection.js +134 -0
  156. package/dist/src/desktop-public-projection.js.map +1 -0
  157. package/dist/src/desktop-request-interactions.d.ts +14 -0
  158. package/dist/src/desktop-request-interactions.js +144 -0
  159. package/dist/src/desktop-request-interactions.js.map +1 -0
  160. package/dist/src/desktop-response-dispatch.d.ts +14 -0
  161. package/dist/src/desktop-response-dispatch.js +19 -0
  162. package/dist/src/desktop-response-dispatch.js.map +1 -0
  163. package/dist/src/desktop-response-evidence.d.ts +4 -0
  164. package/dist/src/desktop-response-evidence.js +19 -0
  165. package/dist/src/desktop-response-evidence.js.map +1 -0
  166. package/dist/src/desktop-response-service.d.ts +11 -0
  167. package/dist/src/desktop-response-service.js +188 -0
  168. package/dist/src/desktop-response-service.js.map +1 -0
  169. package/dist/src/desktop-response-store.d.ts +35 -0
  170. package/dist/src/desktop-response-store.js +58 -0
  171. package/dist/src/desktop-response-store.js.map +1 -0
  172. package/dist/src/desktop-response-types.d.ts +20 -0
  173. package/dist/src/desktop-response-types.js +2 -0
  174. package/dist/src/desktop-response-types.js.map +1 -0
  175. package/dist/src/desktop-response-value.d.ts +6 -0
  176. package/dist/src/desktop-response-value.js +31 -0
  177. package/dist/src/desktop-response-value.js.map +1 -0
  178. package/dist/src/desktop-runtime.d.ts +153 -0
  179. package/dist/src/desktop-runtime.js +88 -0
  180. package/dist/src/desktop-runtime.js.map +1 -0
  181. package/dist/src/desktop-semantic.d.ts +21 -0
  182. package/dist/src/desktop-semantic.js +140 -0
  183. package/dist/src/desktop-semantic.js.map +1 -0
  184. package/dist/src/desktop-session-catalog.d.ts +68 -0
  185. package/dist/src/desktop-session-catalog.js +225 -0
  186. package/dist/src/desktop-session-catalog.js.map +1 -0
  187. package/dist/src/desktop-session-controls.d.ts +145 -0
  188. package/dist/src/desktop-session-controls.js +176 -0
  189. package/dist/src/desktop-session-controls.js.map +1 -0
  190. package/dist/src/desktop-sidebar-metadata.d.ts +27 -0
  191. package/dist/src/desktop-sidebar-metadata.js +83 -0
  192. package/dist/src/desktop-sidebar-metadata.js.map +1 -0
  193. package/dist/src/desktop-sidebar-projects.d.ts +10 -0
  194. package/dist/src/desktop-sidebar-projects.js +31 -0
  195. package/dist/src/desktop-sidebar-projects.js.map +1 -0
  196. package/dist/src/desktop-sidebar-selection.d.ts +28 -0
  197. package/dist/src/desktop-sidebar-selection.js +85 -0
  198. package/dist/src/desktop-sidebar-selection.js.map +1 -0
  199. package/dist/src/desktop-snapshot-details.d.ts +4 -0
  200. package/dist/src/desktop-snapshot-details.js +116 -0
  201. package/dist/src/desktop-snapshot-details.js.map +1 -0
  202. package/dist/src/desktop-snapshot.d.ts +11 -0
  203. package/dist/src/desktop-snapshot.js +276 -0
  204. package/dist/src/desktop-snapshot.js.map +1 -0
  205. package/dist/src/desktop-state-store.d.ts +72 -0
  206. package/dist/src/desktop-state-store.js +269 -0
  207. package/dist/src/desktop-state-store.js.map +1 -0
  208. package/dist/src/desktop-task-interactions.d.ts +10 -0
  209. package/dist/src/desktop-task-interactions.js +93 -0
  210. package/dist/src/desktop-task-interactions.js.map +1 -0
  211. package/dist/src/desktop-task-recovery.d.ts +38 -0
  212. package/dist/src/desktop-task-recovery.js +171 -0
  213. package/dist/src/desktop-task-recovery.js.map +1 -0
  214. package/dist/src/desktop-task-service.d.ts +54 -0
  215. package/dist/src/desktop-task-service.js +441 -0
  216. package/dist/src/desktop-task-service.js.map +1 -0
  217. package/dist/src/desktop-types.d.ts +281 -0
  218. package/dist/src/desktop-types.js +13 -0
  219. package/dist/src/desktop-types.js.map +1 -0
  220. package/dist/src/host-monitor-reconciliation.js +36 -4
  221. package/dist/src/host-monitor-reconciliation.js.map +1 -1
  222. package/dist/src/host-profile-runtime.js +7 -3
  223. package/dist/src/host-profile-runtime.js.map +1 -1
  224. package/dist/src/local-codex-cli-adapter.d.ts +7 -0
  225. package/dist/src/local-codex-cli-adapter.js +13 -0
  226. package/dist/src/local-codex-cli-adapter.js.map +1 -0
  227. package/dist/src/openclaw-callback-transport.js +2 -1
  228. package/dist/src/openclaw-callback-transport.js.map +1 -1
  229. package/dist/src/semantic-conversation-target.d.ts +4 -0
  230. package/dist/src/semantic-conversation-target.js +20 -0
  231. package/dist/src/semantic-conversation-target.js.map +1 -0
  232. package/dist/src/semantic-permission-control.js +47 -9
  233. package/dist/src/semantic-permission-control.js.map +1 -1
  234. package/dist/src/semantic-private-authority-offers.d.ts +1 -1
  235. package/dist/src/semantic-private-authority-offers.js +3 -1
  236. package/dist/src/semantic-private-authority-offers.js.map +1 -1
  237. package/dist/src/semantic-tool-command-helpers.d.ts +6 -0
  238. package/dist/src/semantic-tool-command-helpers.js +199 -78
  239. package/dist/src/semantic-tool-command-helpers.js.map +1 -1
  240. package/dist/src/semantic-tool-descriptions.d.ts +2 -1
  241. package/dist/src/semantic-tool-descriptions.js +81 -35
  242. package/dist/src/semantic-tool-descriptions.js.map +1 -1
  243. package/dist/src/semantic-tool-list-projection.js +66 -2
  244. package/dist/src/semantic-tool-list-projection.js.map +1 -1
  245. package/dist/src/semantic-tool-presentation.js +76 -7
  246. package/dist/src/semantic-tool-presentation.js.map +1 -1
  247. package/dist/src/semantic-tool-runtime.js +129 -29
  248. package/dist/src/semantic-tool-runtime.js.map +1 -1
  249. package/dist/src/semantic-tool-schemas.d.ts +410 -27
  250. package/dist/src/semantic-tool-schemas.js +176 -88
  251. package/dist/src/semantic-tool-schemas.js.map +1 -1
  252. package/dist/src/terminal-action-contracts.js +10 -6
  253. package/dist/src/terminal-action-contracts.js.map +1 -1
  254. package/dist/src/terminal-list-cli-adapter.d.ts +1 -0
  255. package/dist/src/terminal-list-cli-adapter.js +6 -3
  256. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  257. package/dist/src/terminal-model-control-profile.d.ts +3 -1
  258. package/dist/src/terminal-model-control-profile.js +15 -7
  259. package/dist/src/terminal-model-control-profile.js.map +1 -1
  260. package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
  261. package/dist/src/terminal-native-inspection-profile.js +4 -0
  262. package/dist/src/terminal-native-inspection-profile.js.map +1 -1
  263. package/dist/src/terminal-permission-control-list-projection.d.ts +1 -1
  264. package/dist/src/terminal-permission-control.js +5 -1
  265. package/dist/src/terminal-permission-control.js.map +1 -1
  266. package/dist/src/terminal-questionnaire-adapter.js +5 -2
  267. package/dist/src/terminal-questionnaire-adapter.js.map +1 -1
  268. package/dist/src/terminal-user-send-intent.d.ts +2 -0
  269. package/dist/src/terminal-user-send-intent.js +11 -3
  270. package/dist/src/terminal-user-send-intent.js.map +1 -1
  271. package/docs/architecture/current-architecture.md +313 -0
  272. package/docs/architecture/interactive-terminal-response.md +276 -0
  273. package/docs/architecture/issue-126-final-report.md +248 -0
  274. package/docs/architecture/orchestration-refactor-history.md +2987 -0
  275. package/docs/architecture/orchestration-refactor.md +21 -0
  276. package/docs/backend-task-recovery.md +89 -0
  277. package/docs/bidirectional-agent-protocol.md +260 -0
  278. package/docs/codex-0.160.0-compatibility.md +126 -0
  279. package/docs/codex-cli-native-compatibility.md +246 -0
  280. package/docs/codex-desktop-compatibility.md +414 -0
  281. package/docs/codex-permissions.md +12 -1
  282. package/docs/openclaw-operations.md +281 -0
  283. package/docs/openclaw-session-turn-delivery-requirement.md +45 -0
  284. package/docs/operator-guide.md +543 -0
  285. package/docs/storage-and-logging.md +91 -0
  286. package/docs/test-performance-issue-108.md +80 -0
  287. package/docs/test-performance-issue-120.md +226 -0
  288. package/docs/testing.md +628 -0
  289. package/openclaw.plugin.json +7 -3
  290. package/package.json +6 -12
  291. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +69 -18
@@ -0,0 +1,123 @@
1
+ import net from "node:net";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { DesktopIpcError } from "./desktop-types.js";
5
+ const MAX_FRAME_BYTES = 32 * 1024 * 1024;
6
+ /** A private parent prevents another OS user replacing a trusted socket path. */
7
+ export function readDesktopSocketIdentity(socketPath) {
8
+ if (!path.isAbsolute(socketPath) || !process.getuid) {
9
+ throw new DesktopIpcError("unsafe_socket", "Desktop IPC requires an owner-local Unix socket");
10
+ }
11
+ const uid = BigInt(process.getuid());
12
+ const parent = fs.lstatSync(path.dirname(socketPath), { bigint: true });
13
+ const socket = fs.lstatSync(socketPath, { bigint: true });
14
+ if (parent.isSymbolicLink() || !parent.isDirectory() || parent.uid !== uid || (parent.mode & 63n) !== 0n
15
+ || socket.isSymbolicLink() || !socket.isSocket() || socket.uid !== uid || (socket.mode & 63n) !== 0n) {
16
+ throw new DesktopIpcError("unsafe_socket", "Desktop IPC socket and parent must be private to the current user and must not be symlinks");
17
+ }
18
+ return [parent.dev, parent.ino, socket.dev, socket.ino, socket.ctimeNs].join(":");
19
+ }
20
+ /** Desktop's private IPC uses a uint32 little-endian length followed by UTF-8 JSON. */
21
+ export class DesktopFrameDecoder {
22
+ buffered = Buffer.alloc(0);
23
+ push(chunk) {
24
+ if (this.buffered.length + chunk.length > MAX_FRAME_BYTES * 2 + 8) {
25
+ throw new DesktopIpcError("invalid_response", "Desktop IPC receive buffer exceeded limit");
26
+ }
27
+ this.buffered = Buffer.concat([this.buffered, chunk]);
28
+ const messages = [];
29
+ while (this.buffered.length >= 4) {
30
+ const length = this.buffered.readUInt32LE(0);
31
+ if (length === 0 || length > MAX_FRAME_BYTES)
32
+ throw new DesktopIpcError("invalid_response", "Invalid Desktop IPC frame length");
33
+ if (this.buffered.length < length + 4)
34
+ break;
35
+ const payload = this.buffered.subarray(4, length + 4);
36
+ this.buffered = this.buffered.subarray(length + 4);
37
+ try {
38
+ messages.push(JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(payload)));
39
+ }
40
+ catch {
41
+ throw new DesktopIpcError("invalid_response", "Invalid Desktop IPC JSON frame");
42
+ }
43
+ }
44
+ return messages;
45
+ }
46
+ }
47
+ export function encodeDesktopFrame(message) {
48
+ const payload = Buffer.from(JSON.stringify(message), "utf8");
49
+ if (!payload.length || payload.length > MAX_FRAME_BYTES)
50
+ throw new DesktopIpcError("invalid_argument", "Desktop IPC frame exceeds limit");
51
+ const frame = Buffer.allocUnsafe(payload.length + 4);
52
+ frame.writeUInt32LE(payload.length, 0);
53
+ payload.copy(frame, 4);
54
+ return frame;
55
+ }
56
+ export async function connectDesktopIpcTransport(options) {
57
+ const identity = readDesktopSocketIdentity(options.socketPath);
58
+ const assertIdentity = () => {
59
+ if (readDesktopSocketIdentity(options.socketPath) !== identity) {
60
+ throw new DesktopIpcError("unsafe_socket", "Desktop IPC socket identity changed; reconnect required");
61
+ }
62
+ };
63
+ const socket = net.createConnection({ path: options.socketPath });
64
+ const messages = new Set();
65
+ const disconnects = new Set();
66
+ const decoder = new DesktopFrameDecoder();
67
+ let ended;
68
+ const finish = (error) => {
69
+ if (ended)
70
+ return;
71
+ ended = error;
72
+ socket.destroy();
73
+ for (const listener of disconnects)
74
+ listener(error);
75
+ disconnects.clear();
76
+ messages.clear();
77
+ };
78
+ socket.on("data", (chunk) => {
79
+ try {
80
+ for (const message of decoder.push(chunk))
81
+ for (const listener of messages)
82
+ listener(message);
83
+ }
84
+ catch (error) {
85
+ finish(error instanceof Error ? error : new Error("Desktop IPC decode failure"));
86
+ }
87
+ });
88
+ socket.on("error", (error) => finish(error));
89
+ socket.on("close", () => finish(new DesktopIpcError("closed", "Desktop IPC connection closed")));
90
+ try {
91
+ await new Promise((resolve, reject) => {
92
+ const timer = setTimeout(() => { cleanup(); reject(new DesktopIpcError("timeout", "Desktop IPC connection timeout")); }, options.timeoutMs);
93
+ const connected = () => { cleanup(); resolve(); };
94
+ const failed = (error) => { cleanup(); reject(error); };
95
+ const cleanup = () => { clearTimeout(timer); socket.off("connect", connected); disconnects.delete(failed); };
96
+ socket.once("connect", connected);
97
+ disconnects.add(failed);
98
+ });
99
+ assertIdentity();
100
+ }
101
+ catch (error) {
102
+ finish(error instanceof Error ? error : new Error("Desktop IPC connection failed"));
103
+ throw error;
104
+ }
105
+ return {
106
+ send(message) {
107
+ if (ended || socket.destroyed || !socket.writable)
108
+ throw new DesktopIpcError("closed", "Desktop IPC socket is unavailable");
109
+ assertIdentity();
110
+ socket.write(encodeDesktopFrame(message));
111
+ },
112
+ onMessage(listener) { messages.add(listener); return () => messages.delete(listener); },
113
+ onDisconnect(listener) {
114
+ if (ended)
115
+ queueMicrotask(() => listener(ended));
116
+ else
117
+ disconnects.add(listener);
118
+ return () => disconnects.delete(listener);
119
+ },
120
+ close() { finish(new DesktopIpcError("closed", "Desktop IPC client closed")); }
121
+ };
122
+ }
123
+ //# sourceMappingURL=desktop-ipc-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-ipc-transport.js","sourceRoot":"","sources":["../../src/desktop-ipc-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { DesktopRuntime } from "./desktop-runtime.js";
2
+ export declare function listDesktopSessions(runtime: DesktopRuntime, options: Record<string, unknown>): Promise<{
3
+ desktop_sessions: Record<string, unknown>[];
4
+ desktop_watches: Record<string, unknown>[];
5
+ desktop_scan: {
6
+ view: string;
7
+ total_candidates: number;
8
+ history_candidates: number | undefined;
9
+ returned: number;
10
+ next_cursor: string | undefined;
11
+ sidebar_status: "partial" | "supported" | "unavailable" | "unsupported" | undefined;
12
+ sidebar_mode: string | undefined;
13
+ sidebar_selection_scope: "persisted_expanded_membership" | undefined;
14
+ limitations: string[] | undefined;
15
+ live_probe_scope: string;
16
+ catalog_complete: boolean;
17
+ live_count: number;
18
+ application_version: string;
19
+ application_build: string;
20
+ write_contract_verified: boolean;
21
+ watch_error: string | undefined;
22
+ sources: import("./desktop-metadata-reader.js").DesktopMetadataSource[];
23
+ membership_is_not_live_identity: boolean;
24
+ };
25
+ }>;
@@ -0,0 +1,55 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { desktopWritesVerified } from "./desktop-runtime.js";
4
+ import { desktopSessionProjection, desktopTaskProjection } from "./desktop-public-projection.js";
5
+ import { DesktopIpcError } from "./desktop-types.js";
6
+ export async function listDesktopSessions(runtime, options) {
7
+ const limit = options.desktopLimit === undefined ? 30 : Number(options.desktopLimit);
8
+ if (!Number.isSafeInteger(limit) || limit < 1 || limit > 100)
9
+ throw new Error("desktop-limit must be between 1 and 100");
10
+ const view = options.desktopView ?? "sidebar";
11
+ if (view !== "sidebar" && view !== "history")
12
+ throw new Error("desktop-view must be sidebar or history");
13
+ const page = await runtime.catalog.list({ view, limit, cursor: text(options.desktopCursor),
14
+ search: text(options.desktopSearch), project: text(options.desktopProject) });
15
+ const sessions = new Array(page.sessions.length);
16
+ // Bounded parallel read-only probes. Missing owners remain visible, never implicitly loaded.
17
+ let index = 0;
18
+ await Promise.all(Array.from({ length: Math.min(16, page.sessions.length) }, async () => {
19
+ while (index < page.sessions.length) {
20
+ const position = index++;
21
+ const entry = page.sessions[position];
22
+ if (!entry.localVerifiable || !fs.existsSync(path.join(entry.codexHome, "ipc", "ipc.sock"))) {
23
+ sessions[position] = desktopSessionProjection(entry, undefined, false, entry.localVerifiable ? "desktop_not_running" : "unsupported_desktop_host");
24
+ continue;
25
+ }
26
+ try {
27
+ const snapshot = await runtime.transport.observe(entry);
28
+ sessions[position] = desktopSessionProjection(entry, snapshot, desktopWritesVerified(runtime.compatibility));
29
+ }
30
+ catch (error) {
31
+ sessions[position] = desktopSessionProjection(entry, undefined, false, error instanceof DesktopIpcError ? error.code : "live_owner_not_confirmed");
32
+ }
33
+ }
34
+ }));
35
+ let watches = [];
36
+ let watchError;
37
+ try {
38
+ watches = runtime.tasks.list().map(task => desktopTaskProjection(task, desktopWritesVerified(runtime.compatibility)));
39
+ }
40
+ catch {
41
+ watchError = "desktop_watch_store_unavailable";
42
+ }
43
+ return { desktop_sessions: sessions, desktop_watches: watches,
44
+ desktop_scan: { view, total_candidates: page.total, history_candidates: page.historyTotal,
45
+ returned: sessions.length, next_cursor: page.nextCursor,
46
+ sidebar_status: page.sidebar?.status, sidebar_mode: page.sidebar?.mode,
47
+ sidebar_selection_scope: page.sidebar?.selectionScope, limitations: page.sidebar?.limitations,
48
+ live_probe_scope: "returned_page",
49
+ catalog_complete: page.complete, live_count: sessions.filter(row => row.connection_state === "live_owner_verified").length,
50
+ application_version: runtime.compatibility.version, application_build: runtime.compatibility.build,
51
+ write_contract_verified: desktopWritesVerified(runtime.compatibility), watch_error: watchError,
52
+ sources: page.sources, membership_is_not_live_identity: true } };
53
+ }
54
+ function text(value) { return typeof value === "string" ? value : undefined; }
55
+ //# sourceMappingURL=desktop-list.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-list.js","sourceRoot":"","sources":["../../src/desktop-list.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ export type DesktopMetadataRow = Record<string, unknown>;
2
+ export type DesktopMetadataKind = "desktop_catalog" | "state";
3
+ export interface DesktopMetadataSource {
4
+ database: string;
5
+ codexHome: string;
6
+ kind: DesktopMetadataKind;
7
+ status: "ok" | "absent" | "error";
8
+ rowCount?: number;
9
+ pageCount?: number;
10
+ columns?: string[];
11
+ error?: string;
12
+ snapshot?: "stable_copy";
13
+ }
14
+ export interface DesktopMetadataBatch {
15
+ source: DesktopMetadataSource;
16
+ rows: DesktopMetadataRow[];
17
+ hosts?: Record<string, string>;
18
+ }
19
+ export type DesktopMetadataReader = (codexHome: string) => Promise<DesktopMetadataBatch[]>;
20
+ export type DesktopSnapshotQuery = (database: string, sql: string) => Promise<DesktopMetadataRow[]>;
21
+ export interface DesktopMetadataReaderOptions {
22
+ querySnapshot?: DesktopSnapshotQuery;
23
+ temporaryRoot?: string;
24
+ maxRows?: number;
25
+ }
26
+ /** Reads metadata only. Original SQLite files are never opened by SQLite. */
27
+ export declare function readDesktopMetadata(codexHome: string, options?: DesktopMetadataReaderOptions): Promise<DesktopMetadataBatch[]>;
28
+ /** Sequential DB/WAL copy with stat guards, not an atomic SQLite backup. */
29
+ export declare function withDesktopMetadataSnapshot<T>(database: string, read: (copy: string) => Promise<T>, temporaryRoot?: string): Promise<T | undefined>;
30
+ export declare function queryDesktopSnapshot(database: string, sql: string): Promise<DesktopMetadataRow[]>;
@@ -0,0 +1,182 @@
1
+ import { execFile } from "node:child_process";
2
+ import fs from "node:fs/promises";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import { latestStateDbPath } from "./codex-sqlite-thread-query.js";
6
+ const PAGE_SIZE = 100;
7
+ const STATE_COLUMNS = [
8
+ "id", "cwd", "title", "name", "updated_at", "updated_at_ms", "originator",
9
+ "archived", "source", "thread_source", "project_id", "parent_thread_id",
10
+ "is_pinned", "thread_section_id", "section_position", "recency_at_ms"
11
+ ];
12
+ const CATALOG_COLUMNS = [
13
+ "host_id", "thread_id", "display_title", "cwd", "source_updated_at",
14
+ "source_kind", "thread_source", "missing_candidate", "project_id"
15
+ ];
16
+ /** Reads metadata only. Original SQLite files are never opened by SQLite. */
17
+ export async function readDesktopMetadata(codexHome, options = {}) {
18
+ const home = path.resolve(codexHome);
19
+ const statePath = latestStateDbPath(home);
20
+ const sources = [
21
+ { database: path.join(home, "sqlite", "codex.db"), kind: "desktop_catalog" },
22
+ { database: path.join(home, "sqlite", "codex-dev.db"), kind: "desktop_catalog" },
23
+ { database: statePath ?? path.join(home, "state_*.sqlite"), kind: "state" }
24
+ ];
25
+ const result = [];
26
+ for (const source of sources) {
27
+ const metadata = { ...source, codexHome: home, status: "absent" };
28
+ if (source.kind === "state" && !statePath) {
29
+ result.push({ source: metadata, rows: [] });
30
+ continue;
31
+ }
32
+ try {
33
+ const batch = await withDesktopMetadataSnapshot(source.database, async (copy) => {
34
+ const query = options.querySnapshot ?? queryDesktopSnapshot;
35
+ const checks = await query(copy, "PRAGMA quick_check");
36
+ if (checks.length !== 1 || Object.values(checks[0])[0] !== "ok") {
37
+ throw new Error("Metadata snapshot failed SQLite quick_check");
38
+ }
39
+ return readSnapshot(copy, metadata, query, options.maxRows ?? 100_000);
40
+ }, options.temporaryRoot);
41
+ result.push(batch ?? { source: metadata, rows: [] });
42
+ }
43
+ catch (error) {
44
+ result.push({ source: { ...metadata, status: "error", error: error instanceof Error ? error.message : String(error) }, rows: [] });
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+ async function readSnapshot(copy, source, query, maxRows) {
50
+ if (!Number.isSafeInteger(maxRows) || maxRows < 1)
51
+ throw new Error("Invalid metadata row limit");
52
+ const isState = source.kind === "state";
53
+ const table = isState ? "threads" : "local_thread_catalog";
54
+ const columns = await schemaColumns(copy, table, query);
55
+ const required = isState
56
+ ? ["id", "cwd", "title", "archived", "source"]
57
+ : ["host_id", "thread_id", "display_title", "cwd", "source_updated_at", "source_kind", "missing_candidate"];
58
+ if (isState && !columns.includes("updated_at") && !columns.includes("updated_at_ms")) {
59
+ throw new Error("Unsupported threads schema: missing update timestamp");
60
+ }
61
+ requireColumns(table, columns, required);
62
+ const selected = selectedColumns(isState ? STATE_COLUMNS : CATALOG_COLUMNS, columns);
63
+ // Archived metadata is needed to reject stale sidebar assignments and pins.
64
+ // Content/history tables are never read; the catalog filters these rows later.
65
+ const predicate = isState ? "1 = 1" : "missing_candidate = 0";
66
+ const order = isState ? "id" : "host_id, thread_id";
67
+ const { rows, pageCount } = await scanSnapshotRows(copy, query, { table, selected, predicate, order, maxRows });
68
+ const hosts = isState ? Object.create(null) : await readCatalogHosts(copy, query);
69
+ return { source: { ...source, status: "ok", rowCount: rows.length, pageCount, columns, snapshot: "stable_copy" }, rows, hosts };
70
+ }
71
+ function selectedColumns(wanted, available) {
72
+ return wanted.map((column) => {
73
+ if (!available.includes(column))
74
+ return `NULL AS "${column}"`;
75
+ if (["title", "name", "display_title"].includes(column))
76
+ return `substr("${column}",1,160) AS "${column}"`;
77
+ return `"${column}"`;
78
+ }).join(", ");
79
+ }
80
+ async function scanSnapshotRows(copy, query, { table, selected, predicate, order, maxRows }) {
81
+ const counts = await query(copy, `SELECT count(*) AS count FROM "${table}" WHERE ${predicate}`);
82
+ const count = counts[0]?.count;
83
+ if (!Number.isSafeInteger(count) || Number(count) < 0 || Number(count) > maxRows) {
84
+ throw new Error(`Metadata row count is invalid or exceeds ${maxRows}; discovery is incomplete`);
85
+ }
86
+ const rows = [];
87
+ let pageCount = 0;
88
+ while (rows.length < Number(count)) {
89
+ const page = await query(copy, `SELECT ${selected} FROM "${table}" WHERE ${predicate} ORDER BY ${order} LIMIT ${PAGE_SIZE} OFFSET ${rows.length}`);
90
+ if (page.length === 0 || page.length > PAGE_SIZE)
91
+ throw new Error("Metadata page count mismatch");
92
+ rows.push(...page);
93
+ pageCount += 1;
94
+ }
95
+ if (rows.length !== count)
96
+ throw new Error("Metadata scan count mismatch");
97
+ return { rows, pageCount };
98
+ }
99
+ async function readCatalogHosts(copy, query) {
100
+ const hosts = Object.create(null);
101
+ const hostColumns = await schemaColumns(copy, "local_thread_catalog_hosts", query);
102
+ requireColumns("local_thread_catalog_hosts", hostColumns, ["host_id", "host_kind"]);
103
+ for (const row of await query(copy, "SELECT host_id, host_kind FROM local_thread_catalog_hosts")) {
104
+ if (typeof row.host_id !== "string" || typeof row.host_kind !== "string")
105
+ throw new Error("Invalid catalog host metadata");
106
+ hosts[row.host_id] = row.host_kind;
107
+ }
108
+ return hosts;
109
+ }
110
+ async function schemaColumns(copy, table, query) {
111
+ return (await query(copy, `PRAGMA table_info("${table}")`)).map((row) => String(row.name));
112
+ }
113
+ function requireColumns(table, actual, required) {
114
+ const missing = required.filter((column) => !actual.includes(column));
115
+ if (missing.length)
116
+ throw new Error(`Unsupported ${table} schema: missing ${missing.join(", ")}`);
117
+ }
118
+ async function signature(file) {
119
+ try {
120
+ const stat = await fs.stat(file, { bigint: true });
121
+ if (!stat.isFile())
122
+ throw new Error("Metadata path is not a regular file");
123
+ return [stat.dev, stat.ino, stat.size, stat.mtimeNs, stat.ctimeNs].join(":");
124
+ }
125
+ catch (error) {
126
+ if (error?.code === "ENOENT")
127
+ return null;
128
+ throw error;
129
+ }
130
+ }
131
+ /** Sequential DB/WAL copy with stat guards, not an atomic SQLite backup. */
132
+ export async function withDesktopMetadataSnapshot(database, read, temporaryRoot = os.tmpdir()) {
133
+ for (let attempt = 0; attempt < 3; attempt += 1) {
134
+ const files = [database, `${database}-wal`];
135
+ const before = await Promise.all(files.map(signature));
136
+ if (before[0] === null)
137
+ return undefined;
138
+ const directory = await fs.mkdtemp(path.join(temporaryRoot, "akk-desktop-metadata-"));
139
+ try {
140
+ await fs.chmod(directory, 0o700);
141
+ const copy = path.join(directory, path.basename(database));
142
+ for (let index = 0; index < files.length; index += 1) {
143
+ if (before[index] === null)
144
+ continue;
145
+ const destination = `${copy}${index === 0 ? "" : "-wal"}`;
146
+ await fs.copyFile(files[index], destination);
147
+ await fs.chmod(destination, 0o600);
148
+ }
149
+ const after = await Promise.all(files.map(signature));
150
+ if (before.some((value, index) => value !== after[index]))
151
+ continue;
152
+ return await read(copy);
153
+ }
154
+ finally {
155
+ await fs.rm(directory, { recursive: true, force: true });
156
+ }
157
+ }
158
+ throw new Error("Metadata database/WAL changed during every snapshot attempt");
159
+ }
160
+ export function queryDesktopSnapshot(database, sql) {
161
+ return new Promise((resolve, reject) => {
162
+ execFile("sqlite3", ["-batch", "-bail", "-readonly", "-json", "-cmd", "PRAGMA query_only=ON", database, sql], {
163
+ encoding: "utf8", timeout: 10_000, maxBuffer: 10 * 1024 * 1024
164
+ }, (error, stdout) => {
165
+ if (error) {
166
+ reject(new Error(`SQLite metadata query failed (${error.code ?? "unknown"})`));
167
+ return;
168
+ }
169
+ try {
170
+ const rows = stdout.trim() ? JSON.parse(stdout) : [];
171
+ if (!Array.isArray(rows) || rows.some((row) => !row || typeof row !== "object" || Array.isArray(row))) {
172
+ throw new Error("SQLite metadata output is not an array of records");
173
+ }
174
+ resolve(rows);
175
+ }
176
+ catch (error) {
177
+ reject(error);
178
+ }
179
+ });
180
+ });
181
+ }
182
+ //# sourceMappingURL=desktop-metadata-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-metadata-reader.js","sourceRoot":"","sources":["../../src/desktop-metadata-reader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type DesktopRuntimeOptions } from "./desktop-runtime.js";
2
+ export declare function launchDesktopMonitor(watchId: string, options: DesktopRuntimeOptions): Promise<number>;
3
+ /** One detached observer per Watch; host sweeps independently repair missed work. */
4
+ export declare function runDesktopMonitor(watchId: string, options: DesktopRuntimeOptions): Promise<void>;
@@ -0,0 +1,101 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { spawn } from "node:child_process";
5
+ import { ensureDir } from "./store.js";
6
+ import { cliCwd, cliEnv, cliNow, cliNowMs, cliPid, cliSleep, cliSleepSync } from "./cli-runtime-context.js";
7
+ import { createFileLockCliAdapter } from "./file-lock-cli-adapter.js";
8
+ import { desktopTaskNeedsReconciliation } from "./desktop-task-service.js";
9
+ import { createDesktopRuntime } from "./desktop-runtime.js";
10
+ import { isDesktopWatchId } from "./desktop-semantic.js";
11
+ export async function launchDesktopMonitor(watchId, options) {
12
+ if (!isDesktopWatchId(watchId))
13
+ throw new Error("Invalid Desktop Watch ID");
14
+ const args = [fileURLToPath(new URL("./cli.js", import.meta.url)), "monitor-desktop", "--watch", watchId,
15
+ "--store-dir", options.storeDir];
16
+ if (options.openclawBin)
17
+ args.push("--openclaw-bin", options.openclawBin);
18
+ const directory = path.join(options.storeDir, "desktop-monitors");
19
+ ensureDir(directory);
20
+ const fd = fs.openSync(path.join(directory, `${watchId}.log`), fs.constants.O_CREAT | fs.constants.O_APPEND |
21
+ fs.constants.O_WRONLY | fs.constants.O_NOFOLLOW, 0o600);
22
+ try {
23
+ const child = spawn(process.execPath, args, { detached: true, cwd: cliCwd(),
24
+ env: { ...cliEnv(), AKK_DESKTOP_CODEX_HOMES: JSON.stringify(options.codexHomes) }, stdio: ["ignore", fd, fd, "ipc"] });
25
+ const pid = await new Promise((resolve, reject) => {
26
+ const timer = setTimeout(() => finish(new Error("Desktop monitor readiness timed out")), 5000);
27
+ const finish = (error, pid) => {
28
+ clearTimeout(timer);
29
+ child.removeAllListeners("message");
30
+ child.removeAllListeners("exit");
31
+ if (child.connected)
32
+ child.disconnect();
33
+ child.unref();
34
+ if (error)
35
+ reject(error);
36
+ else
37
+ resolve(pid);
38
+ };
39
+ child.once("error", error => finish(error));
40
+ child.once("exit", () => finish(new Error("Desktop monitor exited before readiness")));
41
+ child.on("message", value => {
42
+ const message = value;
43
+ if (message.watchId === watchId && message.ready === true && Number.isSafeInteger(message.pid) && message.pid > 1) {
44
+ finish(undefined, message.pid);
45
+ }
46
+ });
47
+ });
48
+ return pid;
49
+ }
50
+ finally {
51
+ fs.closeSync(fd);
52
+ }
53
+ }
54
+ /** One detached observer per Watch; host sweeps independently repair missed work. */
55
+ export async function runDesktopMonitor(watchId, options) {
56
+ if (!isDesktopWatchId(watchId))
57
+ throw new Error("Invalid Desktop Watch ID");
58
+ const directory = path.join(options.storeDir, "desktop-monitors");
59
+ ensureDir(directory);
60
+ const locks = createFileLockCliAdapter({ now: cliNow, nowMs: cliNowMs, pid: cliPid, sleepSync: cliSleepSync });
61
+ const initial = createDesktopRuntime(options);
62
+ try {
63
+ initial.tasks.status(watchId);
64
+ }
65
+ finally {
66
+ await initial.close();
67
+ }
68
+ const lockPath = path.join(directory, `${watchId}.lock`);
69
+ let release;
70
+ try {
71
+ release = locks.acquire(lockPath, { timeoutMs: 100 });
72
+ }
73
+ catch (error) {
74
+ const owner = locks.owner(lockPath);
75
+ if (owner.pid && owner.pid !== cliPid() && !locks.stale(lockPath)) {
76
+ process.send?.({ watchId, ready: true, pid: owner.pid });
77
+ return;
78
+ }
79
+ throw error;
80
+ }
81
+ try {
82
+ process.send?.({ watchId, ready: true, pid: cliPid() });
83
+ for (;;) {
84
+ const runtime = createDesktopRuntime(options);
85
+ let pending;
86
+ try {
87
+ pending = desktopTaskNeedsReconciliation(await runtime.tasks.reconcile(watchId));
88
+ }
89
+ finally {
90
+ await runtime.close();
91
+ }
92
+ if (!pending)
93
+ return;
94
+ await cliSleep(2000);
95
+ }
96
+ }
97
+ finally {
98
+ release();
99
+ }
100
+ }
101
+ //# sourceMappingURL=desktop-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-monitor.js","sourceRoot":"","sources":["../../src/desktop-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { DesktopCatalogEntry } from "./desktop-session-catalog.js";
2
+ import type { DesktopSnapshot } from "./desktop-types.js";
3
+ import type { DesktopTaskRecord } from "./desktop-state-store.js";
4
+ export declare function desktopSessionProjection(entry: DesktopCatalogEntry, snapshot?: DesktopSnapshot, writesVerified?: boolean, observationError?: string): Record<string, unknown>;
5
+ /** Do not export prompts, internal owner IDs, callback configuration or raw native state. */
6
+ export declare function desktopTaskProjection(task: DesktopTaskRecord, writesVerified?: boolean): Record<string, unknown>;