sliccy 3.5.5 → 3.7.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 (222) hide show
  1. package/README.md +1 -2
  2. package/dist/node-server/_cloud_core/src/errors.d.ts +14 -0
  3. package/dist/node-server/_cloud_core/src/errors.d.ts.map +1 -0
  4. package/dist/node-server/_cloud_core/src/errors.js +13 -0
  5. package/dist/node-server/_cloud_core/src/index.d.ts +19 -0
  6. package/dist/node-server/_cloud_core/src/index.d.ts.map +1 -0
  7. package/dist/node-server/_cloud_core/src/index.js +14 -0
  8. package/dist/node-server/_cloud_core/src/operations/kill.d.ts +18 -0
  9. package/dist/node-server/_cloud_core/src/operations/kill.d.ts.map +1 -0
  10. package/dist/node-server/_cloud_core/src/operations/kill.js +32 -0
  11. package/dist/node-server/_cloud_core/src/operations/list.d.ts +25 -0
  12. package/dist/node-server/_cloud_core/src/operations/list.d.ts.map +1 -0
  13. package/dist/node-server/_cloud_core/src/operations/list.js +145 -0
  14. package/dist/node-server/_cloud_core/src/operations/pause.d.ts +15 -0
  15. package/dist/node-server/_cloud_core/src/operations/pause.d.ts.map +1 -0
  16. package/dist/node-server/_cloud_core/src/operations/pause.js +27 -0
  17. package/dist/node-server/_cloud_core/src/operations/resume.d.ts +22 -0
  18. package/dist/node-server/_cloud_core/src/operations/resume.d.ts.map +1 -0
  19. package/dist/node-server/_cloud_core/src/operations/resume.js +86 -0
  20. package/dist/node-server/_cloud_core/src/operations/start.d.ts +67 -0
  21. package/dist/node-server/_cloud_core/src/operations/start.d.ts.map +1 -0
  22. package/dist/node-server/_cloud_core/src/operations/start.js +228 -0
  23. package/dist/node-server/_cloud_core/src/polling.d.ts +18 -0
  24. package/dist/node-server/_cloud_core/src/polling.d.ts.map +1 -0
  25. package/dist/node-server/_cloud_core/src/polling.js +79 -0
  26. package/dist/node-server/_cloud_core/src/registry.d.ts +27 -0
  27. package/dist/node-server/_cloud_core/src/registry.d.ts.map +1 -0
  28. package/dist/node-server/_cloud_core/src/registry.js +1 -0
  29. package/dist/node-server/_cloud_core/src/secrets-filter.d.ts +2 -0
  30. package/dist/node-server/_cloud_core/src/secrets-filter.d.ts.map +1 -0
  31. package/dist/node-server/_cloud_core/src/secrets-filter.js +17 -0
  32. package/dist/node-server/_cloud_core/src/substrate-factory.d.ts +3 -0
  33. package/dist/node-server/_cloud_core/src/substrate-factory.d.ts.map +1 -0
  34. package/dist/node-server/_cloud_core/src/substrate-factory.js +6 -0
  35. package/dist/node-server/_cloud_core/src/substrate.d.ts +53 -0
  36. package/dist/node-server/_cloud_core/src/substrate.d.ts.map +1 -0
  37. package/dist/node-server/_cloud_core/src/substrate.js +1 -0
  38. package/dist/node-server/_cloud_core/src/substrates/e2b.d.ts +3 -0
  39. package/dist/node-server/_cloud_core/src/substrates/e2b.d.ts.map +1 -0
  40. package/dist/node-server/_cloud_core/src/substrates/e2b.js +98 -0
  41. package/dist/node-server/_cloud_core/src/types.d.ts +94 -0
  42. package/dist/node-server/_cloud_core/src/types.d.ts.map +1 -0
  43. package/dist/node-server/_cloud_core/src/types.js +3 -0
  44. package/dist/node-server/_cloud_core/tests/fixtures/fake-substrate.d.ts +39 -0
  45. package/dist/node-server/_cloud_core/tests/fixtures/fake-substrate.d.ts.map +1 -0
  46. package/dist/node-server/_cloud_core/tests/fixtures/fake-substrate.js +75 -0
  47. package/dist/node-server/_cloud_core/tests/fixtures/index.d.ts +4 -0
  48. package/dist/node-server/_cloud_core/tests/fixtures/index.d.ts.map +1 -0
  49. package/dist/node-server/_cloud_core/tests/fixtures/index.js +2 -0
  50. package/dist/node-server/_cloud_core/tests/fixtures/mem-registry.d.ts +10 -0
  51. package/dist/node-server/_cloud_core/tests/fixtures/mem-registry.d.ts.map +1 -0
  52. package/dist/node-server/_cloud_core/tests/fixtures/mem-registry.js +25 -0
  53. package/dist/node-server/_cloud_core/tests/kill.test.d.ts +2 -0
  54. package/dist/node-server/_cloud_core/tests/kill.test.d.ts.map +1 -0
  55. package/dist/node-server/_cloud_core/tests/kill.test.js +164 -0
  56. package/dist/node-server/_cloud_core/tests/list.test.d.ts +2 -0
  57. package/dist/node-server/_cloud_core/tests/list.test.d.ts.map +1 -0
  58. package/dist/node-server/_cloud_core/tests/list.test.js +300 -0
  59. package/dist/node-server/_cloud_core/tests/pause.test.d.ts +2 -0
  60. package/dist/node-server/_cloud_core/tests/pause.test.d.ts.map +1 -0
  61. package/dist/node-server/_cloud_core/tests/pause.test.js +167 -0
  62. package/dist/node-server/_cloud_core/tests/resume.test.d.ts +2 -0
  63. package/dist/node-server/_cloud_core/tests/resume.test.d.ts.map +1 -0
  64. package/dist/node-server/_cloud_core/tests/resume.test.js +203 -0
  65. package/dist/node-server/_cloud_core/tests/secrets-filter.test.d.ts +2 -0
  66. package/dist/node-server/_cloud_core/tests/secrets-filter.test.d.ts.map +1 -0
  67. package/dist/node-server/_cloud_core/tests/secrets-filter.test.js +30 -0
  68. package/dist/node-server/_cloud_core/tests/start.test.d.ts +2 -0
  69. package/dist/node-server/_cloud_core/tests/start.test.d.ts.map +1 -0
  70. package/dist/node-server/_cloud_core/tests/start.test.js +513 -0
  71. package/dist/node-server/chrome-launch.d.ts +1 -0
  72. package/dist/node-server/chrome-launch.js +3 -0
  73. package/dist/node-server/cloud/dispatch.d.ts +34 -0
  74. package/dist/node-server/cloud/dispatch.js +79 -0
  75. package/dist/node-server/cloud/kill.d.ts +12 -0
  76. package/dist/node-server/cloud/kill.js +11 -0
  77. package/dist/node-server/cloud/list.d.ts +6 -0
  78. package/dist/node-server/cloud/list.js +6 -0
  79. package/dist/node-server/cloud/pause.d.ts +7 -0
  80. package/dist/node-server/cloud/pause.js +6 -0
  81. package/dist/node-server/cloud/registry-file.d.ts +13 -0
  82. package/dist/node-server/cloud/registry-file.js +85 -0
  83. package/dist/node-server/cloud/resume.d.ts +11 -0
  84. package/dist/node-server/cloud/resume.js +17 -0
  85. package/dist/node-server/cloud/start.d.ts +16 -0
  86. package/dist/node-server/cloud/start.js +49 -0
  87. package/dist/node-server/cloud-status.d.ts +11 -0
  88. package/dist/node-server/cloud-status.js +49 -0
  89. package/dist/node-server/hosted-bootstrap.d.ts +21 -0
  90. package/dist/node-server/hosted-bootstrap.js +14 -0
  91. package/dist/node-server/index.js +157 -3
  92. package/dist/node-server/leader-restart.d.ts +29 -0
  93. package/dist/node-server/leader-restart.js +146 -0
  94. package/dist/node-server/runtime-flags.d.ts +1 -0
  95. package/dist/node-server/runtime-flags.js +6 -0
  96. package/dist/ui/assets/{adobe-DSSPywlx.js → adobe-Bb9Koo41.js} +1 -1
  97. package/dist/ui/assets/adobe-C83SQyit.js +2 -0
  98. package/dist/ui/assets/agent-bridge-CqFAtXhQ.js +1 -0
  99. package/dist/ui/assets/{agent-message-to-chat-CsyFcZ2w.js → agent-message-to-chat-B5maV2R5.js} +1 -1
  100. package/dist/ui/assets/{anthropic-DdObQ2i-.js → anthropic-B_W-Zf1F.js} +1 -1
  101. package/dist/ui/assets/{anthropic-04L_IqQ4.js → anthropic-DFqMAkaW.js} +1 -1
  102. package/dist/ui/assets/{apps-BBc8G_er.js → apps-CQcu3SPP.js} +1 -1
  103. package/dist/ui/assets/{azure-openai-maMzaMwe.js → azure-openai-N2PiMhaz.js} +1 -1
  104. package/dist/ui/assets/azure-openai-miFUu6Hv.js +1 -0
  105. package/dist/ui/assets/azure-openai-responses-DOyJjHhU.js +1 -0
  106. package/dist/ui/assets/{azure-openai-responses-Cd0P_ssa.js → azure-openai-responses-k5E1atrw.js} +1 -1
  107. package/dist/ui/assets/{bsh-watchdog-C8BJAFc3.js → bsh-watchdog-CqkW32Q7.js} +1 -1
  108. package/dist/ui/assets/{cdp-DMk0S7sC.js → cdp-DRnArGXe.js} +3 -3
  109. package/dist/ui/assets/cloud-CCHD45tb.js +1 -0
  110. package/dist/ui/assets/cloud-DyAca2cv.css +1 -0
  111. package/dist/ui/assets/cost-command-Qd6vdo4-.js +1 -0
  112. package/dist/ui/assets/{dist-cK1g1pHF.js → dist-ChvbMSOY.js} +1 -1
  113. package/dist/ui/assets/{dist-BTGs16AV.js → dist-CltZJzbd.js} +1 -1
  114. package/dist/ui/assets/{dist-BcBxL8nL.js → dist-cZSF0917.js} +1 -1
  115. package/dist/ui/assets/{dist-Bgcuvc8h.js → dist-ljtB3O-J.js} +1 -1
  116. package/dist/ui/assets/{es-Bjf1BIVF.js → es-HXRnKgrk.js} +1 -1
  117. package/dist/ui/assets/follower-sprinkle-bridge-_PGckvHb.js +1 -0
  118. package/dist/ui/assets/{github-q1jHC2aO.js → github-BENqO11g.js} +1 -1
  119. package/dist/ui/assets/github-C-Z3n5Xc.js +2 -0
  120. package/dist/ui/assets/google-7RDpSFjr.js +1 -0
  121. package/dist/ui/assets/{google-okAFtSPB.js → google-BaN03Ews.js} +1 -1
  122. package/dist/ui/assets/{google-shared-O-0R1H53.js → google-shared-B50LC94Y.js} +1 -1
  123. package/dist/ui/assets/google-shared-DQIr6_u6.js +11 -0
  124. package/dist/ui/assets/{google-vertex-BkZigHmB.js → google-vertex-DmQqHOd3.js} +1 -1
  125. package/dist/ui/assets/google-vertex-fe0XTrlp.js +1 -0
  126. package/dist/ui/assets/{intercepted-oauth-BbYCzrsi.js → intercepted-oauth-DZunMpOb.js} +1 -1
  127. package/dist/ui/assets/{kernel-worker-7oVJDvYj.js → kernel-worker-C5VWVo3p.js} +915 -915
  128. package/dist/ui/assets/{lick-ws-bridge-Cre3RRwL.js → lick-ws-bridge-BlpI5Vfh.js} +1 -1
  129. package/dist/ui/assets/{local-llm-DAe8mBkI.js → local-llm-B9x9dHMp.js} +1 -1
  130. package/dist/ui/assets/magick-wasm-DTuiyppo.js +1 -0
  131. package/dist/ui/assets/{index-BdDYVKjf.js → main-CGBwb-Z7.js} +85 -84
  132. package/dist/ui/assets/{mistral-BgP2Mhzf.js → mistral-Bm98WJNR.js} +1 -1
  133. package/dist/ui/assets/{mistral-DVuMIs98.js → mistral-DNRus666.js} +1 -1
  134. package/dist/ui/assets/modulepreload-polyfill-wMinxHhO.js +1 -0
  135. package/dist/ui/assets/nuke-command-CC3imLyj.js +1 -0
  136. package/dist/ui/assets/{oauth-D12YL9GU.js → oauth-DBX2TVKl.js} +1 -1
  137. package/dist/ui/assets/oauth-bootstrap-DOOX1I7K.js +2 -0
  138. package/dist/ui/assets/oauth-service-Bv4EZbHs.js +1 -0
  139. package/dist/ui/assets/{oauth-service-Copu_4SG.js → oauth-service-v9k7zmDr.js} +1 -1
  140. package/dist/ui/assets/offscreen-client-C8dacNXH.js +1 -0
  141. package/dist/ui/assets/onboarding-orchestrator-C_kYnC4g.js +1 -0
  142. package/dist/ui/assets/{openai-codex-responses-BAPqEmsF.js → openai-codex-responses-DQIglX1K.js} +1 -1
  143. package/dist/ui/assets/{openai-codex-responses-B7pudFjp.js → openai-codex-responses-DW1a9bCj.js} +1 -1
  144. package/dist/ui/assets/openai-completions-ChQDZA6E.js +5 -0
  145. package/dist/ui/assets/{openai-responses-CtIsFZKY.js → openai-responses-CY2Kt17O.js} +1 -1
  146. package/dist/ui/assets/openai-responses-Pm8J-HuA.js +1 -0
  147. package/dist/ui/assets/{openai-responses-shared-CqmlDcXz.js → openai-responses-shared-CVjR8F2I.js} +1 -1
  148. package/dist/ui/assets/{openai-responses-shared-DxBvmwvL.js → openai-responses-shared-DsbHT7ZR.js} +1 -1
  149. package/dist/ui/assets/{openrouter-CdadiGtx.js → openrouter-C17Qgp_a.js} +1 -1
  150. package/dist/ui/assets/openrouter-YvEDVJjZ.js +1 -0
  151. package/dist/ui/assets/panel-rpc-handlers-D3TvKTBJ.js +1 -0
  152. package/dist/ui/assets/{provider-DcrxGcMH.js → provider-CVQ1-hiX.js} +2 -2
  153. package/dist/ui/assets/{provider-DXK8JUs0.js → provider-DQdgU2cB.js} +1 -1
  154. package/dist/ui/assets/provider-store-access-HJH7Oiu7.js +1 -0
  155. package/dist/ui/assets/provider-store-access-R_T_zm3J.js +1 -0
  156. package/dist/ui/assets/proxied-fetch-BD4Aw_98.js +1 -0
  157. package/dist/ui/assets/{pyodide-DlSYVqmj.js → pyodide-DjwZMHCM.js} +2 -2
  158. package/dist/ui/assets/{remote-terminal-view-PnTEWD7p.js → remote-terminal-view-BY0dldZw.js} +1 -1
  159. package/dist/ui/assets/secret-env-CRC281WY.js +1 -0
  160. package/dist/ui/assets/slicc-editor-DWlyJ8F2.js +12 -0
  161. package/dist/ui/assets/{spawn-CfeAB8A4.js → spawn-7IvlkEig.js} +1 -1
  162. package/dist/ui/assets/{sql-wasm-BVmSEJv3.js → sql-wasm-CwnEMigK.js} +1 -1
  163. package/dist/ui/assets/{store-D-IKH6-w.js → store-j2Druu0N.js} +1 -1
  164. package/dist/ui/assets/tray-leave-runtime-Bn8j6E27.js +1 -0
  165. package/dist/ui/assets/{upgrade-detection-CpKdzfSv.js → upgrade-detection-3mhOWPt2.js} +1 -1
  166. package/dist/ui/assets/{xai-grok-DwtbUE6F.js → xai-grok-Che7ONVU.js} +1 -1
  167. package/dist/ui/assets/xai-grok-Doi4Og_5.js +1 -0
  168. package/dist/ui/assets/{xai-grok-sanitize-DtMFuPGU.js → xai-grok-sanitize-C7TgWvwD.js} +1 -1
  169. package/dist/ui/electron-overlay-entry.js +9 -9
  170. package/dist/ui/index.html +3 -2
  171. package/dist/ui/llm-proxy-sw.js +1 -1
  172. package/dist/ui/packages/webapp/cloud/index.html +38 -0
  173. package/dist/ui/packages/webapp/index.html +3 -2
  174. package/package.json +9 -7
  175. package/dist/ui/assets/adobe-DCsfRQn2.js +0 -2
  176. package/dist/ui/assets/agent-bridge-DaJ_nmW3.js +0 -1
  177. package/dist/ui/assets/azure-openai-DzGirHIb.js +0 -1
  178. package/dist/ui/assets/azure-openai-responses-CjukGNgz.js +0 -1
  179. package/dist/ui/assets/cost-command-BtJx6Gwp.js +0 -1
  180. package/dist/ui/assets/follower-sprinkle-bridge-BFLnAii4.js +0 -1
  181. package/dist/ui/assets/github-CcyS4zY-.js +0 -2
  182. package/dist/ui/assets/google-Cgd9E3cB.js +0 -1
  183. package/dist/ui/assets/google-shared-Dz7dBXHI.js +0 -11
  184. package/dist/ui/assets/google-vertex-BSk7Kd0k.js +0 -1
  185. package/dist/ui/assets/magick-wasm-C1izt9i7.js +0 -1
  186. package/dist/ui/assets/nuke-command-BbxGOoiP.js +0 -1
  187. package/dist/ui/assets/oauth-bootstrap-BtJmY6M6.js +0 -2
  188. package/dist/ui/assets/oauth-service-DJF7cZo7.js +0 -1
  189. package/dist/ui/assets/offscreen-client-Cz7pdJA-.js +0 -1
  190. package/dist/ui/assets/onboarding-orchestrator-BKXIEudN.js +0 -1
  191. package/dist/ui/assets/openai-completions-iJ14N4Sw.js +0 -5
  192. package/dist/ui/assets/openai-responses-C4kJ_gQ1.js +0 -1
  193. package/dist/ui/assets/openrouter-CPoeAmgd.js +0 -1
  194. package/dist/ui/assets/panel-rpc-handlers-DbHRM59x.js +0 -1
  195. package/dist/ui/assets/provider-store-access-BjvfvyfX.js +0 -1
  196. package/dist/ui/assets/provider-store-access-auxlQIvP.js +0 -1
  197. package/dist/ui/assets/proxied-fetch-Zr3psZ6-.js +0 -1
  198. package/dist/ui/assets/secret-env-YSczATtn.js +0 -1
  199. package/dist/ui/assets/slicc-editor-BwZ-JdjT.js +0 -12
  200. package/dist/ui/assets/tray-leave-runtime-D9Wr8bCF.js +0 -1
  201. package/dist/ui/assets/xai-grok-CGPoHWCQ.js +0 -1
  202. /package/dist/ui/assets/{active-transport-Cu6hvJXz.js → active-transport-DHcaBd4j.js} +0 -0
  203. /package/dist/ui/assets/{addon-fit-D2MIn2bh.js → addon-fit-CUt9lrQO.js} +0 -0
  204. /package/dist/ui/assets/{azure-ai-foundry-DVqxYCDH.js → azure-ai-foundry-B4QrVklT.js} +0 -0
  205. /package/dist/ui/assets/{chat-fixture-C0wxG6yH.js → chat-fixture-ChGRNFda.js} +0 -0
  206. /package/dist/ui/assets/{dist-BNe7ZIzA.js → dist-CZcDRTma.js} +0 -0
  207. /package/dist/ui/assets/{dist-4mA3RMrN.js → dist-D0kTaNET.js} +0 -0
  208. /package/dist/ui/assets/{git-config-47_ySgKl.js → git-config-DcQbkikl.js} +0 -0
  209. /package/dist/ui/assets/{github-copilot-headers-CTUP_cqn.js → github-copilot-headers-C5CocKfn.js} +0 -0
  210. /package/dist/ui/assets/{global-db-CMspJ2t8.js → global-db-DL3jdM9H.js} +0 -0
  211. /package/dist/ui/assets/{hash-B9Dtr1VK.js → hash-iitWbNjK.js} +0 -0
  212. /package/dist/ui/assets/{headers-AeYLn7L4.js → headers-qDMOQQGF.js} +0 -0
  213. /package/dist/ui/assets/{index-CvlDeETm.css → main-CvlDeETm.css} +0 -0
  214. /package/dist/ui/assets/{openai-Bf1npfRy.js → openai-BR_xAflc.js} +0 -0
  215. /package/dist/ui/assets/{page-storage-sync-3GLxly8J.js → page-storage-sync-sv2ogNKh.js} +0 -0
  216. /package/dist/ui/assets/{rum-CY2gBT8x.js → rum-z5wz4Dnj.js} +0 -0
  217. /package/dist/ui/assets/{sanitize-unicode-h0KEBmEw.js → sanitize-unicode-B1z_Y4Dq.js} +0 -0
  218. /package/dist/ui/assets/{sprinkle-bridge-channel-DAHSl7rf.js → sprinkle-bridge-channel-ChD0T07C.js} +0 -0
  219. /package/dist/ui/assets/{src-BQRb5emh.js → src-DRmQ1wr-.js} +0 -0
  220. /package/dist/ui/assets/{xai-grok-errors-DQQRqci0.js → xai-grok-errors-BdY43UIn.js} +0 -0
  221. /package/dist/ui/assets/{xai-grok-models-D7n8nh39.js → xai-grok-models-C9MIa-Aj.js} +0 -0
  222. /package/dist/ui/assets/{xterm-4j9yS4Tj.js → xterm-VndicwFp.js} +0 -0
@@ -0,0 +1,79 @@
1
+ const VALID_SUBCOMMANDS = ['start', 'list', 'pause', 'resume', 'kill'];
2
+ export function parseCloudArgs(argv) {
3
+ if (argv.includes('--hosted') && argv.includes('--cloud')) {
4
+ throw new Error('--cloud and --hosted are mutually exclusive');
5
+ }
6
+ const cloudIdx = argv.indexOf('--cloud');
7
+ if (cloudIdx === -1)
8
+ return null;
9
+ const sub = argv[cloudIdx + 1];
10
+ if (!sub || !VALID_SUBCOMMANDS.includes(sub)) {
11
+ throw new Error(`unknown subcommand: ${sub ?? '(none)'} (expected one of: ${VALID_SUBCOMMANDS.join(', ')})`);
12
+ }
13
+ const rest = argv.slice(cloudIdx + 2);
14
+ const baseArgs = {
15
+ substrate: 'e2b',
16
+ };
17
+ let i = 0;
18
+ while (i < rest.length) {
19
+ const a = rest[i];
20
+ if (a === '--name') {
21
+ baseArgs.name = rest[++i];
22
+ }
23
+ else if (a === '--env-file') {
24
+ baseArgs.envFile = rest[++i];
25
+ }
26
+ else if (a === '--substrate') {
27
+ const v = rest[++i];
28
+ if (v !== 'e2b')
29
+ throw new Error(`unsupported substrate: ${v} (MVP only supports 'e2b')`);
30
+ baseArgs.substrate = v;
31
+ }
32
+ else if (!a.startsWith('--') &&
33
+ !baseArgs.query &&
34
+ (sub === 'pause' || sub === 'resume' || sub === 'kill')) {
35
+ baseArgs.query = a;
36
+ }
37
+ else {
38
+ throw new Error(`unrecognized arg: ${a}`);
39
+ }
40
+ i++;
41
+ }
42
+ // Build discriminated union based on subcommand
43
+ switch (sub) {
44
+ case 'start':
45
+ return {
46
+ subcommand: 'start',
47
+ args: {
48
+ substrate: baseArgs.substrate,
49
+ name: baseArgs.name,
50
+ envFile: baseArgs.envFile,
51
+ },
52
+ };
53
+ case 'list':
54
+ return { subcommand: 'list', args: { substrate: baseArgs.substrate } };
55
+ case 'pause':
56
+ case 'kill':
57
+ if (!baseArgs.query) {
58
+ throw new Error(`${sub} requires a query argument (sandbox ID or name)`);
59
+ }
60
+ return {
61
+ subcommand: sub,
62
+ args: { substrate: baseArgs.substrate, query: baseArgs.query },
63
+ };
64
+ case 'resume':
65
+ if (!baseArgs.query) {
66
+ throw new Error(`${sub} requires a query argument (sandbox ID or name)`);
67
+ }
68
+ return {
69
+ subcommand: 'resume',
70
+ args: {
71
+ substrate: baseArgs.substrate,
72
+ query: baseArgs.query,
73
+ envFile: baseArgs.envFile,
74
+ },
75
+ };
76
+ default:
77
+ throw new Error(`unknown subcommand: ${sub}`);
78
+ }
79
+ }
@@ -0,0 +1,12 @@
1
+ import { type SandboxSubstrate } from '../_cloud_core/src/index.js';
2
+ export interface RunKillOpts {
3
+ substrate: SandboxSubstrate;
4
+ registryPath: string;
5
+ query: string;
6
+ }
7
+ /**
8
+ * Thin wrapper over killCone from @slicc/cloud-core.
9
+ * Adapts the cloud-core interface to the node-server's file-backed registry.
10
+ * Returns void for backward compatibility with existing callers.
11
+ */
12
+ export declare function runKill(opts: RunKillOpts): Promise<void>;
@@ -0,0 +1,11 @@
1
+ import { killCone } from '../_cloud_core/src/index.js';
2
+ import { FileRegistry } from './registry-file.js';
3
+ /**
4
+ * Thin wrapper over killCone from @slicc/cloud-core.
5
+ * Adapts the cloud-core interface to the node-server's file-backed registry.
6
+ * Returns void for backward compatibility with existing callers.
7
+ */
8
+ export async function runKill(opts) {
9
+ const registry = new FileRegistry(opts.registryPath);
10
+ await killCone({ substrate: opts.substrate, registry }, opts.query);
11
+ }
@@ -0,0 +1,6 @@
1
+ import { type ConeEntry, type SandboxSubstrate } from '../_cloud_core/src/index.js';
2
+ export interface RunListOpts {
3
+ substrate: SandboxSubstrate;
4
+ registryPath: string;
5
+ }
6
+ export declare function runList(opts: RunListOpts): Promise<ConeEntry[]>;
@@ -0,0 +1,6 @@
1
+ import { listCones } from '../_cloud_core/src/index.js';
2
+ import { FileRegistry } from './registry-file.js';
3
+ export async function runList(opts) {
4
+ const registry = new FileRegistry(opts.registryPath);
5
+ return listCones({ substrate: opts.substrate, registry });
6
+ }
@@ -0,0 +1,7 @@
1
+ import { type SandboxSubstrate } from '../_cloud_core/src/index.js';
2
+ export interface RunPauseOpts {
3
+ substrate: SandboxSubstrate;
4
+ registryPath: string;
5
+ query: string;
6
+ }
7
+ export declare function runPause(opts: RunPauseOpts): Promise<void>;
@@ -0,0 +1,6 @@
1
+ import { pauseCone } from '../_cloud_core/src/index.js';
2
+ import { FileRegistry } from './registry-file.js';
3
+ export async function runPause(opts) {
4
+ const registry = new FileRegistry(opts.registryPath);
5
+ return pauseCone({ substrate: opts.substrate, registry }, opts.query);
6
+ }
@@ -0,0 +1,13 @@
1
+ import type { ConeEntry, Registry } from '../_cloud_core/src/index.js';
2
+ export declare class FileRegistry implements Registry {
3
+ private readonly filePath;
4
+ constructor(filePath: string);
5
+ static defaultPath(): string;
6
+ list(): Promise<ConeEntry[]>;
7
+ append(entry: ConeEntry): Promise<void>;
8
+ update(sandboxId: string, patch: Partial<ConeEntry>): Promise<void>;
9
+ remove(sandboxId: string): Promise<void>;
10
+ findByNameOrId(query: string): Promise<ConeEntry | null>;
11
+ private read;
12
+ private write;
13
+ }
@@ -0,0 +1,85 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ function isConeEntry(x) {
4
+ if (typeof x !== 'object' || x === null)
5
+ return false;
6
+ const e = x;
7
+ return (typeof e.substrate === 'string' &&
8
+ typeof e.sandboxId === 'string' &&
9
+ typeof e.createdAt === 'string' &&
10
+ typeof e.joinUrl === 'string' &&
11
+ typeof e.lastSeen === 'string' &&
12
+ typeof e.state === 'string' &&
13
+ (e.state === 'running' || e.state === 'paused' || e.state === 'dead' || e.state === 'reserved'));
14
+ }
15
+ export class FileRegistry {
16
+ filePath;
17
+ constructor(filePath) {
18
+ this.filePath = filePath;
19
+ }
20
+ static defaultPath() {
21
+ const home = process.env['HOME'] ?? process.env['USERPROFILE'] ?? '.';
22
+ return path.join(home, '.slicc', 'cloud-sessions.json');
23
+ }
24
+ async list() {
25
+ const data = await this.read();
26
+ return data.sessions;
27
+ }
28
+ async append(entry) {
29
+ const data = await this.read();
30
+ // UPSERT semantics: filter out existing sandboxId, then push the new entry
31
+ data.sessions = data.sessions.filter((s) => s.sandboxId !== entry.sandboxId);
32
+ data.sessions.push(entry);
33
+ await this.write(data);
34
+ }
35
+ async update(sandboxId, patch) {
36
+ const data = await this.read();
37
+ const idx = data.sessions.findIndex((s) => s.sandboxId === sandboxId);
38
+ if (idx === -1) {
39
+ throw new Error(`entry not found: ${sandboxId}`);
40
+ }
41
+ data.sessions[idx] = { ...data.sessions[idx], ...patch, sandboxId };
42
+ await this.write(data);
43
+ }
44
+ async remove(sandboxId) {
45
+ const data = await this.read();
46
+ data.sessions = data.sessions.filter((s) => s.sandboxId !== sandboxId);
47
+ await this.write(data);
48
+ }
49
+ async findByNameOrId(query) {
50
+ const data = await this.read();
51
+ return (data.sessions.find((s) => s.sandboxId === query) ??
52
+ data.sessions.find((s) => s.name === query) ??
53
+ null);
54
+ }
55
+ async read() {
56
+ let raw;
57
+ try {
58
+ raw = JSON.parse(await fs.readFile(this.filePath, 'utf-8'));
59
+ }
60
+ catch (err) {
61
+ if (err.code === 'ENOENT')
62
+ return { sessions: [] };
63
+ throw err;
64
+ }
65
+ if (typeof raw !== 'object' ||
66
+ raw === null ||
67
+ !Array.isArray(raw.sessions)) {
68
+ console.warn('cloud-sessions.json is malformed; treating as empty', this.filePath);
69
+ return { sessions: [] };
70
+ }
71
+ const candidates = raw.sessions;
72
+ const sessions = [];
73
+ for (const c of candidates) {
74
+ if (isConeEntry(c))
75
+ sessions.push(c);
76
+ else
77
+ console.warn('skipping malformed cloud-sessions entry', c);
78
+ }
79
+ return { sessions };
80
+ }
81
+ async write(data) {
82
+ await fs.mkdir(path.dirname(this.filePath), { recursive: true });
83
+ await fs.writeFile(this.filePath, JSON.stringify(data, null, 2));
84
+ }
85
+ }
@@ -0,0 +1,11 @@
1
+ import { type ResumeResult, type SandboxSubstrate } from '../_cloud_core/src/index.js';
2
+ export interface RunResumeOpts {
3
+ substrate: SandboxSubstrate;
4
+ envFilePath: string;
5
+ registryPath: string;
6
+ query: string;
7
+ localSliccVersion: string;
8
+ pollIntervalMs?: number;
9
+ pollTimeoutMs?: number;
10
+ }
11
+ export declare function runResume(opts: RunResumeOpts): Promise<ResumeResult>;
@@ -0,0 +1,17 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { resumeCone } from '../_cloud_core/src/index.js';
3
+ import { FileRegistry } from './registry-file.js';
4
+ export async function runResume(opts) {
5
+ // Refresh on resume so cones paused for >24h pick up a freshly-issued token
6
+ // from the local secrets.env. This was a pre-existing CLI gap — resume would
7
+ // succeed but Adobe LLM calls would 401 on expired tokens.
8
+ const envContents = await fs.readFile(opts.envFilePath, 'utf-8');
9
+ const registry = new FileRegistry(opts.registryPath);
10
+ return resumeCone({ substrate: opts.substrate, registry }, {
11
+ query: opts.query,
12
+ localSliccVersion: opts.localSliccVersion,
13
+ refreshSecretsContents: envContents,
14
+ pollIntervalMs: opts.pollIntervalMs,
15
+ pollTimeoutMs: opts.pollTimeoutMs,
16
+ });
17
+ }
@@ -0,0 +1,16 @@
1
+ import { type StartResult, type SandboxHandle } from '../_cloud_core/src/index.js';
2
+ import type { SandboxSubstrate } from '../_cloud_core/src/index.js';
3
+ export interface RunStartOpts {
4
+ substrate: SandboxSubstrate;
5
+ envFilePath: string;
6
+ registryPath: string;
7
+ workerBaseUrl: string;
8
+ sliccVersion: string;
9
+ template?: string;
10
+ name?: string;
11
+ pollIntervalMs?: number;
12
+ pollTimeoutMs?: number;
13
+ /** Test-only hook: invoked after substrate.create but before pollCloudStatus. */
14
+ onAfterCreate?: (handle: SandboxHandle) => Promise<void>;
15
+ }
16
+ export declare function runStart(opts: RunStartOpts): Promise<StartResult>;
@@ -0,0 +1,49 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import { startCone } from '../_cloud_core/src/index.js';
3
+ import { FileRegistry } from './registry-file.js';
4
+ /**
5
+ * Extract ADOBE_IMS_TOKEN (+ DOMAINS) from an env-file body so they can be
6
+ * injected as sandbox env vars at Sandbox.create. start.sh writes them to
7
+ * /slicc/secrets.env BEFORE node-server boots, eliminating the historical 5s
8
+ * race window where the page-side bootstrap fetch found no secrets file.
9
+ */
10
+ function extractAdobeBootstrap(envContents) {
11
+ const envs = {};
12
+ for (const line of envContents.split('\n')) {
13
+ const m = line.match(/^\s*(ADOBE_IMS_TOKEN(?:_DOMAINS)?)\s*=\s*(.*)$/);
14
+ if (m)
15
+ envs[m[1]] = m[2].trim();
16
+ }
17
+ return envs;
18
+ }
19
+ export async function runStart(opts) {
20
+ const envContents = await fs.readFile(opts.envFilePath, 'utf-8');
21
+ const adobeBootstrap = extractAdobeBootstrap(envContents);
22
+ const registry = new FileRegistry(opts.registryPath);
23
+ // If we have a test hook, wrap the substrate to inject it.
24
+ let substrate = opts.substrate;
25
+ if (opts.onAfterCreate) {
26
+ const originalCreate = substrate.create.bind(substrate);
27
+ substrate = {
28
+ ...substrate,
29
+ create: async (createOpts) => {
30
+ const handle = await originalCreate(createOpts);
31
+ await opts.onAfterCreate(handle);
32
+ return handle;
33
+ },
34
+ };
35
+ }
36
+ return startCone({ substrate, registry }, {
37
+ envContents,
38
+ envs: adobeBootstrap,
39
+ workerBaseUrl: opts.workerBaseUrl,
40
+ template: opts.template,
41
+ name: opts.name,
42
+ sliccVersion: opts.sliccVersion,
43
+ pollTimeoutMs: opts.pollTimeoutMs,
44
+ pollIntervalMs: opts.pollIntervalMs,
45
+ metadata: {
46
+ createdBy: process.env['USER'] ?? 'unknown',
47
+ },
48
+ });
49
+ }
@@ -0,0 +1,11 @@
1
+ import { type Express, type Request, type Response, type NextFunction } from 'express';
2
+ export interface CloudStatusEndpointOptions {
3
+ joinFilePath: string;
4
+ }
5
+ /**
6
+ * Reject non-loopback requests. The sandbox is a private execution boundary,
7
+ * but defense in depth: someone might wire a port-forward and we want this
8
+ * endpoint to be unreachable from the outside.
9
+ */
10
+ export declare function requireLoopback(req: Request, res: Response, next: NextFunction): void;
11
+ export declare function registerCloudStatusEndpoint(app: Express, options: CloudStatusEndpointOptions): void;
@@ -0,0 +1,49 @@
1
+ import express from 'express';
2
+ import { promises as fs } from 'node:fs';
3
+ function isCloudStatusPayload(x) {
4
+ if (typeof x !== 'object' || x === null)
5
+ return false;
6
+ const p = x;
7
+ if (typeof p.joinUrl !== 'string' || p.joinUrl.length === 0)
8
+ return false;
9
+ // Optional fields: validate type if present, but don't require.
10
+ for (const key of ['trayId', 'controllerUrl', 'webhookUrl', 'runtime', 'sliccVersion']) {
11
+ if (key in p && typeof p[key] !== 'string')
12
+ return false;
13
+ }
14
+ return true;
15
+ }
16
+ /**
17
+ * Reject non-loopback requests. The sandbox is a private execution boundary,
18
+ * but defense in depth: someone might wire a port-forward and we want this
19
+ * endpoint to be unreachable from the outside.
20
+ */
21
+ export function requireLoopback(req, res, next) {
22
+ const addr = req.socket.remoteAddress ?? '';
23
+ const isLoopback = addr === '127.0.0.1' || addr === '::1' || addr === '::ffff:127.0.0.1' || addr === 'localhost';
24
+ if (!isLoopback) {
25
+ res.status(403).json({ error: 'localhost only' });
26
+ return;
27
+ }
28
+ next();
29
+ }
30
+ export function registerCloudStatusEndpoint(app, options) {
31
+ app.post('/api/cloud-status', requireLoopback, express.json(), async (req, res) => {
32
+ if (!isCloudStatusPayload(req.body)) {
33
+ res.status(400).json({ error: 'invalid cloud-status payload' });
34
+ return;
35
+ }
36
+ const body = req.body;
37
+ const payload = {
38
+ joinUrl: body.joinUrl,
39
+ trayId: body.trayId ?? null,
40
+ controllerUrl: body.controllerUrl ?? null,
41
+ webhookUrl: body.webhookUrl ?? null,
42
+ runtime: body.runtime ?? null,
43
+ sliccVersion: body.sliccVersion ?? null,
44
+ updatedAt: new Date().toISOString(),
45
+ };
46
+ await fs.writeFile(options.joinFilePath, JSON.stringify(payload, null, 2));
47
+ res.json({ ok: true });
48
+ });
49
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Loopback-only endpoint that hands the hosted-leader page any pre-acquired
3
+ * provider credentials that were uploaded with secrets.env.
4
+ *
5
+ * Currently exposes ADOBE_IMS_TOKEN so the laptop can paste in an IMS bearer
6
+ * once (avoiding OAuth, which can't complete in headless chromium). The
7
+ * webapp's hosted-leader boot calls saveOAuthAccount with the returned token
8
+ * before any LLM call goes out.
9
+ *
10
+ * Same loopback discipline as /api/cloud-status and /api/leader-restart:
11
+ * chromium-on-localhost is the only thing that can hit it; the laptop-side
12
+ * orchestrator talks to the leader through the tray-worker tunnel, not http.
13
+ */
14
+ import type { Express } from 'express';
15
+ import type { SecretStore } from './secrets/types.js';
16
+ export interface HostedBootstrapPayload {
17
+ adobeImsToken?: string;
18
+ }
19
+ export declare function registerHostedBootstrapEndpoint(app: Express, options: {
20
+ secretStore: SecretStore;
21
+ }): void;
@@ -0,0 +1,14 @@
1
+ import { requireLoopback } from './cloud-status.js';
2
+ export function registerHostedBootstrapEndpoint(app, options) {
3
+ app.get('/api/hosted-bootstrap', requireLoopback, (_req, res) => {
4
+ const payload = {};
5
+ // EnvSecretStore.get(name) requires both the value AND a <name>_DOMAINS
6
+ // entry. The user's secrets.env must contain BOTH:
7
+ // ADOBE_IMS_TOKEN=<bearer>
8
+ // ADOBE_IMS_TOKEN_DOMAINS=adobe-llm-proxy.paolo-moz.workers.dev
9
+ const token = options.secretStore.get('ADOBE_IMS_TOKEN');
10
+ if (token?.value)
11
+ payload.adobeImsToken = token.value;
12
+ res.json(payload);
13
+ });
14
+ }