@platless/axom-cli 0.3.13 → 0.6.36

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 (320) hide show
  1. package/README.md +18 -5
  2. package/dist/axom-patch/cli/README.md +119 -9
  3. package/dist/axom-patch/cli/account-limits/README.md +27 -0
  4. package/dist/axom-patch/cli/account-limits/antigravity-proxy.mjs +47 -0
  5. package/dist/axom-patch/cli/account-limits/antigravity-read.mjs +90 -0
  6. package/dist/axom-patch/cli/account-limits/antigravity.mjs +46 -0
  7. package/dist/axom-patch/cli/account-limits/generate.py +123 -0
  8. package/dist/axom-patch/cli/account-limits/kimi-proxy.mjs +81 -0
  9. package/dist/axom-patch/cli/account-limits/normalize.mjs +151 -0
  10. package/dist/axom-patch/cli/claude-account-limits.json +37 -0
  11. package/dist/axom-patch/cli/codex-account-limits.json +37 -0
  12. package/dist/axom-patch/cli/codex-terminal-output.json +16 -0
  13. package/dist/axom-patch/cli/commandcode-account-limits.json +30 -0
  14. package/dist/axom-patch/cli/kimi-quota.mjs +12 -0
  15. package/dist/axom-patch/cli/kimi-subagents.mjs +173 -0
  16. package/dist/axom-patch/cli/nightly-task.md +194 -0
  17. package/dist/axom-patch/cli/pi-subagent-subwork.json +23 -0
  18. package/dist/axom-patch/cli/probes/claude-late-async-terminal.mjs +5 -1
  19. package/dist/axom-patch/cli/probes/codex-terminal-output.mjs +33 -0
  20. package/dist/axom-patch/cli/probes/kimi-subagent-subwork.mjs +82 -0
  21. package/dist/axom-patch/cli/probes/pi-subagent-subwork.mjs +211 -0
  22. package/dist/axom-patch/cli/probes/zcode-subagent-subwork.mjs +257 -0
  23. package/dist/axom-patch/cli/qoder/dist/axom-acp-compat.mjs +1591 -0
  24. package/dist/axom-patch/cli/qoder/releases/1.1.75.json +360 -0
  25. package/dist/axom-patch/cli/qoder-background-terminal.md +13 -5
  26. package/dist/axom-patch/cli/qoder-foreground-output.md +14 -7
  27. package/dist/axom-patch/cli/qoder-native-acp.json +227 -0
  28. package/dist/axom-patch/cli/qoder-steering.md +20 -25
  29. package/dist/axom-patch/cli/qoder-subagent-subwork.md +17 -68
  30. package/dist/axom-patch/cli/runtime.json +39 -15
  31. package/dist/axom-patch/cli/zcode-account-limits.json +30 -0
  32. package/dist/axom-patch/cli/zcode-models.json +37 -0
  33. package/dist/axom-patch/cli/zcode-subagent-subwork.json +72 -0
  34. package/dist/cli.js +4 -9
  35. package/dist/commands/knowledge.js +47 -0
  36. package/dist/commands/update.js +65 -3
  37. package/dist/commands/workstation.js +73 -7
  38. package/dist/install/claude/commands.js +13 -13
  39. package/dist/keepers/acp/keeper.mjs +3083 -0
  40. package/dist/keepers/acp/manifest.json +9 -0
  41. package/dist/keepers/terminal/keeper.mjs +8469 -0
  42. package/dist/keepers/terminal/manifest.json +9 -0
  43. package/dist/keepers/terminal/node_modules/node-pty/lib/conpty_console_list_agent.js +25 -0
  44. package/dist/keepers/terminal/node_modules/node-pty/lib/eventEmitter2.js +47 -0
  45. package/dist/keepers/terminal/node_modules/node-pty/lib/index.js +52 -0
  46. package/dist/keepers/terminal/node_modules/node-pty/lib/interfaces.js +7 -0
  47. package/dist/keepers/terminal/node_modules/node-pty/lib/shared/conout.js +10 -0
  48. package/dist/keepers/terminal/node_modules/node-pty/lib/terminal.js +190 -0
  49. package/dist/keepers/terminal/node_modules/node-pty/lib/types.js +7 -0
  50. package/dist/keepers/terminal/node_modules/node-pty/lib/unixTerminal.js +351 -0
  51. package/dist/keepers/terminal/node_modules/node-pty/lib/utils.js +38 -0
  52. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsConoutConnection.js +131 -0
  53. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsPtyAgent.js +344 -0
  54. package/dist/keepers/terminal/node_modules/node-pty/lib/windowsTerminal.js +209 -0
  55. package/dist/keepers/terminal/node_modules/node-pty/lib/worker/conoutSocketWorker.js +22 -0
  56. package/dist/keepers/terminal/node_modules/node-pty/package.json +66 -0
  57. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-arm64/pty.node +0 -0
  58. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-arm64/spawn-helper +0 -0
  59. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-x64/pty.node +0 -0
  60. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/darwin-x64/spawn-helper +0 -0
  61. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/linux-arm64/pty.node +0 -0
  62. package/dist/keepers/terminal/node_modules/node-pty/prebuilds/linux-x64/pty.node +0 -0
  63. package/dist/mcp.js +1 -1
  64. package/dist/native/darwin-arm64/axom-quic +0 -0
  65. package/dist/test/keeperKit.js +67 -0
  66. package/dist/workstation/acp/acpAgents.js +2192 -636
  67. package/dist/workstation/acp/acpClient.js +84 -495
  68. package/dist/workstation/acp/adoption.js +10 -396
  69. package/dist/workstation/acp/binaryInstall.js +100 -27
  70. package/dist/workstation/acp/builds/gc.js +245 -0
  71. package/dist/workstation/acp/builds/install/binary.js +28 -0
  72. package/dist/workstation/acp/builds/install/npm.js +324 -0
  73. package/dist/workstation/acp/builds/install/uv.js +254 -0
  74. package/dist/workstation/acp/builds/migrate.js +195 -0
  75. package/dist/workstation/acp/builds/model.js +128 -0
  76. package/dist/workstation/acp/builds/nodeGate.js +100 -0
  77. package/dist/workstation/acp/builds/store.js +352 -0
  78. package/dist/workstation/acp/commandTableProbe.js +68 -0
  79. package/dist/workstation/acp/configOptions.js +103 -1
  80. package/dist/workstation/acp/envSecrets.js +27 -0
  81. package/dist/workstation/acp/initializeResponse.js +290 -0
  82. package/dist/workstation/acp/installErrors.js +12 -2
  83. package/dist/workstation/acp/installProbe.js +1 -1
  84. package/dist/workstation/acp/managedPatches.js +239 -159
  85. package/dist/workstation/acp/managedRuntime.js +314 -0
  86. package/dist/workstation/acp/outbox.js +330 -0
  87. package/dist/workstation/acp/patchAssets.js +60 -3
  88. package/dist/workstation/acp/permission.js +42 -10
  89. package/dist/workstation/acp/processor/checkpoint.js +78 -0
  90. package/dist/workstation/acp/processor/commands.js +35 -0
  91. package/dist/workstation/acp/processor/control.js +282 -0
  92. package/dist/workstation/acp/processor/emit.js +26 -0
  93. package/dist/workstation/acp/processor/jsonrpc.js +172 -0
  94. package/dist/workstation/acp/processor/memoryLog.js +49 -0
  95. package/dist/workstation/acp/processor/origins.js +48 -0
  96. package/dist/workstation/acp/processor/output.js +67 -0
  97. package/dist/workstation/acp/processor/projection.js +42 -0
  98. package/dist/workstation/acp/processor/record.js +128 -0
  99. package/dist/workstation/acp/processor/runtime.js +105 -0
  100. package/dist/workstation/acp/processor/sdkSchemas.js +61 -0
  101. package/dist/workstation/acp/processor/session.js +496 -0
  102. package/dist/workstation/acp/processor/state.js +67 -0
  103. package/dist/workstation/acp/processor/step.js +442 -0
  104. package/dist/workstation/acp/processor/test/fixtureLog.js +58 -0
  105. package/dist/workstation/acp/processor/test/harness.js +120 -0
  106. package/dist/workstation/acp/processor/test/largeIdEcho.js +50 -0
  107. package/dist/workstation/acp/processor/test/rawAgent.js +70 -0
  108. package/dist/workstation/acp/processor/transport/generations.js +76 -0
  109. package/dist/workstation/acp/processor/transport/keeper.js +130 -0
  110. package/dist/workstation/acp/processor/transport/local.js +269 -0
  111. package/dist/workstation/acp/processor/transport/types.js +78 -0
  112. package/dist/workstation/acp/processor/updates.js +390 -0
  113. package/dist/workstation/acp/processorSession.js +1348 -0
  114. package/dist/workstation/acp/registry/catalog.js +189 -41
  115. package/dist/workstation/acp/registry/launch.js +76 -119
  116. package/dist/workstation/acp/sessionUpdateMapper.js +18 -7
  117. package/dist/workstation/acp/steering.js +58 -0
  118. package/dist/workstation/acp/switching.js +111 -0
  119. package/dist/workstation/acp/terminalLogin.js +16 -42
  120. package/dist/workstation/acp/terminalLoginSpec.js +41 -0
  121. package/dist/workstation/acp/test/adapterFixtures.js +256 -0
  122. package/dist/workstation/acp/test/daemonLife.js +106 -0
  123. package/dist/workstation/acp/test/fakeAgent.js +13 -0
  124. package/dist/workstation/acp/test/keeperWorld.js +295 -0
  125. package/dist/workstation/acp/test/memoryOutbox.js +55 -0
  126. package/dist/workstation/acp/test/raw/fixtures.js +196 -0
  127. package/dist/workstation/acp/test/raw/sanitize.js +344 -0
  128. package/dist/workstation/acp/test/raw/sources.js +135 -0
  129. package/dist/workstation/acp/test/realAdapter.js +331 -0
  130. package/dist/workstation/acp/test/scriptAgent.js +214 -0
  131. package/dist/workstation/acp/test/sessionFrames.js +42 -0
  132. package/dist/workstation/acp/timedCommand.js +4 -2
  133. package/dist/workstation/acp/uvxInstall.js +72 -122
  134. package/dist/workstation/agentFlow.js +103 -0
  135. package/dist/workstation/agentSessions.js +1289 -544
  136. package/dist/workstation/channels/agent.js +7 -5
  137. package/dist/workstation/channels/computer.js +69 -21
  138. package/dist/workstation/channels/computerExecs.js +200 -0
  139. package/dist/workstation/channels/management.js +172 -8
  140. package/dist/workstation/channels/url.js +1 -1
  141. package/dist/workstation/config.js +16 -4
  142. package/dist/workstation/connection/encryptedChannel.js +4 -1
  143. package/dist/workstation/control/bindingStore.js +200 -0
  144. package/dist/workstation/control/commands.js +124 -0
  145. package/dist/workstation/control/daemonIdentity.js +53 -0
  146. package/dist/workstation/control/enrollment.js +106 -0
  147. package/dist/workstation/control/inspect.js +71 -0
  148. package/dist/workstation/control/locks.js +63 -0
  149. package/dist/workstation/control/protocol.js +40 -0
  150. package/dist/workstation/control/restartGuard.js +46 -0
  151. package/dist/workstation/control/runtimeClient.js +97 -0
  152. package/dist/workstation/control/runtimeHost.js +148 -0
  153. package/dist/workstation/control/serverIdentity.js +35 -0
  154. package/dist/workstation/daemon.js +393 -12
  155. package/dist/workstation/daemonctl.js +103 -14
  156. package/dist/workstation/desktopControl/audio.js +99 -0
  157. package/dist/workstation/desktopControl/capabilities.js +92 -0
  158. package/dist/workstation/desktopControl/captureModes.js +9 -0
  159. package/dist/workstation/desktopControl/captureTargetLabel.js +9 -0
  160. package/dist/workstation/desktopControl/deviceSockets.js +246 -0
  161. package/dist/workstation/desktopControl/helperProcess.js +353 -0
  162. package/dist/workstation/desktopControl/lobby.js +129 -0
  163. package/dist/workstation/desktopControl/macProvider.js +155 -0
  164. package/dist/workstation/desktopControl/media.js +331 -0
  165. package/dist/workstation/desktopControl/nativeProvider.js +1018 -0
  166. package/dist/workstation/desktopControl/networkEvidence.js +43 -0
  167. package/dist/workstation/desktopControl/overview.js +58 -0
  168. package/dist/workstation/desktopControl/protocol.js +302 -0
  169. package/dist/workstation/desktopControl/quicMedia.js +240 -0
  170. package/dist/workstation/desktopControl/rateController.js +226 -0
  171. package/dist/workstation/desktopControl/supervisor.js +1681 -0
  172. package/dist/workstation/desktopControl/transport.js +27 -0
  173. package/dist/workstation/desktopControl/wallpaper.js +78 -0
  174. package/dist/workstation/exec/attach.js +126 -0
  175. package/dist/workstation/exec/command.js +40 -0
  176. package/dist/workstation/exec/durable.js +517 -0
  177. package/dist/workstation/exec/fallback.js +106 -0
  178. package/dist/workstation/exec/policy.js +837 -0
  179. package/dist/workstation/exec/shaping.js +211 -0
  180. package/dist/workstation/exec.js +3 -112
  181. package/dist/workstation/files/adapters/computerFileFrames.js +51 -0
  182. package/dist/workstation/files/adapters/toolRequests.js +121 -0
  183. package/dist/workstation/files/client.js +455 -0
  184. package/dist/workstation/files/credentials.js +142 -0
  185. package/dist/workstation/files/errors.js +28 -0
  186. package/dist/workstation/files/fence.js +350 -0
  187. package/dist/workstation/files/find/fileIndex.js +153 -0
  188. package/dist/workstation/files/find/fuzzy.js +155 -0
  189. package/dist/workstation/files/host.js +122 -0
  190. package/dist/workstation/files/hostProtocol.js +2 -0
  191. package/dist/workstation/files/media/cache.js +620 -0
  192. package/dist/workstation/files/media/encoding.js +308 -0
  193. package/dist/workstation/files/media/estimator.js +100 -0
  194. package/dist/workstation/files/media/media.js +325 -0
  195. package/dist/workstation/files/media/packedAudio.js +23 -0
  196. package/dist/workstation/files/media/scheduler.js +551 -0
  197. package/dist/workstation/files/media/types.js +5 -0
  198. package/dist/workstation/files/scope.js +45 -0
  199. package/dist/workstation/files/structured.js +284 -0
  200. package/dist/workstation/{fileOps.js → files/text.js} +152 -39
  201. package/dist/workstation/files/uploads.js +351 -0
  202. package/dist/workstation/journal.js +65 -236
  203. package/dist/workstation/keepers/acp/client.js +101 -0
  204. package/dist/workstation/keepers/acp/envelope.js +62 -0
  205. package/dist/workstation/keepers/acp/host.js +419 -0
  206. package/dist/workstation/keepers/acp/main.js +18 -0
  207. package/dist/workstation/keepers/acp/memoryStream.js +121 -0
  208. package/dist/workstation/keepers/acp/params.js +137 -0
  209. package/dist/workstation/keepers/acp/protocol.js +66 -0
  210. package/dist/workstation/keepers/acp/recover.js +120 -0
  211. package/dist/workstation/keepers/acp/session.js +584 -0
  212. package/dist/workstation/keepers/acp/stderr.js +154 -0
  213. package/dist/workstation/keepers/kit/activity.js +103 -0
  214. package/dist/workstation/keepers/kit/bootstrap.js +164 -0
  215. package/dist/workstation/keepers/kit/buildVersion.js +51 -0
  216. package/dist/workstation/keepers/kit/bundle.js +124 -0
  217. package/dist/workstation/keepers/kit/client.js +432 -0
  218. package/dist/workstation/keepers/kit/identity.js +21 -0
  219. package/dist/workstation/keepers/kit/ipc.js +112 -0
  220. package/dist/workstation/keepers/kit/launchConfig.js +8 -0
  221. package/dist/workstation/keepers/kit/launcher.js +289 -0
  222. package/dist/workstation/keepers/kit/lock.js +123 -0
  223. package/dist/workstation/keepers/kit/orphanSweep.js +86 -0
  224. package/dist/workstation/keepers/kit/paths.js +76 -0
  225. package/dist/workstation/keepers/kit/protocol.js +43 -0
  226. package/dist/workstation/keepers/kit/server.js +518 -0
  227. package/dist/workstation/keepers/kit/streamLog.js +697 -0
  228. package/dist/workstation/keepers/legacy.js +296 -0
  229. package/dist/workstation/keepers/policy.js +576 -0
  230. package/dist/workstation/keepers/stop.js +34 -0
  231. package/dist/workstation/keepers/terminal/client.js +213 -0
  232. package/dist/workstation/keepers/terminal/exec.js +981 -0
  233. package/dist/workstation/keepers/terminal/generations.js +129 -0
  234. package/dist/workstation/keepers/terminal/keeper.js +62 -0
  235. package/dist/workstation/keepers/terminal/main.js +43 -0
  236. package/dist/workstation/keepers/terminal/orphanSweep.js +3 -0
  237. package/dist/workstation/keepers/terminal/params.js +27 -0
  238. package/dist/workstation/keepers/terminal/protocol.js +56 -0
  239. package/dist/workstation/keepers/terminal/pty.js +330 -0
  240. package/dist/workstation/managedInstall.js +57 -0
  241. package/dist/workstation/protocol/accountLimits.js +47 -0
  242. package/dist/workstation/protocol/agent.js +50 -19
  243. package/dist/workstation/protocol/common.js +30 -0
  244. package/dist/workstation/protocol/computer.js +15 -4
  245. package/dist/workstation/protocol/management.js +141 -4
  246. package/dist/workstation/protocol/runtimeDiagnostics.js +15 -0
  247. package/dist/workstation/rd/artifact.js +119 -0
  248. package/dist/workstation/rd/control.js +119 -0
  249. package/dist/workstation/rd/display.js +29 -0
  250. package/dist/workstation/rd/provider.js +222 -0
  251. package/dist/workstation/rd/sessions.js +391 -0
  252. package/dist/workstation/rd/state.js +45 -0
  253. package/dist/workstation/rd/update.js +171 -0
  254. package/dist/workstation/rd/upkeep.js +38 -0
  255. package/dist/workstation/register.js +27 -37
  256. package/dist/workstation/service/installer.js +104 -13
  257. package/dist/workstation/service/launchd.js +1 -0
  258. package/dist/workstation/storageMetrics.js +118 -0
  259. package/dist/workstation/systemMetrics.js +154 -93
  260. package/dist/workstation/toolchain.js +94 -0
  261. package/dist/workstation/tools/browser.js +28 -4
  262. package/dist/workstation/tools/client.js +9 -1
  263. package/dist/workstation/tools/info.js +50 -0
  264. package/dist/workstation/tools/keeperProcess.js +15 -5
  265. package/dist/workstation/tools/router.js +55 -0
  266. package/dist/workstation/tools/terminalRouter.js +222 -0
  267. package/dist/workstation/tools/validation.js +37 -1
  268. package/dist/workstation/update/artifact.js +2 -1
  269. package/dist/workstation/update/coordinator.js +3 -0
  270. package/dist/workstation/update/globalInstall.js +116 -0
  271. package/dist/workstation/update/npmInstaller.js +49 -23
  272. package/dist/workstation/update/ptyPreflight.js +21 -0
  273. package/dist/workstation/update/rdRollback.js +145 -0
  274. package/dist/workstation/update/runUpdate.js +3 -2
  275. package/dist/workstation/update/taskRegistry.js +105 -11
  276. package/dist/workstation/update/watchdog.js +16790 -334
  277. package/package.json +11 -8
  278. package/skills/axom/SKILL.md +11 -11
  279. package/skills/axom-definition/SKILL.md +3 -3
  280. package/skills/axom-platform/SKILL.md +3 -3
  281. package/dist/axom-patch/cli/probes/qoder-steering.mjs +0 -89
  282. package/dist/axom-patch/cli/probes/qoder-subagent-origin.mjs +0 -49
  283. package/dist/axom-patch/cli/qoder-steering.json +0 -52
  284. package/dist/axom-patch/cli/qoder-subagent-origin.json +0 -73
  285. package/dist/commands/guide.js +0 -38
  286. package/dist/workstation/acp/acpSession.js +0 -1475
  287. package/dist/workstation/acp/contract.js +0 -499
  288. package/dist/workstation/acp/delegationMcp.js +0 -24
  289. package/dist/workstation/acp/draftInterceptor.js +0 -163
  290. package/dist/workstation/acp/qoderStartup.js +0 -45
  291. package/dist/workstation/acp/sessionScope.js +0 -19
  292. package/dist/workstation/filePaths.js +0 -174
  293. package/dist/workstation/fileWorker.js +0 -81
  294. package/dist/workstation/fileWorkerClient.js +0 -121
  295. package/dist/workstation/qoderAdapter/backgroundProcess.js +0 -106
  296. package/dist/workstation/qoderAdapter/backgroundTerminal.js +0 -262
  297. package/dist/workstation/qoderAdapter/completedContinuation.js +0 -139
  298. package/dist/workstation/qoderAdapter/contract.js +0 -78
  299. package/dist/workstation/qoderAdapter/foregroundOutput.js +0 -30
  300. package/dist/workstation/qoderAdapter/history.js +0 -87
  301. package/dist/workstation/qoderAdapter/identityIndex.js +0 -191
  302. package/dist/workstation/qoderAdapter/inputQueue.js +0 -42
  303. package/dist/workstation/qoderAdapter/main.js +0 -93
  304. package/dist/workstation/qoderAdapter/mapper.js +0 -117
  305. package/dist/workstation/qoderAdapter/observerPlugin.js +0 -245
  306. package/dist/workstation/qoderAdapter/observerReceiver.js +0 -187
  307. package/dist/workstation/qoderAdapter/permissions.js +0 -61
  308. package/dist/workstation/qoderAdapter/profile.js +0 -93
  309. package/dist/workstation/qoderAdapter/sdkDriver.js +0 -49
  310. package/dist/workstation/qoderAdapter/session.js +0 -319
  311. package/dist/workstation/qoderAdapter/subagentMeta.js +0 -28
  312. package/dist/workstation/qoderAdapter/subwork.js +0 -77
  313. package/dist/workstation/qoderAdapter/taskControl.js +0 -38
  314. package/dist/workstation/qoderAdapter/taskEvent.js +0 -26
  315. package/dist/workstation/qoderAdapter/taskLedger.js +0 -163
  316. package/dist/workstation/qoderAdapter/usage.js +0 -37
  317. package/dist/workstation/tools/core.js +0 -50
  318. package/dist/workstation/tools/files.js +0 -525
  319. package/dist/workstation/tools/terminal.js +0 -214
  320. /package/dist/workstation/{qoderAdapter/types.js → desktopControl/provider.js} +0 -0
@@ -0,0 +1,27 @@
1
+ import { z } from 'zod';
2
+ import { DesktopProtocolError, parseDesktopJson } from './protocol.js';
3
+ const sessionId = z.string().regex(/^[0-9a-f]{32}$/);
4
+ const generation = z.number().int().min(1).max(Number.MAX_SAFE_INTEGER);
5
+ const secret = z.string().regex(/^[A-Za-z0-9_-]{43}$/).refine(s => Buffer.from(s, 'base64url').toString('base64url') === s);
6
+ const role = z.enum(['viewer_control', 'viewer_media', 'device_control', 'device_media']);
7
+ const quic = z.strictObject({ port: z.number().int().min(1).max(65535), certificate: z.string().min(64).max(2048).refine(s => Buffer.from(s, 'base64').toString('base64') === s) });
8
+ const schema = z.discriminatedUnion('type', [
9
+ z.strictObject({ type: z.literal('device_attach'), sessionId, grant: secret }),
10
+ z.strictObject({ type: z.literal('viewer_attach'), sessionId, nonce: secret }),
11
+ z.strictObject({ type: z.literal('attached'), sessionId, role, controlGeneration: generation, overviewToken: secret.optional(), audioToken: secret.optional() }),
12
+ z.strictObject({ type: z.literal('media_grant'), sessionId, controlGeneration: generation, grant: secret, quic: quic.optional() }),
13
+ z.strictObject({ type: z.literal('media_nonce'), sessionId, controlGeneration: generation, nonce: secret, quic: quic.optional() }),
14
+ ]);
15
+ export function decodeDesktopTransport(source) {
16
+ try {
17
+ return schema.parse(parseDesktopJson(source, 4096));
18
+ }
19
+ catch {
20
+ throw new DesktopProtocolError('Invalid desktop transport exchange');
21
+ }
22
+ }
23
+ export function encodeDesktopTransport(message) {
24
+ const text = JSON.stringify(message);
25
+ decodeDesktopTransport(text);
26
+ return text;
27
+ }
@@ -0,0 +1,78 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { wallpaperAssetSchema } from './lobby.js';
3
+ export function decodeWallpaper(text) {
4
+ if (Buffer.byteLength(text) > 100_000)
5
+ throw new Error('wallpaper_unavailable');
6
+ const result = JSON.parse(text);
7
+ const asset = wallpaperAssetSchema.parse(result.asset);
8
+ if (typeof result.jpeg !== 'string' || result.jpeg.length > 87384)
9
+ throw new Error('wallpaper_unavailable');
10
+ const jpeg = Buffer.from(result.jpeg, 'base64');
11
+ if (jpeg.length < 4 || jpeg.length > 65536 || jpeg.toString('base64') !== result.jpeg || jpeg[0] !== 255 || jpeg[1] !== 216)
12
+ throw new Error('wallpaper_unavailable');
13
+ const version = createHash('sha256').update(JSON.stringify(asset)).update(jpeg).digest('hex');
14
+ return { asset: { ...asset, version }, jpeg };
15
+ }
16
+ export class XfceWallpaperReader {
17
+ execute;
18
+ constructor(execute) {
19
+ this.execute = execute;
20
+ }
21
+ async discover() {
22
+ const workspaceValue = await this.execute('xprop', ['-root', '_NET_CURRENT_DESKTOP']);
23
+ let workspace = /_NET_CURRENT_DESKTOP\(CARDINAL\)\s*=\s*(\d+)/.exec(workspaceValue)?.[1];
24
+ if (workspace == null || Number(workspace) > 1024)
25
+ throw new Error('wallpaper_unavailable');
26
+ const listed = await this.execute('xfconf-query', ['-c', 'xfce4-desktop', '-l']);
27
+ const read = (property) => this.execute('xfconf-query', ['-c', 'xfce4-desktop', '-p', property]);
28
+ if (listed.split(/\r?\n/).some(line => line.trim() === '/backdrop/single-workspace-mode') &&
29
+ (await read('/backdrop/single-workspace-mode')).trim() === 'true') {
30
+ workspace = (await read('/backdrop/single-workspace-number')).trim();
31
+ if (!/^\d{1,4}$/.test(workspace) || Number(workspace) > 1024)
32
+ throw new Error('wallpaper_unavailable');
33
+ }
34
+ const available = listed.split(/\r?\n/).map(line => line.trim());
35
+ const properties = available
36
+ .filter(line => new RegExp(`^/backdrop/screen0/monitor[^/]+/workspace${workspace}/last-image$`).test(line));
37
+ let selected = properties[0];
38
+ let defaultImage = false;
39
+ if (properties.length === 0) {
40
+ const version = await this.execute('xfdesktop', ['--version']);
41
+ const monitors = await this.execute('xrandr', ['--listactivemonitors']);
42
+ if (!/xfdesktop version 4\.20(?:\.\d+)?\b/.test(version) || !/^Monitors:\s*1\s*$/m.test(monitors))
43
+ throw new Error('wallpaper_unavailable');
44
+ const output = /^\s*0:\s+\S+\s+\S+\s+(\S+)\s*$/m.exec(monitors)?.[1];
45
+ if (!output || !/^[A-Za-z0-9_.:-]+$/.test(output))
46
+ throw new Error('wallpaper_unavailable');
47
+ selected = `/backdrop/screen0/monitor${output}/workspace${workspace}/last-image`;
48
+ defaultImage = true;
49
+ }
50
+ if (properties.length > 1)
51
+ throw new Error('wallpaper_unavailable');
52
+ const file = defaultImage ? '/usr/share/backgrounds/xfce/xfce-x.svg' : (await read(selected)).trim();
53
+ if (!file.startsWith('/') || file.length > 4096 || /[\r\n\0]/.test(file))
54
+ throw new Error('wallpaper_unavailable');
55
+ const prefix = selected.slice(0, -'last-image'.length);
56
+ const style = available.includes(`${prefix}image-style`) ? (await read(`${prefix}image-style`)).trim() : '5';
57
+ const placement = { '1': 'center', '2': 'tile', '3': 'stretch', '4': 'fit', '5': 'cover' }[style];
58
+ if (!placement)
59
+ throw new Error('wallpaper_unavailable');
60
+ let background = '#000000';
61
+ let fidelity = 'exact';
62
+ if (placement !== 'cover' && placement !== 'stretch') {
63
+ try {
64
+ if ((await read(`${prefix}color-style`)).trim() !== '0')
65
+ throw new Error('unsupported_gradient');
66
+ const values = (await read(`${prefix}rgba1`)).split(/\r?\n/).map(line => line.trim())
67
+ .filter(line => /^\d+(?:\.\d+)?$/.test(line)).map(Number);
68
+ if (values.length !== 4 || values.some(value => value < 0 || value > 1) || values[3] !== 1)
69
+ throw new Error('unknown_fill');
70
+ background = '#' + values.slice(0, 3).map(value => Math.round(value * 255).toString(16).padStart(2, '0')).join('');
71
+ }
72
+ catch {
73
+ fidelity = 'approximate';
74
+ }
75
+ }
76
+ return { file, placement, background, fidelity };
77
+ }
78
+ }
@@ -0,0 +1,126 @@
1
+ import { ExecWireText } from './shaping.js';
2
+ /** Spec §4.3: `exec_output` waits while the socket holds more than the high mark, until it drains below the low mark. */
3
+ export const EXEC_WINDOW_HIGH_BYTES = 1024 * 1024;
4
+ export const EXEC_WINDOW_LOW_BYTES = 256 * 1024;
5
+ const WINDOW_POLL_MS = 20;
6
+ /** Records per `exec.read` page (the keeper also caps a page at 1.5 MiB). */
7
+ const PAGE_RECORDS = 1024;
8
+ /** Re-read cadence when nothing new arrived and no progress was signalled. */
9
+ const IDLE_POLL_MS = 500;
10
+ const RETRY_MS = 1000;
11
+ /** The v5 `exec_exit` of an ended durable exec (`exitFrame` is the today-shaped frame, exec/policy.ts `durableExitFrame`). */
12
+ export function wireExitFrame(exitFrame, outcome, gapBytes) {
13
+ const signal = outcome.state === 'exited' ? outcome.exit.signal : null;
14
+ return { ...exitFrame, cancelled: outcome.cancelled, ...(signal ? { signal } : {}), ...(gapBytes > 0 ? { gaps: gapBytes } : {}) };
15
+ }
16
+ const sleep = (ms, signal) => new Promise((resolve) => {
17
+ if (signal.aborted) {
18
+ resolve();
19
+ return;
20
+ }
21
+ const done = () => { clearTimeout(timer); signal.removeEventListener('abort', done); resolve(); };
22
+ const timer = setTimeout(done, ms);
23
+ signal.addEventListener('abort', done, { once: true });
24
+ });
25
+ /** Resolves once the socket has room for more output: at once below the high mark, else when it drained below the low mark. */
26
+ export async function waitForWindow(bufferedAmount, signal, pollMs = WINDOW_POLL_MS) {
27
+ if (bufferedAmount() <= EXEC_WINDOW_HIGH_BYTES)
28
+ return;
29
+ while (!signal.aborted && bufferedAmount() > EXEC_WINDOW_LOW_BYTES)
30
+ await sleep(pollMs, signal);
31
+ }
32
+ /**
33
+ * Streams `exec` to `channel`: reads its records from keeper-terminal from the commit point on (decoding silently up to
34
+ * `fromOffset`), sends one `exec_output` per chunk at or after `fromOffset`, honouring the socket window, then the final
35
+ * `exec_status` and `exec_exit` once the exec ended. A non-streaming exec sends only the final two. `stop()` ends it silently
36
+ * (the channel closed, or a newer attach replaced it); the exec itself is untouched.
37
+ */
38
+ export class ExecAttachment {
39
+ exec;
40
+ channel;
41
+ options;
42
+ abort = new AbortController();
43
+ done;
44
+ constructor(exec, channel, options) {
45
+ this.exec = exec;
46
+ this.channel = channel;
47
+ this.options = options;
48
+ this.done = this.run().catch((error) => { this.options.log?.(`exec ${options.id}: attachment failed: ${error instanceof Error ? error.message : String(error)}`); });
49
+ }
50
+ stop() { this.abort.abort(); }
51
+ get stopped() { return this.abort.signal.aborted; }
52
+ async run() {
53
+ const { exec } = this;
54
+ if (exec.wire?.streaming !== false)
55
+ await this.stream();
56
+ if (this.stopped)
57
+ return;
58
+ const outcome = await Promise.race([exec.outcome, new Promise((resolve) => this.abort.signal.addEventListener('abort', () => resolve(null), { once: true }))]);
59
+ if (outcome === null || this.stopped)
60
+ return;
61
+ const id = this.options.id;
62
+ this.channel.send({ t: 'exec_status', id, state: 'exited', headOffset: exec.finalHead, committedOffset: exec.committedOffset });
63
+ this.channel.send(this.options.exitFrame(outcome));
64
+ }
65
+ /** Waits for more records: a progress signal from the exec's own follower, a stop, or the idle poll. */
66
+ wait(ms) {
67
+ return new Promise((resolve) => {
68
+ const unsubscribe = this.exec.onProgress(() => { unsubscribe(); resolve(); });
69
+ void sleep(ms, this.abort.signal).then(() => { unsubscribe(); resolve(); });
70
+ });
71
+ }
72
+ async stream() {
73
+ const { exec, channel } = this;
74
+ const { id, fromOffset } = this.options;
75
+ const text = new ExecWireText();
76
+ let cursor = exec.commitFloor + 1;
77
+ const hold = exec.hold(cursor);
78
+ try {
79
+ while (!this.stopped) {
80
+ const exitAt = exec.exitRecordOffset;
81
+ if (exitAt !== undefined && cursor > exitAt)
82
+ return;
83
+ let page;
84
+ try {
85
+ page = await exec.read(cursor, PAGE_RECORDS);
86
+ }
87
+ catch (error) {
88
+ if (exec.finished)
89
+ return; // deleted, reclaimed or unreachable: the outcome says so
90
+ this.options.log?.(`exec ${id}: read failed: ${error instanceof Error ? error.message : String(error)}`);
91
+ await this.wait(RETRY_MS);
92
+ continue;
93
+ }
94
+ if (this.stopped)
95
+ return;
96
+ if (page.records.length === 0) {
97
+ if (exec.finished)
98
+ return;
99
+ await this.wait(this.options.idleMs ?? IDLE_POLL_MS);
100
+ continue;
101
+ }
102
+ for (const record of page.records) {
103
+ if (record.o < cursor)
104
+ continue;
105
+ cursor = record.o + 1;
106
+ hold.at = cursor;
107
+ if (record.k === 'exit')
108
+ return;
109
+ if (record.k !== 'out' && record.k !== 'err')
110
+ continue;
111
+ const stream = record.k === 'out' ? 'stdout' : 'stderr';
112
+ const chunk = text.push(stream, record.so, Buffer.from(record.b, 'base64'));
113
+ if (!chunk || record.o < fromOffset)
114
+ continue;
115
+ await waitForWindow(() => channel.bufferedAmount(), this.abort.signal);
116
+ if (this.stopped)
117
+ return;
118
+ channel.send({ t: 'exec_output', id, stream, chunk, offset: record.o, recvAtMs: record.t });
119
+ }
120
+ }
121
+ }
122
+ finally {
123
+ exec.unhold(hold);
124
+ }
125
+ }
126
+ }
@@ -0,0 +1,40 @@
1
+ // What the daemon decides about one `exec_request` before anything runs (spec §4.2 "daemon (policy)" column; analysis E §6.3–6.4):
2
+ // the exact argv, the complete environment and the absolute deadline. Shared by the durable (keeper-terminal) path and the
3
+ // in-process fallback, so both run the same command line in the same environment.
4
+ import path from 'node:path';
5
+ /**
6
+ * `[shell, '-lc', command]`, element by element what the daemon has always spawned (`spawn(req.shell, ['-lc', req.command])`):
7
+ * a login, non-interactive shell of the user's choice reading the command string exactly. Never wrapped (`sh -c`, `; echo $?`, …):
8
+ * any wrapping would go through the user's shell dialect (zsh EQUALS, fish quoting).
9
+ */
10
+ export function execArgv(req) {
11
+ return [req.shell, '-lc', req.command];
12
+ }
13
+ /** The daemon's credential for its own server: never visible to a command (commands/workstation.ts drops it already; again here). */
14
+ export const ACCESS_TOKEN_ENV = 'AXOM_ACCESS_TOKEN';
15
+ /**
16
+ * The complete environment of the command: the daemon's environment without the access token, then the request's `env`, then
17
+ * `pathPrepend` in front of PATH (exactly as the daemon always did). keeper-terminal gets this whole map and never falls back to its
18
+ * own environment (under a systemd transient unit that would be the user manager's, frozen at the keeper's start).
19
+ */
20
+ export function execEnvironment(daemonEnv, req) {
21
+ const env = {};
22
+ for (const [name, value] of Object.entries(daemonEnv))
23
+ if (value !== undefined && name !== ACCESS_TOKEN_ENV)
24
+ env[name] = value;
25
+ Object.assign(env, req.env);
26
+ if (req.pathPrepend.length > 0)
27
+ env.PATH = [...req.pathPrepend, env.PATH ?? ''].filter(Boolean).join(path.delimiter);
28
+ return env;
29
+ }
30
+ /**
31
+ * The absolute deadline, from `timeoutSeconds` and the DAEMON's clock at the moment it first received the request (never the
32
+ * server's clock). No timeout (absent, null, 0 or negative: today's rule) means no deadline.
33
+ */
34
+ export function execDeadline(req, receivedAtMs) {
35
+ return req.timeoutSeconds && req.timeoutSeconds > 0 ? receivedAtMs + req.timeoutSeconds * 1000 : undefined;
36
+ }
37
+ /** keeper-terminal wants an absolute cwd; a relative one resolves against the daemon's cwd, as `spawn` always resolved it. */
38
+ export function execCwd(req) {
39
+ return path.resolve(req.cwd || '.');
40
+ }