bdy 1.16.11-master → 1.16.11-sbs-2

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 (52) hide show
  1. package/distTs/package.json +4 -3
  2. package/distTs/src/api/client.js +78 -2
  3. package/distTs/src/command/agent/install.js +11 -17
  4. package/distTs/src/command/login.js +298 -0
  5. package/distTs/src/command/logout.js +15 -0
  6. package/distTs/src/command/package/download.js +259 -0
  7. package/distTs/src/command/package/publish.js +231 -0
  8. package/distTs/src/command/package.js +14 -0
  9. package/distTs/src/command/project/list.js +61 -0
  10. package/distTs/src/command/project/set.js +85 -0
  11. package/distTs/src/command/project.js +14 -0
  12. package/distTs/src/command/sandbox/command/kill.js +35 -0
  13. package/distTs/src/command/sandbox/command/list.js +54 -0
  14. package/distTs/src/command/sandbox/command/logs.js +133 -0
  15. package/distTs/src/command/sandbox/command/status.js +44 -0
  16. package/distTs/src/command/sandbox/command.js +18 -0
  17. package/distTs/src/command/sandbox/cp.js +123 -0
  18. package/distTs/src/command/sandbox/create.js +99 -0
  19. package/distTs/src/command/sandbox/destroy.js +35 -0
  20. package/distTs/src/command/sandbox/endpoint/add.js +91 -0
  21. package/distTs/src/command/sandbox/endpoint/delete.js +46 -0
  22. package/distTs/src/command/sandbox/endpoint/get.js +58 -0
  23. package/distTs/src/command/sandbox/endpoint/list.js +51 -0
  24. package/distTs/src/command/sandbox/endpoint/update.js +85 -0
  25. package/distTs/src/command/sandbox/endpoint.js +20 -0
  26. package/distTs/src/command/sandbox/exec.js +127 -0
  27. package/distTs/src/command/sandbox/get.js +51 -0
  28. package/distTs/src/command/sandbox/list.js +41 -0
  29. package/distTs/src/command/sandbox/restart.js +49 -0
  30. package/distTs/src/command/sandbox/snapshot/create.js +68 -0
  31. package/distTs/src/command/sandbox/snapshot/delete.js +42 -0
  32. package/distTs/src/command/sandbox/snapshot/get.js +54 -0
  33. package/distTs/src/command/sandbox/snapshot/list.js +48 -0
  34. package/distTs/src/command/sandbox/snapshot.js +18 -0
  35. package/distTs/src/command/sandbox/start.js +49 -0
  36. package/distTs/src/command/sandbox/status.js +35 -0
  37. package/distTs/src/command/sandbox/stop.js +49 -0
  38. package/distTs/src/command/sandbox.js +36 -0
  39. package/distTs/src/command/tunnel/http.js +4 -3
  40. package/distTs/src/command/tunnel/tcp.js +4 -3
  41. package/distTs/src/command/tunnel/tls.js +4 -3
  42. package/distTs/src/command/workspace/list.js +57 -0
  43. package/distTs/src/command/workspace/set.js +81 -0
  44. package/distTs/src/command/workspace.js +14 -0
  45. package/distTs/src/index.js +10 -0
  46. package/distTs/src/input.js +24 -4
  47. package/distTs/src/texts.js +164 -8
  48. package/distTs/src/tunnel/cfg.js +53 -4
  49. package/package.json +4 -3
  50. package/distTs/src/command/agent/standalone/kill.js +0 -22
  51. package/distTs/src/command/agent/standalone.js +0 -136
  52. package/distTs/src/command/vt/scrap.js +0 -193
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const input_1 = __importDefault(require("../../../input"));
10
+ const client_1 = __importDefault(require("../../../api/client"));
11
+ const commandSandboxCommandKill = (0, utils_1.newCommand)('kill', texts_1.DESC_COMMAND_SANDBOX_COMMAND_KILL);
12
+ commandSandboxCommandKill.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
13
+ commandSandboxCommandKill.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
14
+ commandSandboxCommandKill.option('--region <region>', texts_1.OPTION_REST_API_REGION);
15
+ commandSandboxCommandKill.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
16
+ commandSandboxCommandKill.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
17
+ commandSandboxCommandKill.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
18
+ commandSandboxCommandKill.argument('<command-id>', texts_1.OPTION_SANDBOX_COMMAND_ID);
19
+ commandSandboxCommandKill.action(async (identifier, commandId, options) => {
20
+ const token = input_1.default.restApiToken(options.token);
21
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
22
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
23
+ const project = input_1.default.restApiProject(options.project);
24
+ const client = new client_1.default(baseUrl, token);
25
+ // Find sandbox by identifier
26
+ const result = await client.listSandboxes(workspace, project);
27
+ const sandboxes = result.sandboxes || [];
28
+ const found = sandboxes.find((s) => s.identifier === identifier);
29
+ if (!found) {
30
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
31
+ }
32
+ await client.terminateSandboxCommand(workspace, found.id, commandId);
33
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_COMMAND_KILLED)(commandId));
34
+ });
35
+ exports.default = commandSandboxCommandKill;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const input_1 = __importDefault(require("../../../input"));
10
+ const client_1 = __importDefault(require("../../../api/client"));
11
+ const commandSandboxCommandList = (0, utils_1.newCommand)('list', texts_1.DESC_COMMAND_SANDBOX_COMMAND_LIST);
12
+ commandSandboxCommandList.alias('ls');
13
+ commandSandboxCommandList.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
14
+ commandSandboxCommandList.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
15
+ commandSandboxCommandList.option('--region <region>', texts_1.OPTION_REST_API_REGION);
16
+ commandSandboxCommandList.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
17
+ commandSandboxCommandList.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
18
+ commandSandboxCommandList.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
19
+ commandSandboxCommandList.action(async (identifier, options) => {
20
+ const token = input_1.default.restApiToken(options.token);
21
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
22
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
23
+ const project = input_1.default.restApiProject(options.project);
24
+ const client = new client_1.default(baseUrl, token);
25
+ // Find sandbox by identifier
26
+ const result = await client.listSandboxes(workspace, project);
27
+ const sandboxes = result.sandboxes || [];
28
+ const found = sandboxes.find((s) => s.identifier === identifier);
29
+ if (!found) {
30
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
31
+ }
32
+ const commandsResult = await client.listSandboxCommands(workspace, found.id);
33
+ const commands = commandsResult.commands || [];
34
+ if (commands.length === 0) {
35
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NO_COMMANDS);
36
+ }
37
+ // Sort by ID descending (IDs are timestamp-based, so newest first)
38
+ commands.sort((a, b) => (b.id || '').localeCompare(a.id || ''));
39
+ const data = [
40
+ ['ID', 'COMMAND', 'STATUS', 'EXIT CODE', 'RUNTIME'],
41
+ ];
42
+ for (const cmd of commands) {
43
+ data.push([
44
+ cmd.id || '-',
45
+ (cmd.command || '-').substring(0, 40) + (cmd.command?.length > 40 ? '...' : ''),
46
+ cmd.status || '-',
47
+ cmd.exit_code !== undefined ? String(cmd.exit_code) : '-',
48
+ cmd.runtime || 'BASH',
49
+ ]);
50
+ }
51
+ output_1.default.table(data);
52
+ output_1.default.exitNormal();
53
+ });
54
+ exports.default = commandSandboxCommandList;
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const input_1 = __importDefault(require("../../../input"));
10
+ const client_1 = __importDefault(require("../../../api/client"));
11
+ const commandSandboxCommandLogs = (0, utils_1.newCommand)('logs', texts_1.DESC_COMMAND_SANDBOX_COMMAND_LOGS);
12
+ commandSandboxCommandLogs.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
13
+ commandSandboxCommandLogs.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
14
+ commandSandboxCommandLogs.option('--region <region>', texts_1.OPTION_REST_API_REGION);
15
+ commandSandboxCommandLogs.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
16
+ commandSandboxCommandLogs.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
17
+ commandSandboxCommandLogs.option('-f, --follow', texts_1.OPTION_SANDBOX_COMMAND_FOLLOW);
18
+ commandSandboxCommandLogs.option('-l, --last', texts_1.OPTION_SANDBOX_COMMAND_LAST);
19
+ commandSandboxCommandLogs.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
20
+ commandSandboxCommandLogs.argument('[command-id]', texts_1.OPTION_SANDBOX_COMMAND_ID);
21
+ commandSandboxCommandLogs.action(async (identifier, commandId, options) => {
22
+ const token = input_1.default.restApiToken(options.token);
23
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
24
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
25
+ const project = input_1.default.restApiProject(options.project);
26
+ const client = new client_1.default(baseUrl, token);
27
+ // Find sandbox by identifier
28
+ const result = await client.listSandboxes(workspace, project);
29
+ const sandboxes = result.sandboxes || [];
30
+ const found = sandboxes.find((s) => s.identifier === identifier);
31
+ if (!found) {
32
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
33
+ }
34
+ // If --last flag is used or no command-id provided, get the most recent command
35
+ let resolvedCommandId = commandId || '';
36
+ if (options.last || !commandId) {
37
+ const commandsResult = await client.listSandboxCommands(workspace, found.id);
38
+ const commands = commandsResult.commands || [];
39
+ if (commands.length === 0) {
40
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NO_COMMANDS);
41
+ }
42
+ // Sort by ID descending (IDs are timestamp-based, so newest first)
43
+ commands.sort((a, b) => (b.id || '').localeCompare(a.id || ''));
44
+ resolvedCommandId = commands[0].id;
45
+ }
46
+ const logsUrl = await client.getSandboxCommandLogsUrl(workspace, found.id, resolvedCommandId);
47
+ try {
48
+ const response = await fetch(logsUrl, {
49
+ method: 'GET',
50
+ headers: {
51
+ Accept: 'application/jsonl',
52
+ Authorization: `Bearer ${token}`,
53
+ },
54
+ });
55
+ if (response.ok && response.body) {
56
+ if (options.follow) {
57
+ // Streaming mode - read and output as data arrives
58
+ const reader = response.body.getReader();
59
+ const decoder = new TextDecoder();
60
+ let buffer = '';
61
+ while (true) {
62
+ const { done, value } = await reader.read();
63
+ if (done)
64
+ break;
65
+ buffer += decoder.decode(value, { stream: true });
66
+ const lines = buffer.split('\n');
67
+ buffer = lines.pop() || '';
68
+ for (const line of lines) {
69
+ if (!line.trim())
70
+ continue;
71
+ try {
72
+ const logEntry = JSON.parse(line);
73
+ const content = logEntry.data ?? logEntry.message ?? '';
74
+ if (content) {
75
+ if (logEntry.stream === 'stderr' || logEntry.type === 'STDERR') {
76
+ process.stderr.write(content + '\n');
77
+ }
78
+ else {
79
+ process.stdout.write(content + '\n');
80
+ }
81
+ }
82
+ }
83
+ catch {
84
+ process.stdout.write(line + '\n');
85
+ }
86
+ }
87
+ }
88
+ // Process remaining buffer
89
+ if (buffer.trim()) {
90
+ try {
91
+ const logEntry = JSON.parse(buffer);
92
+ const content = logEntry.data ?? logEntry.message ?? '';
93
+ if (content) {
94
+ process.stdout.write(content + '\n');
95
+ }
96
+ }
97
+ catch {
98
+ process.stdout.write(buffer + '\n');
99
+ }
100
+ }
101
+ }
102
+ else {
103
+ // Default mode - fetch all and output at once
104
+ const text = await response.text();
105
+ const lines = text.split('\n');
106
+ for (const line of lines) {
107
+ if (!line.trim())
108
+ continue;
109
+ try {
110
+ const logEntry = JSON.parse(line);
111
+ const content = logEntry.data ?? logEntry.message ?? '';
112
+ if (content) {
113
+ if (logEntry.stream === 'stderr' || logEntry.type === 'STDERR') {
114
+ process.stderr.write(content + '\n');
115
+ }
116
+ else {
117
+ process.stdout.write(content + '\n');
118
+ }
119
+ }
120
+ }
121
+ catch {
122
+ process.stdout.write(line + '\n');
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ catch (err) {
129
+ output_1.default.exitError(err);
130
+ }
131
+ output_1.default.exitNormal();
132
+ });
133
+ exports.default = commandSandboxCommandLogs;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const input_1 = __importDefault(require("../../../input"));
10
+ const client_1 = __importDefault(require("../../../api/client"));
11
+ const commandSandboxCommandStatus = (0, utils_1.newCommand)('status', texts_1.DESC_COMMAND_SANDBOX_COMMAND_STATUS);
12
+ commandSandboxCommandStatus.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
13
+ commandSandboxCommandStatus.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
14
+ commandSandboxCommandStatus.option('--region <region>', texts_1.OPTION_REST_API_REGION);
15
+ commandSandboxCommandStatus.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
16
+ commandSandboxCommandStatus.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
17
+ commandSandboxCommandStatus.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
18
+ commandSandboxCommandStatus.argument('<command-id>', texts_1.OPTION_SANDBOX_COMMAND_ID);
19
+ commandSandboxCommandStatus.action(async (identifier, commandId, options) => {
20
+ const token = input_1.default.restApiToken(options.token);
21
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
22
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
23
+ const project = input_1.default.restApiProject(options.project);
24
+ const client = new client_1.default(baseUrl, token);
25
+ // Find sandbox by identifier
26
+ const result = await client.listSandboxes(workspace, project);
27
+ const sandboxes = result.sandboxes || [];
28
+ const found = sandboxes.find((s) => s.identifier === identifier);
29
+ if (!found) {
30
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
31
+ }
32
+ const cmd = await client.getSandboxCommand(workspace, found.id, commandId);
33
+ const data = [
34
+ ['Property', 'Value'],
35
+ ['Command ID', cmd.id || '-'],
36
+ ['Command', cmd.command || '-'],
37
+ ['Runtime', cmd.runtime || 'BASH'],
38
+ ['Status', cmd.status || '-'],
39
+ ['Exit Code', cmd.exit_code !== undefined ? String(cmd.exit_code) : '-'],
40
+ ];
41
+ output_1.default.table(data);
42
+ output_1.default.exitNormal();
43
+ });
44
+ exports.default = commandSandboxCommandStatus;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../utils");
7
+ const texts_1 = require("../../texts");
8
+ const list_1 = __importDefault(require("./command/list"));
9
+ const status_1 = __importDefault(require("./command/status"));
10
+ const logs_1 = __importDefault(require("./command/logs"));
11
+ const kill_1 = __importDefault(require("./command/kill"));
12
+ const commandSandboxCommand = (0, utils_1.newCommand)('command', texts_1.DESC_COMMAND_SANDBOX_COMMAND);
13
+ commandSandboxCommand.alias('cmd');
14
+ commandSandboxCommand.addCommand(list_1.default);
15
+ commandSandboxCommand.addCommand(status_1.default);
16
+ commandSandboxCommand.addCommand(logs_1.default);
17
+ commandSandboxCommand.addCommand(kill_1.default);
18
+ exports.default = commandSandboxCommand;
@@ -0,0 +1,123 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../utils");
7
+ const texts_1 = require("../../texts");
8
+ const output_1 = __importDefault(require("../../output"));
9
+ const input_1 = __importDefault(require("../../input"));
10
+ const client_1 = __importDefault(require("../../api/client"));
11
+ const fdir_1 = require("fdir");
12
+ const fs_1 = require("fs");
13
+ const path_1 = require("path");
14
+ const commandSandboxCp = (0, utils_1.newCommand)('cp', texts_1.DESC_COMMAND_SANDBOX_CP);
15
+ commandSandboxCp.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
16
+ commandSandboxCp.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
17
+ commandSandboxCp.option('--region <region>', texts_1.OPTION_REST_API_REGION);
18
+ commandSandboxCp.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
19
+ commandSandboxCp.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
20
+ commandSandboxCp.option('-s, --silent', texts_1.OPTION_SANDBOX_CP_SILENT);
21
+ commandSandboxCp.argument('<source>', texts_1.OPTION_SANDBOX_CP_SOURCE);
22
+ commandSandboxCp.argument('<destination>', texts_1.OPTION_SANDBOX_CP_DEST);
23
+ function parseDestination(dest) {
24
+ const colonIndex = dest.indexOf(':');
25
+ if (colonIndex === -1 || colonIndex === 0) {
26
+ return null;
27
+ }
28
+ const identifier = dest.substring(0, colonIndex);
29
+ let remotePath = dest.substring(colonIndex + 1);
30
+ // Ensure remote path starts with /
31
+ if (!remotePath.startsWith('/')) {
32
+ remotePath = '/' + remotePath;
33
+ }
34
+ return { identifier, remotePath };
35
+ }
36
+ async function copyFileToSandbox(client, workspace, sandboxId, localPath, remotePath) {
37
+ const content = (0, fs_1.readFileSync)(localPath);
38
+ const base64 = content.toString('base64');
39
+ // Create parent directory if needed
40
+ const parentDir = (0, path_1.dirname)(remotePath);
41
+ if (parentDir !== '/') {
42
+ await client.executeSandboxCommand(workspace, sandboxId, {
43
+ command: `mkdir -p '${parentDir}'`,
44
+ });
45
+ }
46
+ // Transfer file using base64
47
+ // For files up to ~48KB encoded (fits in typical command line)
48
+ if (base64.length <= 65536) {
49
+ await client.executeSandboxCommand(workspace, sandboxId, {
50
+ command: `echo '${base64}' | base64 -d > '${remotePath}'`,
51
+ });
52
+ }
53
+ else {
54
+ // For larger files, use heredoc approach
55
+ await client.executeSandboxCommand(workspace, sandboxId, {
56
+ command: `base64 -d > '${remotePath}' << 'EOFBASE64'\n${base64}\nEOFBASE64`,
57
+ });
58
+ }
59
+ }
60
+ commandSandboxCp.action(async (source, destination, options) => {
61
+ const token = input_1.default.restApiToken(options.token);
62
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
63
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
64
+ const project = input_1.default.restApiProject(options.project);
65
+ const client = new client_1.default(baseUrl, token);
66
+ // Parse destination
67
+ const parsed = parseDestination(destination);
68
+ if (!parsed) {
69
+ output_1.default.exitError(texts_1.ERR_SANDBOX_CP_INVALID_DEST);
70
+ }
71
+ const { identifier, remotePath } = parsed;
72
+ // Validate source exists
73
+ const sourcePath = (0, path_1.resolve)(source);
74
+ if (!(0, fs_1.existsSync)(sourcePath)) {
75
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_SOURCE_NOT_FOUND)(source));
76
+ }
77
+ // Find sandbox by identifier
78
+ const result = await client.listSandboxes(workspace, project);
79
+ const sandboxes = result.sandboxes || [];
80
+ const found = sandboxes.find((s) => s.identifier === identifier);
81
+ if (!found) {
82
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
83
+ }
84
+ const stats = (0, fs_1.statSync)(sourcePath);
85
+ const silent = options.silent;
86
+ if (stats.isFile()) {
87
+ // Single file copy
88
+ if (!silent)
89
+ output_1.default.gray((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(1, 1, (0, path_1.basename)(sourcePath)));
90
+ await copyFileToSandbox(client, workspace, found.id, sourcePath, remotePath);
91
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(1));
92
+ }
93
+ else if (stats.isDirectory()) {
94
+ // Directory copy - get all files recursively
95
+ const files = new fdir_1.fdir()
96
+ .withFullPaths()
97
+ .crawl(sourcePath)
98
+ .sync();
99
+ if (files.length === 0) {
100
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(0));
101
+ }
102
+ if (!silent)
103
+ output_1.default.normal(`Copying ${files.length} file(s)...`);
104
+ for (let i = 0; i < files.length; i++) {
105
+ const localFile = files[i];
106
+ const relativePath = (0, path_1.relative)(sourcePath, localFile);
107
+ const remoteFile = (0, path_1.join)(remotePath, relativePath).replace(/\\/g, '/');
108
+ if (!silent)
109
+ output_1.default.gray((0, texts_1.TXT_SANDBOX_CP_PROGRESS)(i + 1, files.length, relativePath));
110
+ try {
111
+ await copyFileToSandbox(client, workspace, found.id, localFile, remoteFile);
112
+ }
113
+ catch (err) {
114
+ output_1.default.error(`Failed to copy ${relativePath}: ${err.message || err}`);
115
+ }
116
+ }
117
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CP_DONE)(files.length));
118
+ }
119
+ else {
120
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_CP_SOURCE_NOT_FOUND)(source));
121
+ }
122
+ });
123
+ exports.default = commandSandboxCp;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../utils");
7
+ const texts_1 = require("../../texts");
8
+ const output_1 = __importDefault(require("../../output"));
9
+ const input_1 = __importDefault(require("../../input"));
10
+ const client_1 = __importDefault(require("../../api/client"));
11
+ const human_id_1 = __importDefault(require("human-id"));
12
+ const VALID_RESOURCES = ['1x2', '2x4', '3x6', '4x8', '5x10', '6x12', '7x14', '8x16', '9x18', '10x20', '11x22', '12x24', 'CUSTOM'];
13
+ const commandSandboxCreate = (0, utils_1.newCommand)('create', texts_1.DESC_COMMAND_SANDBOX_CREATE);
14
+ commandSandboxCreate.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
15
+ commandSandboxCreate.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
16
+ commandSandboxCreate.option('--region <region>', texts_1.OPTION_REST_API_REGION);
17
+ commandSandboxCreate.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
18
+ commandSandboxCreate.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
19
+ commandSandboxCreate.option('-n, --name <name>', texts_1.OPTION_SANDBOX_NAME);
20
+ commandSandboxCreate.option('-i, --identifier <identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
21
+ commandSandboxCreate.option('--os <image>', texts_1.OPTION_SANDBOX_OS);
22
+ commandSandboxCreate.option('--snapshot <snapshot-name>', texts_1.OPTION_SANDBOX_FROM_SNAPSHOT);
23
+ commandSandboxCreate.option('--resources <spec>', texts_1.OPTION_SANDBOX_RESOURCES);
24
+ commandSandboxCreate.option('--install-commands <commands...>', texts_1.OPTION_SANDBOX_INSTALL_COMMANDS);
25
+ commandSandboxCreate.option('--run-command <command>', texts_1.OPTION_SANDBOX_RUN_COMMAND);
26
+ commandSandboxCreate.action(async (options) => {
27
+ const token = input_1.default.restApiToken(options.token);
28
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
29
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
30
+ const project = input_1.default.restApiProject(options.project);
31
+ const client = new client_1.default(baseUrl, token);
32
+ // Validate resources if provided
33
+ if (options.resources && !VALID_RESOURCES.includes(options.resources)) {
34
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_INVALID_RESOURCES)(options.resources));
35
+ }
36
+ const defaultName = (0, human_id_1.default)({ separator: '-', capitalize: false });
37
+ const body = {
38
+ name: options.name || defaultName,
39
+ identifier: options.identifier || defaultName,
40
+ };
41
+ // Use snapshot_id if provided, otherwise use os
42
+ if (options.snapshot) {
43
+ // Find snapshot by name across all sandboxes
44
+ const sandboxesResult = await client.listSandboxes(workspace, project);
45
+ const sandboxes = sandboxesResult.sandboxes || [];
46
+ let foundSnapshotId = null;
47
+ for (const sandbox of sandboxes) {
48
+ const snapshotsResult = await client.listSandboxSnapshots(workspace, sandbox.id);
49
+ const snapshots = snapshotsResult.snapshots || [];
50
+ const foundSnapshot = snapshots.find((s) => s.name === options.snapshot);
51
+ if (foundSnapshot) {
52
+ foundSnapshotId = foundSnapshot.id;
53
+ break;
54
+ }
55
+ }
56
+ if (!foundSnapshotId) {
57
+ output_1.default.exitError(texts_1.ERR_SANDBOX_SNAPSHOT_NOT_FOUND);
58
+ }
59
+ body.snapshot_id = foundSnapshotId;
60
+ }
61
+ else {
62
+ body.os = options.os || 'ubuntu:24.04';
63
+ }
64
+ if (options.resources) {
65
+ body.resources = options.resources;
66
+ }
67
+ if (options.installCommands) {
68
+ body.install_commands = options.installCommands.join('\n');
69
+ }
70
+ if (options.runCommand) {
71
+ body.run_command = options.runCommand;
72
+ }
73
+ output_1.default.normal(`Creating sandbox: ${body.name}`);
74
+ const result = await client.createSandbox(workspace, project, body);
75
+ const sandboxId = result.id;
76
+ // If already ready, exit immediately
77
+ if (result.setup_status === 'SUCCESS' || result.setup_status === 'DONE') {
78
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CREATED)(result.name, `${result.html_url}/terminal`));
79
+ }
80
+ // Wait for sandbox to be ready
81
+ output_1.default.normal(texts_1.TXT_SANDBOX_WAITING);
82
+ // Poll until setup_status is SUCCESS or FAILED (max 5 minutes)
83
+ const maxWaitMs = 5 * 60 * 1000;
84
+ const startTime = Date.now();
85
+ while (true) {
86
+ const sandbox = await client.getSandbox(workspace, sandboxId);
87
+ if (sandbox.setup_status === 'SUCCESS' || sandbox.setup_status === 'DONE') {
88
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_CREATED)(sandbox.name, `${sandbox.html_url}/terminal`));
89
+ }
90
+ if (sandbox.setup_status === 'FAILED') {
91
+ output_1.default.exitError(texts_1.ERR_SANDBOX_SETUP_FAILED);
92
+ }
93
+ if (Date.now() - startTime > maxWaitMs) {
94
+ output_1.default.exitError('Timeout waiting for sandbox setup');
95
+ }
96
+ await new Promise((resolve) => setTimeout(resolve, 2000));
97
+ }
98
+ });
99
+ exports.default = commandSandboxCreate;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../utils");
7
+ const texts_1 = require("../../texts");
8
+ const output_1 = __importDefault(require("../../output"));
9
+ const input_1 = __importDefault(require("../../input"));
10
+ const client_1 = __importDefault(require("../../api/client"));
11
+ const commandSandboxDestroy = (0, utils_1.newCommand)('destroy', texts_1.DESC_COMMAND_SANDBOX_DESTROY);
12
+ commandSandboxDestroy.alias('rm');
13
+ commandSandboxDestroy.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
14
+ commandSandboxDestroy.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
15
+ commandSandboxDestroy.option('--region <region>', texts_1.OPTION_REST_API_REGION);
16
+ commandSandboxDestroy.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
17
+ commandSandboxDestroy.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
18
+ commandSandboxDestroy.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
19
+ commandSandboxDestroy.action(async (identifier, options) => {
20
+ const token = input_1.default.restApiToken(options.token);
21
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
22
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
23
+ const project = input_1.default.restApiProject(options.project);
24
+ const client = new client_1.default(baseUrl, token);
25
+ // First list sandboxes to find by identifier
26
+ const result = await client.listSandboxes(workspace, project);
27
+ const sandboxes = result.sandboxes || [];
28
+ const found = sandboxes.find((s) => s.identifier === identifier);
29
+ if (!found) {
30
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
31
+ }
32
+ await client.deleteSandbox(workspace, found.id);
33
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_DESTROYED)(identifier));
34
+ });
35
+ exports.default = commandSandboxDestroy;
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const utils_1 = require("../../../utils");
7
+ const texts_1 = require("../../../texts");
8
+ const output_1 = __importDefault(require("../../../output"));
9
+ const input_1 = __importDefault(require("../../../input"));
10
+ const client_1 = __importDefault(require("../../../api/client"));
11
+ const commandSandboxEndpointAdd = (0, utils_1.newCommand)('add', texts_1.DESC_COMMAND_SANDBOX_ENDPOINT_ADD);
12
+ commandSandboxEndpointAdd.option('--token <token>', texts_1.OPTION_REST_API_TOKEN);
13
+ commandSandboxEndpointAdd.option('--api <url>', texts_1.OPTION_REST_API_ENDPOINT);
14
+ commandSandboxEndpointAdd.option('--region <region>', texts_1.OPTION_REST_API_REGION);
15
+ commandSandboxEndpointAdd.option('-w, --workspace <domain>', texts_1.OPTION_REST_API_WORKSPACE);
16
+ commandSandboxEndpointAdd.option('-p, --project <name>', texts_1.OPTION_REST_API_PROJECT);
17
+ commandSandboxEndpointAdd.argument('<identifier>', texts_1.OPTION_SANDBOX_IDENTIFIER);
18
+ commandSandboxEndpointAdd.requiredOption('-n, --name <name>', texts_1.OPTION_SANDBOX_ENDPOINT_NAME);
19
+ commandSandboxEndpointAdd.requiredOption('--port <port>', texts_1.OPTION_SANDBOX_ENDPOINT_PORT);
20
+ commandSandboxEndpointAdd.option('-t, --type <type>', texts_1.OPTION_SANDBOX_ENDPOINT_TYPE, 'HTTP');
21
+ commandSandboxEndpointAdd.option('--ep-region <region>', texts_1.OPTION_SANDBOX_ENDPOINT_REGION);
22
+ commandSandboxEndpointAdd.option('--whitelist <cidrs...>', texts_1.OPTION_SANDBOX_ENDPOINT_WHITELIST);
23
+ commandSandboxEndpointAdd.option('--auth <type>', texts_1.OPTION_SANDBOX_ENDPOINT_AUTH);
24
+ commandSandboxEndpointAdd.option('--username <username>', texts_1.OPTION_SANDBOX_ENDPOINT_USERNAME);
25
+ commandSandboxEndpointAdd.option('--password <password>', texts_1.OPTION_SANDBOX_ENDPOINT_PASSWORD);
26
+ commandSandboxEndpointAdd.action(async (identifier, options) => {
27
+ const token = input_1.default.restApiToken(options.token);
28
+ const baseUrl = input_1.default.restApiBaseUrl(options.api, options.region);
29
+ const workspace = input_1.default.restApiWorkspace(options.workspace);
30
+ const project = input_1.default.restApiProject(options.project);
31
+ const client = new client_1.default(baseUrl, token);
32
+ // Find sandbox by identifier
33
+ const result = await client.listSandboxes(workspace, project);
34
+ const sandboxes = result.sandboxes || [];
35
+ const found = sandboxes.find((s) => s.identifier === identifier);
36
+ if (!found) {
37
+ output_1.default.exitError(texts_1.ERR_SANDBOX_NOT_FOUND);
38
+ }
39
+ // Get current sandbox to get existing endpoints
40
+ const sandbox = await client.getSandbox(workspace, found.id);
41
+ const endpoints = sandbox.endpoints || [];
42
+ // Check if endpoint with this name already exists
43
+ const existing = endpoints.find((ep) => ep.name === options.name);
44
+ if (existing) {
45
+ output_1.default.exitError((0, texts_1.ERR_SANDBOX_ENDPOINT_EXISTS)(options.name));
46
+ }
47
+ // Create new endpoint
48
+ const newEndpoint = {
49
+ name: options.name,
50
+ endpoint: options.port,
51
+ type: options.type.toUpperCase(),
52
+ };
53
+ // Add optional fields only if provided
54
+ if (options.epRegion) {
55
+ newEndpoint.region = options.epRegion.toUpperCase();
56
+ }
57
+ if (options.whitelist) {
58
+ newEndpoint.whitelist = options.whitelist;
59
+ }
60
+ // Add HTTP-specific options (auth)
61
+ if (options.auth || options.username || options.password) {
62
+ newEndpoint.http = newEndpoint.http || {};
63
+ // Auto-set BASIC auth if username/password provided
64
+ if (options.username || options.password) {
65
+ newEndpoint.http.auth_type = 'BASIC';
66
+ if (options.username) {
67
+ newEndpoint.http.login = options.username;
68
+ }
69
+ if (options.password) {
70
+ newEndpoint.http.password = options.password;
71
+ }
72
+ }
73
+ else if (options.auth) {
74
+ newEndpoint.http.auth_type = options.auth.toUpperCase();
75
+ }
76
+ }
77
+ // Add the new endpoint to the list
78
+ const updatedEndpoints = [...endpoints, newEndpoint];
79
+ // Update sandbox with new endpoints list
80
+ const updatedSandbox = await client.updateSandbox(workspace, found.id, { endpoints: updatedEndpoints });
81
+ // Find the added endpoint to get its URL
82
+ const addedEndpoint = (updatedSandbox.endpoints || []).find((ep) => ep.name === options.name);
83
+ const url = addedEndpoint?.url;
84
+ if (url) {
85
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_ENDPOINT_ADDED)(options.name, url));
86
+ }
87
+ else {
88
+ output_1.default.exitSuccess((0, texts_1.TXT_SANDBOX_ENDPOINT_ADDED)(options.name));
89
+ }
90
+ });
91
+ exports.default = commandSandboxEndpointAdd;