@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/README.md +64 -0
- package/dist/bin/workbench.js +452 -135
- package/dist/bin/workbench.js.map +1 -1
- package/dist/helpers.d.ts +9 -3
- package/dist/helpers.js +3 -2
- package/dist/helpers.js.map +1 -1
- package/dist/index.js +463 -143
- package/dist/index.js.map +1 -1
- package/package.json +13 -11
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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 (
|
|
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(
|
|
1243
|
+
return sandbox.filesystem.readFile(path3);
|
|
983
1244
|
};
|
|
984
1245
|
},
|
|
985
1246
|
get writeFile() {
|
|
986
|
-
return async (
|
|
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(
|
|
1252
|
+
return sandbox.filesystem.writeFile(path3, content);
|
|
992
1253
|
};
|
|
993
1254
|
},
|
|
994
1255
|
get mkdir() {
|
|
995
|
-
return async (
|
|
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(
|
|
1261
|
+
return sandbox.filesystem.mkdir(path3);
|
|
1001
1262
|
};
|
|
1002
1263
|
},
|
|
1003
1264
|
get readdir() {
|
|
1004
|
-
return async (
|
|
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(
|
|
1270
|
+
return sandbox.filesystem.readdir(path3);
|
|
1010
1271
|
};
|
|
1011
1272
|
},
|
|
1012
1273
|
get exists() {
|
|
1013
|
-
return async (
|
|
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(
|
|
1279
|
+
return sandbox.filesystem.exists(path3);
|
|
1019
1280
|
};
|
|
1020
1281
|
},
|
|
1021
1282
|
get remove() {
|
|
1022
|
-
return async (
|
|
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
|
-
|
|
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 =
|
|
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();
|