anycloud 0.0.3 → 0.0.5

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 (68) hide show
  1. package/dist/cli/commands/config/edit.js +15 -0
  2. package/dist/cli/commands/config/edit.js.map +1 -1
  3. package/dist/cli/commands/config/list.js +53 -18
  4. package/dist/cli/commands/config/list.js.map +1 -1
  5. package/dist/cli/commands/config/new.js +21 -0
  6. package/dist/cli/commands/config/new.js.map +1 -1
  7. package/dist/cli/commands/config/remove.js +10 -0
  8. package/dist/cli/commands/config/remove.js.map +1 -1
  9. package/dist/cli/commands/credentials/delete.js +10 -0
  10. package/dist/cli/commands/credentials/delete.js.map +1 -1
  11. package/dist/cli/commands/credentials/edit.js +16 -0
  12. package/dist/cli/commands/credentials/edit.js.map +1 -1
  13. package/dist/cli/commands/credentials/list.js +35 -13
  14. package/dist/cli/commands/credentials/list.js.map +1 -1
  15. package/dist/cli/commands/credentials/new.js +25 -0
  16. package/dist/cli/commands/credentials/new.js.map +1 -1
  17. package/dist/cli/commands/daemon/index.js +8 -6
  18. package/dist/cli/commands/daemon/index.js.map +1 -1
  19. package/dist/cli/commands/list.js +70 -19
  20. package/dist/cli/commands/list.js.map +1 -1
  21. package/dist/cli/commands/login.js +10 -0
  22. package/dist/cli/commands/login.js.map +1 -1
  23. package/dist/cli/commands/logs.js +95 -10
  24. package/dist/cli/commands/logs.js.map +1 -1
  25. package/dist/cli/commands/run.js +110 -0
  26. package/dist/cli/commands/run.js.map +1 -0
  27. package/dist/cli/commands/serve.js +15 -0
  28. package/dist/cli/commands/serve.js.map +1 -0
  29. package/dist/cli/commands/status.js +113 -0
  30. package/dist/cli/commands/status.js.map +1 -0
  31. package/dist/cli/commands/terminate.js +122 -8
  32. package/dist/cli/commands/terminate.js.map +1 -1
  33. package/dist/cli/commands/upgrade.js +66 -8
  34. package/dist/cli/commands/upgrade.js.map +1 -1
  35. package/dist/cli/index.js +6 -4
  36. package/dist/cli/index.js.map +1 -1
  37. package/dist/cli/services/api-client.js +51 -49
  38. package/dist/cli/services/api-client.js.map +1 -1
  39. package/dist/cli/services/config.js +2 -0
  40. package/dist/cli/services/config.js.map +1 -1
  41. package/dist/cli/services/non-interactive.js +3 -3
  42. package/dist/cli/services/non-interactive.js.map +1 -1
  43. package/dist/cli/services/oauth.js +4 -5
  44. package/dist/cli/services/oauth.js.map +1 -1
  45. package/dist/cli/utils/env-parser.js +27 -0
  46. package/dist/cli/utils/env-parser.js.map +1 -0
  47. package/dist/cli/utils/output.js +42 -0
  48. package/dist/cli/utils/output.js.map +1 -1
  49. package/dist/daemon/cluster.js +122 -17
  50. package/dist/daemon/cluster.js.map +1 -1
  51. package/dist/daemon/docker.js +62 -21
  52. package/dist/daemon/docker.js.map +1 -1
  53. package/dist/daemon/preemption.js +127 -0
  54. package/dist/daemon/preemption.js.map +1 -0
  55. package/dist/daemon/server.js +128 -16
  56. package/dist/daemon/server.js.map +1 -1
  57. package/dist/shared/assets/clouds/azure/regions-per-type.json +21584 -1117
  58. package/dist/shared/id-generator.js +20 -0
  59. package/dist/shared/id-generator.js.map +1 -0
  60. package/dist/shared/types.js +5 -1
  61. package/dist/shared/types.js.map +1 -1
  62. package/package.json +16 -8
  63. package/dist/cli/commands/daemon/start.js +0 -32
  64. package/dist/cli/commands/daemon/start.js.map +0 -1
  65. package/dist/cli/commands/job.js +0 -71
  66. package/dist/cli/commands/job.js.map +0 -1
  67. package/dist/cli/commands/new.js +0 -15
  68. package/dist/cli/commands/new.js.map +0 -1
@@ -1,42 +1,93 @@
1
1
  import { Command } from 'commander';
2
+ import Table from 'cli-table3';
3
+ import chalk from 'chalk';
2
4
  import { getGitHubToken } from '../services/auth.js';
3
- import { getDeploymentInfo } from '../services/api-client.js';
5
+ import { listDeployments } from '../services/api-client.js';
4
6
  import { resolveAllDeploymentProfiles } from '../services/config.js';
5
- import { printSuccess, printInfo, printError } from '../utils/output.js';
7
+ import { printInfo, printError, printCloudConfigsTable, createSpinner, } from '../utils/output.js';
8
+ import packageJson from '../../../package.json' with { type: 'json' };
6
9
  export function createListCommand() {
7
10
  return new Command('list')
8
11
  .description('List all deployments across all profiles')
12
+ .addHelpText('after', `
13
+ Examples:
14
+ $ anycloud list
15
+
16
+ Output format:
17
+ ✓ Found 3 deployment(s) | 4 total VMs | 1 spot instance
18
+
19
+ ┌─────────────────────┬──────────────┬─────────┬──────┬──────┐
20
+ │ ID │ Config │ Status │ VMs │ Spot │
21
+ ├─────────────────────┼──────────────┼─────────┼──────┼──────┤
22
+ │ abc123-def456-ghi7… │ my-app │ active │ 3 │ Yes │
23
+ │ xyz789-abc123-def4… │ api-service │ stopped │ 1 │ No │
24
+ └─────────────────────┴──────────────┴─────────┴──────┴──────┘
25
+
26
+ Cloud Configurations:
27
+
28
+ ┌──────────────┬──────────┬──────────────┬────────────────┐
29
+ │ Config │ Provider │ Region │ VM Type │
30
+ ├──────────────┼──────────┼──────────────┼────────────────┤
31
+ │ my-app │ aws │ us-east-1 │ t3.medium │
32
+ │ my-app │ gcp │ us-central1 │ e2-medium │
33
+ │ api-service │ azure │ eastus │ Standard_B2s │
34
+ └──────────────┴──────────┴──────────────┴────────────────┘
35
+ `)
9
36
  .action(async () => {
10
37
  try {
11
38
  // Get GitHub token
12
39
  const accessToken = await getGitHubToken();
13
40
  // Get all deployment configs with resolved credentials
14
- const deployConfigs = await resolveAllDeploymentProfiles();
15
- if (Object.keys(deployConfigs).length === 0) {
41
+ const anycloudConfigs = await resolveAllDeploymentProfiles();
42
+ if (Object.keys(anycloudConfigs).length === 0) {
16
43
  printInfo('No deployment profiles found in anycloud.json');
17
44
  return;
18
45
  }
19
- // Get deployment info for all profiles
20
- const deployments = await getDeploymentInfo(deployConfigs, accessToken);
46
+ // List all deployments
47
+ const spinner = createSpinner('Fetching deployments...').start();
48
+ const deployments = await listDeployments(anycloudConfigs, accessToken, packageJson.version);
21
49
  if (deployments.length === 0) {
50
+ spinner.stop();
22
51
  printInfo('No deployments found.');
23
52
  return;
24
53
  }
25
- printSuccess(`Found ${deployments.length} deployment(s):`);
54
+ // Calculate summary statistics
55
+ const totalVMs = deployments.reduce((sum, deployment) => sum + deployment.size, 0);
56
+ const spotCount = deployments.filter((deployment) => deployment.cloudConfigs.some((config) => config.spot === true)).length;
57
+ // Display summary
58
+ spinner.succeed(`Found ${deployments.length} deployment(s) | ${totalVMs} total VMs | ${spotCount} spot instance${spotCount !== 1 ? 's' : ''}`);
26
59
  console.log('');
27
- // Display deployments in a simple table format
28
- deployments.forEach((deployment, index) => {
29
- console.log(`${index + 1}. Cluster ID: ${deployment.id}`);
30
- printInfo(` URL: ${deployment.url}`);
31
- printInfo(` Deploy Name: ${deployment.deployName}`);
32
- printInfo(` Status: ${deployment.status}`);
33
- printInfo(` Size: ${deployment.size} VM(s)`);
34
- printInfo(` Cloud Configs: ${deployment.cloudConfigs.length} config(s)`);
35
- deployment.cloudConfigs.forEach((config, i) => {
36
- printInfo(` ${i + 1}. ${config.cloudProvider} - ${config.region || 'default region'} (${config.vmType || 'default VM'})`);
37
- });
38
- console.log('');
60
+ // Create deployments table
61
+ const deploymentsTable = new Table({
62
+ head: ['ID', 'Config', 'VMs'].map((h) => chalk.cyan(h)),
63
+ colWidths: [30, 25, 10],
64
+ style: {
65
+ head: [],
66
+ border: ['dim'],
67
+ },
39
68
  });
69
+ deployments.forEach((deployment) => {
70
+ const truncatedId = deployment.id.length > 28
71
+ ? deployment.id.substring(0, 27) + '…'
72
+ : deployment.id;
73
+ deploymentsTable.push([
74
+ truncatedId,
75
+ deployment.configName,
76
+ deployment.size.toString(),
77
+ ]);
78
+ });
79
+ console.log(deploymentsTable.toString());
80
+ console.log('');
81
+ // Create cloud configurations table using shared utility
82
+ const cloudConfigEntries = deployments.flatMap((deployment) => deployment.cloudConfigs.map((config) => ({
83
+ configName: deployment.configName,
84
+ credentialsName: '', // Not used in deployment list
85
+ provider: config.cloudProvider,
86
+ region: config.region,
87
+ vmType: config.vmType,
88
+ spot: config.spot ?? false,
89
+ })));
90
+ printCloudConfigsTable(cloudConfigEntries);
40
91
  }
41
92
  catch (error) {
42
93
  printError(`Failed to list deployments: ${error.message}`);
@@ -1 +1 @@
1
- {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,mBAAmB;YACnB,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;YAE3C,uDAAuD;YACvD,MAAM,aAAa,GAAG,MAAM,4BAA4B,EAAE,CAAC;YAE3D,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5C,SAAS,CAAC,+CAA+C,CAAC,CAAC;gBAC3D,OAAO;YACT,CAAC;YAED,uCAAuC;YACvC,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;YAExE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC7B,SAAS,CAAC,uBAAuB,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;YAED,YAAY,CAAC,SAAS,WAAW,CAAC,MAAM,iBAAiB,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAEhB,+CAA+C;YAC/C,WAAW,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,EAAE;gBACxC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,iBAAiB,UAAU,CAAC,EAAE,EAAE,CAAC,CAAC;gBAC1D,SAAS,CAAC,qBAAqB,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC;gBACjD,SAAS,CAAC,qBAAqB,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC;gBACxD,SAAS,CAAC,qBAAqB,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;gBACpD,SAAS,CAAC,qBAAqB,UAAU,CAAC,IAAI,QAAQ,CAAC,CAAC;gBACxD,SAAS,CACP,qBAAqB,UAAU,CAAC,YAAY,CAAC,MAAM,YAAY,CAChE,CAAC;gBACF,UAAU,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;oBAC5C,SAAS,CACP,SAAS,CAAC,GAAG,CAAC,KAAK,MAAM,CAAC,aAAa,MAAM,MAAM,CAAC,MAAM,IAAI,gBAAgB,KAAK,MAAM,CAAC,MAAM,IAAI,YAAY,GAAG,CACpH,CAAC;gBACJ,CAAC,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,+BAAgC,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"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"}
@@ -4,6 +4,16 @@ import { printError } from '../utils/output.js';
4
4
  export function createLoginCommand() {
5
5
  return new Command('login')
6
6
  .description('Authenticate with GitHub using OAuth Device Flow')
7
+ .addHelpText('after', `
8
+ Examples:
9
+ $ anycloud login
10
+
11
+ Output:
12
+ Enter this code: XXXX-YYYY on https://github.com/login/device
13
+ Or visit: https://github.com/login/device?user_code=XXXX-YYYY
14
+ Waiting for authorization...
15
+ ✓ Successfully authenticated with GitHub!
16
+ `)
7
17
  .action(async () => {
8
18
  try {
9
19
  await authenticateWithGitHub();
@@ -1 +1 @@
1
- {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;SACxB,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,sBAAsB,EAAE,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,iBAAkB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/cli/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;SACxB,WAAW,CAAC,kDAAkD,CAAC;SAC/D,WAAW,CACV,OAAO,EACP;;;;;;;;;CASL,CACI;SACA,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,IAAI,CAAC;YACH,MAAM,sBAAsB,EAAE,CAAC;QACjC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,iBAAkB,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1,20 +1,105 @@
1
1
  import { Command } from 'commander';
2
+ import prompts from 'prompts';
2
3
  import { getGitHubToken } from '../services/auth.js';
3
- import { getDeploymentLogs } from '../services/api-client.js';
4
- import { printInfo, printError } from '../utils/output.js';
4
+ import { getDockerLogs, listDeployments } from '../services/api-client.js';
5
+ import { resolveAllDeploymentProfiles } from '../services/config.js';
6
+ import { printInfo, printError, createSpinner } from '../utils/output.js';
7
+ import { isNonInteractive, getEnvOptional, } from '../services/non-interactive.js';
8
+ import packageJson from '../../../package.json' with { type: 'json' };
5
9
  export function createLogsCommand() {
6
10
  return new Command('logs')
7
- .description('Get deployment logs')
8
- .argument('<clusterId>', 'Cluster ID of the deployment')
9
- .action(async (clusterId) => {
11
+ .description('Get Docker container logs')
12
+ .argument('[id]', 'Deployment ID (optional - will prompt to select if not provided)')
13
+ .option('--tail <n>', 'Number of log lines to show (default: 100)', '100')
14
+ .addHelpText('after', `
15
+ Examples:
16
+ $ anycloud logs abc123-def456-ghi789
17
+ $ anycloud logs abc123-def456-ghi789 --tail 50
18
+ $ anycloud logs
19
+
20
+ Output:
21
+ Fetching logs for: abc123-def456-ghi789
22
+
23
+ Docker Logs:
24
+ ─────────────────────────────────────────────────────
25
+ === VM 1 (1.2.3.4) ===
26
+ [2024-01-15 10:30:00] Application started
27
+ [2024-01-15 10:30:01] Listening on port 8080
28
+ [2024-01-15 10:30:05] Request received: GET /
29
+
30
+ === VM 2 (5.6.7.8) ===
31
+ [2024-01-15 10:30:00] Application started
32
+ [2024-01-15 10:30:01] Listening on port 8080
33
+ ─────────────────────────────────────────────────────
34
+ `)
35
+ .action(async (id, options) => {
10
36
  try {
11
- printInfo(`Fetching logs for cluster: ${clusterId}`);
12
- // Get GitHub token
37
+ let deploymentId = id;
38
+ // If no ID provided, fetch and prompt for selection
39
+ if (!deploymentId) {
40
+ // Check for environment variable in non-interactive mode
41
+ if (isNonInteractive()) {
42
+ deploymentId = getEnvOptional('ANYCLOUD_DEPLOYMENT_ID');
43
+ if (!deploymentId) {
44
+ printError('Non-interactive mode: Deployment ID required.\n' +
45
+ ' Provide ID as argument or set ANYCLOUD_DEPLOYMENT_ID environment variable.');
46
+ process.exit(1);
47
+ }
48
+ }
49
+ else {
50
+ // Get GitHub token
51
+ const accessToken = await getGitHubToken();
52
+ // Get all deployment configs with resolved credentials
53
+ const anycloudConfigs = await resolveAllDeploymentProfiles();
54
+ if (Object.keys(anycloudConfigs).length === 0) {
55
+ printError('No deployment profiles found in anycloud.json');
56
+ printInfo('Please create anycloud.json with deployment profiles.');
57
+ process.exit(1);
58
+ }
59
+ // List all deployments
60
+ const loadingSpinner = createSpinner('Loading deployments...').start();
61
+ const deployments = await listDeployments(anycloudConfigs, accessToken, packageJson.version);
62
+ loadingSpinner.stop();
63
+ if (deployments.length === 0) {
64
+ printError('No deployments found.');
65
+ printInfo('Create a deployment first using: anycloud run --config <config-name>');
66
+ process.exit(1);
67
+ }
68
+ // Prompt for deployment selection
69
+ const selection = await prompts({
70
+ type: 'select',
71
+ name: 'deployment',
72
+ message: 'Select deployment:',
73
+ choices: deployments.map((deployment) => {
74
+ const hasSpot = deployment.cloudConfigs.some((config) => config.spot === true);
75
+ const spotText = hasSpot ? ' | Spot' : '';
76
+ return {
77
+ title: deployment.id,
78
+ value: deployment.id,
79
+ description: `${deployment.configName} | ${deployment.size} VMs${spotText}`,
80
+ };
81
+ }),
82
+ });
83
+ if (!selection.deployment) {
84
+ process.exit(0); // User cancelled
85
+ }
86
+ deploymentId = selection.deployment;
87
+ }
88
+ }
89
+ // Get GitHub token (if not already fetched)
13
90
  const accessToken = await getGitHubToken();
14
- // Get logs
15
- const response = await getDeploymentLogs(clusterId, accessToken);
91
+ // Parse tail option
92
+ const tail = parseInt(options?.tail || '100', 10);
93
+ if (isNaN(tail) || tail < 1) {
94
+ printError('Invalid --tail value. Must be a positive number.');
95
+ process.exit(1);
96
+ }
97
+ // Get Docker logs
98
+ const spinner = createSpinner(`Fetching Docker logs for: ${deploymentId}...`).start();
99
+ const response = await getDockerLogs(deploymentId, accessToken, packageJson.version, tail);
100
+ spinner.stop();
16
101
  console.log('');
17
- console.log('Logs:');
102
+ console.log('Docker Logs:');
18
103
  console.log('─────────────────────────────────────────────────────');
19
104
  console.log(response.logs);
20
105
  console.log('─────────────────────────────────────────────────────');
@@ -1 +1 @@
1
- {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,qBAAqB,CAAC;SAClC,QAAQ,CAAC,aAAa,EAAE,8BAA8B,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,SAAiB,EAAE,EAAE;QAClC,IAAI,CAAC;YACH,SAAS,CAAC,8BAA8B,SAAS,EAAE,CAAC,CAAC;YAErD,mBAAmB;YACnB,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;YAE3C,WAAW;YACX,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;YAEjE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,yBAA0B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,cAAc,GACf,MAAM,gCAAgC,CAAC;AACxC,OAAO,WAAW,MAAM,uBAAuB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtE,MAAM,UAAU,iBAAiB;IAC/B,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;SACvB,WAAW,CAAC,2BAA2B,CAAC;SACxC,QAAQ,CACP,MAAM,EACN,kEAAkE,CACnE;SACA,MAAM,CAAC,YAAY,EAAE,4CAA4C,EAAE,KAAK,CAAC;SACzE,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;CAoBL,CACI;SACA,MAAM,CAAC,KAAK,EAAE,EAAW,EAAE,OAA0B,EAAE,EAAE;QACxD,IAAI,CAAC;YACH,IAAI,YAAY,GAAG,EAAE,CAAC;YAEtB,oDAAoD;YACpD,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,yDAAyD;gBACzD,IAAI,gBAAgB,EAAE,EAAE,CAAC;oBACvB,YAAY,GAAG,cAAc,CAAC,wBAAwB,CAAC,CAAC;oBACxD,IAAI,CAAC,YAAY,EAAE,CAAC;wBAClB,UAAU,CACR,iDAAiD;4BAC/C,+EAA+E,CAClF,CAAC;wBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,mBAAmB;oBACnB,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;oBAE3C,uDAAuD;oBACvD,MAAM,eAAe,GAAG,MAAM,4BAA4B,EAAE,CAAC;oBAE7D,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC9C,UAAU,CAAC,+CAA+C,CAAC,CAAC;wBAC5D,SAAS,CACP,uDAAuD,CACxD,CAAC;wBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;oBAED,uBAAuB;oBACvB,MAAM,cAAc,GAAG,aAAa,CAClC,wBAAwB,CACzB,CAAC,KAAK,EAAE,CAAC;oBACV,MAAM,WAAW,GAAG,MAAM,eAAe,CACvC,eAAe,EACf,WAAW,EACX,WAAW,CAAC,OAAO,CACpB,CAAC;oBACF,cAAc,CAAC,IAAI,EAAE,CAAC;oBAEtB,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC7B,UAAU,CAAC,uBAAuB,CAAC,CAAC;wBACpC,SAAS,CACP,sEAAsE,CACvE,CAAC;wBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAClB,CAAC;oBAED,kCAAkC;oBAClC,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC;wBAC9B,IAAI,EAAE,QAAQ;wBACd,IAAI,EAAE,YAAY;wBAClB,OAAO,EAAE,oBAAoB;wBAC7B,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;4BACtC,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,IAAI,CAC1C,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,IAAI,CACjC,CAAC;4BACF,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC1C,OAAO;gCACL,KAAK,EAAE,UAAU,CAAC,EAAE;gCACpB,KAAK,EAAE,UAAU,CAAC,EAAE;gCACpB,WAAW,EAAE,GAAG,UAAU,CAAC,UAAU,MAAM,UAAU,CAAC,IAAI,OAAO,QAAQ,EAAE;6BAC5E,CAAC;wBACJ,CAAC,CAAC;qBACH,CAAC,CAAC;oBAEH,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;wBAC1B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;oBACpC,CAAC;oBAED,YAAY,GAAG,SAAS,CAAC,UAAU,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,4CAA4C;YAC5C,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;YAE3C,oBAAoB;YACpB,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC,CAAC;YAClD,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC5B,UAAU,CAAC,kDAAkD,CAAC,CAAC;gBAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,kBAAkB;YAClB,MAAM,OAAO,GAAG,aAAa,CAC3B,6BAA6B,YAAY,KAAK,CAC/C,CAAC,KAAK,EAAE,CAAC;YACV,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,YAAY,EACZ,WAAW,EACX,WAAW,CAAC,OAAO,EACnB,IAAI,CACL,CAAC;YACF,OAAO,CAAC,IAAI,EAAE,CAAC;YAEf,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CAAC,yBAA0B,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,110 @@
1
+ import { Command } from 'commander';
2
+ import prompts from 'prompts';
3
+ import { getGitHubToken } from '../services/auth.js';
4
+ import { resolveDeploymentProfile, loadDeploymentProfiles, } from '../services/config.js';
5
+ import { createDeployment } from '../services/api-client.js';
6
+ import { printInfo, printError, createSpinner } from '../utils/output.js';
7
+ import { isNonInteractive, getConfigFromEnv, } from '../services/non-interactive.js';
8
+ import { DeploymentType } from '../../shared/types.js';
9
+ import { generateJobId } from '../../shared/id-generator.js';
10
+ import { parseEnvFile } from '../utils/env-parser.js';
11
+ import packageJson from '../../../package.json' with { type: 'json' };
12
+ export function createRunCommand() {
13
+ return new Command('run')
14
+ .description('Create a new job deployment')
15
+ .argument('<image>', 'Container image (e.g., alpine:latest, ghcr.io/user/job:latest)')
16
+ .option('-c, --config <name>', 'Config name from anycloud.json')
17
+ .option('-i, --id <id>', 'Job identifier')
18
+ .option('-e, --env <file>', 'Environment file (.env format)')
19
+ .addHelpText('after', `
20
+ Examples:
21
+ $ anycloud run alpine:latest
22
+ $ anycloud run alpine:latest --config my-app
23
+ $ anycloud run ghcr.io/myuser/job:v1.0 --config prod --id my-job-123
24
+ $ anycloud run alpine:latest --env prod.env
25
+
26
+ Output:
27
+ Creating job deployment for image: alpine:latest
28
+ Using config: my-app
29
+ ✓ Job deployment created!
30
+
31
+ ID: job-abc123-def456-ghi789
32
+ `)
33
+ .action(async (image, options) => {
34
+ try {
35
+ printInfo(`Creating job deployment for image: ${image}`);
36
+ // Determine config name
37
+ let configName = options.config;
38
+ // Check for environment variable in non-interactive mode
39
+ if (!configName && isNonInteractive()) {
40
+ configName = getConfigFromEnv();
41
+ if (!configName) {
42
+ printError('Non-interactive mode: Config name required.\n' +
43
+ ' Provide --config flag or set ANYCLOUD_CONFIG environment variable.');
44
+ process.exit(1);
45
+ }
46
+ }
47
+ // If --config not provided and not in non-interactive mode, prompt for config selection
48
+ if (!configName) {
49
+ const profiles = await loadDeploymentProfiles();
50
+ const profileNames = Object.keys(profiles);
51
+ if (profileNames.length === 0) {
52
+ printError('No deployment profiles found in anycloud.json');
53
+ printInfo('Please create anycloud.json with deployment profiles.');
54
+ process.exit(1);
55
+ }
56
+ const selection = await prompts({
57
+ type: 'select',
58
+ name: 'profile',
59
+ message: 'Select config:',
60
+ choices: profileNames.map((name) => ({
61
+ title: name,
62
+ value: name,
63
+ description: `${profiles[name].length} config(s)`,
64
+ })),
65
+ });
66
+ if (!selection.profile) {
67
+ process.exit(0); // User cancelled
68
+ }
69
+ configName = selection.profile;
70
+ }
71
+ printInfo(`Using config: ${configName}`);
72
+ // Parse environment variables from file if provided
73
+ let envVars;
74
+ if (options.env) {
75
+ try {
76
+ envVars = parseEnvFile(options.env);
77
+ const count = Object.keys(envVars).length;
78
+ if (count > 0) {
79
+ printInfo(`Loaded ${count} environment variable(s) from ${options.env}`);
80
+ }
81
+ else {
82
+ printInfo(`No environment variables found in ${options.env}`);
83
+ }
84
+ }
85
+ catch (error) {
86
+ printError(error.message);
87
+ process.exit(1);
88
+ }
89
+ }
90
+ // Get GitHub token
91
+ const accessToken = await getGitHubToken();
92
+ // Resolve deployment profile and credentials
93
+ const cloudConfigs = await resolveDeploymentProfile(configName);
94
+ // Generate job ID if not provided
95
+ const jobId = options.name || generateJobId();
96
+ // Create deployment with hardcoded 'job' type
97
+ const spinner = createSpinner('Creating job deployment...').start();
98
+ const response = await createDeployment(image, cloudConfigs, accessToken, configName, DeploymentType.Job, packageJson.version, jobId, envVars);
99
+ spinner.succeed('Job deployment created!');
100
+ console.log('');
101
+ printInfo(`ID: ${response.id}`);
102
+ console.log('');
103
+ }
104
+ catch (error) {
105
+ printError(`Failed to create job deployment: ${error.message}`);
106
+ process.exit(1);
107
+ }
108
+ });
109
+ }
110
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EACL,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,WAAW,MAAM,uBAAuB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEtE,MAAM,UAAU,gBAAgB;IAC9B,OAAO,IAAI,OAAO,CAAC,KAAK,CAAC;SACtB,WAAW,CAAC,6BAA6B,CAAC;SAC1C,QAAQ,CACP,SAAS,EACT,gEAAgE,CACjE;SACA,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,CAAC;SAC/D,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;SACzC,MAAM,CAAC,kBAAkB,EAAE,gCAAgC,CAAC;SAC5D,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;CAaL,CACI;SACA,MAAM,CACL,KAAK,EACH,KAAa,EACb,OAAyD,EACzD,EAAE;QACF,IAAI,CAAC;YACH,SAAS,CAAC,sCAAsC,KAAK,EAAE,CAAC,CAAC;YAEzD,wBAAwB;YACxB,IAAI,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;YAEhC,yDAAyD;YACzD,IAAI,CAAC,UAAU,IAAI,gBAAgB,EAAE,EAAE,CAAC;gBACtC,UAAU,GAAG,gBAAgB,EAAE,CAAC;gBAChC,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,UAAU,CACR,+CAA+C;wBAC7C,uEAAuE,CAC1E,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,wFAAwF;YACxF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,QAAQ,GAAG,MAAM,sBAAsB,EAAE,CAAC;gBAChD,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAE3C,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC9B,UAAU,CAAC,+CAA+C,CAAC,CAAC;oBAC5D,SAAS,CACP,uDAAuD,CACxD,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;gBAED,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC;oBAC9B,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,gBAAgB;oBACzB,OAAO,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;wBACnC,KAAK,EAAE,IAAI;wBACX,KAAK,EAAE,IAAI;wBACX,WAAW,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,YAAY;qBAClD,CAAC,CAAC;iBACJ,CAAC,CAAC;gBAEH,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;oBACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;gBACpC,CAAC;gBAED,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC;YACjC,CAAC;YAED,SAAS,CAAC,iBAAiB,UAAU,EAAE,CAAC,CAAC;YAEzC,oDAAoD;YACpD,IAAI,OAA2C,CAAC;YAChD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBAChB,IAAI,CAAC;oBACH,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;oBACpC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;oBAC1C,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;wBACd,SAAS,CACP,UAAU,KAAK,iCAAiC,OAAO,CAAC,GAAG,EAAE,CAC9D,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,SAAS,CAAC,qCAAqC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;oBAChE,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,UAAU,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC;oBACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBAClB,CAAC;YACH,CAAC;YAED,mBAAmB;YACnB,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC;YAE3C,6CAA6C;YAC7C,MAAM,YAAY,GAAG,MAAM,wBAAwB,CAAC,UAAU,CAAC,CAAC;YAEhE,kCAAkC;YAClC,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,IAAI,aAAa,EAAE,CAAC;YAE9C,8CAA8C;YAC9C,MAAM,OAAO,GAAG,aAAa,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;YACpE,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CACrC,KAAK,EACL,YAAY,EACZ,WAAW,EACX,UAAU,EACV,cAAc,CAAC,GAAG,EAClB,WAAW,CAAC,OAAO,EACnB,KAAK,EACL,OAAO,CACR,CAAC;YAEF,OAAO,CAAC,OAAO,CAAC,yBAAyB,CAAC,CAAC;YAC3C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,SAAS,CAAC,OAAO,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,UAAU,CACR,oCAAqC,KAAe,CAAC,OAAO,EAAE,CAC/D,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CACF,CAAC;AACN,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Command } from 'commander';
2
+ import { printError, printInfo } from '../utils/output.js';
3
+ export function createServeCommand() {
4
+ return new Command('serve')
5
+ .description('Create a new server deployment')
6
+ .argument('<image>', 'Container image (e.g., nginx:latest, ghcr.io/user/app:latest)')
7
+ .option('--config <name>', 'Config name from anycloud.json')
8
+ .option('--name <name>', 'Server name')
9
+ .action(async () => {
10
+ printError('Server deployments are not yet supported.');
11
+ printInfo('Use "anycloud run" for job deployments.');
12
+ process.exit(1);
13
+ });
14
+ }
15
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;SACxB,WAAW,CAAC,gCAAgC,CAAC;SAC7C,QAAQ,CACP,SAAS,EACT,+DAA+D,CAChE;SACA,MAAM,CAAC,iBAAiB,EAAE,gCAAgC,CAAC;SAC3D,MAAM,CAAC,eAAe,EAAE,aAAa,CAAC;SACtC,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,UAAU,CAAC,2CAA2C,CAAC,CAAC;QACxD,SAAS,CAAC,yCAAyC,CAAC,CAAC;QACrD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,113 @@
1
+ import { Command } from 'commander';
2
+ import prompts from 'prompts';
3
+ import { getGitHubToken } from '../services/auth.js';
4
+ import { getDeploymentStatus, listDeployments, } from '../services/api-client.js';
5
+ import { resolveAllDeploymentProfiles } from '../services/config.js';
6
+ import { printInfo, printError, createSpinner } from '../utils/output.js';
7
+ import { isNonInteractive, getEnvOptional, } from '../services/non-interactive.js';
8
+ import packageJson from '../../../package.json' with { type: 'json' };
9
+ export function createStatusCommand() {
10
+ return new Command('status')
11
+ .description('Get deployment status logs')
12
+ .argument('[id]', 'Deployment ID (optional - will prompt to select if not provided)')
13
+ .addHelpText('after', `
14
+ Examples:
15
+ $ anycloud status abc123-def456-ghi789
16
+ $ anycloud status
17
+
18
+ Output:
19
+ Fetching status for: abc123-def456-ghi789
20
+
21
+ Status:
22
+ ─────────────────────────────────────────────────────
23
+ Deploying your service...
24
+ Pulling container image...
25
+ Deployment complete!
26
+ ─────────────────────────────────────────────────────
27
+ `)
28
+ .action(async (id) => {
29
+ try {
30
+ let deploymentId = id;
31
+ // If no ID provided, fetch and prompt for selection
32
+ if (!deploymentId) {
33
+ // Check for environment variable in non-interactive mode
34
+ if (isNonInteractive()) {
35
+ deploymentId = getEnvOptional('ANYCLOUD_DEPLOYMENT_ID');
36
+ if (!deploymentId) {
37
+ printError('Non-interactive mode: Deployment ID required.\n' +
38
+ ' Provide ID as argument or set ANYCLOUD_DEPLOYMENT_ID environment variable.');
39
+ process.exit(1);
40
+ }
41
+ }
42
+ else {
43
+ // Get GitHub token
44
+ const accessToken = await getGitHubToken();
45
+ // Get all deployment configs with resolved credentials
46
+ const anycloudConfigs = await resolveAllDeploymentProfiles();
47
+ if (Object.keys(anycloudConfigs).length === 0) {
48
+ printError('No deployment profiles found in anycloud.json');
49
+ printInfo('Please create anycloud.json with deployment profiles.');
50
+ process.exit(1);
51
+ }
52
+ // List all deployments
53
+ const loadingSpinner = createSpinner('Loading deployments...').start();
54
+ const deployments = await listDeployments(anycloudConfigs, accessToken, packageJson.version);
55
+ loadingSpinner.stop();
56
+ if (deployments.length === 0) {
57
+ printError('No deployments found.');
58
+ printInfo('Create a deployment first using: anycloud run --config <config-name>');
59
+ process.exit(1);
60
+ }
61
+ // Prompt for deployment selection
62
+ const selection = await prompts({
63
+ type: 'select',
64
+ name: 'deployment',
65
+ message: 'Select deployment:',
66
+ choices: deployments.map((deployment) => {
67
+ const hasSpot = deployment.cloudConfigs.some((config) => config.spot === true);
68
+ const spotText = hasSpot ? ' | Spot' : '';
69
+ return {
70
+ title: deployment.id,
71
+ value: deployment.id,
72
+ description: `${deployment.configName} | ${deployment.size} VMs${spotText}`,
73
+ };
74
+ }),
75
+ });
76
+ if (!selection.deployment) {
77
+ process.exit(0); // User cancelled
78
+ }
79
+ deploymentId = selection.deployment;
80
+ }
81
+ }
82
+ // Get GitHub token (if not already fetched)
83
+ const accessToken = await getGitHubToken();
84
+ // Get status
85
+ const spinner = createSpinner(`Fetching status for: ${deploymentId}...`).start();
86
+ const response = await getDeploymentStatus(deploymentId, accessToken, packageJson.version);
87
+ spinner.stop();
88
+ console.log('');
89
+ console.log(`Deployment Health: ${response.status.toUpperCase()}`);
90
+ console.log('');
91
+ // Show per-VM status if available
92
+ if (response.vmStatuses && response.vmStatuses.length > 0) {
93
+ console.log('VM Health:');
94
+ response.vmStatuses.forEach((vm, index) => {
95
+ const healthIcon = vm.healthy ? '✓' : '✗';
96
+ const healthText = vm.healthy ? 'healthy' : 'unhealthy';
97
+ console.log(` ${healthIcon} VM ${index + 1} (${vm.ip}): ${healthText}`);
98
+ });
99
+ console.log('');
100
+ }
101
+ console.log('Deployment Logs:');
102
+ console.log('─────────────────────────────────────────────────────');
103
+ console.log(response.message);
104
+ console.log('─────────────────────────────────────────────────────');
105
+ console.log('');
106
+ }
107
+ catch (error) {
108
+ printError(`Failed to fetch status: ${error.message}`);
109
+ process.exit(1);
110
+ }
111
+ });
112
+ }
113
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}