@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,176 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { DesktopIpcError } from "./desktop-types.js";
3
+ const presets = {
4
+ "read-only": { permissions: ":read-only", approvalPolicy: "on-request", sandboxType: "readOnly", label: "Read Only" },
5
+ default: { permissions: ":workspace", approvalPolicy: "on-request", sandboxType: "workspaceWrite", label: "Default" },
6
+ "full-access": { permissions: ":danger-full-access", approvalPolicy: "never", sandboxType: "dangerFullAccess", label: "Full Access" }
7
+ };
8
+ function sameThread(snapshot, identity) {
9
+ if (snapshot.threadId !== identity.threadId || !snapshot.ownerClientId) {
10
+ throw new DesktopIpcError("invalid_response", "Desktop settings observation changed the selected native thread");
11
+ }
12
+ }
13
+ function idleSnapshot(snapshot, identity) {
14
+ sameThread(snapshot, identity);
15
+ if (!snapshot.canSend || snapshot.runtimeStatus !== "idle") {
16
+ throw new DesktopIpcError("thread_not_idle", "Change Desktop settings while this exact conversation is idle");
17
+ }
18
+ }
19
+ function effectivePermissions(snapshot) {
20
+ const source = snapshot.runtimeStatus === "idle" ? snapshot.threadSettings ?? snapshot.currentPermissions : snapshot.currentPermissions;
21
+ if (!source)
22
+ return undefined;
23
+ return { activePermissionProfile: source.activePermissionProfile, approvalPolicy: source.approvalPolicy,
24
+ approvalsReviewer: source.approvalsReviewer, sandboxPolicy: source.sandboxPolicy, runtimeWorkspaceRoots: source.runtimeWorkspaceRoots };
25
+ }
26
+ function permissionMode(snapshot) {
27
+ const current = effectivePermissions(snapshot);
28
+ return Object.keys(presets).find(mode => {
29
+ const preset = presets[mode];
30
+ return current?.activePermissionProfile?.id === preset.permissions && current.approvalPolicy === preset.approvalPolicy
31
+ && current.approvalsReviewer === "user" && current.sandboxPolicy?.type === preset.sandboxType;
32
+ }) ?? null;
33
+ }
34
+ function modelState(snapshot) {
35
+ return { model: snapshot.latestCollaborationMode?.settings.model ?? snapshot.latestModel ?? null,
36
+ reasoning_effort: snapshot.latestCollaborationMode?.settings.reasoning_effort ?? snapshot.latestReasoningEffort ?? null,
37
+ collaboration_mode: snapshot.latestCollaborationMode?.mode ?? null };
38
+ }
39
+ function matchesModel(snapshot, selection, expectedMode) {
40
+ const current = modelState(snapshot);
41
+ return current.model === selection.model && current.reasoning_effort === selection.reasoningEffort
42
+ && (expectedMode == null || current.collaboration_mode === expectedMode);
43
+ }
44
+ function validateModel(selection) {
45
+ if (!/^[A-Za-z0-9][A-Za-z0-9._:/+\-]{0,159}$/u.test(selection.model)
46
+ || !/^[a-z][a-z0-9_-]{0,63}$/u.test(selection.reasoningEffort)
47
+ || selection.collaborationMode !== undefined && !["plan", "default"].includes(selection.collaborationMode)) {
48
+ throw new DesktopIpcError("invalid_argument", "Desktop model requires an explicit model/effort tuple and optional plan/default mode");
49
+ }
50
+ }
51
+ function errorCode(error) {
52
+ return error instanceof DesktopIpcError ? error.code : "desktop_effective_settings_unconfirmed";
53
+ }
54
+ /** Settings affect one idle native conversation; effective snapshots, not acknowledgements, prove success. */
55
+ export function createDesktopSessionControls(deps) {
56
+ const sleep = deps.sleep ?? (ms => new Promise(resolve => setTimeout(resolve, ms)));
57
+ const uuid = deps.randomUUID ?? randomUUID;
58
+ async function observe(identity) {
59
+ const snapshot = await deps.observe(identity);
60
+ sameThread(snapshot, identity);
61
+ return snapshot;
62
+ }
63
+ async function confirm(identity, owner, matches) {
64
+ for (let attempt = 0; attempt < (deps.observationAttempts ?? 20); attempt++) {
65
+ const snapshot = await observe(identity);
66
+ if (snapshot.ownerClientId !== owner)
67
+ throw new DesktopIpcError("owner_changed", "Desktop owner changed while verifying the requested setting", "unknown");
68
+ if (matches(snapshot))
69
+ return snapshot;
70
+ await sleep(250);
71
+ }
72
+ throw new DesktopIpcError("timeout", "The requested Desktop state has not been observed; refresh Status before another operation", "unknown");
73
+ }
74
+ async function change(identity, before, settings, matches) {
75
+ let dispatchError;
76
+ try {
77
+ await deps.updateSettings(identity, { threadId: identity.threadId, ownerClientId: before.ownerClientId,
78
+ operationId: uuid(), settings, beforeDispatch: async (snapshot) => idleSnapshot(snapshot, identity) });
79
+ }
80
+ catch (error) {
81
+ if (error instanceof DesktopIpcError && error.dispatchState === "not_sent")
82
+ throw error;
83
+ dispatchError = error;
84
+ }
85
+ try {
86
+ return { snapshot: await confirm(identity, before.ownerClientId, matches) };
87
+ }
88
+ catch (error) {
89
+ return { error_code: errorCode(dispatchError ?? error) };
90
+ }
91
+ }
92
+ async function permissionOptions(identity) {
93
+ const snapshot = await observe(identity);
94
+ return { scope: "current_session", current: permissionMode(snapshot), defaults_changed: false,
95
+ settings: effectivePermissions(snapshot), applies_to: snapshot.runtimeStatus === "idle" ? "next_task" : "active_task", choices: Object.keys(presets).map(mode => ({
96
+ id: mode, mode, label: presets[mode].label, description: mode === "full-access"
97
+ ? "Unrestricted execution without approval prompts in this conversation."
98
+ : mode === "read-only" ? "Read-only access; additional access requires approval."
99
+ : "Write in this conversation's workspace; additional access requires approval."
100
+ })) };
101
+ }
102
+ async function setPermissions(identity, mode) {
103
+ if (!Object.hasOwn(presets, mode))
104
+ throw new DesktopIpcError("invalid_argument", "Unknown Desktop permission preset");
105
+ const before = await observe(identity);
106
+ idleSnapshot(before, identity);
107
+ const requested = { mode };
108
+ const previous = permissionMode(before);
109
+ const base = { scope: "current_session", defaults_changed: false, requested };
110
+ if (previous === mode)
111
+ return { ...base, applied: true, do_not_retry: false, outcome: "already_effective", effective: requested };
112
+ const preset = presets[mode];
113
+ const result = await change(identity, before, { permissions: preset.permissions,
114
+ approvalPolicy: preset.approvalPolicy, approvalsReviewer: "user" }, snapshot => permissionMode(snapshot) === mode);
115
+ if (!result.snapshot)
116
+ return { ...base, applied: false, do_not_retry: true, outcome: "unconfirmed", error_code: result.error_code };
117
+ return { ...base, applied: true, do_not_retry: false, outcome: "changed", effective: requested, applies_to: "next_task", settings: effectivePermissions(result.snapshot) };
118
+ }
119
+ async function modelOptions(identity) {
120
+ const snapshot = await observe(identity);
121
+ const settings = await deps.readModelSettings(identity, { threadId: identity.threadId, ownerClientId: snapshot.ownerClientId });
122
+ return { scope: "current_session", current: modelState(snapshot), model_provider: settings.modelProvider,
123
+ catalog_available: false, selection_mode: "explicit_model_id",
124
+ collaboration_modes: ["default", "plan"],
125
+ limitations: ["Desktop owner exposes current model settings but no model catalog. Use an explicitly requested model ID. AKK verifies effective settings; model availability is not exposed."] };
126
+ }
127
+ async function setModel(identity, selection) {
128
+ validateModel(selection);
129
+ const before = await observe(identity);
130
+ idleSnapshot(before, identity);
131
+ const expectedMode = selection.collaborationMode ?? before.latestCollaborationMode?.mode;
132
+ const requested = { model: selection.model, reasoning_effort: selection.reasoningEffort,
133
+ ...(selection.collaborationMode ? { collaboration_mode: selection.collaborationMode } : {}) };
134
+ const base = { scope: "current_session", defaults_changed: false, requested };
135
+ if (matchesModel(before, selection, expectedMode))
136
+ return { ...base, applied: true, do_not_retry: false, outcome: "already_effective", effective: modelState(before) };
137
+ const result = await change(identity, before, { model: selection.model, effort: selection.reasoningEffort,
138
+ ...(selection.collaborationMode ? { collaborationMode: { mode: selection.collaborationMode,
139
+ settings: { model: selection.model, reasoning_effort: selection.reasoningEffort, developer_instructions: null } } } : {})
140
+ }, snapshot => matchesModel(snapshot, selection, expectedMode));
141
+ if (!result.snapshot)
142
+ return { ...base, applied: false, do_not_retry: true, outcome: "unconfirmed", error_code: result.error_code };
143
+ return { ...base, applied: true, do_not_retry: false, outcome: "changed", effective: modelState(result.snapshot) };
144
+ }
145
+ async function interrupt(identity, expectedTurnId) {
146
+ if (!expectedTurnId?.trim())
147
+ throw new DesktopIpcError("invalid_argument", "Desktop cancellation requires its exact native turn");
148
+ const before = await observe(identity);
149
+ const exact = before.turns.find(turn => turn.turnId === expectedTurnId);
150
+ if (exact && ["completed", "failed", "interrupted"].includes(exact.status)) {
151
+ return { native_turn_id: expectedTurnId, interrupted: exact.status === "interrupted", state: exact.status, outcome: "already_settled", do_not_retry: false };
152
+ }
153
+ if (!exact || exact.status !== "inProgress" || before.latestTurnId !== expectedTurnId) {
154
+ throw new DesktopIpcError("stale_interaction", "The selected Desktop task is no longer the active task");
155
+ }
156
+ let dispatchError;
157
+ try {
158
+ await deps.interruptTurn(identity, { threadId: identity.threadId, ownerClientId: before.ownerClientId, expectedTurnId, operationId: uuid() });
159
+ }
160
+ catch (error) {
161
+ if (error instanceof DesktopIpcError && error.dispatchState === "not_sent")
162
+ throw error;
163
+ dispatchError = error;
164
+ }
165
+ try {
166
+ const snapshot = await confirm(identity, before.ownerClientId, state => state.turns.some(turn => turn.turnId === expectedTurnId && ["completed", "failed", "interrupted"].includes(turn.status)));
167
+ const status = snapshot.turns.find(turn => turn.turnId === expectedTurnId).status;
168
+ return { native_turn_id: expectedTurnId, interrupted: status === "interrupted", state: status, outcome: "settled", do_not_retry: false };
169
+ }
170
+ catch (error) {
171
+ return { native_turn_id: expectedTurnId, interrupted: false, state: "unconfirmed", outcome: "unconfirmed", do_not_retry: true, error_code: errorCode(dispatchError ?? error) };
172
+ }
173
+ }
174
+ return { permissionOptions, setPermissions, modelOptions, setModel, interrupt };
175
+ }
176
+ //# sourceMappingURL=desktop-session-controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-session-controls.js","sourceRoot":"","sources":["../../src/desktop-session-controls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ export interface DesktopSidebarMetadata {
2
+ available: boolean;
3
+ mode?: string;
4
+ collapsed: Record<string, boolean>;
5
+ expanded: Record<string, boolean>;
6
+ projects: Record<string, {
7
+ name: string;
8
+ roots: string[];
9
+ }>;
10
+ assignments: Record<string, {
11
+ projectId: string;
12
+ hostId: string;
13
+ }>;
14
+ projectOrder: string[];
15
+ pinnedIds: string[];
16
+ migratedPinnedIds: string[];
17
+ nativePinnedOrder: string[];
18
+ projectIdMappings: Record<string, string>;
19
+ projectlessIds: string[];
20
+ rootHints: Record<string, string>;
21
+ customSectionThreadIds: string[];
22
+ limitations: string[];
23
+ }
24
+ export type DesktopSidebarReader = (codexHome: string) => Promise<DesktopSidebarMetadata>;
25
+ /** Select only layout metadata. Never return the global state, credentials, or drafts. */
26
+ export declare function readDesktopSidebarMetadata(home: string): Promise<DesktopSidebarMetadata>;
27
+ export declare function parseDesktopSidebarMetadata(value: unknown, home: string): DesktopSidebarMetadata;
@@ -0,0 +1,83 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ /** Select only layout metadata. Never return the global state, credentials, or drafts. */
4
+ export async function readDesktopSidebarMetadata(home) {
5
+ try {
6
+ const file = path.join(home, ".codex-global-state.json");
7
+ if ((await fs.stat(file)).size > 16 * 1024 * 1024)
8
+ throw new Error("oversized layout");
9
+ return parseDesktopSidebarMetadata(JSON.parse(await fs.readFile(file, "utf8")), home);
10
+ }
11
+ catch {
12
+ return { available: false, collapsed: {}, expanded: {}, projects: {}, assignments: {}, projectOrder: [],
13
+ pinnedIds: [], migratedPinnedIds: [], nativePinnedOrder: [], projectIdMappings: {},
14
+ projectlessIds: [], rootHints: {}, customSectionThreadIds: [],
15
+ limitations: ["Desktop persisted sidebar layout is unavailable or invalid."] };
16
+ }
17
+ }
18
+ export function parseDesktopSidebarMetadata(value, home) {
19
+ const state = record(value), atoms = record(state["electron-persisted-atom-state"]);
20
+ const preferences = record(atoms["flat-project-sidebar-preferences-v1"]);
21
+ const identity = `local:${home}`;
22
+ const projects = Object.fromEntries(Object.entries(record(state["local-projects"]))
23
+ .filter(([, item]) => typeof record(item).name === "string")
24
+ .map(([id, item]) => [id, { name: String(record(item).name).slice(0, 160), roots: projectRoots(record(item)) }]));
25
+ const limitations = [];
26
+ const sections = Object.values(record(atoms["sidebar-custom-sections-v3"])).flatMap(item => {
27
+ const sectionList = record(item).sections;
28
+ return Array.isArray(sectionList) ? sectionList : [];
29
+ });
30
+ if (sections.length) {
31
+ limitations.push("Custom sidebar sections are not included in this layout projection.");
32
+ }
33
+ if (Object.values(record(atoms["chatgpt-sidebar-state-v2"])).some(item => ["pinnedConversations", "pinnedProjects", "projects"].some(key => Array.isArray(record(item)[key]) && record(item)[key].length))) {
34
+ limitations.push("Cloud sidebar projects and pins are not included in this local layout projection.");
35
+ }
36
+ return { available: true, mode: typeof preferences.mode === "string" ? preferences.mode : undefined,
37
+ collapsed: booleanRecord(atoms["sidebar-collapsed-sections-v1"]),
38
+ expanded: Object.fromEntries(Object.entries(atoms).filter(([key, item]) => key.startsWith("sidebar-project-expanded-v1-codex:") && typeof item === "boolean")
39
+ .map(([key, item]) => [key.slice("sidebar-project-expanded-v1-codex:".length), item])),
40
+ projects, assignments: sidebarAssignments(state, limitations),
41
+ projectOrder: strings(state["project-order"]), pinnedIds: strings(state["pinned-thread-ids"]),
42
+ migratedPinnedIds: strings(record(state["app-server-migrated-pinned-thread-ids-by-host"])[identity]),
43
+ nativePinnedOrder: strings(atoms["app-server-pinned-thread-order-v1"]),
44
+ projectIdMappings: stringRecord(record(state["app-server-project-id-by-legacy-project-id-by-host"])[identity]),
45
+ projectlessIds: strings(state["projectless-thread-ids"]), rootHints: stringRecord(state["thread-workspace-root-hints"]),
46
+ customSectionThreadIds: sections.flatMap(section => strings(record(section).itemKeys))
47
+ .filter(key => key.startsWith("codex:thread:local:")).map(key => key.slice("codex:thread:local:".length)), limitations };
48
+ }
49
+ function projectRoots(project) {
50
+ const aliases = Array.isArray(project.rootPathAliases) ? project.rootPathAliases : [];
51
+ return [...new Set([...strings(project.rootPaths), ...aliases.flatMap(value => {
52
+ const alias = record(value);
53
+ return [alias.alias, alias.pathAlias].filter((item) => typeof item === "string");
54
+ }), ...(typeof project.pathAlias === "string" ? [project.pathAlias] : [])])].filter(item => path.isAbsolute(item)).map(item => path.resolve(item));
55
+ }
56
+ function sidebarAssignments(state, limitations) {
57
+ const hosts = record(state["thread-project-membership-host-ids"]);
58
+ const entries = Object.entries(record(state["thread-project-assignments"]));
59
+ const result = {};
60
+ for (const [id, value] of entries) {
61
+ const item = record(value);
62
+ if (item.projectKind !== "local" || typeof item.projectId !== "string") {
63
+ // Keep an explicit exclusion: dropping the record would let cwd inference
64
+ // incorrectly reassign this thread to a local project.
65
+ result[id] = { projectId: typeof item.projectId === "string" ? item.projectId : "", hostId: "non-local" };
66
+ limitations.push("Non-local project assignments are not included in this layout projection.");
67
+ continue;
68
+ }
69
+ result[id] = { projectId: item.projectId, hostId: typeof hosts[id] === "string" ? hosts[id] : "local" };
70
+ }
71
+ return result;
72
+ }
73
+ function record(value) {
74
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
75
+ }
76
+ function strings(value) { return Array.isArray(value) ? value.filter(item => typeof item === "string") : []; }
77
+ function stringRecord(value) {
78
+ return Object.fromEntries(Object.entries(record(value)).filter((entry) => typeof entry[1] === "string"));
79
+ }
80
+ function booleanRecord(value) {
81
+ return Object.fromEntries(Object.entries(record(value)).filter((entry) => typeof entry[1] === "boolean"));
82
+ }
83
+ //# sourceMappingURL=desktop-sidebar-metadata.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-sidebar-metadata.js","sourceRoot":"","sources":["../../src/desktop-sidebar-metadata.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { DesktopSidebarMetadata } from "./desktop-sidebar-metadata.js";
2
+ export interface DesktopSidebarProjectCandidate {
3
+ hostId: string;
4
+ threadId: string;
5
+ cwd: string | null;
6
+ }
7
+ /** Renderer project membership uses explicit assignment, then its saved root/hint filters. */
8
+ export declare function desktopSidebarProject(entry: DesktopSidebarProjectCandidate, layout: DesktopSidebarMetadata): string | undefined;
9
+ /** Overlapping root ownership also depends on renderer-specific project priority. */
10
+ export declare function desktopSidebarHasOverlappingRoots(layout: DesktopSidebarMetadata): boolean;
@@ -0,0 +1,31 @@
1
+ import path from "node:path";
2
+ /** Renderer project membership uses explicit assignment, then its saved root/hint filters. */
3
+ export function desktopSidebarProject(entry, layout) {
4
+ if (entry.hostId !== "local")
5
+ return undefined;
6
+ const assigned = layout.assignments[entry.threadId];
7
+ if (assigned)
8
+ return assigned.hostId === "local" ? assigned.projectId : undefined;
9
+ if (layout.projectlessIds.includes(entry.threadId))
10
+ return undefined;
11
+ const hint = layout.rootHints[entry.threadId];
12
+ const candidates = Object.entries(layout.projects).flatMap(([id, project]) => project.roots
13
+ .filter(root => hint != null && path.isAbsolute(hint) && root === path.resolve(hint) || rootContains(root, entry.cwd))
14
+ .map(root => ({ id, root })));
15
+ candidates.sort((a, b) => b.root.length - a.root.length || a.id.localeCompare(b.id));
16
+ if (candidates.length > 1 && candidates[1].root === candidates[0].root && candidates[1].id !== candidates[0].id)
17
+ return undefined;
18
+ return candidates[0]?.id;
19
+ }
20
+ /** Overlapping root ownership also depends on renderer-specific project priority. */
21
+ export function desktopSidebarHasOverlappingRoots(layout) {
22
+ const roots = Object.entries(layout.projects).flatMap(([id, project]) => project.roots.map(root => ({ id, root })));
23
+ return roots.some((entry, index) => roots.slice(index + 1).some(other => entry.id !== other.id && (rootContains(entry.root, other.root) || rootContains(other.root, entry.root))));
24
+ }
25
+ function rootContains(root, value) {
26
+ if (!value || !path.isAbsolute(value))
27
+ return false;
28
+ const relative = path.relative(root, path.resolve(value));
29
+ return relative === "" || relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
30
+ }
31
+ //# sourceMappingURL=desktop-sidebar-projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-sidebar-projects.js","sourceRoot":"","sources":["../../src/desktop-sidebar-projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { DesktopSidebarMetadata } from "./desktop-sidebar-metadata.js";
2
+ import { type DesktopSidebarProjectCandidate } from "./desktop-sidebar-projects.js";
3
+ export interface DesktopSidebarSummary {
4
+ status: "supported" | "partial" | "unsupported" | "unavailable";
5
+ mode?: string;
6
+ limitations: string[];
7
+ selectionScope: "persisted_expanded_membership";
8
+ }
9
+ export interface DesktopSidebarMembership {
10
+ section: "pinned" | "project";
11
+ projectId?: string;
12
+ projectName?: string;
13
+ }
14
+ interface SidebarCandidate extends DesktopSidebarProjectCandidate {
15
+ codexHome: string;
16
+ conversationId: string;
17
+ updatedAtMs: number;
18
+ threadSectionId?: string | null;
19
+ sectionPosition?: number;
20
+ sidebar?: DesktopSidebarMembership;
21
+ }
22
+ export declare const DESKTOP_PINNED_SECTION_ID = "01984de2-8f74-7c91-a3b2-5c5e937cf318";
23
+ export declare function selectDesktopSidebar<T extends SidebarCandidate>(entries: T[], layouts: Map<string, DesktopSidebarMetadata>, archivedIds?: Set<string>): {
24
+ sessions: T[];
25
+ sidebar: DesktopSidebarSummary;
26
+ fingerprint: string;
27
+ };
28
+ export {};
@@ -0,0 +1,85 @@
1
+ import { createHash } from "node:crypto";
2
+ import { desktopSidebarProject, desktopSidebarHasOverlappingRoots } from "./desktop-sidebar-projects.js";
3
+ // Codex Desktop's reserved app-server Pinned section; a user section named "Pinned" is not sufficient.
4
+ export const DESKTOP_PINNED_SECTION_ID = "01984de2-8f74-7c91-a3b2-5c5e937cf318";
5
+ export function selectDesktopSidebar(entries, layouts, archivedIds = new Set()) {
6
+ const selected = new Map();
7
+ const summaries = [];
8
+ for (const [home, layout] of layouts) {
9
+ const localEntries = entries.filter(entry => entry.codexHome === home);
10
+ const summary = sidebarSummary(layout);
11
+ summaries.push(summary);
12
+ if (summary.status === "unavailable" || summary.status === "unsupported")
13
+ continue;
14
+ selectLayout(home, localEntries, layout, selected, archivedIds, summary);
15
+ }
16
+ const sidebar = combineSummaries(summaries);
17
+ const sessions = [...selected.values()];
18
+ const fingerprint = createHash("sha256").update(JSON.stringify({ layouts: [...layouts],
19
+ selected: sessions.map(entry => [entry.conversationId, entry.updatedAtMs, entry.sidebar]), sidebar })).digest("hex");
20
+ return { sessions, sidebar, fingerprint };
21
+ }
22
+ function sidebarSummary(layout) {
23
+ const limitations = [...new Set(layout.limitations)];
24
+ if (desktopSidebarHasOverlappingRoots(layout))
25
+ limitations.push("Overlapping project roots use approximate ownership; renderer project-priority ordering is not verified.");
26
+ if (layout.available && layout.mode !== "project")
27
+ limitations.push("This Desktop sidebar mode is not supported; use desktop_view=history for saved candidates.");
28
+ if (layout.available && layout.mode === "project" && layout.collapsed.chats !== true) {
29
+ limitations.push("Expanded Chats include runtime catalog and pagination state; only pinned and expanded-project membership is returned.");
30
+ }
31
+ return { status: !layout.available ? "unavailable" : layout.mode !== "project" ? "unsupported" : limitations.length ? "partial" : "supported",
32
+ mode: layout.mode, limitations, selectionScope: "persisted_expanded_membership" };
33
+ }
34
+ function selectLayout(home, entries, layout, selected, archived, summary) {
35
+ const byThread = new Map(entries.filter(entry => entry.hostId === "local").map(entry => [entry.threadId, entry]));
36
+ const add = (id, membership) => {
37
+ const entry = byThread.get(id);
38
+ if (!entry) {
39
+ if (!archived.has(`${home}\0local\0${id}`)) {
40
+ summary.status = "partial";
41
+ summary.limitations.push("A sidebar member has no supported local catalog metadata.");
42
+ }
43
+ return;
44
+ }
45
+ if (!selected.has(entry.conversationId))
46
+ selected.set(entry.conversationId, { ...entry, sidebar: membership });
47
+ };
48
+ const pinned = new Set(pinnedThreads(entries, layout));
49
+ if (layout.collapsed.pinned !== true) {
50
+ for (const id of pinned)
51
+ add(id, { section: "pinned" });
52
+ }
53
+ for (const projectId of layout.collapsed.threads === true ? [] : orderedProjects(layout)) {
54
+ if (layout.expanded[projectId] === false)
55
+ continue;
56
+ const members = entries.filter(entry => !pinned.has(entry.threadId) && !entry.threadSectionId && !layout.customSectionThreadIds.includes(entry.threadId) &&
57
+ desktopSidebarProject(entry, layout) === projectId);
58
+ for (const entry of members)
59
+ add(entry.threadId, { section: "project", projectId, projectName: layout.projects[projectId]?.name });
60
+ for (const [id, assignment] of Object.entries(layout.assignments)) {
61
+ if (assignment.projectId === projectId && assignment.hostId === "local" && !byThread.has(id))
62
+ add(id, { section: "project", projectId });
63
+ }
64
+ }
65
+ summary.limitations = [...new Set(summary.limitations)];
66
+ }
67
+ function pinnedThreads(entries, layout) {
68
+ const native = entries.filter(entry => entry.hostId === "local" && entry.threadSectionId === DESKTOP_PINNED_SECTION_ID)
69
+ .sort((a, b) => (a.sectionPosition ?? 0) - (b.sectionPosition ?? 0)).map(entry => entry.threadId);
70
+ const migrated = new Set(layout.migratedPinnedIds);
71
+ const retained = new Set([...native, ...layout.pinnedIds.filter(id => !migrated.has(id))]);
72
+ return [...new Set([...layout.nativePinnedOrder.filter(id => retained.has(id)), ...retained])];
73
+ }
74
+ function orderedProjects(layout) {
75
+ return [...new Set([...layout.projectOrder.filter(id => Object.hasOwn(layout.projects, id)), ...Object.keys(layout.projects)])];
76
+ }
77
+ function combineSummaries(items) {
78
+ const usable = items.filter(item => item.status === "supported" || item.status === "partial");
79
+ const status = items.length > 0 && items.every(item => item.status === "supported") ? "supported"
80
+ : usable.length ? "partial" : items.some(item => item.status === "unsupported") ? "unsupported" : "unavailable";
81
+ const modes = [...new Set(items.map(item => item.mode).filter(Boolean))];
82
+ return { status, mode: modes.length === 1 ? modes[0] : undefined,
83
+ limitations: [...new Set(items.flatMap(item => item.limitations))], selectionScope: "persisted_expanded_membership" };
84
+ }
85
+ //# sourceMappingURL=desktop-sidebar-selection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"desktop-sidebar-selection.js","sourceRoot":"","sources":["../../src/desktop-sidebar-selection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { type DesktopCollaborationMode, type DesktopTurnItem, type DesktopSnapshot } from "./desktop-types.js";
2
+ export declare function desktopCollaborationMode(value: unknown): DesktopCollaborationMode;
3
+ export declare function desktopSettingsSnapshot(raw: Record<string, unknown>): Pick<DesktopSnapshot, "threadSettings" | "currentPermissions" | "latestModel" | "latestReasoningEffort" | "latestCollaborationMode">;
4
+ export declare function projectDesktopItemDetails(raw: Record<string, unknown>, result: DesktopTurnItem): void;
@@ -0,0 +1,116 @@
1
+ import { DesktopIpcError } from "./desktop-types.js";
2
+ import { desktopObject, desktopNativeRequestId } from "./desktop-request-interactions.js";
3
+ function invalid() { throw new DesktopIpcError("invalid_response", "Invalid Desktop native detail"); }
4
+ function optionalString(value) {
5
+ if (value == null)
6
+ return undefined;
7
+ if (typeof value !== "string")
8
+ invalid();
9
+ return value;
10
+ }
11
+ function object(value) { if (!desktopObject(value))
12
+ invalid(); return value; }
13
+ export function desktopCollaborationMode(value) {
14
+ const mode = object(value), settings = object(mode.settings);
15
+ if (typeof mode.mode !== "string" || typeof settings.model !== "string")
16
+ invalid();
17
+ return { mode: mode.mode, settings: { model: settings.model,
18
+ reasoning_effort: optionalString(settings.reasoning_effort) ?? null,
19
+ developer_instructions: optionalString(settings.developer_instructions) ?? null } };
20
+ }
21
+ function permissions(value) {
22
+ const raw = object(value), result = {};
23
+ if (raw.activePermissionProfile != null) {
24
+ const profile = object(raw.activePermissionProfile);
25
+ if (typeof profile.id !== "string")
26
+ invalid();
27
+ result.activePermissionProfile = { id: profile.id, extends: optionalString(profile.extends) ?? null };
28
+ }
29
+ else if (raw.activePermissionProfile === null)
30
+ result.activePermissionProfile = null;
31
+ if (raw.approvalPolicy != null)
32
+ result.approvalPolicy = typeof raw.approvalPolicy === "string" ? raw.approvalPolicy : structuredClone(object(raw.approvalPolicy));
33
+ if (raw.approvalsReviewer != null)
34
+ result.approvalsReviewer = optionalString(raw.approvalsReviewer);
35
+ if (raw.sandboxPolicy != null)
36
+ result.sandboxPolicy = structuredClone(object(raw.sandboxPolicy));
37
+ if (raw.runtimeWorkspaceRoots != null) {
38
+ if (!Array.isArray(raw.runtimeWorkspaceRoots) || raw.runtimeWorkspaceRoots.some(root => typeof root !== "string"))
39
+ invalid();
40
+ result.runtimeWorkspaceRoots = [...raw.runtimeWorkspaceRoots];
41
+ }
42
+ return result;
43
+ }
44
+ function threadSettings(value) {
45
+ const raw = object(value), result = permissions(raw);
46
+ for (const field of ["model", "permissions"])
47
+ if (raw[field] != null)
48
+ result[field] = optionalString(raw[field]);
49
+ if (raw.effort !== undefined)
50
+ result.effort = optionalString(raw.effort) ?? null;
51
+ if (raw.collaborationMode != null)
52
+ result.collaborationMode = desktopCollaborationMode(raw.collaborationMode);
53
+ return result;
54
+ }
55
+ export function desktopSettingsSnapshot(raw) {
56
+ return {
57
+ ...(raw.latestThreadSettings == null ? {} : { threadSettings: threadSettings(raw.latestThreadSettings) }),
58
+ ...(raw.currentPermissions == null ? {} : { currentPermissions: permissions(raw.currentPermissions) }),
59
+ ...(raw.latestModel == null ? {} : { latestModel: optionalString(raw.latestModel) }),
60
+ ...(raw.latestReasoningEffort === undefined ? {} : { latestReasoningEffort: optionalString(raw.latestReasoningEffort) ?? null }),
61
+ ...(raw.latestCollaborationMode == null ? {} : { latestCollaborationMode: desktopCollaborationMode(raw.latestCollaborationMode) })
62
+ };
63
+ }
64
+ function fileChanges(value) {
65
+ if (!Array.isArray(value))
66
+ invalid();
67
+ return value.map(raw => {
68
+ const change = object(raw);
69
+ if (typeof change.path !== "string")
70
+ invalid();
71
+ const kind = typeof change.kind === "string" ? change.kind : change.kind == null ? undefined : optionalString(object(change.kind).type);
72
+ const diff = optionalString(change.diff);
73
+ return { path: change.path, ...(kind ? { kind } : {}), ...(diff === undefined ? {} : {
74
+ diff: diff.slice(0, 16_384), ...(diff.length > 16_384 ? { diffTruncated: true } : {})
75
+ }) };
76
+ });
77
+ }
78
+ function inputResponse(value, result) {
79
+ if (value.requestId !== undefined)
80
+ result.requestId = desktopNativeRequestId(value.requestId);
81
+ if (value.turnId !== undefined)
82
+ result.turnId = optionalString(value.turnId);
83
+ if (value.completed !== undefined) {
84
+ if (typeof value.completed !== "boolean")
85
+ invalid();
86
+ result.completed = value.completed;
87
+ }
88
+ if (value.answers !== undefined) {
89
+ const answers = object(value.answers), projected = Object.create(null);
90
+ for (const [id, answer] of Object.entries(answers)) {
91
+ if (!Array.isArray(answer) || answer.some(value => typeof value !== "string"))
92
+ invalid();
93
+ projected[id] = [...answer];
94
+ }
95
+ result.answers = projected;
96
+ }
97
+ }
98
+ export function projectDesktopItemDetails(raw, result) {
99
+ if (result.type === "userInputResponse")
100
+ inputResponse(raw, result);
101
+ if (result.type === "fileChange" && raw.changes != null)
102
+ result.changes = fileChanges(raw.changes);
103
+ if (result.type !== "commandExecution")
104
+ return;
105
+ for (const field of ["command", "cwd"])
106
+ if (raw[field] != null)
107
+ result[field] = optionalString(raw[field]);
108
+ if (raw.aggregatedOutput !== undefined)
109
+ result.aggregatedOutput = optionalString(raw.aggregatedOutput) ?? null;
110
+ if (raw.exitCode !== undefined) {
111
+ if (raw.exitCode !== null && (typeof raw.exitCode !== "number" || !Number.isSafeInteger(raw.exitCode)))
112
+ invalid();
113
+ result.exitCode = raw.exitCode;
114
+ }
115
+ }
116
+ //# sourceMappingURL=desktop-snapshot-details.js.map