@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
@@ -1,4 +1,7 @@
1
+ import { formatDesktopCommandResult } from "./desktop-command-presentation.js";
2
+ import { backendRecoveryTarget, backendRecoveryToolArgs, isBackendTaskWatchId } from "./backend-recovery-semantic.js";
1
3
  import path from "node:path";
4
+ import { isCodexNativeConversationId, parseCodexNativeConversationId } from "./codex-native-identity.js";
2
5
  import { recordValue } from "./value-guards.js";
3
6
  import { isTerminalApprovalDecision } from "./terminal-agent-adapter.js";
4
7
  import { arrayValue, finiteNumber, nonEmptyString, stringArrayValue, truncateText } from "./semantic-tool-value-helpers.js";
@@ -151,9 +154,9 @@ function parseAkkLifecycleCommand(action, rest) {
151
154
  return { action: "doctor" };
152
155
  }
153
156
  if (action === "watch") {
154
- const usage = "Usage: /akk watch <exact-terminal-id>";
157
+ const usage = "Usage: /akk watch <exact-terminal-id|codex-cli-conversation-id>";
155
158
  const { token: terminalId, rest: extra } = takeRequiredToken(rest, usage);
156
- assertExactTerminalId(terminalId, usage);
159
+ assertExactTerminalOrNativeId(terminalId, usage);
157
160
  if (extra.trim()) {
158
161
  throw new Error(usage);
159
162
  }
@@ -179,7 +182,7 @@ function parseAkkLifecycleCommand(action, rest) {
179
182
  if (action === "permissions" || action === "permission-options") {
180
183
  const usage = "Usage: /akk permissions <exact-terminal-id>";
181
184
  const { token: terminalId, rest: extra } = takeRequiredToken(rest, usage);
182
- assertExactTerminalId(terminalId, usage);
185
+ assertExactTerminalOrNativeId(terminalId, usage);
183
186
  if (extra.trim())
184
187
  throw new Error(usage);
185
188
  return { action: "permission-options", terminalId };
@@ -187,7 +190,7 @@ function parseAkkLifecycleCommand(action, rest) {
187
190
  if (action === "set-permissions") {
188
191
  const usage = "Usage: /akk set-permissions <exact-terminal-id> <advertised-mode-id>";
189
192
  const { token: terminalId, rest: modeInput } = takeRequiredToken(rest, usage);
190
- assertExactTerminalId(terminalId, usage);
193
+ assertExactTerminalOrNativeId(terminalId, usage);
191
194
  const { token: mode, rest: extra } = takeRequiredToken(modeInput, usage);
192
195
  if (extra.trim() || !/^[a-z][a-z0-9_-]{0,63}$/u.test(mode))
193
196
  throw new Error(usage);
@@ -316,8 +319,20 @@ function parseAkkTurnCommand(action, rest) {
316
319
  return { action: "renew", turnId, minutes: minutes || undefined };
317
320
  }
318
321
  if (action === "retry-callback" || action === "retry") {
319
- const { token: turnId } = takeRequiredToken(rest, "Usage: /akk retry-callback <turn-selector>");
320
- return { action: "retry-callback", turnId };
322
+ const { token: turnId, rest: notificationInput } = takeRequiredToken(rest, "Usage: /akk retry-callback <turn-selector> [--notification-id <id>]");
323
+ const notification = notificationInput.trim();
324
+ const selection = /^--notification-id\s+(\S+)$/u.exec(notification);
325
+ if (notification && !selection)
326
+ throw new Error("Usage: /akk retry-callback <turn-selector> [--notification-id <id>]");
327
+ return { action: "retry-callback", turnId, ...(selection ? { notificationId: selection[1] } : {}) };
328
+ }
329
+ if (action === "recover") {
330
+ const usage = "Usage: /akk recover <backend-watch-id>";
331
+ const { token: turnId, rest: extra } = takeRequiredToken(rest, usage);
332
+ if (extra.trim())
333
+ throw new Error(usage);
334
+ backendRecoveryTarget({ turn_id: turnId }, "recover");
335
+ return { action: "recover", turnId };
321
336
  }
322
337
  if (action === "close" || action === "done") {
323
338
  return parseAkkCloseCommand(rest);
@@ -382,6 +397,7 @@ export function akkUsageText() {
382
397
  "/akk respond <turn-selector>: <answer>",
383
398
  "/akk approve <turn-selector> [approve_once|reject]",
384
399
  "/akk cancel <turn-selector>",
400
+ "/akk recover <backend-watch-id>",
385
401
  "Native interactions are answered through Status plus the typed respond_interaction tool; there is no raw-key or menu-index /akk command.",
386
402
  "Codex async_question stays parallel to a working task; delivery_mode defaults to advertised steer_current_turn, or explicitly choose advertised queue_next_turn. A blocking questionnaire omits delivery_mode.",
387
403
  "Model control targets one exact physical pane; Codex rollout attribution and identify-foreground are not prerequisites.",
@@ -389,76 +405,84 @@ export function akkUsageText() {
389
405
  "Models normally requires an idle, empty, prompt-free UI with no active Turn; for an exactly advertised profiled Codex 0.154.0/0.155.1 /model residue it may continue that residue into read-only catalog discovery. Successful discovery consumes any residual-entry authority, restores the exact empty UI, and issues a fresh ordinary one-shot set-model offer; set-model accepts only that offer. If the result is uncertain, inspect the pane and do not retry automatically."
390
406
  ].join("\n");
391
407
  }
408
+ function formatAkkTerminalControlLines(terminal) {
409
+ const managed = recordValue(terminal.managed) ?? {};
410
+ const managementConflict = recordValue(terminal.management_conflict);
411
+ const currentTurn = recordValue(managed.current_turn);
412
+ const recentTurn = recordValue(managed.recent_turn);
413
+ const history = arrayValue(managed.history);
414
+ const sessionId = nonEmptyString(managed.session_id);
415
+ const sessionShortRef = nonEmptyString(managed.session_short_ref);
416
+ const hiddenTurnCount = finiteNumber(managed.hidden_turn_count) ?? 0;
417
+ const recovery = orphanedTerminalDispatchRecovery(terminal);
418
+ const terminalId = nonEmptyString(terminal.id);
419
+ const availableActions = recordValue(terminal.available_actions) ?? {};
420
+ const hasLifecycleAction = [
421
+ "list_resumable_threads",
422
+ "new_thread",
423
+ "resume_thread"
424
+ ].some((name) => Object.hasOwn(availableActions, name));
425
+ const hasWatchAction = Object.hasOwn(availableActions, "watch");
426
+ return [
427
+ `- ${formatTerminalLine(terminal)}`,
428
+ ...compatibilityWarningLines(terminal),
429
+ ...(hasLifecycleAction && terminalId
430
+ ? [` lifecycle terminal_id: ${terminalId}`]
431
+ : []),
432
+ ...(hasWatchAction && terminalId
433
+ ? [` AKK Watch available: /akk watch ${terminalId} — observe this exact terminal without input; exact task evidence is preferred and terminal-activity fallback is best-effort.`]
434
+ : []),
435
+ ...(sessionId || sessionShortRef
436
+ ? [` AKK session: ${sessionShortRef ?? sessionId}`]
437
+ : []),
438
+ ...formatAvailableActions("terminal actions", terminal),
439
+ ...(currentTurn
440
+ ? [
441
+ ` current turn: ${formatManagedTurnLine(currentTurn)}`,
442
+ ...formatAvailableActions("current turn actions", currentTurn)
443
+ ]
444
+ : []),
445
+ ...(recentTurn
446
+ ? [
447
+ ` recent turn: ${formatManagedTurnLine(recentTurn)}`,
448
+ ...formatAvailableActions("recent turn actions", recentTurn)
449
+ ]
450
+ : []),
451
+ ...history.slice(0, 20).flatMap((turn) => [
452
+ ` history: ${formatManagedTurnLine(turn)}`,
453
+ ...formatAvailableActions("history actions", turn)
454
+ ]),
455
+ ...(hiddenTurnCount > 0 && history.length === 0
456
+ ? [` older managed turns: ${hiddenTurnCount} (use all=true to include)`]
457
+ : []),
458
+ ...(managementConflict
459
+ ? [
460
+ ` management conflict: ${nonEmptyString(managementConflict.reason) ?? "current terminal ownership is unresolved"}`,
461
+ ...(nonEmptyString(managementConflict.recovery)
462
+ ? [` recovery: ${nonEmptyString(managementConflict.recovery)}`]
463
+ : [])
464
+ ]
465
+ : []),
466
+ ...(recovery ? [` recovery: ${recovery}`] : [])
467
+ ];
468
+ }
392
469
  export function formatAkkListCommandResult(result) {
393
- const terminals = arrayValue(result.terminals);
470
+ const conversations = Array.isArray(result.conversations) ? arrayValue(result.conversations) : undefined;
471
+ const nativeSessions = conversations?.filter(row => row.source === "codex_cli") ?? arrayValue(result.codex_cli_sessions);
472
+ const nativeWatches = arrayValue(result.codex_cli_watches);
473
+ const desktopSessions = conversations?.filter(row => row.source === "codex_desktop") ?? arrayValue(result.desktop_sessions);
474
+ const desktopWatches = arrayValue(result.desktop_watches);
475
+ const terminals = conversations?.filter(row => row.source !== "codex_cli" && row.source !== "codex_desktop") ?? arrayValue(result.terminals);
394
476
  const terminalWatches = arrayValue(result.terminal_watches);
395
477
  const unavailableManagedTurns = arrayValue(result.unavailable_managed_turns);
396
- if (terminals.length === 0 &&
478
+ if (nativeSessions.length === 0 && nativeWatches.length === 0 &&
479
+ desktopSessions.length === 0 && desktopWatches.length === 0 &&
480
+ terminals.length === 0 &&
397
481
  terminalWatches.length === 0 &&
398
482
  unavailableManagedTurns.length === 0) {
399
483
  return "AKK found no live terminals or unavailable managed turns.";
400
484
  }
401
- const terminalLines = terminals.slice(0, 20).flatMap((terminal) => {
402
- const managed = recordValue(terminal.managed) ?? {};
403
- const managementConflict = recordValue(terminal.management_conflict);
404
- const currentTurn = recordValue(managed.current_turn);
405
- const recentTurn = recordValue(managed.recent_turn);
406
- const history = arrayValue(managed.history);
407
- const sessionId = nonEmptyString(managed.session_id);
408
- const sessionShortRef = nonEmptyString(managed.session_short_ref);
409
- const hiddenTurnCount = finiteNumber(managed.hidden_turn_count) ?? 0;
410
- const recovery = orphanedTerminalDispatchRecovery(terminal);
411
- const terminalId = nonEmptyString(terminal.id);
412
- const availableActions = recordValue(terminal.available_actions) ?? {};
413
- const hasLifecycleAction = [
414
- "list_resumable_threads",
415
- "new_thread",
416
- "resume_thread"
417
- ].some((name) => Object.hasOwn(availableActions, name));
418
- const hasWatchAction = Object.hasOwn(availableActions, "watch");
419
- return [
420
- `- ${formatTerminalLine(terminal)}`,
421
- ...compatibilityWarningLines(terminal),
422
- ...(hasLifecycleAction && terminalId
423
- ? [` lifecycle terminal_id: ${terminalId}`]
424
- : []),
425
- ...(hasWatchAction && terminalId
426
- ? [` AKK Watch available: /akk watch ${terminalId} — observe this exact terminal without input; exact task evidence is preferred and terminal-activity fallback is best-effort.`]
427
- : []),
428
- ...(sessionId || sessionShortRef
429
- ? [` AKK session: ${sessionShortRef ?? sessionId}`]
430
- : []),
431
- ...formatAvailableActions("terminal actions", terminal),
432
- ...(currentTurn
433
- ? [
434
- ` current turn: ${formatManagedTurnLine(currentTurn)}`,
435
- ...formatAvailableActions("current turn actions", currentTurn)
436
- ]
437
- : []),
438
- ...(recentTurn
439
- ? [
440
- ` recent turn: ${formatManagedTurnLine(recentTurn)}`,
441
- ...formatAvailableActions("recent turn actions", recentTurn)
442
- ]
443
- : []),
444
- ...history.slice(0, 20).flatMap((turn) => [
445
- ` history: ${formatManagedTurnLine(turn)}`,
446
- ...formatAvailableActions("history actions", turn)
447
- ]),
448
- ...(hiddenTurnCount > 0 && history.length === 0
449
- ? [` older managed turns: ${hiddenTurnCount} (use all=true to include)`]
450
- : []),
451
- ...(managementConflict
452
- ? [
453
- ` management conflict: ${nonEmptyString(managementConflict.reason) ?? "current terminal ownership is unresolved"}`,
454
- ...(nonEmptyString(managementConflict.recovery)
455
- ? [` recovery: ${nonEmptyString(managementConflict.recovery)}`]
456
- : [])
457
- ]
458
- : []),
459
- ...(recovery ? [` recovery: ${recovery}`] : [])
460
- ];
461
- });
485
+ const terminalLines = terminals.slice(0, 20).flatMap(formatAkkTerminalControlLines);
462
486
  const watchLines = terminalWatches.slice(0, 20).flatMap((watch) => [
463
487
  `- ${formatTerminalWatchLine(watch)}`,
464
488
  ...compatibilityWarningLines(watch),
@@ -468,7 +492,17 @@ export function formatAkkListCommandResult(result) {
468
492
  ? `AKK terminals (${terminals.length} live, ${terminalWatches.length} terminal watches, ${unavailableManagedTurns.length} unavailable managed turns):`
469
493
  : `AKK terminals (${terminals.length} live, ${unavailableManagedTurns.length} unavailable managed turns):`;
470
494
  return [
471
- heading,
495
+ conversations ? `AKK conversations (${conversations.length}); select a conversation_id and AKK chooses the transport:` : heading,
496
+ ...(nativeSessions.length ? ["Direct Codex CLI conversations:", ...nativeSessions.flatMap(row => [
497
+ `- ${row.title ?? row.native_thread_id} | ${row.cwd ?? "unknown directory"} | ${row.activity_state ?? "unknown"}`,
498
+ ` conversation_id: ${row.conversation_id}`, ...formatAvailableActions(" actions", row),
499
+ ...arrayValue(row.terminal_controls).flatMap(terminal => [" associated terminal controls:",
500
+ ...formatAkkTerminalControlLines(terminal).map(line => ` ${line}`)])
501
+ ])] : []),
502
+ ...(nativeWatches.length ? ["Direct Codex CLI watches:", ...nativeWatches.map(row => `- ${row.watch_id}: ${row.status}`)] : []),
503
+ ...(desktopSessions.length ? ["Desktop conversations:", ...desktopSessions.map(row => `- ${row.title} | ${row.cwd ?? "unknown directory"} | ${row.activity_state} | ${row.connection_state}\n conversation_id: ${row.conversation_id}`)] : []),
504
+ ...(desktopWatches.length ? ["Desktop watches:", ...desktopWatches.map(row => `- ${row.watch_id}: ${row.status}`)] : []),
505
+ ...(recordValue(result.desktop_scan)?.next_cursor ? [`Desktop next_cursor: ${recordValue(result.desktop_scan)?.next_cursor}`] : []),
472
506
  ...(terminalLines.length > 0
473
507
  ? ["live terminals:", ...terminalLines]
474
508
  : []),
@@ -497,6 +531,8 @@ export function formatAkkListCommandResult(result) {
497
531
  */
498
532
  export { compactAkkListModelProjection } from "./semantic-tool-list-projection.js";
499
533
  export function formatAkkWatchCommandResult(result) {
534
+ if (result.source === "codex_cli")
535
+ return formatCodexNativeCommandResult(result, "Watch started");
500
536
  const watch = terminalWatchRecord(result);
501
537
  return [
502
538
  "AKK Terminal Watch started:",
@@ -514,6 +550,9 @@ export function formatAkkWatchCommandResult(result) {
514
550
  ].join("\n");
515
551
  }
516
552
  export function formatAkkUnwatchCommandResult(result) {
553
+ if (result.source === "codex_cli")
554
+ return formatCodexNativeCommandResult(result, "Watch stopped") +
555
+ "\nObservation stopped; the native task was not interrupted.";
517
556
  const watch = terminalWatchRecord(result);
518
557
  return [
519
558
  "AKK Terminal Watch stopped:",
@@ -523,6 +562,8 @@ export function formatAkkUnwatchCommandResult(result) {
523
562
  ].join("\n");
524
563
  }
525
564
  export function formatAkkWatchStatusCommandResult(result) {
565
+ if (result.source === "codex_cli")
566
+ return formatCodexNativeCommandResult(result, "Watch status");
526
567
  const watch = terminalWatchRecord(result);
527
568
  const userExplicitFallback = watch.source ===
528
569
  "terminal_user_explicit_fallback_watch";
@@ -570,6 +611,45 @@ export function formatAkkWatchStatusCommandResult(result) {
570
611
  : "This is a user-selected read-only exact-task observation; Watch itself did not send, adopt, or mutate the task."
571
612
  ].join("\n");
572
613
  }
614
+ /** Native thread/task identities are not managed Session/Turn or physical pane IDs. */
615
+ export function formatCodexNativeCommandResult(result, operation) {
616
+ const latest = recordValue(result.latest_turn);
617
+ const finalText = nonEmptyString(result.final_text) ?? nonEmptyString(latest?.final_text);
618
+ const notifications = arrayValue(result.callback_notifications);
619
+ const interactions = arrayValue(result.interaction_state);
620
+ const state = nonEmptyString(result.state);
621
+ const sendState = nonEmptyString(result.send_state);
622
+ return [
623
+ `AKK Codex CLI ${operation}:`,
624
+ `conversation: ${nonEmptyString(result.conversation_id) ?? "unknown"}`,
625
+ ...(nonEmptyString(result.watch_id) ? [`watch: ${result.watch_id}`] : []),
626
+ ...(nonEmptyString(result.native_thread_id) ? [`native thread: ${result.native_thread_id}`] : []),
627
+ ...(nonEmptyString(result.native_turn_id) ? [`native task: ${result.native_turn_id}`] : []),
628
+ `status: ${nonEmptyString(result.status) ?? nonEmptyString(result.activity_state) ?? state ?? "unknown"}`,
629
+ ...(sendState ? [`send: ${sendState}; native acceptance: ${nonEmptyString(result.agent_acceptance) ?? "unproven"}`] : []),
630
+ ...formatNativeResponseState(state, result.evidence),
631
+ ...(typeof result.callback_expected === "boolean" ? [`callback expected: ${result.callback_expected}`] : []),
632
+ ...notifications.map(note => `callback: ${nonEmptyString(note.status) ?? "unknown"}`),
633
+ ...(nonEmptyString(result.observation_error) ? [`observation: ${result.observation_error}`] : []),
634
+ ...(finalText ? [`completion: ${truncateText(finalText, 2000)}`] : []),
635
+ ...interactions.flatMap(interaction => [
636
+ `pending ${nonEmptyString(interaction.kind) ?? "interaction"}: ${interaction.interaction_id}`,
637
+ ...(nonEmptyString(interaction.command) ? [` command: ${truncateText(interaction.command, 500)}`] : []),
638
+ ...arrayValue(interaction.questions).map(question => ` ${question.question_id}: ${question.title}`)
639
+ ]),
640
+ ...(interactions.length ? ["Use the current typed Status actions to answer or approve this exact request."] : []),
641
+ ...(sendState && sendState !== "accepted" ? ["Acceptance is not proven. Keep this receipt and refresh Status; do not resend automatically."] : [])
642
+ ].join("\n");
643
+ }
644
+ function formatNativeResponseState(state, evidence) {
645
+ if (!state)
646
+ return [];
647
+ if (state === "confirmed")
648
+ return [`response: confirmed (${nonEmptyString(evidence) ?? "native evidence"})`];
649
+ if (state === "sent")
650
+ return ["response: dispatched; native effect is not yet confirmed."];
651
+ return [`response: ${state}; do not resend automatically.`];
652
+ }
573
653
  export function formatAkkTerminalWatchHint(result) {
574
654
  const hint = recordValue(result.terminal_watch_hint);
575
655
  if (hint?.kind !== "terminal_watch_discovery" ||
@@ -732,6 +812,8 @@ export function formatAkkThreadsCommandResult(result) {
732
812
  ].join("\n");
733
813
  }
734
814
  export function formatAkkModelOptionsCommandResult(result) {
815
+ if (result.source === "codex_desktop")
816
+ return formatDesktopCommandResult(result, "model options");
735
817
  const terminalId = nonEmptyString(result.terminal_id) ?? "unknown";
736
818
  const scope = nonEmptyString(result.scope) ?? "unknown";
737
819
  const current = recordValue(result.current) ?? {};
@@ -760,6 +842,8 @@ export function formatAkkModelOptionsCommandResult(result) {
760
842
  ].join("\n");
761
843
  }
762
844
  export function formatAkkSetModelCommandResult(result) {
845
+ if (result.source === "codex_desktop")
846
+ return formatDesktopCommandResult(result, "set model");
763
847
  const outcome = nonEmptyString(result.outcome) ?? "uncertain";
764
848
  const requested = recordValue(result.requested) ?? {};
765
849
  const effective = recordValue(result.effective) ?? {};
@@ -895,23 +979,26 @@ export function buildAkkCommandCliArgs(command, config, context = {}) {
895
979
  const storeDir = resolvePluginStoreDir(config);
896
980
  const codexHome = nonEmptyString(config.codexHome);
897
981
  const idleTimeoutMinutes = finiteNumberString(config.idleTimeoutMinutes);
982
+ const backendRecovery = buildBackendRecoveryCommandArgs(command, config, context);
983
+ if (backendRecovery)
984
+ return backendRecovery;
898
985
  switch (command.action) {
899
986
  case "list":
900
987
  return withOptionalArgs(["list", "--reconcile"], ["--store-dir", storeDir], ["--idle-timeout-minutes", idleTimeoutMinutes]);
901
988
  case "watch": {
902
- const openclawSession = nonEmptyString(context.sessionKey) ??
989
+ const openclawSession = (isCodexNativeConversationId(command.terminalId) ? requiredNativeController(context.sessionKey) : nonEmptyString(context.sessionKey)) ??
903
990
  "agent:main:main";
904
991
  return withOptionalArgs([
905
992
  "watch-terminal",
906
- "--terminal",
993
+ isCodexNativeConversationId(command.terminalId) ? "--conversation" : "--terminal",
907
994
  command.terminalId
908
995
  ], ["--store-dir", storeDir], [
909
996
  "--hard-timeout-minutes",
910
997
  finiteNumberString(config.agentHardTimeoutMinutes)
911
- ], ["--openclaw-session", openclawSession], ["--openclaw-bin", nonEmptyString(config.openclawBin)]);
998
+ ], ["--openclaw-session", openclawSession], ["--openclaw-bin", nonEmptyString(config.openclawBin)], ["--codex-home", isCodexNativeConversationId(command.terminalId) ? codexHome : undefined]);
912
999
  }
913
1000
  case "unwatch":
914
- return withOptionalArgs(["unwatch-terminal", "--watch", command.watchId], ["--store-dir", storeDir]);
1001
+ return withOptionalArgs(["unwatch-terminal", "--watch", command.watchId], ["--store-dir", storeDir], ["--openclaw-session", isBackendTaskWatchId(command.watchId) ? requiredNativeController(context.sessionKey) : undefined], ["--codex-home", isBackendTaskWatchId(command.watchId) ? codexHome : undefined]);
915
1002
  case "list-resumable-threads":
916
1003
  return withOptionalArgs([
917
1004
  "list-resumable-threads",
@@ -1009,15 +1096,15 @@ export function buildAkkCommandCliArgs(command, config, context = {}) {
1009
1096
  ], ["--store-dir", storeDir], ["--codex-home", codexHome]);
1010
1097
  case "status":
1011
1098
  if (command.watchId) {
1012
- return withOptionalArgs(["watch-status", "--watch", command.watchId], ["--store-dir", storeDir]);
1099
+ return withOptionalArgs(["watch-status", "--watch", command.watchId], ["--store-dir", storeDir], ["--openclaw-session", isBackendTaskWatchId(command.watchId) ? requiredNativeController(context.sessionKey) : undefined], ["--codex-home", isBackendTaskWatchId(command.watchId) ? codexHome : undefined]);
1013
1100
  }
1014
1101
  return withOptionalArgs([
1015
1102
  "status",
1016
1103
  "--reconcile",
1017
1104
  ...(command.turnId
1018
- ? ["--turn", command.turnId]
1105
+ ? [isCodexNativeConversationId(command.turnId) ? "--conversation" : "--turn", command.turnId]
1019
1106
  : [])
1020
- ], ["--store-dir", storeDir], ["--idle-timeout-minutes", idleTimeoutMinutes]);
1107
+ ], ["--store-dir", storeDir], ["--idle-timeout-minutes", idleTimeoutMinutes], ["--openclaw-session", isCodexNativeConversationId(command.turnId) ? requiredNativeController(context.sessionKey) : undefined], ["--codex-home", isCodexNativeConversationId(command.turnId) ? codexHome : undefined]);
1021
1108
  case "send": {
1022
1109
  const openclawSession = nonEmptyString(context.sessionKey) ??
1023
1110
  "agent:main:main";
@@ -1062,8 +1149,41 @@ export function buildAkkCommandCliArgs(command, config, context = {}) {
1062
1149
  ], ["--expected-message-id", command.expectedMessageId], ["--expected-transition-id", command.expectedTransitionId], ["--store-dir", storeDir]);
1063
1150
  }
1064
1151
  }
1152
+ function buildBackendRecoveryCommandArgs(command, config, context) {
1153
+ if (command.action === "renew" || command.action === "recover" || command.action === "retry-callback" || command.action === "close") {
1154
+ const params = { turn_id: command.turnId };
1155
+ if (command.action === "renew" && command.minutes !== undefined)
1156
+ params.minutes = Number(command.minutes);
1157
+ if (command.action === "retry-callback" && command.notificationId !== undefined)
1158
+ params.notification_id = command.notificationId;
1159
+ if (command.action === "close") {
1160
+ params.reason = command.reason;
1161
+ if (command.expectedMessageId !== undefined)
1162
+ params.expected_message_id = command.expectedMessageId;
1163
+ if (command.expectedTransitionId !== undefined)
1164
+ params.expected_transition_id = command.expectedTransitionId;
1165
+ }
1166
+ const backend = backendRecoveryToolArgs(command.action, params, context, {
1167
+ storeDir: resolvePluginStoreDir(config), codexHome: nonEmptyString(config.codexHome), defaultMinutes: config.agentTimeoutMinutes
1168
+ });
1169
+ if (backend)
1170
+ return backend;
1171
+ }
1172
+ }
1065
1173
  function isTerminalWatchId(value) {
1066
- return /^terminal-watch-[A-Za-z0-9._:-]+$/u.test(value);
1174
+ return /^terminal-watch-[A-Za-z0-9._:-]+$/u.test(value) || isBackendTaskWatchId(value);
1175
+ }
1176
+ function requiredNativeController(value) {
1177
+ const key = nonEmptyString(value);
1178
+ if (!key)
1179
+ throw new Error("controller session is required for a direct Codex CLI action");
1180
+ return key;
1181
+ }
1182
+ function assertExactTerminalOrNativeId(value, usage) {
1183
+ if (isCodexNativeConversationId(value))
1184
+ parseCodexNativeConversationId(value);
1185
+ else
1186
+ assertExactTerminalId(value, usage);
1067
1187
  }
1068
1188
  function parseSelectorMessage(input) {
1069
1189
  const match = /^((?:(?:codex|claude):latest|only|latest|codex|claude|@[0-9a-f]+))\s*:\s*([\s\S]*)$/iu.exec(input);
@@ -1261,6 +1381,7 @@ function formatAvailableActions(label, resource) {
1261
1381
  "approve",
1262
1382
  "cancel",
1263
1383
  "renew",
1384
+ "recover",
1264
1385
  "retry_callback",
1265
1386
  "close",
1266
1387
  "list_resumable_threads",