@computesdk/workbench 3.0.0 → 3.1.1

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.
package/dist/index.js CHANGED
@@ -1,4 +1,33 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // ../../node_modules/.pnpm/tsup@8.5.0_jiti@2.6.1_postcss@8.5.6_tsx@4.20.3_typescript@5.8.3_yaml@2.8.0/node_modules/tsup/assets/esm_shims.js
12
+ import path from "path";
13
+ import { fileURLToPath } from "url";
14
+ var init_esm_shims = __esm({
15
+ "../../node_modules/.pnpm/tsup@8.5.0_jiti@2.6.1_postcss@8.5.6_tsx@4.20.3_typescript@5.8.3_yaml@2.8.0/node_modules/tsup/assets/esm_shims.js"() {
16
+ "use strict";
17
+ }
18
+ });
19
+
1
20
  // src/cli/state.ts
21
+ var state_exports = {};
22
+ __export(state_exports, {
23
+ clearSandbox: () => clearSandbox,
24
+ createState: () => createState,
25
+ formatUptime: () => formatUptime,
26
+ getCurrentSandbox: () => getCurrentSandbox,
27
+ getUptimeSeconds: () => getUptimeSeconds,
28
+ hasSandbox: () => hasSandbox,
29
+ setSandbox: () => setSandbox
30
+ });
2
31
  function createState() {
3
32
  return {
4
33
  currentProvider: null,
@@ -7,7 +36,8 @@ function createState() {
7
36
  availableProviders: [],
8
37
  useDirectMode: false,
9
38
  // Default to gateway mode
10
- verbose: false
39
+ verbose: false,
40
+ compute: null
11
41
  };
12
42
  }
13
43
  function getCurrentSandbox(state) {
@@ -61,36 +91,28 @@ function formatUptime(state) {
61
91
  const remainingMinutes = minutes % 60;
62
92
  return `${hours}h ${remainingMinutes}m`;
63
93
  }
64
-
65
- // src/cli/repl.ts
66
- import * as repl from "repl";
67
- import * as cmd from "@computesdk/cmd";
68
-
69
- // src/cli/commands.ts
70
- import { createCompute } from "computesdk";
94
+ var init_state = __esm({
95
+ "src/cli/state.ts"() {
96
+ "use strict";
97
+ init_esm_shims();
98
+ }
99
+ });
71
100
 
72
101
  // src/cli/output.ts
73
- var colors = {
74
- reset: "\x1B[0m",
75
- bright: "\x1B[1m",
76
- dim: "\x1B[2m",
77
- cyan: "\x1B[36m",
78
- green: "\x1B[32m",
79
- yellow: "\x1B[33m",
80
- red: "\x1B[31m",
81
- blue: "\x1B[34m",
82
- magenta: "\x1B[35m"
83
- };
84
- var c = {
85
- bold: (text) => `${colors.bright}${text}${colors.reset}`,
86
- dim: (text) => `${colors.dim}${text}${colors.reset}`,
87
- cyan: (text) => `${colors.cyan}${text}${colors.reset}`,
88
- green: (text) => `${colors.green}${text}${colors.reset}`,
89
- yellow: (text) => `${colors.yellow}${text}${colors.reset}`,
90
- red: (text) => `${colors.red}${text}${colors.reset}`,
91
- blue: (text) => `${colors.blue}${text}${colors.reset}`,
92
- magenta: (text) => `${colors.magenta}${text}${colors.reset}`
93
- };
102
+ var output_exports = {};
103
+ __export(output_exports, {
104
+ Spinner: () => Spinner,
105
+ c: () => c,
106
+ formatDuration: () => formatDuration,
107
+ logCommand: () => logCommand,
108
+ logError: () => logError,
109
+ logInfo: () => logInfo,
110
+ logSuccess: () => logSuccess,
111
+ logWarning: () => logWarning,
112
+ showHelp: () => showHelp,
113
+ showInfo: () => showInfo,
114
+ showWelcome: () => showWelcome
115
+ });
94
116
  function showWelcome(availableProviders, currentProvider, useDirectMode) {
95
117
  console.log(c.bold(c.cyan("\n\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557")));
96
118
  console.log(c.bold(c.cyan("\u2551 ComputeSDK Workbench \u2551")));
@@ -139,39 +161,6 @@ function showInfo(state) {
139
161
  console.log(` Uptime: ${formatUptime(state)}`);
140
162
  console.log("");
141
163
  }
142
- var Spinner = class {
143
- constructor(text) {
144
- this.interval = null;
145
- this.frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
146
- this.currentFrame = 0;
147
- this.text = text;
148
- }
149
- start() {
150
- process.stdout.write("\x1B[?25l");
151
- this.interval = setInterval(() => {
152
- const frame = this.frames[this.currentFrame];
153
- process.stdout.write(`\r${c.cyan(frame)} ${this.text}`);
154
- this.currentFrame = (this.currentFrame + 1) % this.frames.length;
155
- }, 80);
156
- return this;
157
- }
158
- succeed(text) {
159
- this.stop();
160
- console.log(`${c.green("\u2705")} ${text || this.text}`);
161
- }
162
- fail(text) {
163
- this.stop();
164
- console.log(`${c.red("\u274C")} ${text || this.text}`);
165
- }
166
- stop() {
167
- if (this.interval) {
168
- clearInterval(this.interval);
169
- this.interval = null;
170
- }
171
- process.stdout.write("\r\x1B[K");
172
- process.stdout.write("\x1B[?25h");
173
- }
174
- };
175
164
  function formatDuration(ms) {
176
165
  const seconds = ms / 1e3;
177
166
  if (seconds < 1) {
@@ -210,6 +199,9 @@ ${c.bold("Provider Modes:")}
210
199
  ${c.bold("Sandbox Management:")}
211
200
  ${c.cyan("restart")} Restart current sandbox
212
201
  ${c.cyan("destroy")} Destroy current sandbox
202
+ ${c.cyan("connect <url> [token]")} Connect to existing sandbox via URL
203
+ ${c.dim("Example: connect https://sandbox-123.localhost:8080")}
204
+ ${c.dim("Example: connect https://sandbox-123.localhost:8080 your_token")}
213
205
  ${c.cyan("info")} Show sandbox info (provider, uptime)
214
206
 
215
207
  ${c.bold("Environment:")}
@@ -245,6 +237,20 @@ ${c.bold("Running Commands:")}
245
237
  ${c.cyan('filesystem.exists("/path")')}
246
238
  ${c.cyan('filesystem.remove("/file")')}
247
239
 
240
+ ${c.dim("Named Sandboxes (gateway mode only):")}
241
+ ${c.cyan("create()")} ${c.dim("// Create & switch to new sandbox")}
242
+ ${c.cyan('create({ namespace: "h" })')} ${c.dim("// Create with namespace & switch")}
243
+ ${c.cyan('findOrCreate({ name: "my-app" })')} ${c.dim("// Find or create & switch")}
244
+ ${c.cyan('find({ name: "my-app" })')} ${c.dim("// Find existing & switch")}
245
+
246
+ ${c.dim("Note: Prompts before switching if you already have an active sandbox")}
247
+
248
+ ${c.dim("Child Sandboxes (gateway mode only):")}
249
+ ${c.cyan("child.create()")} ${c.dim("// Create child sandbox")}
250
+ ${c.cyan("child.list()")} ${c.dim("// List all children")}
251
+ ${c.cyan('child.retrieve("sandbox-id")')} ${c.dim("// Get child info")}
252
+ ${c.cyan('child.destroy("sandbox-id")')} ${c.dim("// Delete child")}
253
+
248
254
  ${c.dim("Sandbox Methods:")}
249
255
  ${c.cyan("getUrl({ port: 3000 })")} ${c.dim("// Get public URL")}
250
256
  ${c.cyan(`runCode("console.log('hi')", "node")`)}
@@ -280,6 +286,71 @@ function logError(message) {
280
286
  function logWarning(message) {
281
287
  console.log(c.yellow(`\u26A0\uFE0F ${message}`));
282
288
  }
289
+ function logInfo(message) {
290
+ console.log(c.blue(`\u2139\uFE0F ${message}`));
291
+ }
292
+ var colors, c, Spinner;
293
+ var init_output = __esm({
294
+ "src/cli/output.ts"() {
295
+ "use strict";
296
+ init_esm_shims();
297
+ init_state();
298
+ colors = {
299
+ reset: "\x1B[0m",
300
+ bright: "\x1B[1m",
301
+ dim: "\x1B[2m",
302
+ cyan: "\x1B[36m",
303
+ green: "\x1B[32m",
304
+ yellow: "\x1B[33m",
305
+ red: "\x1B[31m",
306
+ blue: "\x1B[34m",
307
+ magenta: "\x1B[35m"
308
+ };
309
+ c = {
310
+ bold: (text) => `${colors.bright}${text}${colors.reset}`,
311
+ dim: (text) => `${colors.dim}${text}${colors.reset}`,
312
+ cyan: (text) => `${colors.cyan}${text}${colors.reset}`,
313
+ green: (text) => `${colors.green}${text}${colors.reset}`,
314
+ yellow: (text) => `${colors.yellow}${text}${colors.reset}`,
315
+ red: (text) => `${colors.red}${text}${colors.reset}`,
316
+ blue: (text) => `${colors.blue}${text}${colors.reset}`,
317
+ magenta: (text) => `${colors.magenta}${text}${colors.reset}`
318
+ };
319
+ Spinner = class {
320
+ constructor(text) {
321
+ this.interval = null;
322
+ this.frames = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
323
+ this.currentFrame = 0;
324
+ this.text = text;
325
+ }
326
+ start() {
327
+ process.stdout.write("\x1B[?25l");
328
+ this.interval = setInterval(() => {
329
+ const frame = this.frames[this.currentFrame];
330
+ process.stdout.write(`\r${c.cyan(frame)} ${this.text}`);
331
+ this.currentFrame = (this.currentFrame + 1) % this.frames.length;
332
+ }, 80);
333
+ return this;
334
+ }
335
+ succeed(text) {
336
+ this.stop();
337
+ console.log(`${c.green("\u2705")} ${text || this.text}`);
338
+ }
339
+ fail(text) {
340
+ this.stop();
341
+ console.log(`${c.red("\u274C")} ${text || this.text}`);
342
+ }
343
+ stop() {
344
+ if (this.interval) {
345
+ clearInterval(this.interval);
346
+ this.interval = null;
347
+ }
348
+ process.stdout.write("\r\x1B[K");
349
+ process.stdout.write("\x1B[?25h");
350
+ }
351
+ };
352
+ }
353
+ });
283
354
 
284
355
  // src/cli/providers.ts
285
356
  import {
@@ -287,14 +358,6 @@ import {
287
358
  PROVIDER_NAMES as SHARED_PROVIDER_NAMES,
288
359
  getProviderConfigFromEnv
289
360
  } from "computesdk";
290
- var PROVIDER_NAMES = [
291
- "gateway",
292
- ...SHARED_PROVIDER_NAMES
293
- ];
294
- var PROVIDER_AUTH = {
295
- gateway: [["COMPUTESDK_API_KEY"]],
296
- ...SHARED_PROVIDER_AUTH
297
- };
298
361
  function getProviderStatus(provider) {
299
362
  const authOptions = PROVIDER_AUTH[provider];
300
363
  if (typeof process === "undefined") {
@@ -476,29 +539,102 @@ function getProviderConfig(providerName) {
476
539
  }
477
540
  return getProviderConfigFromEnv(providerName);
478
541
  }
542
+ var PROVIDER_NAMES, PROVIDER_AUTH;
543
+ var init_providers = __esm({
544
+ "src/cli/providers.ts"() {
545
+ "use strict";
546
+ init_esm_shims();
547
+ init_output();
548
+ PROVIDER_NAMES = [
549
+ "gateway",
550
+ ...SHARED_PROVIDER_NAMES
551
+ ];
552
+ PROVIDER_AUTH = {
553
+ gateway: [["COMPUTESDK_API_KEY"]],
554
+ ...SHARED_PROVIDER_AUTH
555
+ };
556
+ }
557
+ });
479
558
 
480
559
  // src/cli/commands.ts
560
+ var commands_exports = {};
561
+ __export(commands_exports, {
562
+ cleanupOnExit: () => cleanupOnExit,
563
+ confirmSandboxSwitch: () => confirmSandboxSwitch,
564
+ connectToSandbox: () => connectToSandbox,
565
+ createSandbox: () => createSandbox,
566
+ defineProviderCommand: () => defineProviderCommand,
567
+ destroySandbox: () => destroySandbox,
568
+ ensureSandbox: () => ensureSandbox,
569
+ getComputeInstance: () => getComputeInstance,
570
+ restartSandbox: () => restartSandbox,
571
+ runCommand: () => runCommand,
572
+ showMode: () => showMode,
573
+ showVerbose: () => showVerbose,
574
+ switchProvider: () => switchProvider,
575
+ toggleMode: () => toggleMode,
576
+ toggleVerbose: () => toggleVerbose
577
+ });
578
+ import { createCompute } from "@computesdk/provider";
481
579
  import * as readline from "readline";
482
- async function confirm(question) {
580
+ async function confirm(question, defaultYes = false) {
483
581
  return new Promise((resolve) => {
484
582
  const rl = readline.createInterface({
485
583
  input: process.stdin,
486
584
  output: process.stdout
487
585
  });
488
586
  process.stdin.resume();
489
- rl.question(`${question} (y/N): `, (answer) => {
587
+ const promptSuffix = defaultYes ? "(Y/n)" : "(y/N)";
588
+ rl.question(`${question} ${promptSuffix}: `, (answer) => {
490
589
  rl.close();
491
590
  const trimmed = answer.trim().toLowerCase();
492
- resolve(trimmed === "y" || trimmed === "yes");
591
+ if (trimmed === "") {
592
+ resolve(defaultYes);
593
+ } else {
594
+ resolve(trimmed === "y" || trimmed === "yes");
595
+ }
493
596
  });
494
597
  });
495
598
  }
599
+ async function confirmSandboxSwitch(state) {
600
+ if (!hasSandbox(state)) {
601
+ return true;
602
+ }
603
+ return await confirm("Switch to new sandbox?", true);
604
+ }
496
605
  async function ensureSandbox(state) {
497
606
  if (hasSandbox(state)) {
498
607
  return;
499
608
  }
500
609
  await createSandbox(state);
501
610
  }
611
+ async function getComputeInstance(state) {
612
+ if (state.compute) {
613
+ return state.compute;
614
+ }
615
+ const providerName = state.currentProvider || autoDetectProvider(false);
616
+ const useDirect = state.useDirectMode;
617
+ if (!providerName) {
618
+ throw new Error("No provider configured.");
619
+ }
620
+ let compute2;
621
+ if (useDirect) {
622
+ const providerModule = await loadProvider(providerName);
623
+ const providerFactory = providerModule[providerName];
624
+ if (!providerFactory) {
625
+ throw new Error(`Provider ${providerName} does not export a factory function`);
626
+ }
627
+ const config = getProviderConfig(providerName);
628
+ compute2 = createCompute({
629
+ defaultProvider: providerFactory(config)
630
+ });
631
+ } else {
632
+ const { compute: gatewayCompute } = await import("computesdk");
633
+ compute2 = gatewayCompute;
634
+ }
635
+ state.compute = compute2;
636
+ return compute2;
637
+ }
502
638
  async function createSandbox(state) {
503
639
  const providerName = state.currentProvider || autoDetectProvider(false);
504
640
  const useDirect = state.useDirectMode;
@@ -528,55 +664,7 @@ async function createSandbox(state) {
528
664
  const spinner = new Spinner(`Creating sandbox with ${modeLabel}...`).start();
529
665
  const startTime = Date.now();
530
666
  try {
531
- let compute2;
532
- if (useDirect) {
533
- const providerModule = await loadProvider(providerName);
534
- const providerFactory = providerModule[providerName];
535
- if (!providerFactory) {
536
- throw new Error(`Provider ${providerName} does not export a factory function`);
537
- }
538
- const config = getProviderConfig(providerName);
539
- compute2 = createCompute({
540
- defaultProvider: providerFactory(config)
541
- });
542
- } else {
543
- const gatewayModule = await import("computesdk");
544
- const gatewayFactory = gatewayModule.gateway;
545
- const providerConfig = getProviderConfig(providerName);
546
- const providerHeaders = {};
547
- switch (providerName) {
548
- case "e2b":
549
- if (providerConfig.apiKey) providerHeaders["X-E2B-API-Key"] = providerConfig.apiKey;
550
- break;
551
- case "railway":
552
- if (providerConfig.apiKey) providerHeaders["X-Railway-API-Key"] = providerConfig.apiKey;
553
- if (providerConfig.projectId) providerHeaders["X-Railway-Project-ID"] = providerConfig.projectId;
554
- if (providerConfig.environmentId) providerHeaders["X-Railway-Environment-ID"] = providerConfig.environmentId;
555
- break;
556
- case "daytona":
557
- if (providerConfig.apiKey) providerHeaders["X-Daytona-API-Key"] = providerConfig.apiKey;
558
- break;
559
- case "modal":
560
- if (providerConfig.tokenId) providerHeaders["X-Modal-Token-ID"] = providerConfig.tokenId;
561
- if (providerConfig.tokenSecret) providerHeaders["X-Modal-Token-Secret"] = providerConfig.tokenSecret;
562
- break;
563
- case "vercel":
564
- if (providerConfig.token) providerHeaders["X-Vercel-Token"] = providerConfig.token;
565
- if (providerConfig.teamId) providerHeaders["X-Vercel-Team-ID"] = providerConfig.teamId;
566
- if (providerConfig.projectId) providerHeaders["X-Vercel-Project-ID"] = providerConfig.projectId;
567
- break;
568
- }
569
- const config = {
570
- apiKey: process.env.COMPUTESDK_API_KEY,
571
- provider: providerName,
572
- // Tell gateway which backend to use
573
- providerHeaders
574
- // Pass provider credentials via headers
575
- };
576
- compute2 = createCompute({
577
- defaultProvider: gatewayFactory(config)
578
- });
579
- }
667
+ const compute2 = await getComputeInstance(state);
580
668
  const result = await compute2.sandbox.create();
581
669
  const duration = Date.now() - startTime;
582
670
  setSandbox(state, result, providerName);
@@ -600,10 +688,6 @@ Install it with: ${c.cyan(`npm install @computesdk/${providerName}`)}
600
688
  }
601
689
  }
602
690
  async function destroySandbox(state) {
603
- if (!hasSandbox(state)) {
604
- logWarning("No active sandbox");
605
- return;
606
- }
607
691
  const spinner = new Spinner("Destroying sandbox...").start();
608
692
  try {
609
693
  const sandbox = getCurrentSandbox(state);
@@ -720,6 +804,7 @@ async function switchProvider(state, mode, providerName) {
720
804
  await destroySandbox(state);
721
805
  state.currentProvider = actualProvider;
722
806
  state.useDirectMode = useDirect;
807
+ state.compute = null;
723
808
  const modeStr = useDirect ? `${actualProvider} (direct)` : `${actualProvider} (via gateway)`;
724
809
  logSuccess(`Switched to ${modeStr}`);
725
810
  } else {
@@ -728,11 +813,12 @@ async function switchProvider(state, mode, providerName) {
728
813
  } else {
729
814
  state.currentProvider = actualProvider;
730
815
  state.useDirectMode = useDirect;
816
+ state.compute = null;
731
817
  const modeStr = useDirect ? `${actualProvider} (direct)` : `${actualProvider} (via gateway)`;
732
818
  logSuccess(`Switched to ${modeStr}`);
733
819
  }
734
820
  }
735
- function createProviderCommand(state) {
821
+ function defineProviderCommand(state) {
736
822
  return async function provider(mode, providerName) {
737
823
  if (!mode) {
738
824
  if (state.currentProvider) {
@@ -805,6 +891,62 @@ Verbose mode: ${status}`);
805
891
  Toggle with: ${c.cyan("verbose")}
806
892
  `);
807
893
  }
894
+ async function connectToSandbox(state, sandboxUrl, token) {
895
+ if (!sandboxUrl) {
896
+ logError("Usage: connect <sandbox_url> [token]");
897
+ console.log("Example: connect https://sandbox-123.localhost:8080");
898
+ console.log("Example: connect https://sandbox-123.localhost:8080 your_access_token");
899
+ return;
900
+ }
901
+ const cleanUrl = sandboxUrl.replace(/\/$/, "");
902
+ if (hasSandbox(state)) {
903
+ const shouldDestroy = await confirm("Disconnect from current sandbox?");
904
+ if (!shouldDestroy) {
905
+ logWarning("Keeping current sandbox. Connection cancelled.");
906
+ return;
907
+ }
908
+ clearSandbox(state);
909
+ }
910
+ const spinner = new Spinner(`Connecting to ${cleanUrl}...`).start();
911
+ const startTime = Date.now();
912
+ try {
913
+ const { Sandbox } = await import("computesdk");
914
+ let WebSocket;
915
+ try {
916
+ const wsModule = await import("ws");
917
+ WebSocket = wsModule.default;
918
+ } catch {
919
+ logError('Failed to import "ws" module. Please install it: pnpm add ws');
920
+ throw new Error('Missing "ws" dependency');
921
+ }
922
+ const sandbox = new Sandbox({
923
+ sandboxUrl: cleanUrl,
924
+ sandboxId: "",
925
+ // Will be populated when we get info
926
+ provider: "connected",
927
+ // Mark as directly connected
928
+ token,
929
+ // Optional access token
930
+ WebSocket
931
+ });
932
+ const info = await sandbox.getInfo();
933
+ const duration = Date.now() - startTime;
934
+ setSandbox(state, sandbox, "connected");
935
+ spinner.succeed(`Connected to sandbox ${c.dim(`(${formatDuration(duration)})`)}`);
936
+ console.log(c.dim(`Provider: ${info.provider || "unknown"}`));
937
+ console.log(c.dim(`Sandbox ID: ${info.id || "unknown"}`));
938
+ } catch (error) {
939
+ const duration = Date.now() - startTime;
940
+ spinner.fail(`Failed to connect ${c.dim(`(${formatDuration(duration)})`)}`);
941
+ if (error instanceof Error) {
942
+ logError(`Error: ${error.message}`);
943
+ if (error.stack) {
944
+ console.log(c.dim(error.stack));
945
+ }
946
+ }
947
+ throw error;
948
+ }
949
+ }
808
950
  async function cleanupOnExit(state, replServer) {
809
951
  if (!hasSandbox(state)) {
810
952
  return;
@@ -813,6 +955,10 @@ async function cleanupOnExit(state, replServer) {
813
955
  replServer.pause();
814
956
  }
815
957
  console.log("");
958
+ if (state.currentProvider === "connected") {
959
+ logWarning("Disconnecting from external sandbox (not destroying).");
960
+ return;
961
+ }
816
962
  const shouldDestroy = await confirm("Destroy active sandbox?");
817
963
  if (shouldDestroy) {
818
964
  await destroySandbox(state);
@@ -820,14 +966,36 @@ async function cleanupOnExit(state, replServer) {
820
966
  logWarning("Sandbox left running. It may incur costs.");
821
967
  }
822
968
  }
969
+ var init_commands = __esm({
970
+ "src/cli/commands.ts"() {
971
+ "use strict";
972
+ init_esm_shims();
973
+ init_state();
974
+ init_output();
975
+ init_providers();
976
+ }
977
+ });
978
+
979
+ // src/cli/index.ts
980
+ init_esm_shims();
981
+ init_state();
982
+
983
+ // src/cli/repl.ts
984
+ init_esm_shims();
985
+ init_commands();
986
+ init_output();
987
+ init_providers();
988
+ import * as repl from "repl";
989
+ import * as cmd from "@computesdk/cmd";
823
990
 
824
991
  // src/cli/types.ts
992
+ init_esm_shims();
825
993
  function isCommand(value) {
826
994
  return Array.isArray(value) && value.length > 0 && typeof value[0] === "string";
827
995
  }
828
996
 
829
997
  // src/cli/repl.ts
830
- import * as path from "path";
998
+ import * as path2 from "path";
831
999
  import * as os from "os";
832
1000
  function createREPL(state) {
833
1001
  const replServer = repl.start({
@@ -925,7 +1093,7 @@ function injectCmdContext(replServer) {
925
1093
  replServer.context.zsh = cmd.zsh;
926
1094
  }
927
1095
  function injectWorkbenchCommands(replServer, state) {
928
- replServer.context.provider = createProviderCommand(state);
1096
+ replServer.context.provider = defineProviderCommand(state);
929
1097
  replServer.context.providers = () => showProviders();
930
1098
  replServer.context.mode = async (modeName) => {
931
1099
  if (!modeName) {
@@ -940,6 +1108,9 @@ function injectWorkbenchCommands(replServer, state) {
940
1108
  replServer.context.destroy = async () => {
941
1109
  await destroySandbox(state);
942
1110
  };
1111
+ replServer.context.connect = async (url, token) => {
1112
+ await connectToSandbox(state, url, token);
1113
+ };
943
1114
  replServer.context.info = () => showInfo(state);
944
1115
  replServer.context.verbose = () => {
945
1116
  toggleVerbose(state);
@@ -972,59 +1143,203 @@ function injectWorkbenchCommands(replServer, state) {
972
1143
  }
973
1144
  return sandbox.runCode(code, runtime);
974
1145
  };
1146
+ replServer.context.create = async (options) => {
1147
+ if (state.useDirectMode) {
1148
+ throw new Error('Named sandboxes are only available in gateway mode. Use "mode gateway" to switch.');
1149
+ }
1150
+ const { getComputeInstance: getComputeInstance2, confirmSandboxSwitch: confirmSandboxSwitch2 } = await Promise.resolve().then(() => (init_commands(), commands_exports));
1151
+ const { setSandbox: setSandbox2 } = await Promise.resolve().then(() => (init_state(), state_exports));
1152
+ const { logSuccess: logSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
1153
+ const shouldSwitch = await confirmSandboxSwitch2(state);
1154
+ if (!shouldSwitch) {
1155
+ const compute3 = await getComputeInstance2(state);
1156
+ const sandbox2 = await compute3.sandbox.create(options);
1157
+ return {
1158
+ sandboxId: sandbox2.sandboxId,
1159
+ provider: sandbox2.provider,
1160
+ metadata: sandbox2.getInstance().config.metadata || {}
1161
+ };
1162
+ }
1163
+ const compute2 = await getComputeInstance2(state);
1164
+ const sandbox = await compute2.sandbox.create(options);
1165
+ setSandbox2(state, sandbox, sandbox.provider);
1166
+ logSuccess2(`Switched to sandbox ${sandbox.sandboxId}`);
1167
+ return {
1168
+ sandboxId: sandbox.sandboxId,
1169
+ provider: sandbox.provider,
1170
+ metadata: sandbox.getInstance().config.metadata || {}
1171
+ };
1172
+ };
1173
+ replServer.context.findOrCreate = async (options) => {
1174
+ if (state.useDirectMode) {
1175
+ throw new Error('Named sandboxes (findOrCreate) are only available in gateway mode. Use "mode gateway" to switch.');
1176
+ }
1177
+ const { getComputeInstance: getComputeInstance2, confirmSandboxSwitch: confirmSandboxSwitch2 } = await Promise.resolve().then(() => (init_commands(), commands_exports));
1178
+ const { setSandbox: setSandbox2 } = await Promise.resolve().then(() => (init_state(), state_exports));
1179
+ const { logSuccess: logSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
1180
+ const shouldSwitch = await confirmSandboxSwitch2(state);
1181
+ if (!shouldSwitch) {
1182
+ const compute3 = await getComputeInstance2(state);
1183
+ const sandbox2 = await compute3.sandbox.findOrCreate(options);
1184
+ return {
1185
+ sandboxId: sandbox2.sandboxId,
1186
+ provider: sandbox2.provider,
1187
+ name: options.name,
1188
+ namespace: options.namespace || "default",
1189
+ metadata: sandbox2.getInstance().config.metadata || {}
1190
+ };
1191
+ }
1192
+ const compute2 = await getComputeInstance2(state);
1193
+ const sandbox = await compute2.sandbox.findOrCreate(options);
1194
+ setSandbox2(state, sandbox, sandbox.provider);
1195
+ logSuccess2(`Switched to sandbox ${sandbox.sandboxId}`);
1196
+ return {
1197
+ sandboxId: sandbox.sandboxId,
1198
+ provider: sandbox.provider,
1199
+ name: options.name,
1200
+ namespace: options.namespace || "default",
1201
+ metadata: sandbox.getInstance().config.metadata || {}
1202
+ };
1203
+ };
1204
+ replServer.context.find = async (options) => {
1205
+ if (state.useDirectMode) {
1206
+ throw new Error('Named sandboxes (find) are only available in gateway mode. Use "mode gateway" to switch.');
1207
+ }
1208
+ const { getComputeInstance: getComputeInstance2, confirmSandboxSwitch: confirmSandboxSwitch2 } = await Promise.resolve().then(() => (init_commands(), commands_exports));
1209
+ const { setSandbox: setSandbox2 } = await Promise.resolve().then(() => (init_state(), state_exports));
1210
+ const { logSuccess: logSuccess2 } = await Promise.resolve().then(() => (init_output(), output_exports));
1211
+ const compute2 = await getComputeInstance2(state);
1212
+ const sandbox = await compute2.sandbox.find(options);
1213
+ if (!sandbox) {
1214
+ return null;
1215
+ }
1216
+ const shouldSwitch = await confirmSandboxSwitch2(state);
1217
+ if (!shouldSwitch) {
1218
+ return {
1219
+ sandboxId: sandbox.sandboxId,
1220
+ provider: sandbox.provider,
1221
+ name: options.name,
1222
+ namespace: options.namespace || "default",
1223
+ metadata: sandbox.getInstance().config.metadata || {}
1224
+ };
1225
+ }
1226
+ setSandbox2(state, sandbox, sandbox.provider);
1227
+ logSuccess2(`Switched to sandbox ${sandbox.sandboxId}`);
1228
+ return {
1229
+ sandboxId: sandbox.sandboxId,
1230
+ provider: sandbox.provider,
1231
+ name: options.name,
1232
+ namespace: options.namespace || "default",
1233
+ metadata: sandbox.getInstance().config.metadata || {}
1234
+ };
1235
+ };
975
1236
  replServer.context.filesystem = {
976
1237
  get readFile() {
977
- return async (path2) => {
1238
+ return async (path3) => {
978
1239
  const sandbox = state.currentSandbox;
979
1240
  if (!sandbox) {
980
1241
  throw new Error("No active sandbox. Run a command to auto-create one.");
981
1242
  }
982
- return sandbox.filesystem.readFile(path2);
1243
+ return sandbox.filesystem.readFile(path3);
983
1244
  };
984
1245
  },
985
1246
  get writeFile() {
986
- return async (path2, content) => {
1247
+ return async (path3, content) => {
987
1248
  const sandbox = state.currentSandbox;
988
1249
  if (!sandbox) {
989
1250
  throw new Error("No active sandbox. Run a command to auto-create one.");
990
1251
  }
991
- return sandbox.filesystem.writeFile(path2, content);
1252
+ return sandbox.filesystem.writeFile(path3, content);
992
1253
  };
993
1254
  },
994
1255
  get mkdir() {
995
- return async (path2) => {
1256
+ return async (path3) => {
996
1257
  const sandbox = state.currentSandbox;
997
1258
  if (!sandbox) {
998
1259
  throw new Error("No active sandbox. Run a command to auto-create one.");
999
1260
  }
1000
- return sandbox.filesystem.mkdir(path2);
1261
+ return sandbox.filesystem.mkdir(path3);
1001
1262
  };
1002
1263
  },
1003
1264
  get readdir() {
1004
- return async (path2) => {
1265
+ return async (path3) => {
1005
1266
  const sandbox = state.currentSandbox;
1006
1267
  if (!sandbox) {
1007
1268
  throw new Error("No active sandbox. Run a command to auto-create one.");
1008
1269
  }
1009
- return sandbox.filesystem.readdir(path2);
1270
+ return sandbox.filesystem.readdir(path3);
1010
1271
  };
1011
1272
  },
1012
1273
  get exists() {
1013
- return async (path2) => {
1274
+ return async (path3) => {
1014
1275
  const sandbox = state.currentSandbox;
1015
1276
  if (!sandbox) {
1016
1277
  throw new Error("No active sandbox. Run a command to auto-create one.");
1017
1278
  }
1018
- return sandbox.filesystem.exists(path2);
1279
+ return sandbox.filesystem.exists(path3);
1019
1280
  };
1020
1281
  },
1021
1282
  get remove() {
1022
- return async (path2) => {
1283
+ return async (path3) => {
1284
+ const sandbox = state.currentSandbox;
1285
+ if (!sandbox) {
1286
+ throw new Error("No active sandbox. Run a command to auto-create one.");
1287
+ }
1288
+ return sandbox.filesystem.remove(path3);
1289
+ };
1290
+ }
1291
+ };
1292
+ replServer.context.child = {
1293
+ get create() {
1294
+ return async () => {
1295
+ if (state.useDirectMode) {
1296
+ throw new Error('Child sandboxes are only available in gateway mode. Use "mode gateway" to switch.');
1297
+ }
1298
+ const sandbox = state.currentSandbox;
1299
+ if (!sandbox) {
1300
+ throw new Error("No active sandbox. Run a command to auto-create one.");
1301
+ }
1302
+ const instance = sandbox.getInstance();
1303
+ return instance.child.create();
1304
+ };
1305
+ },
1306
+ get list() {
1307
+ return async () => {
1308
+ if (state.useDirectMode) {
1309
+ throw new Error('Child sandboxes are only available in gateway mode. Use "mode gateway" to switch.');
1310
+ }
1311
+ const sandbox = state.currentSandbox;
1312
+ if (!sandbox) {
1313
+ throw new Error("No active sandbox. Run a command to auto-create one.");
1314
+ }
1315
+ const instance = sandbox.getInstance();
1316
+ return instance.child.list();
1317
+ };
1318
+ },
1319
+ get retrieve() {
1320
+ return async (subdomain) => {
1321
+ if (state.useDirectMode) {
1322
+ throw new Error('Child sandboxes are only available in gateway mode. Use "mode gateway" to switch.');
1323
+ }
1324
+ const sandbox = state.currentSandbox;
1325
+ if (!sandbox) {
1326
+ throw new Error("No active sandbox. Run a command to auto-create one.");
1327
+ }
1328
+ const instance = sandbox.getInstance();
1329
+ return instance.child.retrieve(subdomain);
1330
+ };
1331
+ },
1332
+ get destroy() {
1333
+ return async (subdomain, options) => {
1334
+ if (state.useDirectMode) {
1335
+ throw new Error('Child sandboxes are only available in gateway mode. Use "mode gateway" to switch.');
1336
+ }
1023
1337
  const sandbox = state.currentSandbox;
1024
1338
  if (!sandbox) {
1025
1339
  throw new Error("No active sandbox. Run a command to auto-create one.");
1026
1340
  }
1027
- return sandbox.filesystem.remove(path2);
1341
+ const instance = sandbox.getInstance();
1342
+ return instance.child.destroy(subdomain, options);
1028
1343
  };
1029
1344
  }
1030
1345
  };
@@ -1038,7 +1353,7 @@ function injectWorkbenchCommands(replServer, state) {
1038
1353
  }
1039
1354
  function setupSmartEvaluator(replServer, state) {
1040
1355
  const originalEval = replServer.eval;
1041
- const workbenchCommands = /* @__PURE__ */ new Set(["help", "providers", "info", "env", "restart", "destroy", "mode", "verbose", "sandboxInfo"]);
1356
+ const workbenchCommands = /* @__PURE__ */ new Set(["help", "providers", "info", "env", "restart", "destroy", "mode", "verbose", "sandboxInfo", "connect"]);
1042
1357
  replServer.eval = function(cmd3, context, filename, callback) {
1043
1358
  const trimmedCmd = cmd3.trim();
1044
1359
  const providerMatch = trimmedCmd.match(/^provider(?:\s+(direct|gateway))?\s+(\w+)$/);
@@ -1119,6 +1434,8 @@ function setupAutocomplete(replServer, state) {
1119
1434
  "providers": [],
1120
1435
  "restart": [],
1121
1436
  "destroy": [],
1437
+ "connect": [],
1438
+ // Connect takes a URL argument
1122
1439
  "info": [],
1123
1440
  "env": [],
1124
1441
  "help": [],
@@ -1204,7 +1521,7 @@ function setupAutocomplete(replServer, state) {
1204
1521
  };
1205
1522
  }
1206
1523
  function setupHistory(replServer) {
1207
- const historyFile = path.join(os.homedir(), ".computesdk_workbench_history");
1524
+ const historyFile = path2.join(os.homedir(), ".computesdk_workbench_history");
1208
1525
  replServer.setupHistory(historyFile, (err) => {
1209
1526
  if (err) {
1210
1527
  }
@@ -1212,6 +1529,9 @@ function setupHistory(replServer) {
1212
1529
  }
1213
1530
 
1214
1531
  // src/cli/index.ts
1532
+ init_output();
1533
+ init_providers();
1534
+ init_commands();
1215
1535
  async function startWorkbench() {
1216
1536
  const state = createState();
1217
1537
  state.availableProviders = getAvailableProviders();