@scotthuang/agent-knock-knock 0.13.18 → 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 (270) hide show
  1. package/CHANGELOG.md +31 -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-native-cli-adapter.d.ts +6 -0
  22. package/dist/src/codex-native-cli-adapter.js +273 -0
  23. package/dist/src/codex-native-cli-adapter.js.map +1 -0
  24. package/dist/src/codex-native-client-interactions.d.ts +6 -0
  25. package/dist/src/codex-native-client-interactions.js +124 -0
  26. package/dist/src/codex-native-client-interactions.js.map +1 -0
  27. package/dist/src/codex-native-client-rpc.d.ts +21 -0
  28. package/dist/src/codex-native-client-rpc.js +137 -0
  29. package/dist/src/codex-native-client-rpc.js.map +1 -0
  30. package/dist/src/codex-native-client.d.ts +42 -0
  31. package/dist/src/codex-native-client.js +326 -0
  32. package/dist/src/codex-native-client.js.map +1 -0
  33. package/dist/src/codex-native-identity.d.ts +6 -0
  34. package/dist/src/codex-native-identity.js +42 -0
  35. package/dist/src/codex-native-identity.js.map +1 -0
  36. package/dist/src/codex-native-monitor.d.ts +4 -0
  37. package/dist/src/codex-native-monitor.js +92 -0
  38. package/dist/src/codex-native-monitor.js.map +1 -0
  39. package/dist/src/codex-native-outbox.d.ts +16 -0
  40. package/dist/src/codex-native-outbox.js +120 -0
  41. package/dist/src/codex-native-outbox.js.map +1 -0
  42. package/dist/src/codex-native-public-projection.d.ts +545 -0
  43. package/dist/src/codex-native-public-projection.js +182 -0
  44. package/dist/src/codex-native-public-projection.js.map +1 -0
  45. package/dist/src/codex-native-record-store.d.ts +27 -0
  46. package/dist/src/codex-native-record-store.js +111 -0
  47. package/dist/src/codex-native-record-store.js.map +1 -0
  48. package/dist/src/codex-native-response-service.d.ts +69 -0
  49. package/dist/src/codex-native-response-service.js +244 -0
  50. package/dist/src/codex-native-response-service.js.map +1 -0
  51. package/dist/src/codex-native-runtime.d.ts +46 -0
  52. package/dist/src/codex-native-runtime.js +112 -0
  53. package/dist/src/codex-native-runtime.js.map +1 -0
  54. package/dist/src/codex-native-semantic.d.ts +17 -0
  55. package/dist/src/codex-native-semantic.js +175 -0
  56. package/dist/src/codex-native-semantic.js.map +1 -0
  57. package/dist/src/codex-native-snapshot.d.ts +19 -0
  58. package/dist/src/codex-native-snapshot.js +160 -0
  59. package/dist/src/codex-native-snapshot.js.map +1 -0
  60. package/dist/src/codex-native-state-store.d.ts +61 -0
  61. package/dist/src/codex-native-state-store.js +132 -0
  62. package/dist/src/codex-native-state-store.js.map +1 -0
  63. package/dist/src/codex-native-task-service.d.ts +71 -0
  64. package/dist/src/codex-native-task-service.js +502 -0
  65. package/dist/src/codex-native-task-service.js.map +1 -0
  66. package/dist/src/codex-native-types.d.ts +92 -0
  67. package/dist/src/codex-native-types.js +15 -0
  68. package/dist/src/codex-native-types.js.map +1 -0
  69. package/dist/src/conversation-list.d.ts +12 -0
  70. package/dist/src/conversation-list.js +30 -0
  71. package/dist/src/conversation-list.js.map +1 -0
  72. package/dist/src/conversation-route-dispatch.d.ts +13 -0
  73. package/dist/src/conversation-route-dispatch.js +66 -0
  74. package/dist/src/conversation-route-dispatch.js.map +1 -0
  75. package/dist/src/conversation-route-legacy.d.ts +18 -0
  76. package/dist/src/conversation-route-legacy.js +54 -0
  77. package/dist/src/conversation-route-legacy.js.map +1 -0
  78. package/dist/src/conversation-route-store.d.ts +51 -0
  79. package/dist/src/conversation-route-store.js +126 -0
  80. package/dist/src/conversation-route-store.js.map +1 -0
  81. package/dist/src/conversation-routing-cli-adapter.d.ts +12 -0
  82. package/dist/src/conversation-routing-cli-adapter.js +211 -0
  83. package/dist/src/conversation-routing-cli-adapter.js.map +1 -0
  84. package/dist/src/conversation-routing-commands.d.ts +11 -0
  85. package/dist/src/conversation-routing-commands.js +85 -0
  86. package/dist/src/conversation-routing-commands.js.map +1 -0
  87. package/dist/src/conversation-routing-home.d.ts +26 -0
  88. package/dist/src/conversation-routing-home.js +105 -0
  89. package/dist/src/conversation-routing-home.js.map +1 -0
  90. package/dist/src/conversation-routing-identity.d.ts +40 -0
  91. package/dist/src/conversation-routing-identity.js +174 -0
  92. package/dist/src/conversation-routing-identity.js.map +1 -0
  93. package/dist/src/conversation-runtime-route-store.d.ts +11 -0
  94. package/dist/src/conversation-runtime-route-store.js +118 -0
  95. package/dist/src/conversation-runtime-route-store.js.map +1 -0
  96. package/dist/src/desktop-async-interactions.d.ts +15 -0
  97. package/dist/src/desktop-async-interactions.js +88 -0
  98. package/dist/src/desktop-async-interactions.js.map +1 -0
  99. package/dist/src/desktop-async-state.d.ts +5 -0
  100. package/dist/src/desktop-async-state.js +53 -0
  101. package/dist/src/desktop-async-state.js.map +1 -0
  102. package/dist/src/desktop-cli-adapter.d.ts +7 -0
  103. package/dist/src/desktop-cli-adapter.js +322 -0
  104. package/dist/src/desktop-cli-adapter.js.map +1 -0
  105. package/dist/src/desktop-cli-controls.d.ts +9 -0
  106. package/dist/src/desktop-cli-controls.js +45 -0
  107. package/dist/src/desktop-cli-controls.js.map +1 -0
  108. package/dist/src/desktop-command-presentation.d.ts +2 -0
  109. package/dist/src/desktop-command-presentation.js +31 -0
  110. package/dist/src/desktop-command-presentation.js.map +1 -0
  111. package/dist/src/desktop-control-semantic.d.ts +8 -0
  112. package/dist/src/desktop-control-semantic.js +68 -0
  113. package/dist/src/desktop-control-semantic.js.map +1 -0
  114. package/dist/src/desktop-identity.d.ts +5 -0
  115. package/dist/src/desktop-identity.js +40 -0
  116. package/dist/src/desktop-identity.js.map +1 -0
  117. package/dist/src/desktop-interaction-projection.d.ts +57 -0
  118. package/dist/src/desktop-interaction-projection.js +196 -0
  119. package/dist/src/desktop-interaction-projection.js.map +1 -0
  120. package/dist/src/desktop-interaction-state.d.ts +3 -0
  121. package/dist/src/desktop-interaction-state.js +48 -0
  122. package/dist/src/desktop-interaction-state.js.map +1 -0
  123. package/dist/src/desktop-ipc-async-answer.d.ts +9 -0
  124. package/dist/src/desktop-ipc-async-answer.js +71 -0
  125. package/dist/src/desktop-ipc-async-answer.js.map +1 -0
  126. package/dist/src/desktop-ipc-client.d.ts +47 -0
  127. package/dist/src/desktop-ipc-client.js +400 -0
  128. package/dist/src/desktop-ipc-client.js.map +1 -0
  129. package/dist/src/desktop-ipc-native-operations.d.ts +11 -0
  130. package/dist/src/desktop-ipc-native-operations.js +126 -0
  131. package/dist/src/desktop-ipc-native-operations.js.map +1 -0
  132. package/dist/src/desktop-ipc-transport.d.ts +13 -0
  133. package/dist/src/desktop-ipc-transport.js +123 -0
  134. package/dist/src/desktop-ipc-transport.js.map +1 -0
  135. package/dist/src/desktop-list.d.ts +25 -0
  136. package/dist/src/desktop-list.js +55 -0
  137. package/dist/src/desktop-list.js.map +1 -0
  138. package/dist/src/desktop-metadata-reader.d.ts +30 -0
  139. package/dist/src/desktop-metadata-reader.js +182 -0
  140. package/dist/src/desktop-metadata-reader.js.map +1 -0
  141. package/dist/src/desktop-monitor.d.ts +4 -0
  142. package/dist/src/desktop-monitor.js +101 -0
  143. package/dist/src/desktop-monitor.js.map +1 -0
  144. package/dist/src/desktop-public-projection.d.ts +6 -0
  145. package/dist/src/desktop-public-projection.js +134 -0
  146. package/dist/src/desktop-public-projection.js.map +1 -0
  147. package/dist/src/desktop-request-interactions.d.ts +14 -0
  148. package/dist/src/desktop-request-interactions.js +144 -0
  149. package/dist/src/desktop-request-interactions.js.map +1 -0
  150. package/dist/src/desktop-response-dispatch.d.ts +14 -0
  151. package/dist/src/desktop-response-dispatch.js +19 -0
  152. package/dist/src/desktop-response-dispatch.js.map +1 -0
  153. package/dist/src/desktop-response-evidence.d.ts +4 -0
  154. package/dist/src/desktop-response-evidence.js +19 -0
  155. package/dist/src/desktop-response-evidence.js.map +1 -0
  156. package/dist/src/desktop-response-service.d.ts +11 -0
  157. package/dist/src/desktop-response-service.js +188 -0
  158. package/dist/src/desktop-response-service.js.map +1 -0
  159. package/dist/src/desktop-response-store.d.ts +35 -0
  160. package/dist/src/desktop-response-store.js +58 -0
  161. package/dist/src/desktop-response-store.js.map +1 -0
  162. package/dist/src/desktop-response-types.d.ts +20 -0
  163. package/dist/src/desktop-response-types.js +2 -0
  164. package/dist/src/desktop-response-types.js.map +1 -0
  165. package/dist/src/desktop-response-value.d.ts +6 -0
  166. package/dist/src/desktop-response-value.js +31 -0
  167. package/dist/src/desktop-response-value.js.map +1 -0
  168. package/dist/src/desktop-runtime.d.ts +153 -0
  169. package/dist/src/desktop-runtime.js +88 -0
  170. package/dist/src/desktop-runtime.js.map +1 -0
  171. package/dist/src/desktop-semantic.d.ts +21 -0
  172. package/dist/src/desktop-semantic.js +140 -0
  173. package/dist/src/desktop-semantic.js.map +1 -0
  174. package/dist/src/desktop-session-catalog.d.ts +68 -0
  175. package/dist/src/desktop-session-catalog.js +225 -0
  176. package/dist/src/desktop-session-catalog.js.map +1 -0
  177. package/dist/src/desktop-session-controls.d.ts +145 -0
  178. package/dist/src/desktop-session-controls.js +176 -0
  179. package/dist/src/desktop-session-controls.js.map +1 -0
  180. package/dist/src/desktop-sidebar-metadata.d.ts +27 -0
  181. package/dist/src/desktop-sidebar-metadata.js +83 -0
  182. package/dist/src/desktop-sidebar-metadata.js.map +1 -0
  183. package/dist/src/desktop-sidebar-projects.d.ts +10 -0
  184. package/dist/src/desktop-sidebar-projects.js +31 -0
  185. package/dist/src/desktop-sidebar-projects.js.map +1 -0
  186. package/dist/src/desktop-sidebar-selection.d.ts +28 -0
  187. package/dist/src/desktop-sidebar-selection.js +85 -0
  188. package/dist/src/desktop-sidebar-selection.js.map +1 -0
  189. package/dist/src/desktop-snapshot-details.d.ts +4 -0
  190. package/dist/src/desktop-snapshot-details.js +116 -0
  191. package/dist/src/desktop-snapshot-details.js.map +1 -0
  192. package/dist/src/desktop-snapshot.d.ts +11 -0
  193. package/dist/src/desktop-snapshot.js +276 -0
  194. package/dist/src/desktop-snapshot.js.map +1 -0
  195. package/dist/src/desktop-state-store.d.ts +72 -0
  196. package/dist/src/desktop-state-store.js +269 -0
  197. package/dist/src/desktop-state-store.js.map +1 -0
  198. package/dist/src/desktop-task-interactions.d.ts +10 -0
  199. package/dist/src/desktop-task-interactions.js +93 -0
  200. package/dist/src/desktop-task-interactions.js.map +1 -0
  201. package/dist/src/desktop-task-recovery.d.ts +38 -0
  202. package/dist/src/desktop-task-recovery.js +171 -0
  203. package/dist/src/desktop-task-recovery.js.map +1 -0
  204. package/dist/src/desktop-task-service.d.ts +54 -0
  205. package/dist/src/desktop-task-service.js +441 -0
  206. package/dist/src/desktop-task-service.js.map +1 -0
  207. package/dist/src/desktop-types.d.ts +281 -0
  208. package/dist/src/desktop-types.js +13 -0
  209. package/dist/src/desktop-types.js.map +1 -0
  210. package/dist/src/host-monitor-reconciliation.js +36 -4
  211. package/dist/src/host-monitor-reconciliation.js.map +1 -1
  212. package/dist/src/host-profile-runtime.js +7 -3
  213. package/dist/src/host-profile-runtime.js.map +1 -1
  214. package/dist/src/local-codex-cli-adapter.d.ts +7 -0
  215. package/dist/src/local-codex-cli-adapter.js +13 -0
  216. package/dist/src/local-codex-cli-adapter.js.map +1 -0
  217. package/dist/src/openclaw-callback-transport.js +2 -1
  218. package/dist/src/openclaw-callback-transport.js.map +1 -1
  219. package/dist/src/semantic-conversation-target.d.ts +4 -0
  220. package/dist/src/semantic-conversation-target.js +20 -0
  221. package/dist/src/semantic-conversation-target.js.map +1 -0
  222. package/dist/src/semantic-permission-control.js +47 -9
  223. package/dist/src/semantic-permission-control.js.map +1 -1
  224. package/dist/src/semantic-private-authority-offers.d.ts +1 -1
  225. package/dist/src/semantic-private-authority-offers.js +3 -1
  226. package/dist/src/semantic-private-authority-offers.js.map +1 -1
  227. package/dist/src/semantic-tool-command-helpers.d.ts +6 -0
  228. package/dist/src/semantic-tool-command-helpers.js +199 -78
  229. package/dist/src/semantic-tool-command-helpers.js.map +1 -1
  230. package/dist/src/semantic-tool-descriptions.d.ts +2 -1
  231. package/dist/src/semantic-tool-descriptions.js +81 -35
  232. package/dist/src/semantic-tool-descriptions.js.map +1 -1
  233. package/dist/src/semantic-tool-list-projection.js +66 -2
  234. package/dist/src/semantic-tool-list-projection.js.map +1 -1
  235. package/dist/src/semantic-tool-presentation.js +76 -7
  236. package/dist/src/semantic-tool-presentation.js.map +1 -1
  237. package/dist/src/semantic-tool-runtime.js +129 -29
  238. package/dist/src/semantic-tool-runtime.js.map +1 -1
  239. package/dist/src/semantic-tool-schemas.d.ts +410 -27
  240. package/dist/src/semantic-tool-schemas.js +176 -88
  241. package/dist/src/semantic-tool-schemas.js.map +1 -1
  242. package/dist/src/terminal-action-contracts.js +10 -6
  243. package/dist/src/terminal-action-contracts.js.map +1 -1
  244. package/dist/src/terminal-list-cli-adapter.d.ts +1 -0
  245. package/dist/src/terminal-list-cli-adapter.js +6 -3
  246. package/dist/src/terminal-list-cli-adapter.js.map +1 -1
  247. package/dist/src/terminal-monitor-decision-policy.d.ts +1 -1
  248. package/dist/src/terminal-permission-control-list-projection.d.ts +1 -1
  249. package/dist/src/terminal-user-send-intent.d.ts +2 -0
  250. package/dist/src/terminal-user-send-intent.js +11 -3
  251. package/dist/src/terminal-user-send-intent.js.map +1 -1
  252. package/docs/architecture/current-architecture.md +313 -0
  253. package/docs/architecture/interactive-terminal-response.md +276 -0
  254. package/docs/architecture/issue-126-final-report.md +248 -0
  255. package/docs/architecture/orchestration-refactor-history.md +2987 -0
  256. package/docs/architecture/orchestration-refactor.md +21 -0
  257. package/docs/backend-task-recovery.md +89 -0
  258. package/docs/bidirectional-agent-protocol.md +260 -0
  259. package/docs/codex-cli-native-compatibility.md +246 -0
  260. package/docs/codex-desktop-compatibility.md +414 -0
  261. package/docs/openclaw-operations.md +281 -0
  262. package/docs/openclaw-session-turn-delivery-requirement.md +45 -0
  263. package/docs/operator-guide.md +543 -0
  264. package/docs/storage-and-logging.md +91 -0
  265. package/docs/test-performance-issue-108.md +80 -0
  266. package/docs/test-performance-issue-120.md +226 -0
  267. package/docs/testing.md +628 -0
  268. package/openclaw.plugin.json +7 -3
  269. package/package.json +6 -13
  270. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +66 -15
@@ -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":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAqB7B,0FAA0F;AAC1F,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,IAAY;IAC3D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;QACvF,OAAO,2BAA2B,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACxF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE;YACrG,SAAS,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB,EAAE,EAAE;YAClF,cAAc,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,sBAAsB,EAAE,EAAE;YAC7D,WAAW,EAAE,CAAC,6DAA6D,CAAC,EAAE,CAAC;IACnF,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,KAAc,EAAE,IAAY;IACtE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;IACpF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,SAAS,IAAI,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC,CAAC;SAChF,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;SAC3D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACpH,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACzF,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;QAAC,OAAO,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;IAClG,CAAC,CAAC,CAAC;IACH,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACpB,WAAW,CAAC,IAAI,CAAC,qEAAqE,CAAC,CAAC;IAC1F,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACvE,CAAC,qBAAqB,EAAE,gBAAgB,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAK,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAe,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QAClJ,WAAW,CAAC,IAAI,CAAC,mFAAmF,CAAC,CAAC;IACxG,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,WAAW,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;QACjG,SAAS,EAAE,aAAa,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAChE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CACxE,GAAG,CAAC,UAAU,CAAC,oCAAoC,CAAC,IAAI,OAAO,IAAI,KAAK,SAAS,CAAC;aACjF,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC,MAAM,CAAC,EAAE,IAAe,CAAC,CAAC,CAAC;QACnG,QAAQ,EAAE,WAAW,EAAE,kBAAkB,CAAC,KAAK,EAAE,WAAW,CAAC;QAC7D,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;QAC7F,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACpG,iBAAiB,EAAE,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACtE,iBAAiB,EAAE,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC9G,cAAc,EAAE,OAAO,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC,EAAE,SAAS,EAAE,YAAY,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACvH,sBAAsB,EAAE,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC;aACnF,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;AAC/H,CAAC;AAED,SAAS,YAAY,CAAC,OAAgC;IACpD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;IACtF,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;gBAC5E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC;YAChI,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACrJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAA8B,EAAE,WAAqB;IAC/E,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;IAClE,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,MAAM,GAA0C,EAAE,CAAC;IACzD,KAAK,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC3B,IAAI,IAAI,CAAC,WAAW,KAAK,OAAO,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;YACvE,0EAA0E;YAC1E,uDAAuD;YACvD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;YAC1G,WAAW,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;YAAC,SAAS;QAC1G,CAAC;QACD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IACpH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAgC,CAAC,CAAC,CAAC,EAAE,CAAC;AACtH,CAAC;AACD,SAAS,OAAO,CAAC,KAAc,IAAc,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AACjI,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAA6B,EAAE,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;AACtI,CAAC;AACD,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAA8B,EAAE,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC;AACxI,CAAC"}
@@ -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