@hasna/sandboxes 0.1.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 (53) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +256 -0
  3. package/dist/cli/index.d.ts +3 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +3777 -0
  6. package/dist/db/agents.d.ts +8 -0
  7. package/dist/db/agents.d.ts.map +1 -0
  8. package/dist/db/database.d.ts +9 -0
  9. package/dist/db/database.d.ts.map +1 -0
  10. package/dist/db/events.d.ts +16 -0
  11. package/dist/db/events.d.ts.map +1 -0
  12. package/dist/db/projects.d.ts +9 -0
  13. package/dist/db/projects.d.ts.map +1 -0
  14. package/dist/db/sandboxes.d.ts +12 -0
  15. package/dist/db/sandboxes.d.ts.map +1 -0
  16. package/dist/db/sessions.d.ts +11 -0
  17. package/dist/db/sessions.d.ts.map +1 -0
  18. package/dist/db/webhooks.d.ts +7 -0
  19. package/dist/db/webhooks.d.ts.map +1 -0
  20. package/dist/index.d.ts +13 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +1431 -0
  23. package/dist/lib/agent-runner.d.ts +12 -0
  24. package/dist/lib/agent-runner.d.ts.map +1 -0
  25. package/dist/lib/config.d.ts +10 -0
  26. package/dist/lib/config.d.ts.map +1 -0
  27. package/dist/lib/keepalive.d.ts +5 -0
  28. package/dist/lib/keepalive.d.ts.map +1 -0
  29. package/dist/lib/stream.d.ts +13 -0
  30. package/dist/lib/stream.d.ts.map +1 -0
  31. package/dist/lib/webhook.d.ts +14 -0
  32. package/dist/lib/webhook.d.ts.map +1 -0
  33. package/dist/mcp/index.d.ts +3 -0
  34. package/dist/mcp/index.d.ts.map +1 -0
  35. package/dist/mcp/index.js +5546 -0
  36. package/dist/providers/daytona.d.ts +17 -0
  37. package/dist/providers/daytona.d.ts.map +1 -0
  38. package/dist/providers/e2b.d.ts +17 -0
  39. package/dist/providers/e2b.d.ts.map +1 -0
  40. package/dist/providers/index.d.ts +5 -0
  41. package/dist/providers/index.d.ts.map +1 -0
  42. package/dist/providers/modal.d.ts +25 -0
  43. package/dist/providers/modal.d.ts.map +1 -0
  44. package/dist/providers/types.d.ts +30 -0
  45. package/dist/providers/types.d.ts.map +1 -0
  46. package/dist/server/index.d.ts +3 -0
  47. package/dist/server/index.d.ts.map +1 -0
  48. package/dist/server/index.js +1552 -0
  49. package/dist/server/serve.d.ts +2 -0
  50. package/dist/server/serve.d.ts.map +1 -0
  51. package/dist/types/index.d.ts +199 -0
  52. package/dist/types/index.d.ts.map +1 -0
  53. package/package.json +78 -0
@@ -0,0 +1,3777 @@
1
+ #!/usr/bin/env bun
2
+ // @bun
3
+ var __create = Object.create;
4
+ var __getProtoOf = Object.getPrototypeOf;
5
+ var __defProp = Object.defineProperty;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __toESM = (mod, isNodeMode, target) => {
9
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
10
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
+ for (let key of __getOwnPropNames(mod))
12
+ if (!__hasOwnProp.call(to, key))
13
+ __defProp(to, key, {
14
+ get: () => mod[key],
15
+ enumerable: true
16
+ });
17
+ return to;
18
+ };
19
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
20
+ var __export = (target, all) => {
21
+ for (var name in all)
22
+ __defProp(target, name, {
23
+ get: all[name],
24
+ enumerable: true,
25
+ configurable: true,
26
+ set: (newValue) => all[name] = () => newValue
27
+ });
28
+ };
29
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
30
+ var __require = import.meta.require;
31
+
32
+ // node_modules/commander/lib/error.js
33
+ var require_error = __commonJS((exports) => {
34
+ class CommanderError extends Error {
35
+ constructor(exitCode, code, message) {
36
+ super(message);
37
+ Error.captureStackTrace(this, this.constructor);
38
+ this.name = this.constructor.name;
39
+ this.code = code;
40
+ this.exitCode = exitCode;
41
+ this.nestedError = undefined;
42
+ }
43
+ }
44
+
45
+ class InvalidArgumentError extends CommanderError {
46
+ constructor(message) {
47
+ super(1, "commander.invalidArgument", message);
48
+ Error.captureStackTrace(this, this.constructor);
49
+ this.name = this.constructor.name;
50
+ }
51
+ }
52
+ exports.CommanderError = CommanderError;
53
+ exports.InvalidArgumentError = InvalidArgumentError;
54
+ });
55
+
56
+ // node_modules/commander/lib/argument.js
57
+ var require_argument = __commonJS((exports) => {
58
+ var { InvalidArgumentError } = require_error();
59
+
60
+ class Argument {
61
+ constructor(name, description) {
62
+ this.description = description || "";
63
+ this.variadic = false;
64
+ this.parseArg = undefined;
65
+ this.defaultValue = undefined;
66
+ this.defaultValueDescription = undefined;
67
+ this.argChoices = undefined;
68
+ switch (name[0]) {
69
+ case "<":
70
+ this.required = true;
71
+ this._name = name.slice(1, -1);
72
+ break;
73
+ case "[":
74
+ this.required = false;
75
+ this._name = name.slice(1, -1);
76
+ break;
77
+ default:
78
+ this.required = true;
79
+ this._name = name;
80
+ break;
81
+ }
82
+ if (this._name.length > 3 && this._name.slice(-3) === "...") {
83
+ this.variadic = true;
84
+ this._name = this._name.slice(0, -3);
85
+ }
86
+ }
87
+ name() {
88
+ return this._name;
89
+ }
90
+ _concatValue(value, previous) {
91
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
92
+ return [value];
93
+ }
94
+ return previous.concat(value);
95
+ }
96
+ default(value, description) {
97
+ this.defaultValue = value;
98
+ this.defaultValueDescription = description;
99
+ return this;
100
+ }
101
+ argParser(fn) {
102
+ this.parseArg = fn;
103
+ return this;
104
+ }
105
+ choices(values) {
106
+ this.argChoices = values.slice();
107
+ this.parseArg = (arg, previous) => {
108
+ if (!this.argChoices.includes(arg)) {
109
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
110
+ }
111
+ if (this.variadic) {
112
+ return this._concatValue(arg, previous);
113
+ }
114
+ return arg;
115
+ };
116
+ return this;
117
+ }
118
+ argRequired() {
119
+ this.required = true;
120
+ return this;
121
+ }
122
+ argOptional() {
123
+ this.required = false;
124
+ return this;
125
+ }
126
+ }
127
+ function humanReadableArgName(arg) {
128
+ const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
129
+ return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
130
+ }
131
+ exports.Argument = Argument;
132
+ exports.humanReadableArgName = humanReadableArgName;
133
+ });
134
+
135
+ // node_modules/commander/lib/help.js
136
+ var require_help = __commonJS((exports) => {
137
+ var { humanReadableArgName } = require_argument();
138
+
139
+ class Help {
140
+ constructor() {
141
+ this.helpWidth = undefined;
142
+ this.minWidthToWrap = 40;
143
+ this.sortSubcommands = false;
144
+ this.sortOptions = false;
145
+ this.showGlobalOptions = false;
146
+ }
147
+ prepareContext(contextOptions) {
148
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
149
+ }
150
+ visibleCommands(cmd) {
151
+ const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
152
+ const helpCommand = cmd._getHelpCommand();
153
+ if (helpCommand && !helpCommand._hidden) {
154
+ visibleCommands.push(helpCommand);
155
+ }
156
+ if (this.sortSubcommands) {
157
+ visibleCommands.sort((a, b) => {
158
+ return a.name().localeCompare(b.name());
159
+ });
160
+ }
161
+ return visibleCommands;
162
+ }
163
+ compareOptions(a, b) {
164
+ const getSortKey = (option) => {
165
+ return option.short ? option.short.replace(/^-/, "") : option.long.replace(/^--/, "");
166
+ };
167
+ return getSortKey(a).localeCompare(getSortKey(b));
168
+ }
169
+ visibleOptions(cmd) {
170
+ const visibleOptions = cmd.options.filter((option) => !option.hidden);
171
+ const helpOption = cmd._getHelpOption();
172
+ if (helpOption && !helpOption.hidden) {
173
+ const removeShort = helpOption.short && cmd._findOption(helpOption.short);
174
+ const removeLong = helpOption.long && cmd._findOption(helpOption.long);
175
+ if (!removeShort && !removeLong) {
176
+ visibleOptions.push(helpOption);
177
+ } else if (helpOption.long && !removeLong) {
178
+ visibleOptions.push(cmd.createOption(helpOption.long, helpOption.description));
179
+ } else if (helpOption.short && !removeShort) {
180
+ visibleOptions.push(cmd.createOption(helpOption.short, helpOption.description));
181
+ }
182
+ }
183
+ if (this.sortOptions) {
184
+ visibleOptions.sort(this.compareOptions);
185
+ }
186
+ return visibleOptions;
187
+ }
188
+ visibleGlobalOptions(cmd) {
189
+ if (!this.showGlobalOptions)
190
+ return [];
191
+ const globalOptions = [];
192
+ for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
193
+ const visibleOptions = ancestorCmd.options.filter((option) => !option.hidden);
194
+ globalOptions.push(...visibleOptions);
195
+ }
196
+ if (this.sortOptions) {
197
+ globalOptions.sort(this.compareOptions);
198
+ }
199
+ return globalOptions;
200
+ }
201
+ visibleArguments(cmd) {
202
+ if (cmd._argsDescription) {
203
+ cmd.registeredArguments.forEach((argument) => {
204
+ argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
205
+ });
206
+ }
207
+ if (cmd.registeredArguments.find((argument) => argument.description)) {
208
+ return cmd.registeredArguments;
209
+ }
210
+ return [];
211
+ }
212
+ subcommandTerm(cmd) {
213
+ const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
214
+ return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + (args ? " " + args : "");
215
+ }
216
+ optionTerm(option) {
217
+ return option.flags;
218
+ }
219
+ argumentTerm(argument) {
220
+ return argument.name();
221
+ }
222
+ longestSubcommandTermLength(cmd, helper) {
223
+ return helper.visibleCommands(cmd).reduce((max, command) => {
224
+ return Math.max(max, this.displayWidth(helper.styleSubcommandTerm(helper.subcommandTerm(command))));
225
+ }, 0);
226
+ }
227
+ longestOptionTermLength(cmd, helper) {
228
+ return helper.visibleOptions(cmd).reduce((max, option) => {
229
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
230
+ }, 0);
231
+ }
232
+ longestGlobalOptionTermLength(cmd, helper) {
233
+ return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
234
+ return Math.max(max, this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option))));
235
+ }, 0);
236
+ }
237
+ longestArgumentTermLength(cmd, helper) {
238
+ return helper.visibleArguments(cmd).reduce((max, argument) => {
239
+ return Math.max(max, this.displayWidth(helper.styleArgumentTerm(helper.argumentTerm(argument))));
240
+ }, 0);
241
+ }
242
+ commandUsage(cmd) {
243
+ let cmdName = cmd._name;
244
+ if (cmd._aliases[0]) {
245
+ cmdName = cmdName + "|" + cmd._aliases[0];
246
+ }
247
+ let ancestorCmdNames = "";
248
+ for (let ancestorCmd = cmd.parent;ancestorCmd; ancestorCmd = ancestorCmd.parent) {
249
+ ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
250
+ }
251
+ return ancestorCmdNames + cmdName + " " + cmd.usage();
252
+ }
253
+ commandDescription(cmd) {
254
+ return cmd.description();
255
+ }
256
+ subcommandDescription(cmd) {
257
+ return cmd.summary() || cmd.description();
258
+ }
259
+ optionDescription(option) {
260
+ const extraInfo = [];
261
+ if (option.argChoices) {
262
+ extraInfo.push(`choices: ${option.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
263
+ }
264
+ if (option.defaultValue !== undefined) {
265
+ const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean";
266
+ if (showDefault) {
267
+ extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
268
+ }
269
+ }
270
+ if (option.presetArg !== undefined && option.optional) {
271
+ extraInfo.push(`preset: ${JSON.stringify(option.presetArg)}`);
272
+ }
273
+ if (option.envVar !== undefined) {
274
+ extraInfo.push(`env: ${option.envVar}`);
275
+ }
276
+ if (extraInfo.length > 0) {
277
+ return `${option.description} (${extraInfo.join(", ")})`;
278
+ }
279
+ return option.description;
280
+ }
281
+ argumentDescription(argument) {
282
+ const extraInfo = [];
283
+ if (argument.argChoices) {
284
+ extraInfo.push(`choices: ${argument.argChoices.map((choice) => JSON.stringify(choice)).join(", ")}`);
285
+ }
286
+ if (argument.defaultValue !== undefined) {
287
+ extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
288
+ }
289
+ if (extraInfo.length > 0) {
290
+ const extraDescription = `(${extraInfo.join(", ")})`;
291
+ if (argument.description) {
292
+ return `${argument.description} ${extraDescription}`;
293
+ }
294
+ return extraDescription;
295
+ }
296
+ return argument.description;
297
+ }
298
+ formatHelp(cmd, helper) {
299
+ const termWidth = helper.padWidth(cmd, helper);
300
+ const helpWidth = helper.helpWidth ?? 80;
301
+ function callFormatItem(term, description) {
302
+ return helper.formatItem(term, termWidth, description, helper);
303
+ }
304
+ let output = [
305
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
306
+ ""
307
+ ];
308
+ const commandDescription = helper.commandDescription(cmd);
309
+ if (commandDescription.length > 0) {
310
+ output = output.concat([
311
+ helper.boxWrap(helper.styleCommandDescription(commandDescription), helpWidth),
312
+ ""
313
+ ]);
314
+ }
315
+ const argumentList = helper.visibleArguments(cmd).map((argument) => {
316
+ return callFormatItem(helper.styleArgumentTerm(helper.argumentTerm(argument)), helper.styleArgumentDescription(helper.argumentDescription(argument)));
317
+ });
318
+ if (argumentList.length > 0) {
319
+ output = output.concat([
320
+ helper.styleTitle("Arguments:"),
321
+ ...argumentList,
322
+ ""
323
+ ]);
324
+ }
325
+ const optionList = helper.visibleOptions(cmd).map((option) => {
326
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
327
+ });
328
+ if (optionList.length > 0) {
329
+ output = output.concat([
330
+ helper.styleTitle("Options:"),
331
+ ...optionList,
332
+ ""
333
+ ]);
334
+ }
335
+ if (helper.showGlobalOptions) {
336
+ const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
337
+ return callFormatItem(helper.styleOptionTerm(helper.optionTerm(option)), helper.styleOptionDescription(helper.optionDescription(option)));
338
+ });
339
+ if (globalOptionList.length > 0) {
340
+ output = output.concat([
341
+ helper.styleTitle("Global Options:"),
342
+ ...globalOptionList,
343
+ ""
344
+ ]);
345
+ }
346
+ }
347
+ const commandList = helper.visibleCommands(cmd).map((cmd2) => {
348
+ return callFormatItem(helper.styleSubcommandTerm(helper.subcommandTerm(cmd2)), helper.styleSubcommandDescription(helper.subcommandDescription(cmd2)));
349
+ });
350
+ if (commandList.length > 0) {
351
+ output = output.concat([
352
+ helper.styleTitle("Commands:"),
353
+ ...commandList,
354
+ ""
355
+ ]);
356
+ }
357
+ return output.join(`
358
+ `);
359
+ }
360
+ displayWidth(str) {
361
+ return stripColor(str).length;
362
+ }
363
+ styleTitle(str) {
364
+ return str;
365
+ }
366
+ styleUsage(str) {
367
+ return str.split(" ").map((word) => {
368
+ if (word === "[options]")
369
+ return this.styleOptionText(word);
370
+ if (word === "[command]")
371
+ return this.styleSubcommandText(word);
372
+ if (word[0] === "[" || word[0] === "<")
373
+ return this.styleArgumentText(word);
374
+ return this.styleCommandText(word);
375
+ }).join(" ");
376
+ }
377
+ styleCommandDescription(str) {
378
+ return this.styleDescriptionText(str);
379
+ }
380
+ styleOptionDescription(str) {
381
+ return this.styleDescriptionText(str);
382
+ }
383
+ styleSubcommandDescription(str) {
384
+ return this.styleDescriptionText(str);
385
+ }
386
+ styleArgumentDescription(str) {
387
+ return this.styleDescriptionText(str);
388
+ }
389
+ styleDescriptionText(str) {
390
+ return str;
391
+ }
392
+ styleOptionTerm(str) {
393
+ return this.styleOptionText(str);
394
+ }
395
+ styleSubcommandTerm(str) {
396
+ return str.split(" ").map((word) => {
397
+ if (word === "[options]")
398
+ return this.styleOptionText(word);
399
+ if (word[0] === "[" || word[0] === "<")
400
+ return this.styleArgumentText(word);
401
+ return this.styleSubcommandText(word);
402
+ }).join(" ");
403
+ }
404
+ styleArgumentTerm(str) {
405
+ return this.styleArgumentText(str);
406
+ }
407
+ styleOptionText(str) {
408
+ return str;
409
+ }
410
+ styleArgumentText(str) {
411
+ return str;
412
+ }
413
+ styleSubcommandText(str) {
414
+ return str;
415
+ }
416
+ styleCommandText(str) {
417
+ return str;
418
+ }
419
+ padWidth(cmd, helper) {
420
+ return Math.max(helper.longestOptionTermLength(cmd, helper), helper.longestGlobalOptionTermLength(cmd, helper), helper.longestSubcommandTermLength(cmd, helper), helper.longestArgumentTermLength(cmd, helper));
421
+ }
422
+ preformatted(str) {
423
+ return /\n[^\S\r\n]/.test(str);
424
+ }
425
+ formatItem(term, termWidth, description, helper) {
426
+ const itemIndent = 2;
427
+ const itemIndentStr = " ".repeat(itemIndent);
428
+ if (!description)
429
+ return itemIndentStr + term;
430
+ const paddedTerm = term.padEnd(termWidth + term.length - helper.displayWidth(term));
431
+ const spacerWidth = 2;
432
+ const helpWidth = this.helpWidth ?? 80;
433
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
434
+ let formattedDescription;
435
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
436
+ formattedDescription = description;
437
+ } else {
438
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
439
+ formattedDescription = wrappedDescription.replace(/\n/g, `
440
+ ` + " ".repeat(termWidth + spacerWidth));
441
+ }
442
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
443
+ ${itemIndentStr}`);
444
+ }
445
+ boxWrap(str, width) {
446
+ if (width < this.minWidthToWrap)
447
+ return str;
448
+ const rawLines = str.split(/\r\n|\n/);
449
+ const chunkPattern = /[\s]*[^\s]+/g;
450
+ const wrappedLines = [];
451
+ rawLines.forEach((line) => {
452
+ const chunks = line.match(chunkPattern);
453
+ if (chunks === null) {
454
+ wrappedLines.push("");
455
+ return;
456
+ }
457
+ let sumChunks = [chunks.shift()];
458
+ let sumWidth = this.displayWidth(sumChunks[0]);
459
+ chunks.forEach((chunk) => {
460
+ const visibleWidth = this.displayWidth(chunk);
461
+ if (sumWidth + visibleWidth <= width) {
462
+ sumChunks.push(chunk);
463
+ sumWidth += visibleWidth;
464
+ return;
465
+ }
466
+ wrappedLines.push(sumChunks.join(""));
467
+ const nextChunk = chunk.trimStart();
468
+ sumChunks = [nextChunk];
469
+ sumWidth = this.displayWidth(nextChunk);
470
+ });
471
+ wrappedLines.push(sumChunks.join(""));
472
+ });
473
+ return wrappedLines.join(`
474
+ `);
475
+ }
476
+ }
477
+ function stripColor(str) {
478
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
479
+ return str.replace(sgrPattern, "");
480
+ }
481
+ exports.Help = Help;
482
+ exports.stripColor = stripColor;
483
+ });
484
+
485
+ // node_modules/commander/lib/option.js
486
+ var require_option = __commonJS((exports) => {
487
+ var { InvalidArgumentError } = require_error();
488
+
489
+ class Option {
490
+ constructor(flags, description) {
491
+ this.flags = flags;
492
+ this.description = description || "";
493
+ this.required = flags.includes("<");
494
+ this.optional = flags.includes("[");
495
+ this.variadic = /\w\.\.\.[>\]]$/.test(flags);
496
+ this.mandatory = false;
497
+ const optionFlags = splitOptionFlags(flags);
498
+ this.short = optionFlags.shortFlag;
499
+ this.long = optionFlags.longFlag;
500
+ this.negate = false;
501
+ if (this.long) {
502
+ this.negate = this.long.startsWith("--no-");
503
+ }
504
+ this.defaultValue = undefined;
505
+ this.defaultValueDescription = undefined;
506
+ this.presetArg = undefined;
507
+ this.envVar = undefined;
508
+ this.parseArg = undefined;
509
+ this.hidden = false;
510
+ this.argChoices = undefined;
511
+ this.conflictsWith = [];
512
+ this.implied = undefined;
513
+ }
514
+ default(value, description) {
515
+ this.defaultValue = value;
516
+ this.defaultValueDescription = description;
517
+ return this;
518
+ }
519
+ preset(arg) {
520
+ this.presetArg = arg;
521
+ return this;
522
+ }
523
+ conflicts(names) {
524
+ this.conflictsWith = this.conflictsWith.concat(names);
525
+ return this;
526
+ }
527
+ implies(impliedOptionValues) {
528
+ let newImplied = impliedOptionValues;
529
+ if (typeof impliedOptionValues === "string") {
530
+ newImplied = { [impliedOptionValues]: true };
531
+ }
532
+ this.implied = Object.assign(this.implied || {}, newImplied);
533
+ return this;
534
+ }
535
+ env(name) {
536
+ this.envVar = name;
537
+ return this;
538
+ }
539
+ argParser(fn) {
540
+ this.parseArg = fn;
541
+ return this;
542
+ }
543
+ makeOptionMandatory(mandatory = true) {
544
+ this.mandatory = !!mandatory;
545
+ return this;
546
+ }
547
+ hideHelp(hide = true) {
548
+ this.hidden = !!hide;
549
+ return this;
550
+ }
551
+ _concatValue(value, previous) {
552
+ if (previous === this.defaultValue || !Array.isArray(previous)) {
553
+ return [value];
554
+ }
555
+ return previous.concat(value);
556
+ }
557
+ choices(values) {
558
+ this.argChoices = values.slice();
559
+ this.parseArg = (arg, previous) => {
560
+ if (!this.argChoices.includes(arg)) {
561
+ throw new InvalidArgumentError(`Allowed choices are ${this.argChoices.join(", ")}.`);
562
+ }
563
+ if (this.variadic) {
564
+ return this._concatValue(arg, previous);
565
+ }
566
+ return arg;
567
+ };
568
+ return this;
569
+ }
570
+ name() {
571
+ if (this.long) {
572
+ return this.long.replace(/^--/, "");
573
+ }
574
+ return this.short.replace(/^-/, "");
575
+ }
576
+ attributeName() {
577
+ if (this.negate) {
578
+ return camelcase(this.name().replace(/^no-/, ""));
579
+ }
580
+ return camelcase(this.name());
581
+ }
582
+ is(arg) {
583
+ return this.short === arg || this.long === arg;
584
+ }
585
+ isBoolean() {
586
+ return !this.required && !this.optional && !this.negate;
587
+ }
588
+ }
589
+
590
+ class DualOptions {
591
+ constructor(options) {
592
+ this.positiveOptions = new Map;
593
+ this.negativeOptions = new Map;
594
+ this.dualOptions = new Set;
595
+ options.forEach((option) => {
596
+ if (option.negate) {
597
+ this.negativeOptions.set(option.attributeName(), option);
598
+ } else {
599
+ this.positiveOptions.set(option.attributeName(), option);
600
+ }
601
+ });
602
+ this.negativeOptions.forEach((value, key) => {
603
+ if (this.positiveOptions.has(key)) {
604
+ this.dualOptions.add(key);
605
+ }
606
+ });
607
+ }
608
+ valueFromOption(value, option) {
609
+ const optionKey = option.attributeName();
610
+ if (!this.dualOptions.has(optionKey))
611
+ return true;
612
+ const preset = this.negativeOptions.get(optionKey).presetArg;
613
+ const negativeValue = preset !== undefined ? preset : false;
614
+ return option.negate === (negativeValue === value);
615
+ }
616
+ }
617
+ function camelcase(str) {
618
+ return str.split("-").reduce((str2, word) => {
619
+ return str2 + word[0].toUpperCase() + word.slice(1);
620
+ });
621
+ }
622
+ function splitOptionFlags(flags) {
623
+ let shortFlag;
624
+ let longFlag;
625
+ const shortFlagExp = /^-[^-]$/;
626
+ const longFlagExp = /^--[^-]/;
627
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
628
+ if (shortFlagExp.test(flagParts[0]))
629
+ shortFlag = flagParts.shift();
630
+ if (longFlagExp.test(flagParts[0]))
631
+ longFlag = flagParts.shift();
632
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
633
+ shortFlag = flagParts.shift();
634
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
635
+ shortFlag = longFlag;
636
+ longFlag = flagParts.shift();
637
+ }
638
+ if (flagParts[0].startsWith("-")) {
639
+ const unsupportedFlag = flagParts[0];
640
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
641
+ if (/^-[^-][^-]/.test(unsupportedFlag))
642
+ throw new Error(`${baseError}
643
+ - a short flag is a single dash and a single character
644
+ - either use a single dash and a single character (for a short flag)
645
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`);
646
+ if (shortFlagExp.test(unsupportedFlag))
647
+ throw new Error(`${baseError}
648
+ - too many short flags`);
649
+ if (longFlagExp.test(unsupportedFlag))
650
+ throw new Error(`${baseError}
651
+ - too many long flags`);
652
+ throw new Error(`${baseError}
653
+ - unrecognised flag format`);
654
+ }
655
+ if (shortFlag === undefined && longFlag === undefined)
656
+ throw new Error(`option creation failed due to no flags found in '${flags}'.`);
657
+ return { shortFlag, longFlag };
658
+ }
659
+ exports.Option = Option;
660
+ exports.DualOptions = DualOptions;
661
+ });
662
+
663
+ // node_modules/commander/lib/suggestSimilar.js
664
+ var require_suggestSimilar = __commonJS((exports) => {
665
+ var maxDistance = 3;
666
+ function editDistance(a, b) {
667
+ if (Math.abs(a.length - b.length) > maxDistance)
668
+ return Math.max(a.length, b.length);
669
+ const d = [];
670
+ for (let i = 0;i <= a.length; i++) {
671
+ d[i] = [i];
672
+ }
673
+ for (let j = 0;j <= b.length; j++) {
674
+ d[0][j] = j;
675
+ }
676
+ for (let j = 1;j <= b.length; j++) {
677
+ for (let i = 1;i <= a.length; i++) {
678
+ let cost = 1;
679
+ if (a[i - 1] === b[j - 1]) {
680
+ cost = 0;
681
+ } else {
682
+ cost = 1;
683
+ }
684
+ d[i][j] = Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
685
+ if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
686
+ d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
687
+ }
688
+ }
689
+ }
690
+ return d[a.length][b.length];
691
+ }
692
+ function suggestSimilar(word, candidates) {
693
+ if (!candidates || candidates.length === 0)
694
+ return "";
695
+ candidates = Array.from(new Set(candidates));
696
+ const searchingOptions = word.startsWith("--");
697
+ if (searchingOptions) {
698
+ word = word.slice(2);
699
+ candidates = candidates.map((candidate) => candidate.slice(2));
700
+ }
701
+ let similar = [];
702
+ let bestDistance = maxDistance;
703
+ const minSimilarity = 0.4;
704
+ candidates.forEach((candidate) => {
705
+ if (candidate.length <= 1)
706
+ return;
707
+ const distance = editDistance(word, candidate);
708
+ const length = Math.max(word.length, candidate.length);
709
+ const similarity = (length - distance) / length;
710
+ if (similarity > minSimilarity) {
711
+ if (distance < bestDistance) {
712
+ bestDistance = distance;
713
+ similar = [candidate];
714
+ } else if (distance === bestDistance) {
715
+ similar.push(candidate);
716
+ }
717
+ }
718
+ });
719
+ similar.sort((a, b) => a.localeCompare(b));
720
+ if (searchingOptions) {
721
+ similar = similar.map((candidate) => `--${candidate}`);
722
+ }
723
+ if (similar.length > 1) {
724
+ return `
725
+ (Did you mean one of ${similar.join(", ")}?)`;
726
+ }
727
+ if (similar.length === 1) {
728
+ return `
729
+ (Did you mean ${similar[0]}?)`;
730
+ }
731
+ return "";
732
+ }
733
+ exports.suggestSimilar = suggestSimilar;
734
+ });
735
+
736
+ // node_modules/commander/lib/command.js
737
+ var require_command = __commonJS((exports) => {
738
+ var EventEmitter = __require("events").EventEmitter;
739
+ var childProcess = __require("child_process");
740
+ var path = __require("path");
741
+ var fs = __require("fs");
742
+ var process2 = __require("process");
743
+ var { Argument, humanReadableArgName } = require_argument();
744
+ var { CommanderError } = require_error();
745
+ var { Help, stripColor } = require_help();
746
+ var { Option, DualOptions } = require_option();
747
+ var { suggestSimilar } = require_suggestSimilar();
748
+
749
+ class Command extends EventEmitter {
750
+ constructor(name) {
751
+ super();
752
+ this.commands = [];
753
+ this.options = [];
754
+ this.parent = null;
755
+ this._allowUnknownOption = false;
756
+ this._allowExcessArguments = false;
757
+ this.registeredArguments = [];
758
+ this._args = this.registeredArguments;
759
+ this.args = [];
760
+ this.rawArgs = [];
761
+ this.processedArgs = [];
762
+ this._scriptPath = null;
763
+ this._name = name || "";
764
+ this._optionValues = {};
765
+ this._optionValueSources = {};
766
+ this._storeOptionsAsProperties = false;
767
+ this._actionHandler = null;
768
+ this._executableHandler = false;
769
+ this._executableFile = null;
770
+ this._executableDir = null;
771
+ this._defaultCommandName = null;
772
+ this._exitCallback = null;
773
+ this._aliases = [];
774
+ this._combineFlagAndOptionalValue = true;
775
+ this._description = "";
776
+ this._summary = "";
777
+ this._argsDescription = undefined;
778
+ this._enablePositionalOptions = false;
779
+ this._passThroughOptions = false;
780
+ this._lifeCycleHooks = {};
781
+ this._showHelpAfterError = false;
782
+ this._showSuggestionAfterError = true;
783
+ this._savedState = null;
784
+ this._outputConfiguration = {
785
+ writeOut: (str) => process2.stdout.write(str),
786
+ writeErr: (str) => process2.stderr.write(str),
787
+ outputError: (str, write) => write(str),
788
+ getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : undefined,
789
+ getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : undefined,
790
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
791
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
792
+ stripColor: (str) => stripColor(str)
793
+ };
794
+ this._hidden = false;
795
+ this._helpOption = undefined;
796
+ this._addImplicitHelpCommand = undefined;
797
+ this._helpCommand = undefined;
798
+ this._helpConfiguration = {};
799
+ }
800
+ copyInheritedSettings(sourceCommand) {
801
+ this._outputConfiguration = sourceCommand._outputConfiguration;
802
+ this._helpOption = sourceCommand._helpOption;
803
+ this._helpCommand = sourceCommand._helpCommand;
804
+ this._helpConfiguration = sourceCommand._helpConfiguration;
805
+ this._exitCallback = sourceCommand._exitCallback;
806
+ this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
807
+ this._combineFlagAndOptionalValue = sourceCommand._combineFlagAndOptionalValue;
808
+ this._allowExcessArguments = sourceCommand._allowExcessArguments;
809
+ this._enablePositionalOptions = sourceCommand._enablePositionalOptions;
810
+ this._showHelpAfterError = sourceCommand._showHelpAfterError;
811
+ this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
812
+ return this;
813
+ }
814
+ _getCommandAndAncestors() {
815
+ const result = [];
816
+ for (let command = this;command; command = command.parent) {
817
+ result.push(command);
818
+ }
819
+ return result;
820
+ }
821
+ command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
822
+ let desc = actionOptsOrExecDesc;
823
+ let opts = execOpts;
824
+ if (typeof desc === "object" && desc !== null) {
825
+ opts = desc;
826
+ desc = null;
827
+ }
828
+ opts = opts || {};
829
+ const [, name, args] = nameAndArgs.match(/([^ ]+) *(.*)/);
830
+ const cmd = this.createCommand(name);
831
+ if (desc) {
832
+ cmd.description(desc);
833
+ cmd._executableHandler = true;
834
+ }
835
+ if (opts.isDefault)
836
+ this._defaultCommandName = cmd._name;
837
+ cmd._hidden = !!(opts.noHelp || opts.hidden);
838
+ cmd._executableFile = opts.executableFile || null;
839
+ if (args)
840
+ cmd.arguments(args);
841
+ this._registerCommand(cmd);
842
+ cmd.parent = this;
843
+ cmd.copyInheritedSettings(this);
844
+ if (desc)
845
+ return this;
846
+ return cmd;
847
+ }
848
+ createCommand(name) {
849
+ return new Command(name);
850
+ }
851
+ createHelp() {
852
+ return Object.assign(new Help, this.configureHelp());
853
+ }
854
+ configureHelp(configuration) {
855
+ if (configuration === undefined)
856
+ return this._helpConfiguration;
857
+ this._helpConfiguration = configuration;
858
+ return this;
859
+ }
860
+ configureOutput(configuration) {
861
+ if (configuration === undefined)
862
+ return this._outputConfiguration;
863
+ Object.assign(this._outputConfiguration, configuration);
864
+ return this;
865
+ }
866
+ showHelpAfterError(displayHelp = true) {
867
+ if (typeof displayHelp !== "string")
868
+ displayHelp = !!displayHelp;
869
+ this._showHelpAfterError = displayHelp;
870
+ return this;
871
+ }
872
+ showSuggestionAfterError(displaySuggestion = true) {
873
+ this._showSuggestionAfterError = !!displaySuggestion;
874
+ return this;
875
+ }
876
+ addCommand(cmd, opts) {
877
+ if (!cmd._name) {
878
+ throw new Error(`Command passed to .addCommand() must have a name
879
+ - specify the name in Command constructor or using .name()`);
880
+ }
881
+ opts = opts || {};
882
+ if (opts.isDefault)
883
+ this._defaultCommandName = cmd._name;
884
+ if (opts.noHelp || opts.hidden)
885
+ cmd._hidden = true;
886
+ this._registerCommand(cmd);
887
+ cmd.parent = this;
888
+ cmd._checkForBrokenPassThrough();
889
+ return this;
890
+ }
891
+ createArgument(name, description) {
892
+ return new Argument(name, description);
893
+ }
894
+ argument(name, description, fn, defaultValue) {
895
+ const argument = this.createArgument(name, description);
896
+ if (typeof fn === "function") {
897
+ argument.default(defaultValue).argParser(fn);
898
+ } else {
899
+ argument.default(fn);
900
+ }
901
+ this.addArgument(argument);
902
+ return this;
903
+ }
904
+ arguments(names) {
905
+ names.trim().split(/ +/).forEach((detail) => {
906
+ this.argument(detail);
907
+ });
908
+ return this;
909
+ }
910
+ addArgument(argument) {
911
+ const previousArgument = this.registeredArguments.slice(-1)[0];
912
+ if (previousArgument && previousArgument.variadic) {
913
+ throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
914
+ }
915
+ if (argument.required && argument.defaultValue !== undefined && argument.parseArg === undefined) {
916
+ throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
917
+ }
918
+ this.registeredArguments.push(argument);
919
+ return this;
920
+ }
921
+ helpCommand(enableOrNameAndArgs, description) {
922
+ if (typeof enableOrNameAndArgs === "boolean") {
923
+ this._addImplicitHelpCommand = enableOrNameAndArgs;
924
+ return this;
925
+ }
926
+ enableOrNameAndArgs = enableOrNameAndArgs ?? "help [command]";
927
+ const [, helpName, helpArgs] = enableOrNameAndArgs.match(/([^ ]+) *(.*)/);
928
+ const helpDescription = description ?? "display help for command";
929
+ const helpCommand = this.createCommand(helpName);
930
+ helpCommand.helpOption(false);
931
+ if (helpArgs)
932
+ helpCommand.arguments(helpArgs);
933
+ if (helpDescription)
934
+ helpCommand.description(helpDescription);
935
+ this._addImplicitHelpCommand = true;
936
+ this._helpCommand = helpCommand;
937
+ return this;
938
+ }
939
+ addHelpCommand(helpCommand, deprecatedDescription) {
940
+ if (typeof helpCommand !== "object") {
941
+ this.helpCommand(helpCommand, deprecatedDescription);
942
+ return this;
943
+ }
944
+ this._addImplicitHelpCommand = true;
945
+ this._helpCommand = helpCommand;
946
+ return this;
947
+ }
948
+ _getHelpCommand() {
949
+ const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
950
+ if (hasImplicitHelpCommand) {
951
+ if (this._helpCommand === undefined) {
952
+ this.helpCommand(undefined, undefined);
953
+ }
954
+ return this._helpCommand;
955
+ }
956
+ return null;
957
+ }
958
+ hook(event, listener) {
959
+ const allowedValues = ["preSubcommand", "preAction", "postAction"];
960
+ if (!allowedValues.includes(event)) {
961
+ throw new Error(`Unexpected value for event passed to hook : '${event}'.
962
+ Expecting one of '${allowedValues.join("', '")}'`);
963
+ }
964
+ if (this._lifeCycleHooks[event]) {
965
+ this._lifeCycleHooks[event].push(listener);
966
+ } else {
967
+ this._lifeCycleHooks[event] = [listener];
968
+ }
969
+ return this;
970
+ }
971
+ exitOverride(fn) {
972
+ if (fn) {
973
+ this._exitCallback = fn;
974
+ } else {
975
+ this._exitCallback = (err) => {
976
+ if (err.code !== "commander.executeSubCommandAsync") {
977
+ throw err;
978
+ } else {}
979
+ };
980
+ }
981
+ return this;
982
+ }
983
+ _exit(exitCode, code, message) {
984
+ if (this._exitCallback) {
985
+ this._exitCallback(new CommanderError(exitCode, code, message));
986
+ }
987
+ process2.exit(exitCode);
988
+ }
989
+ action(fn) {
990
+ const listener = (args) => {
991
+ const expectedArgsCount = this.registeredArguments.length;
992
+ const actionArgs = args.slice(0, expectedArgsCount);
993
+ if (this._storeOptionsAsProperties) {
994
+ actionArgs[expectedArgsCount] = this;
995
+ } else {
996
+ actionArgs[expectedArgsCount] = this.opts();
997
+ }
998
+ actionArgs.push(this);
999
+ return fn.apply(this, actionArgs);
1000
+ };
1001
+ this._actionHandler = listener;
1002
+ return this;
1003
+ }
1004
+ createOption(flags, description) {
1005
+ return new Option(flags, description);
1006
+ }
1007
+ _callParseArg(target, value, previous, invalidArgumentMessage) {
1008
+ try {
1009
+ return target.parseArg(value, previous);
1010
+ } catch (err) {
1011
+ if (err.code === "commander.invalidArgument") {
1012
+ const message = `${invalidArgumentMessage} ${err.message}`;
1013
+ this.error(message, { exitCode: err.exitCode, code: err.code });
1014
+ }
1015
+ throw err;
1016
+ }
1017
+ }
1018
+ _registerOption(option) {
1019
+ const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
1020
+ if (matchingOption) {
1021
+ const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
1022
+ throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
1023
+ - already used by option '${matchingOption.flags}'`);
1024
+ }
1025
+ this.options.push(option);
1026
+ }
1027
+ _registerCommand(command) {
1028
+ const knownBy = (cmd) => {
1029
+ return [cmd.name()].concat(cmd.aliases());
1030
+ };
1031
+ const alreadyUsed = knownBy(command).find((name) => this._findCommand(name));
1032
+ if (alreadyUsed) {
1033
+ const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
1034
+ const newCmd = knownBy(command).join("|");
1035
+ throw new Error(`cannot add command '${newCmd}' as already have command '${existingCmd}'`);
1036
+ }
1037
+ this.commands.push(command);
1038
+ }
1039
+ addOption(option) {
1040
+ this._registerOption(option);
1041
+ const oname = option.name();
1042
+ const name = option.attributeName();
1043
+ if (option.negate) {
1044
+ const positiveLongFlag = option.long.replace(/^--no-/, "--");
1045
+ if (!this._findOption(positiveLongFlag)) {
1046
+ this.setOptionValueWithSource(name, option.defaultValue === undefined ? true : option.defaultValue, "default");
1047
+ }
1048
+ } else if (option.defaultValue !== undefined) {
1049
+ this.setOptionValueWithSource(name, option.defaultValue, "default");
1050
+ }
1051
+ const handleOptionValue = (val, invalidValueMessage, valueSource) => {
1052
+ if (val == null && option.presetArg !== undefined) {
1053
+ val = option.presetArg;
1054
+ }
1055
+ const oldValue = this.getOptionValue(name);
1056
+ if (val !== null && option.parseArg) {
1057
+ val = this._callParseArg(option, val, oldValue, invalidValueMessage);
1058
+ } else if (val !== null && option.variadic) {
1059
+ val = option._concatValue(val, oldValue);
1060
+ }
1061
+ if (val == null) {
1062
+ if (option.negate) {
1063
+ val = false;
1064
+ } else if (option.isBoolean() || option.optional) {
1065
+ val = true;
1066
+ } else {
1067
+ val = "";
1068
+ }
1069
+ }
1070
+ this.setOptionValueWithSource(name, val, valueSource);
1071
+ };
1072
+ this.on("option:" + oname, (val) => {
1073
+ const invalidValueMessage = `error: option '${option.flags}' argument '${val}' is invalid.`;
1074
+ handleOptionValue(val, invalidValueMessage, "cli");
1075
+ });
1076
+ if (option.envVar) {
1077
+ this.on("optionEnv:" + oname, (val) => {
1078
+ const invalidValueMessage = `error: option '${option.flags}' value '${val}' from env '${option.envVar}' is invalid.`;
1079
+ handleOptionValue(val, invalidValueMessage, "env");
1080
+ });
1081
+ }
1082
+ return this;
1083
+ }
1084
+ _optionEx(config, flags, description, fn, defaultValue) {
1085
+ if (typeof flags === "object" && flags instanceof Option) {
1086
+ throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
1087
+ }
1088
+ const option = this.createOption(flags, description);
1089
+ option.makeOptionMandatory(!!config.mandatory);
1090
+ if (typeof fn === "function") {
1091
+ option.default(defaultValue).argParser(fn);
1092
+ } else if (fn instanceof RegExp) {
1093
+ const regex = fn;
1094
+ fn = (val, def) => {
1095
+ const m = regex.exec(val);
1096
+ return m ? m[0] : def;
1097
+ };
1098
+ option.default(defaultValue).argParser(fn);
1099
+ } else {
1100
+ option.default(fn);
1101
+ }
1102
+ return this.addOption(option);
1103
+ }
1104
+ option(flags, description, parseArg, defaultValue) {
1105
+ return this._optionEx({}, flags, description, parseArg, defaultValue);
1106
+ }
1107
+ requiredOption(flags, description, parseArg, defaultValue) {
1108
+ return this._optionEx({ mandatory: true }, flags, description, parseArg, defaultValue);
1109
+ }
1110
+ combineFlagAndOptionalValue(combine = true) {
1111
+ this._combineFlagAndOptionalValue = !!combine;
1112
+ return this;
1113
+ }
1114
+ allowUnknownOption(allowUnknown = true) {
1115
+ this._allowUnknownOption = !!allowUnknown;
1116
+ return this;
1117
+ }
1118
+ allowExcessArguments(allowExcess = true) {
1119
+ this._allowExcessArguments = !!allowExcess;
1120
+ return this;
1121
+ }
1122
+ enablePositionalOptions(positional = true) {
1123
+ this._enablePositionalOptions = !!positional;
1124
+ return this;
1125
+ }
1126
+ passThroughOptions(passThrough = true) {
1127
+ this._passThroughOptions = !!passThrough;
1128
+ this._checkForBrokenPassThrough();
1129
+ return this;
1130
+ }
1131
+ _checkForBrokenPassThrough() {
1132
+ if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
1133
+ throw new Error(`passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`);
1134
+ }
1135
+ }
1136
+ storeOptionsAsProperties(storeAsProperties = true) {
1137
+ if (this.options.length) {
1138
+ throw new Error("call .storeOptionsAsProperties() before adding options");
1139
+ }
1140
+ if (Object.keys(this._optionValues).length) {
1141
+ throw new Error("call .storeOptionsAsProperties() before setting option values");
1142
+ }
1143
+ this._storeOptionsAsProperties = !!storeAsProperties;
1144
+ return this;
1145
+ }
1146
+ getOptionValue(key) {
1147
+ if (this._storeOptionsAsProperties) {
1148
+ return this[key];
1149
+ }
1150
+ return this._optionValues[key];
1151
+ }
1152
+ setOptionValue(key, value) {
1153
+ return this.setOptionValueWithSource(key, value, undefined);
1154
+ }
1155
+ setOptionValueWithSource(key, value, source) {
1156
+ if (this._storeOptionsAsProperties) {
1157
+ this[key] = value;
1158
+ } else {
1159
+ this._optionValues[key] = value;
1160
+ }
1161
+ this._optionValueSources[key] = source;
1162
+ return this;
1163
+ }
1164
+ getOptionValueSource(key) {
1165
+ return this._optionValueSources[key];
1166
+ }
1167
+ getOptionValueSourceWithGlobals(key) {
1168
+ let source;
1169
+ this._getCommandAndAncestors().forEach((cmd) => {
1170
+ if (cmd.getOptionValueSource(key) !== undefined) {
1171
+ source = cmd.getOptionValueSource(key);
1172
+ }
1173
+ });
1174
+ return source;
1175
+ }
1176
+ _prepareUserArgs(argv, parseOptions) {
1177
+ if (argv !== undefined && !Array.isArray(argv)) {
1178
+ throw new Error("first parameter to parse must be array or undefined");
1179
+ }
1180
+ parseOptions = parseOptions || {};
1181
+ if (argv === undefined && parseOptions.from === undefined) {
1182
+ if (process2.versions?.electron) {
1183
+ parseOptions.from = "electron";
1184
+ }
1185
+ const execArgv = process2.execArgv ?? [];
1186
+ if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
1187
+ parseOptions.from = "eval";
1188
+ }
1189
+ }
1190
+ if (argv === undefined) {
1191
+ argv = process2.argv;
1192
+ }
1193
+ this.rawArgs = argv.slice();
1194
+ let userArgs;
1195
+ switch (parseOptions.from) {
1196
+ case undefined:
1197
+ case "node":
1198
+ this._scriptPath = argv[1];
1199
+ userArgs = argv.slice(2);
1200
+ break;
1201
+ case "electron":
1202
+ if (process2.defaultApp) {
1203
+ this._scriptPath = argv[1];
1204
+ userArgs = argv.slice(2);
1205
+ } else {
1206
+ userArgs = argv.slice(1);
1207
+ }
1208
+ break;
1209
+ case "user":
1210
+ userArgs = argv.slice(0);
1211
+ break;
1212
+ case "eval":
1213
+ userArgs = argv.slice(1);
1214
+ break;
1215
+ default:
1216
+ throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
1217
+ }
1218
+ if (!this._name && this._scriptPath)
1219
+ this.nameFromFilename(this._scriptPath);
1220
+ this._name = this._name || "program";
1221
+ return userArgs;
1222
+ }
1223
+ parse(argv, parseOptions) {
1224
+ this._prepareForParse();
1225
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
1226
+ this._parseCommand([], userArgs);
1227
+ return this;
1228
+ }
1229
+ async parseAsync(argv, parseOptions) {
1230
+ this._prepareForParse();
1231
+ const userArgs = this._prepareUserArgs(argv, parseOptions);
1232
+ await this._parseCommand([], userArgs);
1233
+ return this;
1234
+ }
1235
+ _prepareForParse() {
1236
+ if (this._savedState === null) {
1237
+ this.saveStateBeforeParse();
1238
+ } else {
1239
+ this.restoreStateBeforeParse();
1240
+ }
1241
+ }
1242
+ saveStateBeforeParse() {
1243
+ this._savedState = {
1244
+ _name: this._name,
1245
+ _optionValues: { ...this._optionValues },
1246
+ _optionValueSources: { ...this._optionValueSources }
1247
+ };
1248
+ }
1249
+ restoreStateBeforeParse() {
1250
+ if (this._storeOptionsAsProperties)
1251
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
1252
+ - either make a new Command for each call to parse, or stop storing options as properties`);
1253
+ this._name = this._savedState._name;
1254
+ this._scriptPath = null;
1255
+ this.rawArgs = [];
1256
+ this._optionValues = { ...this._savedState._optionValues };
1257
+ this._optionValueSources = { ...this._savedState._optionValueSources };
1258
+ this.args = [];
1259
+ this.processedArgs = [];
1260
+ }
1261
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
1262
+ if (fs.existsSync(executableFile))
1263
+ return;
1264
+ const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
1265
+ const executableMissing = `'${executableFile}' does not exist
1266
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1267
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1268
+ - ${executableDirMessage}`;
1269
+ throw new Error(executableMissing);
1270
+ }
1271
+ _executeSubCommand(subcommand, args) {
1272
+ args = args.slice();
1273
+ let launchWithNode = false;
1274
+ const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1275
+ function findFile(baseDir, baseName) {
1276
+ const localBin = path.resolve(baseDir, baseName);
1277
+ if (fs.existsSync(localBin))
1278
+ return localBin;
1279
+ if (sourceExt.includes(path.extname(baseName)))
1280
+ return;
1281
+ const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
1282
+ if (foundExt)
1283
+ return `${localBin}${foundExt}`;
1284
+ return;
1285
+ }
1286
+ this._checkForMissingMandatoryOptions();
1287
+ this._checkForConflictingOptions();
1288
+ let executableFile = subcommand._executableFile || `${this._name}-${subcommand._name}`;
1289
+ let executableDir = this._executableDir || "";
1290
+ if (this._scriptPath) {
1291
+ let resolvedScriptPath;
1292
+ try {
1293
+ resolvedScriptPath = fs.realpathSync(this._scriptPath);
1294
+ } catch {
1295
+ resolvedScriptPath = this._scriptPath;
1296
+ }
1297
+ executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
1298
+ }
1299
+ if (executableDir) {
1300
+ let localFile = findFile(executableDir, executableFile);
1301
+ if (!localFile && !subcommand._executableFile && this._scriptPath) {
1302
+ const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
1303
+ if (legacyName !== this._name) {
1304
+ localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
1305
+ }
1306
+ }
1307
+ executableFile = localFile || executableFile;
1308
+ }
1309
+ launchWithNode = sourceExt.includes(path.extname(executableFile));
1310
+ let proc;
1311
+ if (process2.platform !== "win32") {
1312
+ if (launchWithNode) {
1313
+ args.unshift(executableFile);
1314
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1315
+ proc = childProcess.spawn(process2.argv[0], args, { stdio: "inherit" });
1316
+ } else {
1317
+ proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1318
+ }
1319
+ } else {
1320
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1321
+ args.unshift(executableFile);
1322
+ args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1323
+ proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
1324
+ }
1325
+ if (!proc.killed) {
1326
+ const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
1327
+ signals.forEach((signal) => {
1328
+ process2.on(signal, () => {
1329
+ if (proc.killed === false && proc.exitCode === null) {
1330
+ proc.kill(signal);
1331
+ }
1332
+ });
1333
+ });
1334
+ }
1335
+ const exitCallback = this._exitCallback;
1336
+ proc.on("close", (code) => {
1337
+ code = code ?? 1;
1338
+ if (!exitCallback) {
1339
+ process2.exit(code);
1340
+ } else {
1341
+ exitCallback(new CommanderError(code, "commander.executeSubCommandAsync", "(close)"));
1342
+ }
1343
+ });
1344
+ proc.on("error", (err) => {
1345
+ if (err.code === "ENOENT") {
1346
+ this._checkForMissingExecutable(executableFile, executableDir, subcommand._name);
1347
+ } else if (err.code === "EACCES") {
1348
+ throw new Error(`'${executableFile}' not executable`);
1349
+ }
1350
+ if (!exitCallback) {
1351
+ process2.exit(1);
1352
+ } else {
1353
+ const wrappedError = new CommanderError(1, "commander.executeSubCommandAsync", "(error)");
1354
+ wrappedError.nestedError = err;
1355
+ exitCallback(wrappedError);
1356
+ }
1357
+ });
1358
+ this.runningCommand = proc;
1359
+ }
1360
+ _dispatchSubcommand(commandName, operands, unknown) {
1361
+ const subCommand = this._findCommand(commandName);
1362
+ if (!subCommand)
1363
+ this.help({ error: true });
1364
+ subCommand._prepareForParse();
1365
+ let promiseChain;
1366
+ promiseChain = this._chainOrCallSubCommandHook(promiseChain, subCommand, "preSubcommand");
1367
+ promiseChain = this._chainOrCall(promiseChain, () => {
1368
+ if (subCommand._executableHandler) {
1369
+ this._executeSubCommand(subCommand, operands.concat(unknown));
1370
+ } else {
1371
+ return subCommand._parseCommand(operands, unknown);
1372
+ }
1373
+ });
1374
+ return promiseChain;
1375
+ }
1376
+ _dispatchHelpCommand(subcommandName) {
1377
+ if (!subcommandName) {
1378
+ this.help();
1379
+ }
1380
+ const subCommand = this._findCommand(subcommandName);
1381
+ if (subCommand && !subCommand._executableHandler) {
1382
+ subCommand.help();
1383
+ }
1384
+ return this._dispatchSubcommand(subcommandName, [], [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]);
1385
+ }
1386
+ _checkNumberOfArguments() {
1387
+ this.registeredArguments.forEach((arg, i) => {
1388
+ if (arg.required && this.args[i] == null) {
1389
+ this.missingArgument(arg.name());
1390
+ }
1391
+ });
1392
+ if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
1393
+ return;
1394
+ }
1395
+ if (this.args.length > this.registeredArguments.length) {
1396
+ this._excessArguments(this.args);
1397
+ }
1398
+ }
1399
+ _processArguments() {
1400
+ const myParseArg = (argument, value, previous) => {
1401
+ let parsedValue = value;
1402
+ if (value !== null && argument.parseArg) {
1403
+ const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
1404
+ parsedValue = this._callParseArg(argument, value, previous, invalidValueMessage);
1405
+ }
1406
+ return parsedValue;
1407
+ };
1408
+ this._checkNumberOfArguments();
1409
+ const processedArgs = [];
1410
+ this.registeredArguments.forEach((declaredArg, index) => {
1411
+ let value = declaredArg.defaultValue;
1412
+ if (declaredArg.variadic) {
1413
+ if (index < this.args.length) {
1414
+ value = this.args.slice(index);
1415
+ if (declaredArg.parseArg) {
1416
+ value = value.reduce((processed, v) => {
1417
+ return myParseArg(declaredArg, v, processed);
1418
+ }, declaredArg.defaultValue);
1419
+ }
1420
+ } else if (value === undefined) {
1421
+ value = [];
1422
+ }
1423
+ } else if (index < this.args.length) {
1424
+ value = this.args[index];
1425
+ if (declaredArg.parseArg) {
1426
+ value = myParseArg(declaredArg, value, declaredArg.defaultValue);
1427
+ }
1428
+ }
1429
+ processedArgs[index] = value;
1430
+ });
1431
+ this.processedArgs = processedArgs;
1432
+ }
1433
+ _chainOrCall(promise, fn) {
1434
+ if (promise && promise.then && typeof promise.then === "function") {
1435
+ return promise.then(() => fn());
1436
+ }
1437
+ return fn();
1438
+ }
1439
+ _chainOrCallHooks(promise, event) {
1440
+ let result = promise;
1441
+ const hooks = [];
1442
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== undefined).forEach((hookedCommand) => {
1443
+ hookedCommand._lifeCycleHooks[event].forEach((callback) => {
1444
+ hooks.push({ hookedCommand, callback });
1445
+ });
1446
+ });
1447
+ if (event === "postAction") {
1448
+ hooks.reverse();
1449
+ }
1450
+ hooks.forEach((hookDetail) => {
1451
+ result = this._chainOrCall(result, () => {
1452
+ return hookDetail.callback(hookDetail.hookedCommand, this);
1453
+ });
1454
+ });
1455
+ return result;
1456
+ }
1457
+ _chainOrCallSubCommandHook(promise, subCommand, event) {
1458
+ let result = promise;
1459
+ if (this._lifeCycleHooks[event] !== undefined) {
1460
+ this._lifeCycleHooks[event].forEach((hook) => {
1461
+ result = this._chainOrCall(result, () => {
1462
+ return hook(this, subCommand);
1463
+ });
1464
+ });
1465
+ }
1466
+ return result;
1467
+ }
1468
+ _parseCommand(operands, unknown) {
1469
+ const parsed = this.parseOptions(unknown);
1470
+ this._parseOptionsEnv();
1471
+ this._parseOptionsImplied();
1472
+ operands = operands.concat(parsed.operands);
1473
+ unknown = parsed.unknown;
1474
+ this.args = operands.concat(unknown);
1475
+ if (operands && this._findCommand(operands[0])) {
1476
+ return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
1477
+ }
1478
+ if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
1479
+ return this._dispatchHelpCommand(operands[1]);
1480
+ }
1481
+ if (this._defaultCommandName) {
1482
+ this._outputHelpIfRequested(unknown);
1483
+ return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
1484
+ }
1485
+ if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
1486
+ this.help({ error: true });
1487
+ }
1488
+ this._outputHelpIfRequested(parsed.unknown);
1489
+ this._checkForMissingMandatoryOptions();
1490
+ this._checkForConflictingOptions();
1491
+ const checkForUnknownOptions = () => {
1492
+ if (parsed.unknown.length > 0) {
1493
+ this.unknownOption(parsed.unknown[0]);
1494
+ }
1495
+ };
1496
+ const commandEvent = `command:${this.name()}`;
1497
+ if (this._actionHandler) {
1498
+ checkForUnknownOptions();
1499
+ this._processArguments();
1500
+ let promiseChain;
1501
+ promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
1502
+ promiseChain = this._chainOrCall(promiseChain, () => this._actionHandler(this.processedArgs));
1503
+ if (this.parent) {
1504
+ promiseChain = this._chainOrCall(promiseChain, () => {
1505
+ this.parent.emit(commandEvent, operands, unknown);
1506
+ });
1507
+ }
1508
+ promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
1509
+ return promiseChain;
1510
+ }
1511
+ if (this.parent && this.parent.listenerCount(commandEvent)) {
1512
+ checkForUnknownOptions();
1513
+ this._processArguments();
1514
+ this.parent.emit(commandEvent, operands, unknown);
1515
+ } else if (operands.length) {
1516
+ if (this._findCommand("*")) {
1517
+ return this._dispatchSubcommand("*", operands, unknown);
1518
+ }
1519
+ if (this.listenerCount("command:*")) {
1520
+ this.emit("command:*", operands, unknown);
1521
+ } else if (this.commands.length) {
1522
+ this.unknownCommand();
1523
+ } else {
1524
+ checkForUnknownOptions();
1525
+ this._processArguments();
1526
+ }
1527
+ } else if (this.commands.length) {
1528
+ checkForUnknownOptions();
1529
+ this.help({ error: true });
1530
+ } else {
1531
+ checkForUnknownOptions();
1532
+ this._processArguments();
1533
+ }
1534
+ }
1535
+ _findCommand(name) {
1536
+ if (!name)
1537
+ return;
1538
+ return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
1539
+ }
1540
+ _findOption(arg) {
1541
+ return this.options.find((option) => option.is(arg));
1542
+ }
1543
+ _checkForMissingMandatoryOptions() {
1544
+ this._getCommandAndAncestors().forEach((cmd) => {
1545
+ cmd.options.forEach((anOption) => {
1546
+ if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === undefined) {
1547
+ cmd.missingMandatoryOptionValue(anOption);
1548
+ }
1549
+ });
1550
+ });
1551
+ }
1552
+ _checkForConflictingLocalOptions() {
1553
+ const definedNonDefaultOptions = this.options.filter((option) => {
1554
+ const optionKey = option.attributeName();
1555
+ if (this.getOptionValue(optionKey) === undefined) {
1556
+ return false;
1557
+ }
1558
+ return this.getOptionValueSource(optionKey) !== "default";
1559
+ });
1560
+ const optionsWithConflicting = definedNonDefaultOptions.filter((option) => option.conflictsWith.length > 0);
1561
+ optionsWithConflicting.forEach((option) => {
1562
+ const conflictingAndDefined = definedNonDefaultOptions.find((defined) => option.conflictsWith.includes(defined.attributeName()));
1563
+ if (conflictingAndDefined) {
1564
+ this._conflictingOption(option, conflictingAndDefined);
1565
+ }
1566
+ });
1567
+ }
1568
+ _checkForConflictingOptions() {
1569
+ this._getCommandAndAncestors().forEach((cmd) => {
1570
+ cmd._checkForConflictingLocalOptions();
1571
+ });
1572
+ }
1573
+ parseOptions(argv) {
1574
+ const operands = [];
1575
+ const unknown = [];
1576
+ let dest = operands;
1577
+ const args = argv.slice();
1578
+ function maybeOption(arg) {
1579
+ return arg.length > 1 && arg[0] === "-";
1580
+ }
1581
+ let activeVariadicOption = null;
1582
+ while (args.length) {
1583
+ const arg = args.shift();
1584
+ if (arg === "--") {
1585
+ if (dest === unknown)
1586
+ dest.push(arg);
1587
+ dest.push(...args);
1588
+ break;
1589
+ }
1590
+ if (activeVariadicOption && !maybeOption(arg)) {
1591
+ this.emit(`option:${activeVariadicOption.name()}`, arg);
1592
+ continue;
1593
+ }
1594
+ activeVariadicOption = null;
1595
+ if (maybeOption(arg)) {
1596
+ const option = this._findOption(arg);
1597
+ if (option) {
1598
+ if (option.required) {
1599
+ const value = args.shift();
1600
+ if (value === undefined)
1601
+ this.optionMissingArgument(option);
1602
+ this.emit(`option:${option.name()}`, value);
1603
+ } else if (option.optional) {
1604
+ let value = null;
1605
+ if (args.length > 0 && !maybeOption(args[0])) {
1606
+ value = args.shift();
1607
+ }
1608
+ this.emit(`option:${option.name()}`, value);
1609
+ } else {
1610
+ this.emit(`option:${option.name()}`);
1611
+ }
1612
+ activeVariadicOption = option.variadic ? option : null;
1613
+ continue;
1614
+ }
1615
+ }
1616
+ if (arg.length > 2 && arg[0] === "-" && arg[1] !== "-") {
1617
+ const option = this._findOption(`-${arg[1]}`);
1618
+ if (option) {
1619
+ if (option.required || option.optional && this._combineFlagAndOptionalValue) {
1620
+ this.emit(`option:${option.name()}`, arg.slice(2));
1621
+ } else {
1622
+ this.emit(`option:${option.name()}`);
1623
+ args.unshift(`-${arg.slice(2)}`);
1624
+ }
1625
+ continue;
1626
+ }
1627
+ }
1628
+ if (/^--[^=]+=/.test(arg)) {
1629
+ const index = arg.indexOf("=");
1630
+ const option = this._findOption(arg.slice(0, index));
1631
+ if (option && (option.required || option.optional)) {
1632
+ this.emit(`option:${option.name()}`, arg.slice(index + 1));
1633
+ continue;
1634
+ }
1635
+ }
1636
+ if (maybeOption(arg)) {
1637
+ dest = unknown;
1638
+ }
1639
+ if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
1640
+ if (this._findCommand(arg)) {
1641
+ operands.push(arg);
1642
+ if (args.length > 0)
1643
+ unknown.push(...args);
1644
+ break;
1645
+ } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
1646
+ operands.push(arg);
1647
+ if (args.length > 0)
1648
+ operands.push(...args);
1649
+ break;
1650
+ } else if (this._defaultCommandName) {
1651
+ unknown.push(arg);
1652
+ if (args.length > 0)
1653
+ unknown.push(...args);
1654
+ break;
1655
+ }
1656
+ }
1657
+ if (this._passThroughOptions) {
1658
+ dest.push(arg);
1659
+ if (args.length > 0)
1660
+ dest.push(...args);
1661
+ break;
1662
+ }
1663
+ dest.push(arg);
1664
+ }
1665
+ return { operands, unknown };
1666
+ }
1667
+ opts() {
1668
+ if (this._storeOptionsAsProperties) {
1669
+ const result = {};
1670
+ const len = this.options.length;
1671
+ for (let i = 0;i < len; i++) {
1672
+ const key = this.options[i].attributeName();
1673
+ result[key] = key === this._versionOptionName ? this._version : this[key];
1674
+ }
1675
+ return result;
1676
+ }
1677
+ return this._optionValues;
1678
+ }
1679
+ optsWithGlobals() {
1680
+ return this._getCommandAndAncestors().reduce((combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()), {});
1681
+ }
1682
+ error(message, errorOptions) {
1683
+ this._outputConfiguration.outputError(`${message}
1684
+ `, this._outputConfiguration.writeErr);
1685
+ if (typeof this._showHelpAfterError === "string") {
1686
+ this._outputConfiguration.writeErr(`${this._showHelpAfterError}
1687
+ `);
1688
+ } else if (this._showHelpAfterError) {
1689
+ this._outputConfiguration.writeErr(`
1690
+ `);
1691
+ this.outputHelp({ error: true });
1692
+ }
1693
+ const config = errorOptions || {};
1694
+ const exitCode = config.exitCode || 1;
1695
+ const code = config.code || "commander.error";
1696
+ this._exit(exitCode, code, message);
1697
+ }
1698
+ _parseOptionsEnv() {
1699
+ this.options.forEach((option) => {
1700
+ if (option.envVar && option.envVar in process2.env) {
1701
+ const optionKey = option.attributeName();
1702
+ if (this.getOptionValue(optionKey) === undefined || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
1703
+ if (option.required || option.optional) {
1704
+ this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
1705
+ } else {
1706
+ this.emit(`optionEnv:${option.name()}`);
1707
+ }
1708
+ }
1709
+ }
1710
+ });
1711
+ }
1712
+ _parseOptionsImplied() {
1713
+ const dualHelper = new DualOptions(this.options);
1714
+ const hasCustomOptionValue = (optionKey) => {
1715
+ return this.getOptionValue(optionKey) !== undefined && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
1716
+ };
1717
+ this.options.filter((option) => option.implied !== undefined && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
1718
+ Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
1719
+ this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
1720
+ });
1721
+ });
1722
+ }
1723
+ missingArgument(name) {
1724
+ const message = `error: missing required argument '${name}'`;
1725
+ this.error(message, { code: "commander.missingArgument" });
1726
+ }
1727
+ optionMissingArgument(option) {
1728
+ const message = `error: option '${option.flags}' argument missing`;
1729
+ this.error(message, { code: "commander.optionMissingArgument" });
1730
+ }
1731
+ missingMandatoryOptionValue(option) {
1732
+ const message = `error: required option '${option.flags}' not specified`;
1733
+ this.error(message, { code: "commander.missingMandatoryOptionValue" });
1734
+ }
1735
+ _conflictingOption(option, conflictingOption) {
1736
+ const findBestOptionFromValue = (option2) => {
1737
+ const optionKey = option2.attributeName();
1738
+ const optionValue = this.getOptionValue(optionKey);
1739
+ const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
1740
+ const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
1741
+ if (negativeOption && (negativeOption.presetArg === undefined && optionValue === false || negativeOption.presetArg !== undefined && optionValue === negativeOption.presetArg)) {
1742
+ return negativeOption;
1743
+ }
1744
+ return positiveOption || option2;
1745
+ };
1746
+ const getErrorMessage = (option2) => {
1747
+ const bestOption = findBestOptionFromValue(option2);
1748
+ const optionKey = bestOption.attributeName();
1749
+ const source = this.getOptionValueSource(optionKey);
1750
+ if (source === "env") {
1751
+ return `environment variable '${bestOption.envVar}'`;
1752
+ }
1753
+ return `option '${bestOption.flags}'`;
1754
+ };
1755
+ const message = `error: ${getErrorMessage(option)} cannot be used with ${getErrorMessage(conflictingOption)}`;
1756
+ this.error(message, { code: "commander.conflictingOption" });
1757
+ }
1758
+ unknownOption(flag) {
1759
+ if (this._allowUnknownOption)
1760
+ return;
1761
+ let suggestion = "";
1762
+ if (flag.startsWith("--") && this._showSuggestionAfterError) {
1763
+ let candidateFlags = [];
1764
+ let command = this;
1765
+ do {
1766
+ const moreFlags = command.createHelp().visibleOptions(command).filter((option) => option.long).map((option) => option.long);
1767
+ candidateFlags = candidateFlags.concat(moreFlags);
1768
+ command = command.parent;
1769
+ } while (command && !command._enablePositionalOptions);
1770
+ suggestion = suggestSimilar(flag, candidateFlags);
1771
+ }
1772
+ const message = `error: unknown option '${flag}'${suggestion}`;
1773
+ this.error(message, { code: "commander.unknownOption" });
1774
+ }
1775
+ _excessArguments(receivedArgs) {
1776
+ if (this._allowExcessArguments)
1777
+ return;
1778
+ const expected = this.registeredArguments.length;
1779
+ const s = expected === 1 ? "" : "s";
1780
+ const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
1781
+ const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
1782
+ this.error(message, { code: "commander.excessArguments" });
1783
+ }
1784
+ unknownCommand() {
1785
+ const unknownName = this.args[0];
1786
+ let suggestion = "";
1787
+ if (this._showSuggestionAfterError) {
1788
+ const candidateNames = [];
1789
+ this.createHelp().visibleCommands(this).forEach((command) => {
1790
+ candidateNames.push(command.name());
1791
+ if (command.alias())
1792
+ candidateNames.push(command.alias());
1793
+ });
1794
+ suggestion = suggestSimilar(unknownName, candidateNames);
1795
+ }
1796
+ const message = `error: unknown command '${unknownName}'${suggestion}`;
1797
+ this.error(message, { code: "commander.unknownCommand" });
1798
+ }
1799
+ version(str, flags, description) {
1800
+ if (str === undefined)
1801
+ return this._version;
1802
+ this._version = str;
1803
+ flags = flags || "-V, --version";
1804
+ description = description || "output the version number";
1805
+ const versionOption = this.createOption(flags, description);
1806
+ this._versionOptionName = versionOption.attributeName();
1807
+ this._registerOption(versionOption);
1808
+ this.on("option:" + versionOption.name(), () => {
1809
+ this._outputConfiguration.writeOut(`${str}
1810
+ `);
1811
+ this._exit(0, "commander.version", str);
1812
+ });
1813
+ return this;
1814
+ }
1815
+ description(str, argsDescription) {
1816
+ if (str === undefined && argsDescription === undefined)
1817
+ return this._description;
1818
+ this._description = str;
1819
+ if (argsDescription) {
1820
+ this._argsDescription = argsDescription;
1821
+ }
1822
+ return this;
1823
+ }
1824
+ summary(str) {
1825
+ if (str === undefined)
1826
+ return this._summary;
1827
+ this._summary = str;
1828
+ return this;
1829
+ }
1830
+ alias(alias) {
1831
+ if (alias === undefined)
1832
+ return this._aliases[0];
1833
+ let command = this;
1834
+ if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
1835
+ command = this.commands[this.commands.length - 1];
1836
+ }
1837
+ if (alias === command._name)
1838
+ throw new Error("Command alias can't be the same as its name");
1839
+ const matchingCommand = this.parent?._findCommand(alias);
1840
+ if (matchingCommand) {
1841
+ const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
1842
+ throw new Error(`cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`);
1843
+ }
1844
+ command._aliases.push(alias);
1845
+ return this;
1846
+ }
1847
+ aliases(aliases) {
1848
+ if (aliases === undefined)
1849
+ return this._aliases;
1850
+ aliases.forEach((alias) => this.alias(alias));
1851
+ return this;
1852
+ }
1853
+ usage(str) {
1854
+ if (str === undefined) {
1855
+ if (this._usage)
1856
+ return this._usage;
1857
+ const args = this.registeredArguments.map((arg) => {
1858
+ return humanReadableArgName(arg);
1859
+ });
1860
+ return [].concat(this.options.length || this._helpOption !== null ? "[options]" : [], this.commands.length ? "[command]" : [], this.registeredArguments.length ? args : []).join(" ");
1861
+ }
1862
+ this._usage = str;
1863
+ return this;
1864
+ }
1865
+ name(str) {
1866
+ if (str === undefined)
1867
+ return this._name;
1868
+ this._name = str;
1869
+ return this;
1870
+ }
1871
+ nameFromFilename(filename) {
1872
+ this._name = path.basename(filename, path.extname(filename));
1873
+ return this;
1874
+ }
1875
+ executableDir(path2) {
1876
+ if (path2 === undefined)
1877
+ return this._executableDir;
1878
+ this._executableDir = path2;
1879
+ return this;
1880
+ }
1881
+ helpInformation(contextOptions) {
1882
+ const helper = this.createHelp();
1883
+ const context = this._getOutputContext(contextOptions);
1884
+ helper.prepareContext({
1885
+ error: context.error,
1886
+ helpWidth: context.helpWidth,
1887
+ outputHasColors: context.hasColors
1888
+ });
1889
+ const text = helper.formatHelp(this, helper);
1890
+ if (context.hasColors)
1891
+ return text;
1892
+ return this._outputConfiguration.stripColor(text);
1893
+ }
1894
+ _getOutputContext(contextOptions) {
1895
+ contextOptions = contextOptions || {};
1896
+ const error = !!contextOptions.error;
1897
+ let baseWrite;
1898
+ let hasColors;
1899
+ let helpWidth;
1900
+ if (error) {
1901
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
1902
+ hasColors = this._outputConfiguration.getErrHasColors();
1903
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
1904
+ } else {
1905
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
1906
+ hasColors = this._outputConfiguration.getOutHasColors();
1907
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
1908
+ }
1909
+ const write = (str) => {
1910
+ if (!hasColors)
1911
+ str = this._outputConfiguration.stripColor(str);
1912
+ return baseWrite(str);
1913
+ };
1914
+ return { error, write, hasColors, helpWidth };
1915
+ }
1916
+ outputHelp(contextOptions) {
1917
+ let deprecatedCallback;
1918
+ if (typeof contextOptions === "function") {
1919
+ deprecatedCallback = contextOptions;
1920
+ contextOptions = undefined;
1921
+ }
1922
+ const outputContext = this._getOutputContext(contextOptions);
1923
+ const eventContext = {
1924
+ error: outputContext.error,
1925
+ write: outputContext.write,
1926
+ command: this
1927
+ };
1928
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
1929
+ this.emit("beforeHelp", eventContext);
1930
+ let helpInformation = this.helpInformation({ error: outputContext.error });
1931
+ if (deprecatedCallback) {
1932
+ helpInformation = deprecatedCallback(helpInformation);
1933
+ if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
1934
+ throw new Error("outputHelp callback must return a string or a Buffer");
1935
+ }
1936
+ }
1937
+ outputContext.write(helpInformation);
1938
+ if (this._getHelpOption()?.long) {
1939
+ this.emit(this._getHelpOption().long);
1940
+ }
1941
+ this.emit("afterHelp", eventContext);
1942
+ this._getCommandAndAncestors().forEach((command) => command.emit("afterAllHelp", eventContext));
1943
+ }
1944
+ helpOption(flags, description) {
1945
+ if (typeof flags === "boolean") {
1946
+ if (flags) {
1947
+ this._helpOption = this._helpOption ?? undefined;
1948
+ } else {
1949
+ this._helpOption = null;
1950
+ }
1951
+ return this;
1952
+ }
1953
+ flags = flags ?? "-h, --help";
1954
+ description = description ?? "display help for command";
1955
+ this._helpOption = this.createOption(flags, description);
1956
+ return this;
1957
+ }
1958
+ _getHelpOption() {
1959
+ if (this._helpOption === undefined) {
1960
+ this.helpOption(undefined, undefined);
1961
+ }
1962
+ return this._helpOption;
1963
+ }
1964
+ addHelpOption(option) {
1965
+ this._helpOption = option;
1966
+ return this;
1967
+ }
1968
+ help(contextOptions) {
1969
+ this.outputHelp(contextOptions);
1970
+ let exitCode = Number(process2.exitCode ?? 0);
1971
+ if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
1972
+ exitCode = 1;
1973
+ }
1974
+ this._exit(exitCode, "commander.help", "(outputHelp)");
1975
+ }
1976
+ addHelpText(position, text) {
1977
+ const allowedValues = ["beforeAll", "before", "after", "afterAll"];
1978
+ if (!allowedValues.includes(position)) {
1979
+ throw new Error(`Unexpected value for position to addHelpText.
1980
+ Expecting one of '${allowedValues.join("', '")}'`);
1981
+ }
1982
+ const helpEvent = `${position}Help`;
1983
+ this.on(helpEvent, (context) => {
1984
+ let helpStr;
1985
+ if (typeof text === "function") {
1986
+ helpStr = text({ error: context.error, command: context.command });
1987
+ } else {
1988
+ helpStr = text;
1989
+ }
1990
+ if (helpStr) {
1991
+ context.write(`${helpStr}
1992
+ `);
1993
+ }
1994
+ });
1995
+ return this;
1996
+ }
1997
+ _outputHelpIfRequested(args) {
1998
+ const helpOption = this._getHelpOption();
1999
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
2000
+ if (helpRequested) {
2001
+ this.outputHelp();
2002
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
2003
+ }
2004
+ }
2005
+ }
2006
+ function incrementNodeInspectorPort(args) {
2007
+ return args.map((arg) => {
2008
+ if (!arg.startsWith("--inspect")) {
2009
+ return arg;
2010
+ }
2011
+ let debugOption;
2012
+ let debugHost = "127.0.0.1";
2013
+ let debugPort = "9229";
2014
+ let match;
2015
+ if ((match = arg.match(/^(--inspect(-brk)?)$/)) !== null) {
2016
+ debugOption = match[1];
2017
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+)$/)) !== null) {
2018
+ debugOption = match[1];
2019
+ if (/^\d+$/.test(match[3])) {
2020
+ debugPort = match[3];
2021
+ } else {
2022
+ debugHost = match[3];
2023
+ }
2024
+ } else if ((match = arg.match(/^(--inspect(-brk|-port)?)=([^:]+):(\d+)$/)) !== null) {
2025
+ debugOption = match[1];
2026
+ debugHost = match[3];
2027
+ debugPort = match[4];
2028
+ }
2029
+ if (debugOption && debugPort !== "0") {
2030
+ return `${debugOption}=${debugHost}:${parseInt(debugPort) + 1}`;
2031
+ }
2032
+ return arg;
2033
+ });
2034
+ }
2035
+ function useColor() {
2036
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
2037
+ return false;
2038
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== undefined)
2039
+ return true;
2040
+ return;
2041
+ }
2042
+ exports.Command = Command;
2043
+ exports.useColor = useColor;
2044
+ });
2045
+
2046
+ // node_modules/commander/index.js
2047
+ var require_commander = __commonJS((exports) => {
2048
+ var { Argument } = require_argument();
2049
+ var { Command } = require_command();
2050
+ var { CommanderError, InvalidArgumentError } = require_error();
2051
+ var { Help } = require_help();
2052
+ var { Option } = require_option();
2053
+ exports.program = new Command;
2054
+ exports.createCommand = (name) => new Command(name);
2055
+ exports.createOption = (flags, description) => new Option(flags, description);
2056
+ exports.createArgument = (name, description) => new Argument(name, description);
2057
+ exports.Command = Command;
2058
+ exports.Option = Option;
2059
+ exports.Argument = Argument;
2060
+ exports.Help = Help;
2061
+ exports.CommanderError = CommanderError;
2062
+ exports.InvalidArgumentError = InvalidArgumentError;
2063
+ exports.InvalidOptionArgumentError = InvalidArgumentError;
2064
+ });
2065
+
2066
+ // src/db/database.ts
2067
+ import { Database } from "bun:sqlite";
2068
+ import { existsSync, mkdirSync } from "fs";
2069
+ import { dirname, join, resolve } from "path";
2070
+ import { randomUUID } from "crypto";
2071
+ function isInMemoryDb(path) {
2072
+ return path === ":memory:" || path.startsWith("file::memory:");
2073
+ }
2074
+ function findNearestDb(startDir) {
2075
+ let dir = resolve(startDir);
2076
+ while (true) {
2077
+ const candidate = join(dir, ".sandboxes", "sandboxes.db");
2078
+ if (existsSync(candidate))
2079
+ return candidate;
2080
+ const parent = dirname(dir);
2081
+ if (parent === dir)
2082
+ break;
2083
+ dir = parent;
2084
+ }
2085
+ return null;
2086
+ }
2087
+ function getDbPath() {
2088
+ if (process.env["SANDBOXES_DB_PATH"]) {
2089
+ return process.env["SANDBOXES_DB_PATH"];
2090
+ }
2091
+ const cwd = process.cwd();
2092
+ const nearest = findNearestDb(cwd);
2093
+ if (nearest)
2094
+ return nearest;
2095
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
2096
+ return join(home, ".sandboxes", "sandboxes.db");
2097
+ }
2098
+ function ensureDir(filePath) {
2099
+ if (isInMemoryDb(filePath))
2100
+ return;
2101
+ const dir = dirname(resolve(filePath));
2102
+ if (!existsSync(dir)) {
2103
+ mkdirSync(dir, { recursive: true });
2104
+ }
2105
+ }
2106
+ function runMigrations(database) {
2107
+ database.exec("CREATE TABLE IF NOT EXISTS _migrations (id INTEGER PRIMARY KEY, applied_at TEXT NOT NULL DEFAULT (datetime('now')))");
2108
+ const applied = new Set(database.query("SELECT id FROM _migrations").all().map((r) => r.id));
2109
+ for (let i = 0;i < MIGRATIONS.length; i++) {
2110
+ const migrationId = i + 1;
2111
+ if (!applied.has(migrationId)) {
2112
+ database.exec(MIGRATIONS[i]);
2113
+ }
2114
+ }
2115
+ }
2116
+ function getDatabase() {
2117
+ if (db)
2118
+ return db;
2119
+ const dbPath = getDbPath();
2120
+ ensureDir(dbPath);
2121
+ db = new Database(dbPath);
2122
+ db.exec("PRAGMA journal_mode = WAL");
2123
+ db.exec("PRAGMA foreign_keys = ON");
2124
+ runMigrations(db);
2125
+ return db;
2126
+ }
2127
+ function uuid() {
2128
+ return randomUUID();
2129
+ }
2130
+ function now() {
2131
+ return new Date().toISOString().replace("T", " ").replace("Z", "");
2132
+ }
2133
+ function resolvePartialId(table, partialId) {
2134
+ const database = getDatabase();
2135
+ const rows = database.query(`SELECT id FROM ${table} WHERE id LIKE ? || '%'`).all(partialId);
2136
+ if (rows.length === 1)
2137
+ return rows[0].id;
2138
+ if (rows.length === 0)
2139
+ return null;
2140
+ const exact = rows.find((r) => r.id === partialId);
2141
+ if (exact)
2142
+ return exact.id;
2143
+ return null;
2144
+ }
2145
+ var MIGRATIONS, db = null;
2146
+ var init_database = __esm(() => {
2147
+ MIGRATIONS = [
2148
+ `
2149
+ CREATE TABLE IF NOT EXISTS projects (
2150
+ id TEXT PRIMARY KEY,
2151
+ name TEXT NOT NULL,
2152
+ path TEXT UNIQUE NOT NULL,
2153
+ description TEXT,
2154
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
2155
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
2156
+ );
2157
+
2158
+ CREATE TABLE IF NOT EXISTS agents (
2159
+ id TEXT PRIMARY KEY,
2160
+ name TEXT NOT NULL UNIQUE,
2161
+ description TEXT,
2162
+ metadata TEXT DEFAULT '{}',
2163
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
2164
+ last_seen_at TEXT NOT NULL DEFAULT (datetime('now'))
2165
+ );
2166
+ CREATE INDEX IF NOT EXISTS idx_agents_name ON agents(name);
2167
+
2168
+ CREATE TABLE IF NOT EXISTS sandboxes (
2169
+ id TEXT PRIMARY KEY,
2170
+ provider TEXT NOT NULL CHECK(provider IN ('e2b', 'daytona', 'modal')),
2171
+ provider_sandbox_id TEXT,
2172
+ name TEXT,
2173
+ status TEXT NOT NULL DEFAULT 'creating' CHECK(status IN ('creating', 'running', 'paused', 'stopped', 'deleted', 'error')),
2174
+ image TEXT,
2175
+ timeout INTEGER DEFAULT 3600,
2176
+ config TEXT DEFAULT '{}',
2177
+ env_vars TEXT DEFAULT '{}',
2178
+ keep_alive_until TEXT,
2179
+ project_id TEXT REFERENCES projects(id) ON DELETE SET NULL,
2180
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
2181
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
2182
+ );
2183
+ CREATE INDEX IF NOT EXISTS idx_sandboxes_status ON sandboxes(status);
2184
+ CREATE INDEX IF NOT EXISTS idx_sandboxes_provider ON sandboxes(provider);
2185
+ CREATE INDEX IF NOT EXISTS idx_sandboxes_project ON sandboxes(project_id);
2186
+
2187
+ CREATE TABLE IF NOT EXISTS sandbox_sessions (
2188
+ id TEXT PRIMARY KEY,
2189
+ sandbox_id TEXT NOT NULL REFERENCES sandboxes(id) ON DELETE CASCADE,
2190
+ agent_name TEXT,
2191
+ agent_type TEXT CHECK(agent_type IN ('claude', 'codex', 'gemini', 'custom')),
2192
+ command TEXT,
2193
+ status TEXT NOT NULL DEFAULT 'running' CHECK(status IN ('running', 'completed', 'failed', 'killed')),
2194
+ exit_code INTEGER,
2195
+ started_at TEXT NOT NULL DEFAULT (datetime('now')),
2196
+ ended_at TEXT
2197
+ );
2198
+ CREATE INDEX IF NOT EXISTS idx_sessions_sandbox ON sandbox_sessions(sandbox_id);
2199
+ CREATE INDEX IF NOT EXISTS idx_sessions_status ON sandbox_sessions(status);
2200
+
2201
+ CREATE TABLE IF NOT EXISTS sandbox_events (
2202
+ id TEXT PRIMARY KEY,
2203
+ sandbox_id TEXT NOT NULL REFERENCES sandboxes(id) ON DELETE CASCADE,
2204
+ session_id TEXT REFERENCES sandbox_sessions(id) ON DELETE CASCADE,
2205
+ type TEXT NOT NULL CHECK(type IN ('stdout', 'stderr', 'lifecycle', 'agent')),
2206
+ data TEXT,
2207
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
2208
+ );
2209
+ CREATE INDEX IF NOT EXISTS idx_events_sandbox ON sandbox_events(sandbox_id);
2210
+ CREATE INDEX IF NOT EXISTS idx_events_session ON sandbox_events(session_id);
2211
+ CREATE INDEX IF NOT EXISTS idx_events_type ON sandbox_events(type);
2212
+
2213
+ CREATE TABLE IF NOT EXISTS webhooks (
2214
+ id TEXT PRIMARY KEY,
2215
+ url TEXT NOT NULL,
2216
+ events TEXT NOT NULL DEFAULT '[]',
2217
+ secret TEXT,
2218
+ active INTEGER NOT NULL DEFAULT 1,
2219
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
2220
+ );
2221
+
2222
+ CREATE TABLE IF NOT EXISTS _migrations (
2223
+ id INTEGER PRIMARY KEY,
2224
+ applied_at TEXT NOT NULL DEFAULT (datetime('now'))
2225
+ );
2226
+
2227
+ INSERT OR IGNORE INTO _migrations (id) VALUES (1);
2228
+ `
2229
+ ];
2230
+ });
2231
+
2232
+ // src/types/index.ts
2233
+ var SandboxNotFoundError, SessionNotFoundError, ProviderError, AgentNotFoundError;
2234
+ var init_types = __esm(() => {
2235
+ SandboxNotFoundError = class SandboxNotFoundError extends Error {
2236
+ constructor(id) {
2237
+ super(`Sandbox not found: ${id}`);
2238
+ this.name = "SandboxNotFoundError";
2239
+ }
2240
+ };
2241
+ SessionNotFoundError = class SessionNotFoundError extends Error {
2242
+ constructor(id) {
2243
+ super(`Session not found: ${id}`);
2244
+ this.name = "SessionNotFoundError";
2245
+ }
2246
+ };
2247
+ ProviderError = class ProviderError extends Error {
2248
+ provider;
2249
+ constructor(provider, message) {
2250
+ super(`[${provider}] ${message}`);
2251
+ this.name = "ProviderError";
2252
+ this.provider = provider;
2253
+ }
2254
+ };
2255
+ AgentNotFoundError = class AgentNotFoundError extends Error {
2256
+ constructor(id) {
2257
+ super(`Agent not found: ${id}`);
2258
+ this.name = "AgentNotFoundError";
2259
+ }
2260
+ };
2261
+ });
2262
+
2263
+ // src/db/sandboxes.ts
2264
+ function rowToSandbox(row) {
2265
+ return {
2266
+ id: row.id,
2267
+ provider: row.provider,
2268
+ provider_sandbox_id: row.provider_sandbox_id,
2269
+ name: row.name,
2270
+ status: row.status,
2271
+ image: row.image,
2272
+ timeout: row.timeout,
2273
+ config: JSON.parse(row.config),
2274
+ env_vars: JSON.parse(row.env_vars),
2275
+ keep_alive_until: row.keep_alive_until,
2276
+ project_id: row.project_id,
2277
+ created_at: row.created_at,
2278
+ updated_at: row.updated_at
2279
+ };
2280
+ }
2281
+ function createSandbox(input) {
2282
+ const db2 = getDatabase();
2283
+ const id = uuid();
2284
+ const timestamp = now();
2285
+ const provider = input.provider ?? "e2b";
2286
+ const name = input.name ?? null;
2287
+ const image = input.image ?? null;
2288
+ const timeout = input.timeout ?? 3600;
2289
+ const config = JSON.stringify(input.config ?? {});
2290
+ const env_vars = JSON.stringify(input.env_vars ?? {});
2291
+ const project_id = input.project_id ?? null;
2292
+ db2.query(`INSERT INTO sandboxes (id, provider, name, status, image, timeout, config, env_vars, project_id, created_at, updated_at)
2293
+ VALUES (?, ?, ?, 'creating', ?, ?, ?, ?, ?, ?, ?)`).run(id, provider, name, image, timeout, config, env_vars, project_id, timestamp, timestamp);
2294
+ return getSandbox(id);
2295
+ }
2296
+ function getSandbox(id) {
2297
+ const db2 = getDatabase();
2298
+ const resolvedId = resolvePartialId("sandboxes", id);
2299
+ if (!resolvedId)
2300
+ throw new SandboxNotFoundError(id);
2301
+ const row = db2.query("SELECT * FROM sandboxes WHERE id = ?").get(resolvedId);
2302
+ if (!row)
2303
+ throw new SandboxNotFoundError(id);
2304
+ return rowToSandbox(row);
2305
+ }
2306
+ function listSandboxes(opts) {
2307
+ const db2 = getDatabase();
2308
+ const conditions = [];
2309
+ const params = [];
2310
+ if (opts?.status) {
2311
+ conditions.push("status = ?");
2312
+ params.push(opts.status);
2313
+ }
2314
+ if (opts?.provider) {
2315
+ conditions.push("provider = ?");
2316
+ params.push(opts.provider);
2317
+ }
2318
+ if (opts?.project_id) {
2319
+ conditions.push("project_id = ?");
2320
+ params.push(opts.project_id);
2321
+ }
2322
+ const where = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "";
2323
+ const rows = db2.query(`SELECT * FROM sandboxes${where} ORDER BY created_at DESC`).all(...params);
2324
+ return rows.map(rowToSandbox);
2325
+ }
2326
+ function updateSandbox(id, updates) {
2327
+ const db2 = getDatabase();
2328
+ const resolvedId = resolvePartialId("sandboxes", id);
2329
+ if (!resolvedId)
2330
+ throw new SandboxNotFoundError(id);
2331
+ const setClauses = [];
2332
+ const params = [];
2333
+ if (updates.status !== undefined) {
2334
+ setClauses.push("status = ?");
2335
+ params.push(updates.status);
2336
+ }
2337
+ if (updates.provider_sandbox_id !== undefined) {
2338
+ setClauses.push("provider_sandbox_id = ?");
2339
+ params.push(updates.provider_sandbox_id);
2340
+ }
2341
+ if (updates.name !== undefined) {
2342
+ setClauses.push("name = ?");
2343
+ params.push(updates.name);
2344
+ }
2345
+ if (updates.image !== undefined) {
2346
+ setClauses.push("image = ?");
2347
+ params.push(updates.image);
2348
+ }
2349
+ if (updates.timeout !== undefined) {
2350
+ setClauses.push("timeout = ?");
2351
+ params.push(updates.timeout);
2352
+ }
2353
+ if (updates.config !== undefined) {
2354
+ setClauses.push("config = ?");
2355
+ params.push(JSON.stringify(updates.config));
2356
+ }
2357
+ if (updates.env_vars !== undefined) {
2358
+ setClauses.push("env_vars = ?");
2359
+ params.push(JSON.stringify(updates.env_vars));
2360
+ }
2361
+ if (updates.keep_alive_until !== undefined) {
2362
+ setClauses.push("keep_alive_until = ?");
2363
+ params.push(updates.keep_alive_until);
2364
+ }
2365
+ if (setClauses.length === 0) {
2366
+ return getSandbox(resolvedId);
2367
+ }
2368
+ setClauses.push("updated_at = ?");
2369
+ params.push(now());
2370
+ params.push(resolvedId);
2371
+ db2.query(`UPDATE sandboxes SET ${setClauses.join(", ")} WHERE id = ?`).run(...params);
2372
+ return getSandbox(resolvedId);
2373
+ }
2374
+ function deleteSandbox(id) {
2375
+ const db2 = getDatabase();
2376
+ const resolvedId = resolvePartialId("sandboxes", id);
2377
+ if (!resolvedId)
2378
+ throw new SandboxNotFoundError(id);
2379
+ db2.query("DELETE FROM sandboxes WHERE id = ?").run(resolvedId);
2380
+ }
2381
+ var init_sandboxes = __esm(() => {
2382
+ init_database();
2383
+ init_types();
2384
+ });
2385
+
2386
+ // src/db/sessions.ts
2387
+ function rowToSession(row) {
2388
+ return {
2389
+ ...row,
2390
+ agent_type: row.agent_type,
2391
+ status: row.status
2392
+ };
2393
+ }
2394
+ function createSession(input) {
2395
+ const db2 = getDatabase();
2396
+ const id = uuid();
2397
+ const startedAt = now();
2398
+ db2.query(`INSERT INTO sandbox_sessions (id, sandbox_id, agent_name, agent_type, command, status, started_at)
2399
+ VALUES (?, ?, ?, ?, ?, 'running', ?)`).run(id, input.sandbox_id, input.agent_name ?? null, input.agent_type ?? null, input.command ?? null, startedAt);
2400
+ return getSession(id);
2401
+ }
2402
+ function getSession(id) {
2403
+ const db2 = getDatabase();
2404
+ const resolvedId = resolvePartialId("sandbox_sessions", id) ?? id;
2405
+ const row = db2.query("SELECT * FROM sandbox_sessions WHERE id = ?").get(resolvedId);
2406
+ if (!row)
2407
+ throw new SessionNotFoundError(id);
2408
+ return rowToSession(row);
2409
+ }
2410
+ function endSession(id, exit_code, status) {
2411
+ const session = getSession(id);
2412
+ const endedAt = now();
2413
+ const finalStatus = status ?? "completed";
2414
+ const db2 = getDatabase();
2415
+ db2.query(`UPDATE sandbox_sessions SET status = ?, exit_code = ?, ended_at = ? WHERE id = ?`).run(finalStatus, exit_code, endedAt, session.id);
2416
+ return getSession(session.id);
2417
+ }
2418
+ var init_sessions = __esm(() => {
2419
+ init_database();
2420
+ init_types();
2421
+ });
2422
+
2423
+ // src/db/events.ts
2424
+ function rowToEvent(row) {
2425
+ return {
2426
+ id: row.id,
2427
+ sandbox_id: row.sandbox_id,
2428
+ session_id: row.session_id,
2429
+ type: row.type,
2430
+ data: row.data,
2431
+ created_at: row.created_at
2432
+ };
2433
+ }
2434
+ function addEvent(input) {
2435
+ const db2 = getDatabase();
2436
+ const id = uuid();
2437
+ db2.query(`INSERT INTO sandbox_events (id, sandbox_id, session_id, type, data)
2438
+ VALUES (?, ?, ?, ?, ?)`).run(id, input.sandbox_id, input.session_id ?? null, input.type, input.data ?? null);
2439
+ const row = db2.query("SELECT * FROM sandbox_events WHERE id = ?").get(id);
2440
+ return rowToEvent(row);
2441
+ }
2442
+ function listEvents(opts) {
2443
+ const db2 = getDatabase();
2444
+ const conditions = [];
2445
+ const params = [];
2446
+ if (opts?.sandbox_id) {
2447
+ conditions.push("sandbox_id = ?");
2448
+ params.push(opts.sandbox_id);
2449
+ }
2450
+ if (opts?.session_id) {
2451
+ conditions.push("session_id = ?");
2452
+ params.push(opts.session_id);
2453
+ }
2454
+ if (opts?.type) {
2455
+ conditions.push("type = ?");
2456
+ params.push(opts.type);
2457
+ }
2458
+ const where = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "";
2459
+ const limit = opts?.limit ?? 100;
2460
+ const offset = opts?.offset ?? 0;
2461
+ const rows = db2.query(`SELECT * FROM sandbox_events${where} ORDER BY created_at ASC LIMIT ? OFFSET ?`).all(...[...params, limit, offset]);
2462
+ return rows.map(rowToEvent);
2463
+ }
2464
+ var init_events = __esm(() => {
2465
+ init_database();
2466
+ });
2467
+
2468
+ // src/lib/config.ts
2469
+ import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
2470
+ import { dirname as dirname2, join as join2 } from "path";
2471
+ function getConfigPath() {
2472
+ const home = process.env["HOME"] || process.env["USERPROFILE"] || "~";
2473
+ return join2(home, ".sandboxes", "config.json");
2474
+ }
2475
+ function loadConfig() {
2476
+ const configPath = getConfigPath();
2477
+ if (!existsSync2(configPath))
2478
+ return {};
2479
+ try {
2480
+ const raw = readFileSync(configPath, "utf-8");
2481
+ return JSON.parse(raw);
2482
+ } catch {
2483
+ return {};
2484
+ }
2485
+ }
2486
+ function saveConfig(config) {
2487
+ const configPath = getConfigPath();
2488
+ const dir = dirname2(configPath);
2489
+ if (!existsSync2(dir)) {
2490
+ mkdirSync2(dir, { recursive: true });
2491
+ }
2492
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + `
2493
+ `, "utf-8");
2494
+ }
2495
+ function getDefaultProvider() {
2496
+ const config = loadConfig();
2497
+ return config.default_provider || "e2b";
2498
+ }
2499
+ function getDefaultTimeout() {
2500
+ const config = loadConfig();
2501
+ return config.default_timeout || 3600;
2502
+ }
2503
+ function getDefaultImage() {
2504
+ const config = loadConfig();
2505
+ return config.default_image;
2506
+ }
2507
+ function getProviderApiKey(provider) {
2508
+ const config = loadConfig();
2509
+ const providerConfig = config.providers?.[provider];
2510
+ if (providerConfig?.api_key)
2511
+ return providerConfig.api_key;
2512
+ const envKey = ENV_KEYS[provider];
2513
+ if (envKey)
2514
+ return process.env[envKey];
2515
+ return;
2516
+ }
2517
+ function setConfigValue(key, value) {
2518
+ const config = loadConfig();
2519
+ if (key === "default_provider") {
2520
+ config.default_provider = value;
2521
+ } else if (key === "default_image") {
2522
+ config.default_image = value;
2523
+ } else if (key === "default_timeout") {
2524
+ config.default_timeout = parseInt(value, 10);
2525
+ } else if (key.startsWith("providers.")) {
2526
+ const parts = key.split(".");
2527
+ const provider = parts[1];
2528
+ const field = parts[2];
2529
+ if (!config.providers)
2530
+ config.providers = {};
2531
+ if (!config.providers[provider]) {
2532
+ config.providers[provider] = {};
2533
+ }
2534
+ if (field) {
2535
+ config.providers[provider][field] = value;
2536
+ }
2537
+ }
2538
+ saveConfig(config);
2539
+ }
2540
+ function getConfigValue(key) {
2541
+ const config = loadConfig();
2542
+ if (key === "default_provider")
2543
+ return config.default_provider;
2544
+ if (key === "default_image")
2545
+ return config.default_image;
2546
+ if (key === "default_timeout")
2547
+ return config.default_timeout?.toString();
2548
+ if (key.startsWith("providers.")) {
2549
+ const parts = key.split(".");
2550
+ const provider = parts[1];
2551
+ const field = parts[2];
2552
+ const providerConfig = config.providers?.[provider];
2553
+ if (providerConfig && field)
2554
+ return providerConfig[field];
2555
+ }
2556
+ return;
2557
+ }
2558
+ var ENV_KEYS;
2559
+ var init_config = __esm(() => {
2560
+ ENV_KEYS = {
2561
+ e2b: "E2B_API_KEY",
2562
+ daytona: "DAYTONA_API_KEY",
2563
+ modal: "MODAL_TOKEN_ID"
2564
+ };
2565
+ });
2566
+
2567
+ // src/providers/e2b.ts
2568
+ var exports_e2b = {};
2569
+ __export(exports_e2b, {
2570
+ E2BProvider: () => E2BProvider
2571
+ });
2572
+ import { Sandbox as E2BSandbox } from "@e2b/code-interpreter";
2573
+
2574
+ class E2BProvider {
2575
+ name = "e2b";
2576
+ apiKey;
2577
+ constructor(apiKey) {
2578
+ this.apiKey = apiKey;
2579
+ }
2580
+ async create(opts) {
2581
+ try {
2582
+ const sandbox = await E2BSandbox.create({
2583
+ apiKey: this.apiKey,
2584
+ timeoutMs: (opts?.timeout || 3600) * 1000
2585
+ });
2586
+ instanceCache.set(sandbox.sandboxId, sandbox);
2587
+ return {
2588
+ id: sandbox.sandboxId,
2589
+ status: "running"
2590
+ };
2591
+ } catch (err) {
2592
+ throw new ProviderError("e2b", `Failed to create sandbox: ${err.message}`);
2593
+ }
2594
+ }
2595
+ async getInstance(sandboxId) {
2596
+ const cached = instanceCache.get(sandboxId);
2597
+ if (cached)
2598
+ return cached;
2599
+ try {
2600
+ const sandbox = await E2BSandbox.connect(sandboxId, {
2601
+ apiKey: this.apiKey
2602
+ });
2603
+ instanceCache.set(sandboxId, sandbox);
2604
+ return sandbox;
2605
+ } catch (err) {
2606
+ throw new ProviderError("e2b", `Failed to connect to sandbox ${sandboxId}: ${err.message}`);
2607
+ }
2608
+ }
2609
+ async exec(sandboxId, command, opts) {
2610
+ const sandbox = await this.getInstance(sandboxId);
2611
+ try {
2612
+ if (opts?.background) {
2613
+ const handle = await sandbox.commands.run(command, {
2614
+ background: true,
2615
+ onStdout: opts.onStdout ? (data) => opts.onStdout(data) : undefined,
2616
+ onStderr: opts.onStderr ? (data) => opts.onStderr(data) : undefined,
2617
+ envs: opts.env,
2618
+ cwd: opts.cwd,
2619
+ timeoutMs: opts.timeout ? opts.timeout * 1000 : undefined
2620
+ });
2621
+ return {
2622
+ kill: async () => {
2623
+ await handle.kill();
2624
+ },
2625
+ wait: async () => {
2626
+ const result2 = await handle.wait();
2627
+ return {
2628
+ exit_code: result2.exitCode,
2629
+ stdout: result2.stdout,
2630
+ stderr: result2.stderr
2631
+ };
2632
+ }
2633
+ };
2634
+ }
2635
+ const result = await sandbox.commands.run(command, {
2636
+ onStdout: opts?.onStdout ? (data) => opts.onStdout(data) : undefined,
2637
+ onStderr: opts?.onStderr ? (data) => opts.onStderr(data) : undefined,
2638
+ envs: opts?.env,
2639
+ cwd: opts?.cwd,
2640
+ timeoutMs: opts?.timeout ? opts.timeout * 1000 : undefined
2641
+ });
2642
+ return {
2643
+ exit_code: result.exitCode,
2644
+ stdout: result.stdout,
2645
+ stderr: result.stderr
2646
+ };
2647
+ } catch (err) {
2648
+ throw new ProviderError("e2b", `Failed to exec command: ${err.message}`);
2649
+ }
2650
+ }
2651
+ async readFile(sandboxId, path) {
2652
+ const sandbox = await this.getInstance(sandboxId);
2653
+ try {
2654
+ return await sandbox.files.read(path, { format: "text" });
2655
+ } catch (err) {
2656
+ throw new ProviderError("e2b", `Failed to read file ${path}: ${err.message}`);
2657
+ }
2658
+ }
2659
+ async writeFile(sandboxId, path, content) {
2660
+ const sandbox = await this.getInstance(sandboxId);
2661
+ try {
2662
+ await sandbox.files.write(path, content);
2663
+ } catch (err) {
2664
+ throw new ProviderError("e2b", `Failed to write file ${path}: ${err.message}`);
2665
+ }
2666
+ }
2667
+ async listFiles(sandboxId, path) {
2668
+ const sandbox = await this.getInstance(sandboxId);
2669
+ try {
2670
+ const entries = await sandbox.files.list(path);
2671
+ return entries.map((e) => ({
2672
+ path: e.path,
2673
+ name: e.name,
2674
+ is_dir: e.type === "dir",
2675
+ size: 0
2676
+ }));
2677
+ } catch (err) {
2678
+ throw new ProviderError("e2b", `Failed to list files at ${path}: ${err.message}`);
2679
+ }
2680
+ }
2681
+ async stop(sandboxId) {
2682
+ const sandbox = await this.getInstance(sandboxId);
2683
+ try {
2684
+ await sandbox.kill();
2685
+ instanceCache.delete(sandboxId);
2686
+ } catch (err) {
2687
+ throw new ProviderError("e2b", `Failed to stop sandbox: ${err.message}`);
2688
+ }
2689
+ }
2690
+ async delete(sandboxId) {
2691
+ await this.stop(sandboxId);
2692
+ }
2693
+ async keepAlive(sandboxId, durationMs) {
2694
+ const sandbox = await this.getInstance(sandboxId);
2695
+ try {
2696
+ await sandbox.keepAlive(durationMs || 300000);
2697
+ } catch (err) {
2698
+ throw new ProviderError("e2b", `Failed to keep alive: ${err.message}`);
2699
+ }
2700
+ }
2701
+ }
2702
+ var instanceCache;
2703
+ var init_e2b = __esm(() => {
2704
+ init_types();
2705
+ instanceCache = new Map;
2706
+ });
2707
+
2708
+ // src/providers/daytona.ts
2709
+ var exports_daytona = {};
2710
+ __export(exports_daytona, {
2711
+ DaytonaProvider: () => DaytonaProvider
2712
+ });
2713
+ import { Daytona } from "@daytonaio/sdk";
2714
+
2715
+ class DaytonaProvider {
2716
+ name = "daytona";
2717
+ client;
2718
+ constructor(apiKey) {
2719
+ process.env.DAYTONA_API_KEY = apiKey;
2720
+ this.client = new Daytona({ apiKey });
2721
+ }
2722
+ async create(opts) {
2723
+ try {
2724
+ const sandbox = await this.client.create({
2725
+ language: "typescript",
2726
+ image: opts?.image,
2727
+ envVars: opts?.envVars,
2728
+ autoStopInterval: 0
2729
+ }, opts?.timeout || 60);
2730
+ instanceCache2.set(sandbox.id, sandbox);
2731
+ return {
2732
+ id: sandbox.id,
2733
+ status: "running"
2734
+ };
2735
+ } catch (err) {
2736
+ throw new ProviderError("daytona", `Failed to create sandbox: ${err.message}`);
2737
+ }
2738
+ }
2739
+ async getInstance(sandboxId) {
2740
+ const cached = instanceCache2.get(sandboxId);
2741
+ if (cached)
2742
+ return cached;
2743
+ try {
2744
+ const sandbox = await this.client.get(sandboxId);
2745
+ instanceCache2.set(sandboxId, sandbox);
2746
+ return sandbox;
2747
+ } catch (err) {
2748
+ throw new ProviderError("daytona", `Failed to connect to sandbox ${sandboxId}: ${err.message}`);
2749
+ }
2750
+ }
2751
+ async exec(sandboxId, command, opts) {
2752
+ const sandbox = await this.getInstance(sandboxId);
2753
+ try {
2754
+ if (opts?.background) {
2755
+ const sessionId = `bg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
2756
+ await sandbox.process.createSession(sessionId);
2757
+ const response = await sandbox.process.executeSessionCommand(sessionId, { command, runAsync: true }, opts.timeout);
2758
+ const cmdId = response.cmdId;
2759
+ if (opts.onStdout || opts.onStderr) {
2760
+ const logCallback = (chunk) => {
2761
+ if (opts.onStdout)
2762
+ opts.onStdout(chunk);
2763
+ };
2764
+ sandbox.process.getSessionCommandLogs(sessionId, cmdId, logCallback).catch(() => {});
2765
+ }
2766
+ return {
2767
+ kill: async () => {
2768
+ try {
2769
+ await sandbox.process.deleteSession(sessionId);
2770
+ } catch {}
2771
+ },
2772
+ wait: async () => {
2773
+ let exitCode;
2774
+ let output = "";
2775
+ while (true) {
2776
+ const cmd = await sandbox.process.getSessionCommand(sessionId, cmdId);
2777
+ if (cmd.exitCode !== undefined && cmd.exitCode !== null) {
2778
+ exitCode = cmd.exitCode;
2779
+ break;
2780
+ }
2781
+ await new Promise((r) => setTimeout(r, 500));
2782
+ }
2783
+ try {
2784
+ output = await sandbox.process.getSessionCommandLogs(sessionId, cmdId);
2785
+ } catch {}
2786
+ return {
2787
+ exit_code: exitCode,
2788
+ stdout: output,
2789
+ stderr: ""
2790
+ };
2791
+ }
2792
+ };
2793
+ }
2794
+ const result = await sandbox.process.executeCommand(command, opts?.cwd, opts?.env, opts?.timeout);
2795
+ return {
2796
+ exit_code: result.exitCode,
2797
+ stdout: result.result,
2798
+ stderr: ""
2799
+ };
2800
+ } catch (err) {
2801
+ throw new ProviderError("daytona", `Failed to exec command: ${err.message}`);
2802
+ }
2803
+ }
2804
+ async readFile(sandboxId, path) {
2805
+ const sandbox = await this.getInstance(sandboxId);
2806
+ try {
2807
+ const buffer = await sandbox.fs.downloadFile(path);
2808
+ return buffer.toString("utf-8");
2809
+ } catch (err) {
2810
+ throw new ProviderError("daytona", `Failed to read file ${path}: ${err.message}`);
2811
+ }
2812
+ }
2813
+ async writeFile(sandboxId, path, content) {
2814
+ const sandbox = await this.getInstance(sandboxId);
2815
+ try {
2816
+ await sandbox.fs.uploadFile(Buffer.from(content, "utf-8"), path);
2817
+ } catch (err) {
2818
+ throw new ProviderError("daytona", `Failed to write file ${path}: ${err.message}`);
2819
+ }
2820
+ }
2821
+ async listFiles(sandboxId, path) {
2822
+ const sandbox = await this.getInstance(sandboxId);
2823
+ try {
2824
+ const entries = await sandbox.fs.listFiles(path);
2825
+ return entries.map((e) => ({
2826
+ path: `${path.replace(/\/$/, "")}/${e.name}`,
2827
+ name: e.name,
2828
+ is_dir: e.isDir,
2829
+ size: e.size
2830
+ }));
2831
+ } catch (err) {
2832
+ throw new ProviderError("daytona", `Failed to list files at ${path}: ${err.message}`);
2833
+ }
2834
+ }
2835
+ async stop(sandboxId) {
2836
+ const sandbox = await this.getInstance(sandboxId);
2837
+ try {
2838
+ await sandbox.stop();
2839
+ instanceCache2.delete(sandboxId);
2840
+ } catch (err) {
2841
+ throw new ProviderError("daytona", `Failed to stop sandbox: ${err.message}`);
2842
+ }
2843
+ }
2844
+ async delete(sandboxId) {
2845
+ const sandbox = await this.getInstance(sandboxId);
2846
+ try {
2847
+ await sandbox.delete();
2848
+ instanceCache2.delete(sandboxId);
2849
+ } catch (err) {
2850
+ throw new ProviderError("daytona", `Failed to delete sandbox: ${err.message}`);
2851
+ }
2852
+ }
2853
+ async keepAlive(sandboxId, durationMs) {
2854
+ const sandbox = await this.getInstance(sandboxId);
2855
+ try {
2856
+ const minutes = durationMs ? Math.ceil(durationMs / 60000) : 0;
2857
+ await sandbox.setAutostopInterval(minutes);
2858
+ } catch (err) {
2859
+ throw new ProviderError("daytona", `Failed to keep alive: ${err.message}`);
2860
+ }
2861
+ }
2862
+ }
2863
+ var instanceCache2;
2864
+ var init_daytona = __esm(() => {
2865
+ init_types();
2866
+ instanceCache2 = new Map;
2867
+ });
2868
+
2869
+ // src/providers/modal.ts
2870
+ var exports_modal = {};
2871
+ __export(exports_modal, {
2872
+ ModalProvider: () => ModalProvider
2873
+ });
2874
+ import { ModalClient } from "modal";
2875
+
2876
+ class ModalProvider {
2877
+ name = "modal";
2878
+ client;
2879
+ constructor(apiKey) {
2880
+ if (apiKey) {
2881
+ process.env.MODAL_TOKEN_SECRET = apiKey;
2882
+ }
2883
+ this.client = new ModalClient;
2884
+ }
2885
+ async create(opts) {
2886
+ try {
2887
+ const app = await this.client.apps.fromName("open-sandboxes", {
2888
+ createIfMissing: true
2889
+ });
2890
+ const imageName = opts?.image || "ubuntu:22.04";
2891
+ const image = this.client.images.fromRegistry(imageName);
2892
+ const timeout = opts?.timeout || 3600;
2893
+ const createOpts = { timeout };
2894
+ if (opts?.envVars && Object.keys(opts.envVars).length > 0) {
2895
+ createOpts.envVars = opts.envVars;
2896
+ }
2897
+ const sandbox = await this.client.sandboxes.create(app, image, createOpts);
2898
+ const sandboxId = sandbox.id || sandbox.sandboxId || String(sandbox);
2899
+ sandboxCache.set(sandboxId, sandbox);
2900
+ return {
2901
+ id: sandboxId,
2902
+ status: "running"
2903
+ };
2904
+ } catch (err) {
2905
+ throw new ProviderError("modal", `Failed to create sandbox: ${err.message}`);
2906
+ }
2907
+ }
2908
+ getSandbox(sandboxId) {
2909
+ const cached = sandboxCache.get(sandboxId);
2910
+ if (!cached) {
2911
+ throw new ProviderError("modal", `Sandbox ${sandboxId} not found in cache. Modal sandboxes must be created via this provider.`);
2912
+ }
2913
+ return cached;
2914
+ }
2915
+ async exec(sandboxId, command, opts) {
2916
+ const sandbox = this.getSandbox(sandboxId);
2917
+ try {
2918
+ const parts = this.parseCommand(command);
2919
+ const program2 = parts[0];
2920
+ const args = parts.slice(1);
2921
+ if (opts?.background) {
2922
+ const proc2 = await sandbox.exec(program2, ...args);
2923
+ return {
2924
+ kill: async () => {
2925
+ try {
2926
+ if (proc2.kill)
2927
+ await proc2.kill();
2928
+ else if (proc2.terminate)
2929
+ await proc2.terminate();
2930
+ } catch {}
2931
+ },
2932
+ wait: async () => {
2933
+ let stdout2 = "";
2934
+ let stderr2 = "";
2935
+ try {
2936
+ if (proc2.stdout && proc2.stdout.read) {
2937
+ stdout2 = await proc2.stdout.read();
2938
+ }
2939
+ if (proc2.stderr && proc2.stderr.read) {
2940
+ stderr2 = await proc2.stderr.read();
2941
+ }
2942
+ } catch {}
2943
+ const exitCode2 = proc2.exitCode ?? proc2.exit_code ?? proc2.returncode ?? 0;
2944
+ if (opts?.onStdout && stdout2)
2945
+ opts.onStdout(stdout2);
2946
+ if (opts?.onStderr && stderr2)
2947
+ opts.onStderr(stderr2);
2948
+ return {
2949
+ exit_code: exitCode2,
2950
+ stdout: stdout2,
2951
+ stderr: stderr2
2952
+ };
2953
+ }
2954
+ };
2955
+ }
2956
+ const proc = await sandbox.exec(program2, ...args);
2957
+ let stdout = "";
2958
+ let stderr = "";
2959
+ if (proc.stdout && proc.stdout.read) {
2960
+ stdout = await proc.stdout.read();
2961
+ }
2962
+ if (proc.stderr && proc.stderr.read) {
2963
+ stderr = await proc.stderr.read();
2964
+ }
2965
+ const exitCode = proc.exitCode ?? proc.exit_code ?? proc.returncode ?? 0;
2966
+ if (opts?.onStdout && stdout)
2967
+ opts.onStdout(stdout);
2968
+ if (opts?.onStderr && stderr)
2969
+ opts.onStderr(stderr);
2970
+ return {
2971
+ exit_code: exitCode,
2972
+ stdout,
2973
+ stderr
2974
+ };
2975
+ } catch (err) {
2976
+ throw new ProviderError("modal", `Failed to exec command: ${err.message}`);
2977
+ }
2978
+ }
2979
+ async readFile(sandboxId, path) {
2980
+ try {
2981
+ const result = await this.exec(sandboxId, `cat ${this.shellEscape(path)}`);
2982
+ const execResult = result;
2983
+ if (execResult.exit_code !== 0) {
2984
+ throw new Error(execResult.stderr || `cat exited with code ${execResult.exit_code}`);
2985
+ }
2986
+ return execResult.stdout;
2987
+ } catch (err) {
2988
+ if (err instanceof ProviderError)
2989
+ throw err;
2990
+ throw new ProviderError("modal", `Failed to read file ${path}: ${err.message}`);
2991
+ }
2992
+ }
2993
+ async writeFile(sandboxId, path, content) {
2994
+ try {
2995
+ const encoded = Buffer.from(content).toString("base64");
2996
+ const dirPath = path.substring(0, path.lastIndexOf("/")) || "/";
2997
+ const cmd = `mkdir -p ${this.shellEscape(dirPath)} && echo ${encoded} | base64 -d > ${this.shellEscape(path)}`;
2998
+ const result = await this.exec(sandboxId, `sh -c ${this.shellEscape(cmd)}`);
2999
+ const execResult = result;
3000
+ if (execResult.exit_code !== 0) {
3001
+ throw new Error(execResult.stderr || `write exited with code ${execResult.exit_code}`);
3002
+ }
3003
+ } catch (err) {
3004
+ if (err instanceof ProviderError)
3005
+ throw err;
3006
+ throw new ProviderError("modal", `Failed to write file ${path}: ${err.message}`);
3007
+ }
3008
+ }
3009
+ async listFiles(sandboxId, path) {
3010
+ try {
3011
+ const result = await this.exec(sandboxId, `ls -la ${this.shellEscape(path)}`);
3012
+ const execResult = result;
3013
+ if (execResult.exit_code !== 0) {
3014
+ throw new Error(execResult.stderr || `ls exited with code ${execResult.exit_code}`);
3015
+ }
3016
+ const lines = execResult.stdout.split(`
3017
+ `).filter((l) => l.trim());
3018
+ const files = [];
3019
+ for (const line of lines) {
3020
+ if (line.startsWith("total "))
3021
+ continue;
3022
+ const parts = line.split(/\s+/);
3023
+ if (parts.length < 9)
3024
+ continue;
3025
+ const permissions = parts[0] || "";
3026
+ const size = parseInt(parts[4] || "0", 10) || 0;
3027
+ const name = parts.slice(8).join(" ");
3028
+ if (name === "." || name === "..")
3029
+ continue;
3030
+ const isDir = permissions.startsWith("d");
3031
+ const normalizedPath = path.endsWith("/") ? path : path + "/";
3032
+ files.push({
3033
+ path: normalizedPath + name,
3034
+ name,
3035
+ is_dir: isDir,
3036
+ size
3037
+ });
3038
+ }
3039
+ return files;
3040
+ } catch (err) {
3041
+ if (err instanceof ProviderError)
3042
+ throw err;
3043
+ throw new ProviderError("modal", `Failed to list files at ${path}: ${err.message}`);
3044
+ }
3045
+ }
3046
+ async stop(sandboxId) {
3047
+ const sandbox = this.getSandbox(sandboxId);
3048
+ try {
3049
+ await sandbox.terminate();
3050
+ sandboxCache.delete(sandboxId);
3051
+ } catch (err) {
3052
+ throw new ProviderError("modal", `Failed to stop sandbox: ${err.message}`);
3053
+ }
3054
+ }
3055
+ async delete(sandboxId) {
3056
+ await this.stop(sandboxId);
3057
+ }
3058
+ async keepAlive(_sandboxId, _durationMs) {}
3059
+ parseCommand(command) {
3060
+ const args = [];
3061
+ let current = "";
3062
+ let inSingle = false;
3063
+ let inDouble = false;
3064
+ let escape = false;
3065
+ for (const char of command) {
3066
+ if (escape) {
3067
+ current += char;
3068
+ escape = false;
3069
+ continue;
3070
+ }
3071
+ if (char === "\\") {
3072
+ escape = true;
3073
+ continue;
3074
+ }
3075
+ if (char === "'" && !inDouble) {
3076
+ inSingle = !inSingle;
3077
+ continue;
3078
+ }
3079
+ if (char === '"' && !inSingle) {
3080
+ inDouble = !inDouble;
3081
+ continue;
3082
+ }
3083
+ if (char === " " && !inSingle && !inDouble) {
3084
+ if (current) {
3085
+ args.push(current);
3086
+ current = "";
3087
+ }
3088
+ continue;
3089
+ }
3090
+ current += char;
3091
+ }
3092
+ if (current)
3093
+ args.push(current);
3094
+ return args;
3095
+ }
3096
+ shellEscape(str) {
3097
+ return "'" + str.replace(/'/g, "'\\''") + "'";
3098
+ }
3099
+ }
3100
+ var sandboxCache;
3101
+ var init_modal = __esm(() => {
3102
+ init_types();
3103
+ sandboxCache = new Map;
3104
+ });
3105
+
3106
+ // src/providers/index.ts
3107
+ async function getProvider(name, apiKey) {
3108
+ const key = apiKey || getProviderApiKey(name);
3109
+ const cacheKey = `${name}:${key || "default"}`;
3110
+ const cached = providerCache.get(cacheKey);
3111
+ if (cached)
3112
+ return cached;
3113
+ let provider;
3114
+ switch (name) {
3115
+ case "e2b": {
3116
+ if (!key)
3117
+ throw new ProviderError("e2b", "API key required. Set E2B_API_KEY or configure via `sandboxes config set providers.e2b.api_key <key>`");
3118
+ const { E2BProvider: E2BProvider2 } = await Promise.resolve().then(() => (init_e2b(), exports_e2b));
3119
+ provider = new E2BProvider2(key);
3120
+ break;
3121
+ }
3122
+ case "daytona": {
3123
+ if (!key)
3124
+ throw new ProviderError("daytona", "API key required. Set DAYTONA_API_KEY or configure via `sandboxes config set providers.daytona.api_key <key>`");
3125
+ const { DaytonaProvider: DaytonaProvider2 } = await Promise.resolve().then(() => (init_daytona(), exports_daytona));
3126
+ provider = new DaytonaProvider2(key);
3127
+ break;
3128
+ }
3129
+ case "modal": {
3130
+ const { ModalProvider: ModalProvider2 } = await Promise.resolve().then(() => (init_modal(), exports_modal));
3131
+ provider = new ModalProvider2(key);
3132
+ break;
3133
+ }
3134
+ default:
3135
+ throw new ProviderError(name, `Unknown provider: ${name}`);
3136
+ }
3137
+ providerCache.set(cacheKey, provider);
3138
+ return provider;
3139
+ }
3140
+ var providerCache;
3141
+ var init_providers = __esm(() => {
3142
+ init_types();
3143
+ init_config();
3144
+ providerCache = new Map;
3145
+ });
3146
+
3147
+ // src/lib/stream.ts
3148
+ function notifyListeners(sandboxId, type, data) {
3149
+ const sandboxListeners = listeners.get(sandboxId);
3150
+ if (sandboxListeners) {
3151
+ for (const listener of sandboxListeners) {
3152
+ try {
3153
+ listener(type, data);
3154
+ } catch {}
3155
+ }
3156
+ }
3157
+ }
3158
+ function createStreamCollector(sandboxId, sessionId) {
3159
+ let stdout = "";
3160
+ let stderr = "";
3161
+ return {
3162
+ onStdout: (data) => {
3163
+ stdout += data;
3164
+ addEvent({
3165
+ sandbox_id: sandboxId,
3166
+ session_id: sessionId,
3167
+ type: "stdout",
3168
+ data
3169
+ });
3170
+ notifyListeners(sandboxId, "stdout", data);
3171
+ },
3172
+ onStderr: (data) => {
3173
+ stderr += data;
3174
+ addEvent({
3175
+ sandbox_id: sandboxId,
3176
+ session_id: sessionId,
3177
+ type: "stderr",
3178
+ data
3179
+ });
3180
+ notifyListeners(sandboxId, "stderr", data);
3181
+ },
3182
+ getOutput: () => ({ stdout, stderr })
3183
+ };
3184
+ }
3185
+ function emitLifecycleEvent(sandboxId, message) {
3186
+ addEvent({
3187
+ sandbox_id: sandboxId,
3188
+ type: "lifecycle",
3189
+ data: message
3190
+ });
3191
+ notifyListeners(sandboxId, "lifecycle", message);
3192
+ }
3193
+ var listeners;
3194
+ var init_stream = __esm(() => {
3195
+ init_events();
3196
+ listeners = new Map;
3197
+ });
3198
+
3199
+ // src/lib/agent-runner.ts
3200
+ var exports_agent_runner = {};
3201
+ __export(exports_agent_runner, {
3202
+ stopAgent: () => stopAgent,
3203
+ runAgent: () => runAgent
3204
+ });
3205
+ async function runAgent(sandboxId, opts) {
3206
+ const sandbox = getSandbox(sandboxId);
3207
+ if (!sandbox.provider_sandbox_id) {
3208
+ throw new Error("Sandbox has no provider instance");
3209
+ }
3210
+ const cmd = opts.command || AGENT_COMMANDS[opts.agentType]?.(opts.prompt) || opts.prompt;
3211
+ const session = createSession({
3212
+ sandbox_id: sandbox.id,
3213
+ agent_name: opts.agentName,
3214
+ agent_type: opts.agentType,
3215
+ command: cmd
3216
+ });
3217
+ emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} started: ${opts.prompt.slice(0, 100)}`);
3218
+ const collector = createStreamCollector(sandbox.id, session.id);
3219
+ const provider = await getProvider(sandbox.provider);
3220
+ try {
3221
+ const result = await provider.exec(sandbox.provider_sandbox_id, cmd, {
3222
+ onStdout: (data) => {
3223
+ collector.onStdout(data);
3224
+ opts.onStdout?.(data);
3225
+ },
3226
+ onStderr: (data) => {
3227
+ collector.onStderr(data);
3228
+ opts.onStderr?.(data);
3229
+ },
3230
+ background: true
3231
+ });
3232
+ if ("exit_code" in result) {
3233
+ const exitResult = result;
3234
+ const status = exitResult.exit_code === 0 ? "completed" : "failed";
3235
+ return endSession(session.id, exitResult.exit_code, status);
3236
+ }
3237
+ return session;
3238
+ } catch (err) {
3239
+ endSession(session.id, 1, "failed");
3240
+ emitLifecycleEvent(sandbox.id, `Agent ${opts.agentType} failed: ${err.message}`);
3241
+ throw err;
3242
+ }
3243
+ }
3244
+ async function stopAgent(sandboxId) {
3245
+ const sandbox = getSandbox(sandboxId);
3246
+ if (!sandbox.provider_sandbox_id)
3247
+ return;
3248
+ const provider = await getProvider(sandbox.provider);
3249
+ try {
3250
+ await provider.exec(sandbox.provider_sandbox_id, "pkill -f 'claude\\|codex\\|gemini' || true");
3251
+ } catch {}
3252
+ emitLifecycleEvent(sandbox.id, "Agent stopped by user");
3253
+ }
3254
+ var AGENT_COMMANDS;
3255
+ var init_agent_runner = __esm(() => {
3256
+ init_sandboxes();
3257
+ init_sessions();
3258
+ init_providers();
3259
+ init_stream();
3260
+ AGENT_COMMANDS = {
3261
+ claude: (prompt) => `claude --dangerously-skip-permissions -p ${JSON.stringify(prompt)}`,
3262
+ codex: (prompt) => `codex -q ${JSON.stringify(prompt)}`,
3263
+ gemini: (prompt) => `gemini -p ${JSON.stringify(prompt)}`
3264
+ };
3265
+ });
3266
+
3267
+ // node_modules/commander/esm.mjs
3268
+ var import__ = __toESM(require_commander(), 1);
3269
+ var {
3270
+ program,
3271
+ createCommand,
3272
+ createArgument,
3273
+ createOption,
3274
+ CommanderError,
3275
+ InvalidArgumentError,
3276
+ InvalidOptionArgumentError,
3277
+ Command,
3278
+ Argument,
3279
+ Option,
3280
+ Help
3281
+ } = import__.default;
3282
+
3283
+ // src/cli/index.tsx
3284
+ init_sandboxes();
3285
+ init_sessions();
3286
+ init_events();
3287
+ import chalk from "chalk";
3288
+ import { execSync } from "child_process";
3289
+
3290
+ // src/db/agents.ts
3291
+ init_database();
3292
+ init_types();
3293
+ function rowToAgent(row) {
3294
+ return {
3295
+ id: row.id,
3296
+ name: row.name,
3297
+ description: row.description,
3298
+ metadata: JSON.parse(row.metadata),
3299
+ created_at: row.created_at,
3300
+ last_seen_at: row.last_seen_at
3301
+ };
3302
+ }
3303
+ function registerAgent(input) {
3304
+ const db2 = getDatabase();
3305
+ const timestamp = now();
3306
+ const existing = getAgentByName(input.name);
3307
+ if (existing) {
3308
+ db2.query("UPDATE agents SET last_seen_at = ? WHERE id = ?").run(timestamp, existing.id);
3309
+ return getAgent(existing.id);
3310
+ }
3311
+ const id = uuid();
3312
+ const description = input.description ?? null;
3313
+ db2.query(`INSERT OR IGNORE INTO agents (id, name, description, metadata, created_at, last_seen_at)
3314
+ VALUES (?, ?, ?, '{}', ?, ?)`).run(id, input.name, description, timestamp, timestamp);
3315
+ return getAgent(id);
3316
+ }
3317
+ function getAgent(id) {
3318
+ const db2 = getDatabase();
3319
+ const resolvedId = resolvePartialId("agents", id);
3320
+ if (!resolvedId)
3321
+ throw new AgentNotFoundError(id);
3322
+ const row = db2.query("SELECT * FROM agents WHERE id = ?").get(resolvedId);
3323
+ if (!row)
3324
+ throw new AgentNotFoundError(id);
3325
+ return rowToAgent(row);
3326
+ }
3327
+ function getAgentByName(name) {
3328
+ const db2 = getDatabase();
3329
+ const row = db2.query("SELECT * FROM agents WHERE name = ?").get(name);
3330
+ if (!row)
3331
+ return null;
3332
+ return rowToAgent(row);
3333
+ }
3334
+ function listAgents() {
3335
+ const db2 = getDatabase();
3336
+ const rows = db2.query("SELECT * FROM agents ORDER BY last_seen_at DESC").all();
3337
+ return rows.map(rowToAgent);
3338
+ }
3339
+
3340
+ // src/cli/index.tsx
3341
+ init_providers();
3342
+ init_config();
3343
+ init_stream();
3344
+ function printTable(headers, rows) {
3345
+ const widths = headers.map((h, i) => Math.max(h.length, ...rows.map((r) => (r[i] || "").length)));
3346
+ const headerLine = headers.map((h, i) => chalk.bold(h.padEnd(widths[i]))).join(" ");
3347
+ const separator = widths.map((w) => "\u2500".repeat(w)).join("\u2500\u2500");
3348
+ console.log(headerLine);
3349
+ console.log(chalk.dim(separator));
3350
+ for (const row of rows) {
3351
+ console.log(row.map((c, i) => (c || "").padEnd(widths[i])).join(" "));
3352
+ }
3353
+ }
3354
+ function statusColor(status) {
3355
+ switch (status) {
3356
+ case "running":
3357
+ return chalk.green(status);
3358
+ case "creating":
3359
+ return chalk.yellow(status);
3360
+ case "paused":
3361
+ return chalk.blue(status);
3362
+ case "stopped":
3363
+ return chalk.gray(status);
3364
+ case "deleted":
3365
+ return chalk.dim(status);
3366
+ case "error":
3367
+ return chalk.red(status);
3368
+ default:
3369
+ return status;
3370
+ }
3371
+ }
3372
+ function shortId(id) {
3373
+ return id.slice(0, 8);
3374
+ }
3375
+ function handleError(err) {
3376
+ if (err instanceof Error) {
3377
+ console.error(chalk.red(`Error: ${err.message}`));
3378
+ } else {
3379
+ console.error(chalk.red("An unknown error occurred"));
3380
+ }
3381
+ process.exit(1);
3382
+ }
3383
+ function parseEnvVars(envArgs) {
3384
+ const vars = {};
3385
+ for (const arg of envArgs) {
3386
+ const idx = arg.indexOf("=");
3387
+ if (idx === -1) {
3388
+ console.error(chalk.red(`Invalid env var format: ${arg} (expected KEY=VALUE)`));
3389
+ process.exit(1);
3390
+ }
3391
+ vars[arg.slice(0, idx)] = arg.slice(idx + 1);
3392
+ }
3393
+ return vars;
3394
+ }
3395
+ var program2 = new Command().name("sandboxes").description("Universal cloud sandbox manager for AI coding agents").version("0.1.0");
3396
+ program2.command("create").description("Create a new sandbox").option("-p, --provider <provider>", "Provider (e2b, daytona, modal)").option("-i, --image <image>", "Container image").option("-t, --timeout <seconds>", "Timeout in seconds").option("-n, --name <name>", "Sandbox name").option("-e, --env <KEY=VAL...>", "Environment variables", (val, acc) => {
3397
+ acc.push(val);
3398
+ return acc;
3399
+ }, []).action(async (opts) => {
3400
+ try {
3401
+ const provider = opts.provider || getDefaultProvider();
3402
+ const timeout = opts.timeout ? parseInt(opts.timeout, 10) : getDefaultTimeout();
3403
+ const image = opts.image || getDefaultImage();
3404
+ const envVars = opts.env.length > 0 ? parseEnvVars(opts.env) : undefined;
3405
+ const sandbox = createSandbox({
3406
+ provider,
3407
+ name: opts.name,
3408
+ image,
3409
+ timeout,
3410
+ env_vars: envVars
3411
+ });
3412
+ console.log(chalk.dim("Creating sandbox..."));
3413
+ const p = await getProvider(provider);
3414
+ const result = await p.create({
3415
+ image: sandbox.image || undefined,
3416
+ timeout: sandbox.timeout,
3417
+ envVars: sandbox.env_vars
3418
+ });
3419
+ const updated = updateSandbox(sandbox.id, {
3420
+ provider_sandbox_id: result.id,
3421
+ status: "running"
3422
+ });
3423
+ console.log(chalk.green("Sandbox created"));
3424
+ console.log(` ${chalk.bold("ID:")} ${updated.id}`);
3425
+ console.log(` ${chalk.bold("Provider:")} ${updated.provider}`);
3426
+ console.log(` ${chalk.bold("Status:")} ${statusColor(updated.status)}`);
3427
+ if (updated.name) {
3428
+ console.log(` ${chalk.bold("Name:")} ${updated.name}`);
3429
+ }
3430
+ } catch (err) {
3431
+ handleError(err);
3432
+ }
3433
+ });
3434
+ program2.command("list").description("List sandboxes").option("-s, --status <status>", "Filter by status").option("-p, --provider <provider>", "Filter by provider").option("--json", "Output as JSON").action((opts) => {
3435
+ try {
3436
+ const sandboxes = listSandboxes({
3437
+ status: opts.status,
3438
+ provider: opts.provider
3439
+ });
3440
+ if (opts.json) {
3441
+ console.log(JSON.stringify(sandboxes, null, 2));
3442
+ return;
3443
+ }
3444
+ if (sandboxes.length === 0) {
3445
+ console.log(chalk.dim("No sandboxes found."));
3446
+ return;
3447
+ }
3448
+ printTable(["ID", "NAME", "PROVIDER", "STATUS", "IMAGE", "CREATED"], sandboxes.map((s) => [
3449
+ shortId(s.id),
3450
+ s.name || chalk.dim("\u2014"),
3451
+ s.provider,
3452
+ statusColor(s.status),
3453
+ s.image || chalk.dim("default"),
3454
+ new Date(s.created_at).toLocaleString()
3455
+ ]));
3456
+ } catch (err) {
3457
+ handleError(err);
3458
+ }
3459
+ });
3460
+ program2.command("show <id>").description("Show sandbox details").action((id) => {
3461
+ try {
3462
+ const sandbox = getSandbox(id);
3463
+ console.log(chalk.bold("Sandbox Details"));
3464
+ console.log(` ${chalk.bold("ID:")} ${sandbox.id}`);
3465
+ console.log(` ${chalk.bold("Provider:")} ${sandbox.provider}`);
3466
+ console.log(` ${chalk.bold("Provider Sandbox:")} ${sandbox.provider_sandbox_id || chalk.dim("none")}`);
3467
+ console.log(` ${chalk.bold("Name:")} ${sandbox.name || chalk.dim("none")}`);
3468
+ console.log(` ${chalk.bold("Status:")} ${statusColor(sandbox.status)}`);
3469
+ console.log(` ${chalk.bold("Image:")} ${sandbox.image || chalk.dim("default")}`);
3470
+ console.log(` ${chalk.bold("Timeout:")} ${sandbox.timeout}s`);
3471
+ console.log(` ${chalk.bold("Created:")} ${sandbox.created_at}`);
3472
+ console.log(` ${chalk.bold("Updated:")} ${sandbox.updated_at}`);
3473
+ if (Object.keys(sandbox.env_vars).length > 0) {
3474
+ console.log(` ${chalk.bold("Env Vars:")}`);
3475
+ for (const [k, v] of Object.entries(sandbox.env_vars)) {
3476
+ console.log(` ${k}=${v}`);
3477
+ }
3478
+ }
3479
+ if (Object.keys(sandbox.config).length > 0) {
3480
+ console.log(` ${chalk.bold("Config:")} ${JSON.stringify(sandbox.config)}`);
3481
+ }
3482
+ } catch (err) {
3483
+ handleError(err);
3484
+ }
3485
+ });
3486
+ program2.command("exec <id> <command...>").description("Execute a command in a sandbox").action(async (id, commandParts) => {
3487
+ try {
3488
+ const sandbox = getSandbox(id);
3489
+ if (!sandbox.provider_sandbox_id) {
3490
+ console.error(chalk.red("Sandbox has no provider ID \u2014 it may not have been created yet."));
3491
+ process.exit(1);
3492
+ }
3493
+ const cmd = commandParts.join(" ");
3494
+ const session = createSession({
3495
+ sandbox_id: sandbox.id,
3496
+ command: cmd
3497
+ });
3498
+ const collector = createStreamCollector(sandbox.id, session.id);
3499
+ const p = await getProvider(sandbox.provider);
3500
+ const result = await p.exec(sandbox.provider_sandbox_id, cmd, {
3501
+ onStdout: (data) => {
3502
+ process.stdout.write(data);
3503
+ collector.onStdout(data);
3504
+ },
3505
+ onStderr: (data) => {
3506
+ process.stderr.write(data);
3507
+ collector.onStderr(data);
3508
+ }
3509
+ });
3510
+ const execResult = "exit_code" in result ? result : await result.wait();
3511
+ endSession(session.id, execResult.exit_code, execResult.exit_code === 0 ? "completed" : "failed");
3512
+ process.exit(execResult.exit_code);
3513
+ } catch (err) {
3514
+ handleError(err);
3515
+ }
3516
+ });
3517
+ program2.command("stop <id>").description("Stop a sandbox").action(async (id) => {
3518
+ try {
3519
+ const sandbox = getSandbox(id);
3520
+ if (sandbox.provider_sandbox_id) {
3521
+ const p = await getProvider(sandbox.provider);
3522
+ await p.stop(sandbox.provider_sandbox_id);
3523
+ }
3524
+ updateSandbox(sandbox.id, { status: "stopped" });
3525
+ console.log(chalk.green(`Sandbox ${shortId(sandbox.id)} stopped.`));
3526
+ } catch (err) {
3527
+ handleError(err);
3528
+ }
3529
+ });
3530
+ program2.command("delete <id>").description("Delete a sandbox").action(async (id) => {
3531
+ try {
3532
+ const sandbox = getSandbox(id);
3533
+ if (sandbox.provider_sandbox_id) {
3534
+ try {
3535
+ const p = await getProvider(sandbox.provider);
3536
+ await p.delete(sandbox.provider_sandbox_id);
3537
+ } catch {}
3538
+ }
3539
+ deleteSandbox(sandbox.id);
3540
+ console.log(chalk.green(`Sandbox ${shortId(sandbox.id)} deleted.`));
3541
+ } catch (err) {
3542
+ handleError(err);
3543
+ }
3544
+ });
3545
+ program2.command("logs <id>").description("Show event logs for a sandbox").option("-f, --follow", "Follow log output").option("-s, --session <session_id>", "Filter by session ID").option("-l, --limit <n>", "Max number of events", "50").action(async (id, opts) => {
3546
+ try {
3547
+ const sandbox = getSandbox(id);
3548
+ const limit = parseInt(opts.limit, 10);
3549
+ const printEvents = (events2) => {
3550
+ for (const event of events2) {
3551
+ const time = chalk.dim(new Date(event.created_at).toLocaleTimeString());
3552
+ const type = event.type === "stderr" ? chalk.red(event.type) : event.type === "stdout" ? chalk.green(event.type) : chalk.blue(event.type);
3553
+ const data = event.data || "";
3554
+ console.log(`${time} ${type} ${data}`);
3555
+ }
3556
+ };
3557
+ const events = listEvents({
3558
+ sandbox_id: sandbox.id,
3559
+ session_id: opts.session,
3560
+ limit
3561
+ });
3562
+ printEvents(events);
3563
+ if (opts.follow) {
3564
+ let lastCount = events.length;
3565
+ const poll = setInterval(() => {
3566
+ const newEvents = listEvents({
3567
+ sandbox_id: sandbox.id,
3568
+ session_id: opts.session,
3569
+ limit: 100,
3570
+ offset: lastCount
3571
+ });
3572
+ if (newEvents.length > 0) {
3573
+ printEvents(newEvents);
3574
+ lastCount += newEvents.length;
3575
+ }
3576
+ }, 1000);
3577
+ process.on("SIGINT", () => {
3578
+ clearInterval(poll);
3579
+ process.exit(0);
3580
+ });
3581
+ }
3582
+ } catch (err) {
3583
+ handleError(err);
3584
+ }
3585
+ });
3586
+ var filesCmd = program2.command("files").description("File operations on a sandbox");
3587
+ filesCmd.command("ls <id> <path>").description("List files in a sandbox directory").action(async (id, path) => {
3588
+ try {
3589
+ const sandbox = getSandbox(id);
3590
+ if (!sandbox.provider_sandbox_id) {
3591
+ console.error(chalk.red("Sandbox has no provider ID."));
3592
+ process.exit(1);
3593
+ }
3594
+ const p = await getProvider(sandbox.provider);
3595
+ const files = await p.listFiles(sandbox.provider_sandbox_id, path);
3596
+ if (files.length === 0) {
3597
+ console.log(chalk.dim("No files found."));
3598
+ return;
3599
+ }
3600
+ printTable(["NAME", "TYPE", "SIZE"], files.map((f) => [
3601
+ f.is_dir ? chalk.blue(f.name + "/") : f.name,
3602
+ f.is_dir ? "dir" : "file",
3603
+ f.is_dir ? chalk.dim("\u2014") : `${f.size}`
3604
+ ]));
3605
+ } catch (err) {
3606
+ handleError(err);
3607
+ }
3608
+ });
3609
+ filesCmd.command("read <id> <path>").description("Read a file from a sandbox").action(async (id, path) => {
3610
+ try {
3611
+ const sandbox = getSandbox(id);
3612
+ if (!sandbox.provider_sandbox_id) {
3613
+ console.error(chalk.red("Sandbox has no provider ID."));
3614
+ process.exit(1);
3615
+ }
3616
+ const p = await getProvider(sandbox.provider);
3617
+ const content = await p.readFile(sandbox.provider_sandbox_id, path);
3618
+ process.stdout.write(content);
3619
+ } catch (err) {
3620
+ handleError(err);
3621
+ }
3622
+ });
3623
+ filesCmd.command("write <id> <path>").description("Write content to a file in a sandbox").requiredOption("-c, --content <content>", "Content to write").action(async (id, path, opts) => {
3624
+ try {
3625
+ const sandbox = getSandbox(id);
3626
+ if (!sandbox.provider_sandbox_id) {
3627
+ console.error(chalk.red("Sandbox has no provider ID."));
3628
+ process.exit(1);
3629
+ }
3630
+ const p = await getProvider(sandbox.provider);
3631
+ await p.writeFile(sandbox.provider_sandbox_id, path, opts.content);
3632
+ console.log(chalk.green(`Written to ${path}`));
3633
+ } catch (err) {
3634
+ handleError(err);
3635
+ }
3636
+ });
3637
+ var agentCmd = program2.command("agent").description("Run and manage AI agents in sandboxes");
3638
+ agentCmd.command("run <id>").description("Run an AI agent inside a sandbox").requiredOption("-t, --type <type>", "Agent type: claude, codex, gemini, custom").requiredOption("-p, --prompt <prompt>", "Prompt for the agent").option("-n, --name <name>", "Agent name").option("-c, --command <cmd>", "Custom command (for 'custom' type)").action(async (id, opts) => {
3639
+ try {
3640
+ const { runAgent: runAgent2 } = await Promise.resolve().then(() => (init_agent_runner(), exports_agent_runner));
3641
+ const session = await runAgent2(id, {
3642
+ agentType: opts.type,
3643
+ prompt: opts.prompt,
3644
+ agentName: opts.name,
3645
+ command: opts.command,
3646
+ onStdout: (data) => process.stdout.write(data),
3647
+ onStderr: (data) => process.stderr.write(data)
3648
+ });
3649
+ console.log(chalk.green(`
3650
+ Agent session: ${session.id} (${session.status})`));
3651
+ } catch (err) {
3652
+ handleError(err);
3653
+ }
3654
+ });
3655
+ agentCmd.command("stop <id>").description("Stop a running agent in a sandbox").action(async (id) => {
3656
+ try {
3657
+ const { stopAgent: stopAgent2 } = await Promise.resolve().then(() => (init_agent_runner(), exports_agent_runner));
3658
+ await stopAgent2(id);
3659
+ console.log(chalk.green("Agent stopped."));
3660
+ } catch (err) {
3661
+ handleError(err);
3662
+ }
3663
+ });
3664
+ agentCmd.command("stream <id>").description("Stream agent output from a sandbox").option("-s, --session <session>", "Session ID").action(async (id, opts) => {
3665
+ try {
3666
+ const sandbox = getSandbox(id);
3667
+ const events = listEvents({
3668
+ sandbox_id: sandbox.id,
3669
+ session_id: opts.session
3670
+ });
3671
+ for (const event of events) {
3672
+ if (event.type === "stdout" && event.data) {
3673
+ process.stdout.write(event.data);
3674
+ } else if (event.type === "stderr" && event.data) {
3675
+ process.stderr.write(event.data);
3676
+ }
3677
+ }
3678
+ } catch (err) {
3679
+ handleError(err);
3680
+ }
3681
+ });
3682
+ var configCmd = program2.command("config").description("Configuration management");
3683
+ configCmd.command("set <key> <value>").description("Set a config value").action((key, value) => {
3684
+ try {
3685
+ setConfigValue(key, value);
3686
+ console.log(chalk.green(`Set ${key} = ${value}`));
3687
+ } catch (err) {
3688
+ handleError(err);
3689
+ }
3690
+ });
3691
+ configCmd.command("get <key>").description("Get a config value").action((key) => {
3692
+ try {
3693
+ const value = getConfigValue(key);
3694
+ if (value === undefined) {
3695
+ console.log(chalk.dim("(not set)"));
3696
+ } else {
3697
+ console.log(value);
3698
+ }
3699
+ } catch (err) {
3700
+ handleError(err);
3701
+ }
3702
+ });
3703
+ program2.command("init").description("Register an agent").requiredOption("-n, --name <name>", "Agent name").option("-d, --description <desc>", "Agent description").action((opts) => {
3704
+ try {
3705
+ const agent = registerAgent({
3706
+ name: opts.name,
3707
+ description: opts.description
3708
+ });
3709
+ console.log(chalk.green(`Agent registered: ${agent.name}`));
3710
+ console.log(` ${chalk.bold("ID:")} ${agent.id}`);
3711
+ } catch (err) {
3712
+ handleError(err);
3713
+ }
3714
+ });
3715
+ program2.command("agents").description("List registered agents").action(() => {
3716
+ try {
3717
+ const agents = listAgents();
3718
+ if (agents.length === 0) {
3719
+ console.log(chalk.dim("No agents registered."));
3720
+ return;
3721
+ }
3722
+ printTable(["ID", "NAME", "DESCRIPTION", "LAST SEEN"], agents.map((a) => [
3723
+ shortId(a.id),
3724
+ a.name,
3725
+ a.description || chalk.dim("\u2014"),
3726
+ new Date(a.last_seen_at).toLocaleString()
3727
+ ]));
3728
+ } catch (err) {
3729
+ handleError(err);
3730
+ }
3731
+ });
3732
+ program2.command("mcp").description("Install MCP server for AI agents").option("--claude", "Install for Claude Code (default)").option("--codex", "Install for Codex").option("--gemini", "Install for Gemini").action((opts) => {
3733
+ try {
3734
+ const targets = [];
3735
+ if (opts.codex)
3736
+ targets.push("codex");
3737
+ if (opts.gemini)
3738
+ targets.push("gemini");
3739
+ if (opts.claude || targets.length === 0)
3740
+ targets.push("claude");
3741
+ for (const target of targets) {
3742
+ switch (target) {
3743
+ case "claude": {
3744
+ const cmd = `claude mcp add --transport stdio --scope user sandboxes -- bunx @hasna/sandboxes sandboxes-mcp`;
3745
+ console.log(chalk.dim(`Running: ${cmd}`));
3746
+ execSync(cmd, { stdio: "inherit" });
3747
+ console.log(chalk.green("Installed MCP server for Claude Code."));
3748
+ break;
3749
+ }
3750
+ case "codex": {
3751
+ console.log(chalk.yellow("Codex MCP installation: add the following to ~/.codex/config.toml:"));
3752
+ console.log();
3753
+ console.log(`[mcp_servers.sandboxes]`);
3754
+ console.log(`command = "bunx"`);
3755
+ console.log(`args = ["@hasna/sandboxes", "sandboxes-mcp"]`);
3756
+ break;
3757
+ }
3758
+ case "gemini": {
3759
+ console.log(chalk.yellow("Gemini MCP installation: add the following to ~/.gemini/settings.json:"));
3760
+ console.log();
3761
+ console.log(JSON.stringify({
3762
+ mcpServers: {
3763
+ sandboxes: {
3764
+ command: "bunx",
3765
+ args: ["@hasna/sandboxes", "sandboxes-mcp"]
3766
+ }
3767
+ }
3768
+ }, null, 2));
3769
+ break;
3770
+ }
3771
+ }
3772
+ }
3773
+ } catch (err) {
3774
+ handleError(err);
3775
+ }
3776
+ });
3777
+ program2.parse();