@edgible-team/cli 1.2.15 → 1.2.19

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 (212) hide show
  1. package/README.md +5 -3
  2. package/dist/client/api-client.d.ts +26 -1
  3. package/dist/client/api-client.d.ts.map +1 -1
  4. package/dist/client/api-client.js +31 -0
  5. package/dist/commands/agent/install.d.ts +2 -1
  6. package/dist/commands/agent/install.d.ts.map +1 -1
  7. package/dist/commands/agent/install.js +24 -7
  8. package/dist/commands/agent/start.d.ts +5 -1
  9. package/dist/commands/agent/start.d.ts.map +1 -1
  10. package/dist/commands/agent/start.js +19 -280
  11. package/dist/commands/agent/uninstall.d.ts.map +1 -1
  12. package/dist/commands/agent/uninstall.js +14 -7
  13. package/dist/commands/agent.d.ts.map +1 -1
  14. package/dist/commands/agent.js +3 -2
  15. package/dist/commands/ai/setup.d.ts +1 -1
  16. package/dist/commands/ai/setup.d.ts.map +1 -1
  17. package/dist/commands/ai.js +1 -1
  18. package/dist/commands/application/create-docker-compose.d.ts +3 -1
  19. package/dist/commands/application/create-docker-compose.d.ts.map +1 -1
  20. package/dist/commands/application/create-docker-compose.js +25 -69
  21. package/dist/commands/application/create-existing.d.ts +2 -2
  22. package/dist/commands/application/create-existing.d.ts.map +1 -1
  23. package/dist/commands/application/create-existing.js +27 -132
  24. package/dist/commands/application/create-managed-process.d.ts +3 -1
  25. package/dist/commands/application/create-managed-process.d.ts.map +1 -1
  26. package/dist/commands/application/create-managed-process.js +31 -75
  27. package/dist/commands/application/create-stubs.d.ts +0 -1
  28. package/dist/commands/application/create-stubs.d.ts.map +1 -1
  29. package/dist/commands/application/create-stubs.js +0 -4
  30. package/dist/commands/application/create-vm.d.ts +19 -0
  31. package/dist/commands/application/create-vm.d.ts.map +1 -0
  32. package/dist/commands/application/create-vm.js +390 -0
  33. package/dist/commands/application/delete.d.ts +2 -1
  34. package/dist/commands/application/delete.d.ts.map +1 -1
  35. package/dist/commands/application/delete.js +19 -5
  36. package/dist/commands/application/get.d.ts.map +1 -1
  37. package/dist/commands/application/get.js +29 -1
  38. package/dist/commands/application/ssh.d.ts +7 -0
  39. package/dist/commands/application/ssh.d.ts.map +1 -0
  40. package/dist/commands/application/ssh.js +146 -0
  41. package/dist/commands/application/update.d.ts +3 -0
  42. package/dist/commands/application/update.d.ts.map +1 -1
  43. package/dist/commands/application/update.js +45 -1
  44. package/dist/commands/application.d.ts.map +1 -1
  45. package/dist/commands/application.js +81 -26
  46. package/dist/commands/auth.d.ts.map +1 -1
  47. package/dist/commands/auth.js +44 -0
  48. package/dist/commands/debug.js +1 -1
  49. package/dist/commands/device/application-health.d.ts +7 -0
  50. package/dist/commands/device/application-health.d.ts.map +1 -0
  51. package/dist/commands/device/application-health.js +103 -0
  52. package/dist/commands/device/delete.d.ts +7 -0
  53. package/dist/commands/device/delete.d.ts.map +1 -0
  54. package/dist/commands/device/delete.js +69 -0
  55. package/dist/commands/device/health.d.ts +7 -0
  56. package/dist/commands/device/health.d.ts.map +1 -0
  57. package/dist/commands/device/health.js +78 -0
  58. package/dist/commands/device/list.d.ts +5 -0
  59. package/dist/commands/device/list.d.ts.map +1 -0
  60. package/dist/commands/device/list.js +46 -0
  61. package/dist/commands/device/telemetry.d.ts +8 -0
  62. package/dist/commands/device/telemetry.d.ts.map +1 -0
  63. package/dist/commands/device/telemetry.js +59 -0
  64. package/dist/commands/device.d.ts +6 -0
  65. package/dist/commands/device.d.ts.map +1 -0
  66. package/dist/commands/device.js +86 -0
  67. package/dist/commands/stack/deploy.d.ts +3 -1
  68. package/dist/commands/stack/deploy.d.ts.map +1 -1
  69. package/dist/commands/stack/deploy.js +5 -2
  70. package/dist/commands/stack/diff.d.ts +1 -1
  71. package/dist/commands/stack/diff.d.ts.map +1 -1
  72. package/dist/commands/stack/diff.js +4 -2
  73. package/dist/commands/stack/status.d.ts +1 -1
  74. package/dist/commands/stack/status.d.ts.map +1 -1
  75. package/dist/commands/stack/status.js +4 -2
  76. package/dist/commands/stack/teardown.d.ts +3 -1
  77. package/dist/commands/stack/teardown.d.ts.map +1 -1
  78. package/dist/commands/stack/teardown.js +5 -2
  79. package/dist/commands/stack/validate.d.ts +1 -1
  80. package/dist/commands/stack/validate.d.ts.map +1 -1
  81. package/dist/commands/stack/validate.js +4 -2
  82. package/dist/commands/stack.d.ts.map +1 -1
  83. package/dist/commands/stack.js +10 -5
  84. package/dist/commands/utils/auth-prompt.d.ts +25 -0
  85. package/dist/commands/utils/auth-prompt.d.ts.map +1 -0
  86. package/dist/commands/utils/auth-prompt.js +115 -0
  87. package/dist/commands/utils/device-prompt.d.ts +18 -0
  88. package/dist/commands/utils/device-prompt.d.ts.map +1 -0
  89. package/dist/commands/utils/device-prompt.js +58 -0
  90. package/dist/commands/utils/output-formatter.d.ts +13 -0
  91. package/dist/commands/utils/output-formatter.d.ts.map +1 -1
  92. package/dist/commands/utils/output-formatter.js +21 -0
  93. package/dist/index.js +2 -0
  94. package/dist/services/LocalAgentManager.d.ts +2 -1
  95. package/dist/services/LocalAgentManager.d.ts.map +1 -1
  96. package/dist/services/LocalAgentManager.js +6 -4
  97. package/dist/services/application/ApplicationService.d.ts +41 -2
  98. package/dist/services/application/ApplicationService.d.ts.map +1 -1
  99. package/dist/services/application/ApplicationService.js +49 -1
  100. package/dist/services/device/DeviceService.d.ts +62 -0
  101. package/dist/services/device/DeviceService.d.ts.map +1 -0
  102. package/dist/services/device/DeviceService.js +235 -0
  103. package/dist/services/edgible.d.ts +3 -1
  104. package/dist/services/edgible.d.ts.map +1 -1
  105. package/dist/services/edgible.js +5 -4
  106. package/dist/services/instances.d.ts +4 -1
  107. package/dist/services/instances.d.ts.map +1 -1
  108. package/dist/services/instances.js +8 -4
  109. package/dist/types/AgentConfig.d.ts +26 -0
  110. package/dist/types/AgentConfig.d.ts.map +1 -1
  111. package/dist/types/ApiRequests.d.ts +5 -1
  112. package/dist/types/ApiRequests.d.ts.map +1 -1
  113. package/dist/types/ApiResponses.d.ts +9 -0
  114. package/dist/types/ApiResponses.d.ts.map +1 -1
  115. package/dist/types/JobTypes.d.ts +103 -0
  116. package/dist/types/JobTypes.d.ts.map +1 -0
  117. package/dist/types/JobTypes.js +80 -0
  118. package/dist/types/WebSocketMessages.d.ts +89 -0
  119. package/dist/types/WebSocketMessages.d.ts.map +1 -0
  120. package/dist/types/WebSocketMessages.js +5 -0
  121. package/dist/types/Workload.d.ts +1 -1
  122. package/dist/types/Workload.d.ts.map +1 -1
  123. package/dist/types/backendJobs.d.ts +102 -0
  124. package/dist/types/backendJobs.d.ts.map +1 -0
  125. package/dist/types/backendJobs.js +5 -0
  126. package/dist/types/models/ApplicationData.d.ts +1 -1
  127. package/dist/types/models/ApplicationData.d.ts.map +1 -1
  128. package/dist/types/models/DeviceData.d.ts +4 -0
  129. package/dist/types/models/DeviceData.d.ts.map +1 -1
  130. package/dist/types/stack.d.ts +9 -1
  131. package/dist/types/stack.d.ts.map +1 -1
  132. package/dist/types/validation/schemas.d.ts +5 -5
  133. package/dist/types/validation/schemas.js +1 -1
  134. package/dist/utils/stack-file.d.ts +11 -0
  135. package/dist/utils/stack-file.d.ts.map +1 -0
  136. package/dist/utils/stack-file.js +66 -0
  137. package/dist/validation/stack-schemas.d.ts +319 -27
  138. package/dist/validation/stack-schemas.d.ts.map +1 -1
  139. package/dist/validation/stack-schemas.js +20 -5
  140. package/package.json +1 -1
  141. package/dist/commands/agent/agent-handlers.d.ts +0 -45
  142. package/dist/commands/agent/agent-handlers.d.ts.map +0 -1
  143. package/dist/commands/agent/agent-handlers.js +0 -1159
  144. package/dist/commands/application/api-keys.d.ts +0 -3
  145. package/dist/commands/application/api-keys.d.ts.map +0 -1
  146. package/dist/commands/application/api-keys.js +0 -227
  147. package/dist/commands/application/create-compose.d.ts +0 -3
  148. package/dist/commands/application/create-compose.d.ts.map +0 -1
  149. package/dist/commands/application/create-compose.js +0 -381
  150. package/dist/commands/application/create-interactive.d.ts +0 -3
  151. package/dist/commands/application/create-interactive.d.ts.map +0 -1
  152. package/dist/commands/application/create-interactive.js +0 -326
  153. package/dist/commands/application/create-workload.d.ts +0 -5
  154. package/dist/commands/application/create-workload.d.ts.map +0 -1
  155. package/dist/commands/application/create-workload.js +0 -48
  156. package/dist/commands/application/short-codes.d.ts +0 -3
  157. package/dist/commands/application/short-codes.d.ts.map +0 -1
  158. package/dist/commands/application/short-codes.js +0 -226
  159. package/dist/commands/application/toggle.d.ts +0 -2
  160. package/dist/commands/application/toggle.d.ts.map +0 -1
  161. package/dist/commands/application/toggle.js +0 -78
  162. package/dist/commands/examples/migrated-command-example.d.ts +0 -31
  163. package/dist/commands/examples/migrated-command-example.d.ts.map +0 -1
  164. package/dist/commands/examples/migrated-command-example.js +0 -180
  165. package/dist/commands/managedGateway/create.d.ts +0 -6
  166. package/dist/commands/managedGateway/create.d.ts.map +0 -1
  167. package/dist/commands/managedGateway/create.js +0 -50
  168. package/dist/commands/managedGateway/delete.d.ts +0 -5
  169. package/dist/commands/managedGateway/delete.d.ts.map +0 -1
  170. package/dist/commands/managedGateway/delete.js +0 -57
  171. package/dist/commands/managedGateway/get.d.ts +0 -4
  172. package/dist/commands/managedGateway/get.d.ts.map +0 -1
  173. package/dist/commands/managedGateway/get.js +0 -71
  174. package/dist/commands/managedGateway/haproxy-stats.d.ts +0 -6
  175. package/dist/commands/managedGateway/haproxy-stats.d.ts.map +0 -1
  176. package/dist/commands/managedGateway/haproxy-stats.js +0 -131
  177. package/dist/commands/managedGateway/list.d.ts +0 -4
  178. package/dist/commands/managedGateway/list.d.ts.map +0 -1
  179. package/dist/commands/managedGateway/list.js +0 -50
  180. package/dist/commands/managedGateway/logs.d.ts +0 -10
  181. package/dist/commands/managedGateway/logs.d.ts.map +0 -1
  182. package/dist/commands/managedGateway/logs.js +0 -100
  183. package/dist/commands/managedGateway/reboot.d.ts +0 -5
  184. package/dist/commands/managedGateway/reboot.d.ts.map +0 -1
  185. package/dist/commands/managedGateway/reboot.js +0 -95
  186. package/dist/commands/managedGateway/resync.d.ts +0 -10
  187. package/dist/commands/managedGateway/resync.d.ts.map +0 -1
  188. package/dist/commands/managedGateway/resync.js +0 -69
  189. package/dist/commands/managedGateway/ssh.d.ts +0 -4
  190. package/dist/commands/managedGateway/ssh.d.ts.map +0 -1
  191. package/dist/commands/managedGateway/ssh.js +0 -130
  192. package/dist/commands/managedGateway/wipe-logs.d.ts +0 -4
  193. package/dist/commands/managedGateway/wipe-logs.d.ts.map +0 -1
  194. package/dist/commands/managedGateway/wipe-logs.js +0 -67
  195. package/dist/commands/managedGateway/wireguard.d.ts +0 -4
  196. package/dist/commands/managedGateway/wireguard.d.ts.map +0 -1
  197. package/dist/commands/managedGateway/wireguard.js +0 -68
  198. package/dist/di/bindings.d.ts +0 -15
  199. package/dist/di/bindings.d.ts.map +0 -1
  200. package/dist/di/bindings.js +0 -99
  201. package/dist/di/container.d.ts +0 -44
  202. package/dist/di/container.d.ts.map +0 -1
  203. package/dist/di/container.js +0 -88
  204. package/dist/di/types.d.ts +0 -23
  205. package/dist/di/types.d.ts.map +0 -1
  206. package/dist/di/types.js +0 -32
  207. package/dist/repositories/config-repository.d.ts +0 -46
  208. package/dist/repositories/config-repository.d.ts.map +0 -1
  209. package/dist/repositories/config-repository.js +0 -62
  210. package/dist/repositories/gateway-repository.d.ts +0 -37
  211. package/dist/repositories/gateway-repository.d.ts.map +0 -1
  212. package/dist/repositories/gateway-repository.js +0 -35
@@ -14,15 +14,29 @@ async function handleApplicationDelete(options) {
14
14
  requireAuth: true,
15
15
  requireOrganization: true,
16
16
  });
17
+ let appId = options.appId ?? null;
18
+ // Resolve --name to app ID if provided
19
+ if (!appId && options.name) {
20
+ const applications = await instances_1.applicationService.getApplications();
21
+ const matches = applications.filter((app) => app.name === options.name);
22
+ if (matches.length === 0) {
23
+ throw new Error(`No application found with name "${options.name}". Use "edgible application list" to see names.`);
24
+ }
25
+ if (matches.length > 1) {
26
+ throw new Error(`Multiple applications found with name "${options.name}". Use --app-id <id> to specify which to delete.`);
27
+ }
28
+ appId = matches[0].id;
29
+ instances_1.logger.debug('Resolved application name to ID', { name: options.name, appId });
30
+ }
17
31
  // Interactive mode: prompt for application if not provided
18
- const appId = options.interactive !== false
19
- ? await (0, application_prompt_1.getApplicationId)(instances_1.applicationService, options.appId, {
32
+ if (!appId && options.nonInteractive !== true) {
33
+ appId = await (0, application_prompt_1.getApplicationId)(instances_1.applicationService, undefined, {
20
34
  message: 'Select application to delete:',
21
35
  required: true,
22
- })
23
- : options.appId;
36
+ });
37
+ }
24
38
  if (!appId) {
25
- throw new Error('--app-id is required in non-interactive mode. Usage: edgible application delete --app-id <id>');
39
+ throw new Error('Either --app-id or --name is required in non-interactive mode. Usage: edgible application delete --app-id <id> or edgible application delete --name <name>');
26
40
  }
27
41
  instances_1.logger.debug('Deleting application', { appId });
28
42
  // Get application details for confirmation
@@ -1 +1 @@
1
- {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/application/get.ts"],"names":[],"mappings":"AAMA,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCrG"}
1
+ {"version":3,"file":"get.d.ts","sourceRoot":"","sources":["../../../src/commands/application/get.ts"],"names":[],"mappings":"AAMA,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA2CrG"}
@@ -1,6 +1,10 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.handleApplicationGet = handleApplicationGet;
7
+ const chalk_1 = __importDefault(require("chalk"));
4
8
  const instances_1 = require("../../services/instances");
5
9
  const config_validator_1 = require("../utils/config-validator");
6
10
  const output_formatter_1 = require("../utils/output-formatter");
@@ -18,7 +22,10 @@ async function handleApplicationGet(options) {
18
22
  throw new Error('Application ID is required');
19
23
  }
20
24
  instances_1.logger.debug('Getting application', { appId });
21
- const app = await instances_1.applicationService.getApplication(appId);
25
+ const [app, details] = await Promise.all([
26
+ instances_1.applicationService.getApplication(appId),
27
+ instances_1.applicationService.getApplicationDetails(appId),
28
+ ]);
22
29
  if (options.json) {
23
30
  console.log(JSON.stringify({
24
31
  id: app.id,
@@ -29,12 +36,33 @@ async function handleApplicationGet(options) {
29
36
  port: app.port,
30
37
  protocol: app.protocol,
31
38
  status: app.status,
39
+ subtype: details.subtype,
40
+ configuration: details.configuration,
32
41
  workloadId: app.workloadId || '',
33
42
  createdAt: app.createdAt,
34
43
  }, null, 2));
35
44
  }
36
45
  else {
37
46
  console.log((0, output_formatter_1.formatApplication)(app));
47
+ if (details.subtype === 'vm') {
48
+ printVmDetails(details.configuration ?? {}, app.id);
49
+ }
38
50
  }
39
51
  }
52
+ function printVmDetails(cfg, appId) {
53
+ console.log(chalk_1.default.blue('\nVM Details:'));
54
+ if (cfg.vmBackend)
55
+ console.log(chalk_1.default.gray(` Backend: ${cfg.vmBackend}`));
56
+ if (cfg.diskImage)
57
+ console.log(chalk_1.default.gray(` Disk image: ${cfg.diskImage}`));
58
+ if (cfg.memory)
59
+ console.log(chalk_1.default.gray(` Memory: ${cfg.memory} MiB`));
60
+ if (cfg.cpus)
61
+ console.log(chalk_1.default.gray(` CPUs: ${cfg.cpus}`));
62
+ if (cfg.sshPort)
63
+ console.log(chalk_1.default.gray(` SSH port: ${cfg.sshPort}`));
64
+ if (cfg.vmArch)
65
+ console.log(chalk_1.default.gray(` Arch: ${cfg.vmArch}`));
66
+ console.log(chalk_1.default.gray(` SSH access: edgible application ssh --id ${appId}`));
67
+ }
40
68
  //# sourceMappingURL=get.js.map
@@ -0,0 +1,7 @@
1
+ export declare function handleApplicationSsh(options: {
2
+ id?: string;
3
+ user?: string;
4
+ key?: string;
5
+ command?: string;
6
+ }): Promise<void>;
7
+ //# sourceMappingURL=ssh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh.d.ts","sourceRoot":"","sources":["../../../src/commands/application/ssh.ts"],"names":[],"mappings":"AAQA,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6EhB"}
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.handleApplicationSsh = handleApplicationSsh;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const child_process_1 = require("child_process");
42
+ const fs_1 = require("fs");
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const instances_1 = require("../../services/instances");
46
+ const config_validator_1 = require("../utils/config-validator");
47
+ async function handleApplicationSsh(options) {
48
+ (0, config_validator_1.validateConfig)(instances_1.configManager, {
49
+ requireAuth: true,
50
+ requireOrganization: true,
51
+ });
52
+ const appId = options.id;
53
+ if (!appId)
54
+ throw new Error('--id is required');
55
+ console.log(chalk_1.default.gray(`Fetching application ${appId}...`));
56
+ const app = await instances_1.applicationService.getApplicationDetails(appId);
57
+ if (app.subtype !== 'vm') {
58
+ throw new Error(`Application "${app.name}" is not a VM application (subtype: ${app.subtype}). ` +
59
+ `Only vm applications support SSH access via this command.`);
60
+ }
61
+ const sshPort = Number(app.configuration?.sshPort) || 2222;
62
+ const sshUser = options.user ?? 'ubuntu';
63
+ // Resolve target host from serving device WireGuard IP
64
+ const deviceConfigs = (app.deviceApplicationConfigs ?? {});
65
+ const servingEntry = Object.values(deviceConfigs).find((c) => c.deviceType === 'serving' && c.deviceIp);
66
+ if (!servingEntry?.deviceIp) {
67
+ throw new Error(`Could not resolve serving device IP for application "${app.name}". ` +
68
+ `Ensure the agent is registered, connected, and the application is deployed.`);
69
+ }
70
+ const targetHost = servingEntry.deviceIp;
71
+ // Resolve the private key: explicit --key flag → auto-fetch from backend → error
72
+ let resolvedKeyPath = options.key;
73
+ let tempKeyPath;
74
+ if (!resolvedKeyPath) {
75
+ console.log(chalk_1.default.gray('No --key provided, fetching SSH key from backend...'));
76
+ try {
77
+ const privateKey = await instances_1.applicationService.getApplicationVmSshKey(appId);
78
+ if (privateKey) {
79
+ tempKeyPath = path.join(os.tmpdir(), `edgible-vm-ssh-${appId}-${Date.now()}.pem`);
80
+ await fs_1.promises.writeFile(tempKeyPath, privateKey, { mode: 0o600, encoding: 'utf-8' });
81
+ resolvedKeyPath = tempKeyPath;
82
+ console.log(chalk_1.default.gray('SSH key retrieved from backend.'));
83
+ }
84
+ }
85
+ catch (err) {
86
+ instances_1.logger.debug('Failed to auto-fetch VM SSH key', err);
87
+ }
88
+ }
89
+ if (!resolvedKeyPath) {
90
+ throw new Error('No SSH key available. Either:\n' +
91
+ ' - Pass --key <path> to your private key, or\n' +
92
+ ' - Re-create the application with --ssh-public-key to inject a key via cloud-init.');
93
+ }
94
+ try {
95
+ await runSshSession({
96
+ host: targetHost,
97
+ port: sshPort,
98
+ user: sshUser,
99
+ keyPath: resolvedKeyPath,
100
+ command: options.command,
101
+ });
102
+ }
103
+ finally {
104
+ if (tempKeyPath) {
105
+ try {
106
+ await fs_1.promises.unlink(tempKeyPath);
107
+ }
108
+ catch { /* already gone */ }
109
+ }
110
+ }
111
+ }
112
+ async function runSshSession(opts) {
113
+ const { host, port, user, keyPath, command } = opts;
114
+ const sshArgs = [
115
+ '-o', 'StrictHostKeyChecking=no',
116
+ '-o', 'UserKnownHostsFile=/dev/null',
117
+ '-p', String(port),
118
+ ];
119
+ if (keyPath)
120
+ sshArgs.push('-i', keyPath);
121
+ sshArgs.push(`${user}@${host}`);
122
+ if (command)
123
+ sshArgs.push(command);
124
+ console.log(chalk_1.default.blue(`\nConnecting to VM: ${user}@${host}:${port}`));
125
+ if (!command) {
126
+ console.log(chalk_1.default.yellow('Opening interactive SSH session...\n'));
127
+ console.log(chalk_1.default.gray('Tip: Type "exit" to disconnect\n'));
128
+ }
129
+ const proc = (0, child_process_1.spawn)('ssh', sshArgs, { stdio: 'inherit' });
130
+ await new Promise((resolve, reject) => {
131
+ proc.on('error', (err) => {
132
+ instances_1.logger.error('SSH error', err);
133
+ console.error(chalk_1.default.red('āœ— SSH error:'), err.message);
134
+ reject(err);
135
+ });
136
+ proc.on('exit', (code) => {
137
+ if (!command)
138
+ console.log(chalk_1.default.gray('\nSSH session ended'));
139
+ if (code === 0 || code === null)
140
+ resolve();
141
+ else
142
+ reject(new Error(`SSH exited with code ${code}`));
143
+ });
144
+ });
145
+ }
146
+ //# sourceMappingURL=ssh.js.map
@@ -1,4 +1,7 @@
1
1
  export declare function handleApplicationUpdate(options: {
2
2
  appId?: string;
3
+ name?: string;
4
+ authModes?: string;
5
+ allowedOrgs?: string;
3
6
  }): Promise<void>;
4
7
  //# sourceMappingURL=update.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/application/update.ts"],"names":[],"mappings":"AAEA,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAExF"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../../src/commands/application/update.ts"],"names":[],"mappings":"AAMA,wBAAsB,uBAAuB,CAAC,OAAO,EAAE;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDhB"}
@@ -5,7 +5,51 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.handleApplicationUpdate = handleApplicationUpdate;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
+ const instances_1 = require("../../services/instances");
9
+ const config_validator_1 = require("../utils/config-validator");
10
+ const application_prompt_1 = require("../utils/application-prompt");
11
+ const auth_prompt_1 = require("../utils/auth-prompt");
8
12
  async function handleApplicationUpdate(options) {
9
- console.log(chalk_1.default.yellow('Not yet implemented.'));
13
+ (0, config_validator_1.validateConfig)(instances_1.configManager, {
14
+ requireAuth: true,
15
+ requireOrganization: true,
16
+ });
17
+ const appId = await (0, application_prompt_1.getApplicationId)(instances_1.applicationService, options.appId, {
18
+ message: 'Select application to update:',
19
+ required: true,
20
+ });
21
+ if (!appId) {
22
+ throw new Error('Application ID is required');
23
+ }
24
+ const updates = {};
25
+ if (options.name !== undefined && options.name.trim().length > 0) {
26
+ updates.name = options.name.trim();
27
+ }
28
+ if (options.authModes !== undefined && options.authModes.trim().length > 0) {
29
+ const parsed = (0, auth_prompt_1.parseAuthModes)(options.authModes.trim());
30
+ if (parsed && parsed.length > 0) {
31
+ updates.authModes = parsed;
32
+ }
33
+ }
34
+ if (options.allowedOrgs !== undefined && options.allowedOrgs.trim().length > 0) {
35
+ updates.allowedOrganizations = options.allowedOrgs
36
+ .split(',')
37
+ .map((s) => s.trim())
38
+ .filter(Boolean);
39
+ }
40
+ if (Object.keys(updates).length === 0) {
41
+ console.log(chalk_1.default.yellow('No updates specified. Use --name, --auth-modes, or --allowed-orgs.'));
42
+ return;
43
+ }
44
+ instances_1.logger.debug('Updating application', { appId, updates });
45
+ await instances_1.applicationService.updateApplication(appId, updates);
46
+ console.log(chalk_1.default.green('āœ“ Application updated successfully.'));
47
+ if (updates.name)
48
+ console.log(chalk_1.default.gray(` Name: ${updates.name}`));
49
+ if (updates.authModes)
50
+ console.log(chalk_1.default.gray(` Auth modes: ${updates.authModes.join(', ')}`));
51
+ if (updates.allowedOrganizations && updates.allowedOrganizations.length > 0) {
52
+ console.log(chalk_1.default.gray(` Allowed organizations: ${updates.allowedOrganizations.join(', ')}`));
53
+ }
10
54
  }
11
55
  //# sourceMappingURL=update.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/commands/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkBpC;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwY/D"}
1
+ {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../../src/commands/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4d/D"}
@@ -11,6 +11,8 @@ const create_existing_1 = require("./application/create-existing");
11
11
  const create_docker_compose_1 = require("./application/create-docker-compose");
12
12
  const create_managed_process_1 = require("./application/create-managed-process");
13
13
  const create_stubs_1 = require("./application/create-stubs");
14
+ const create_vm_1 = require("./application/create-vm");
15
+ const ssh_1 = require("./application/ssh");
14
16
  const list_2 = require("./application/api-keys/list");
15
17
  const create_1 = require("./application/api-keys/create");
16
18
  const delete_2 = require("./application/api-keys/delete");
@@ -47,20 +49,22 @@ function setupApplicationCommands(program) {
47
49
  .description('Create application for an existing port that is open on the computer')
48
50
  .addHelpText('after', `
49
51
  Examples:
50
- $ edgible application create existing --name myapp --port 3000 --device-id <serving-device> --gateway-ids <gw1,gw2>
51
- $ edgible application create existing --name myapp --port 8080 --protocol https --device-id <serving-device> --gateway-ids <gw>
52
- $ edgible application create existing --name myapp --port 3000 --https-upgrade --device-id <serving-device> --gateway-ids <gw>
53
- $ edgible application create existing --no-interactive
52
+ $ edgible application create existing --name myapp --port 3000 --device-id <serving-device>
53
+ $ edgible application create existing --name myapp --port 8080 --device-id <serving-device> --gateway-ids <gw1,gw2>
54
+ $ edgible application create existing --name myapp --port 3000 --auth-modes org,api-key --device-id <serving-device>
55
+ $ edgible application create existing --non-interactive --name myapp --port 3000 --device-id <serving-device>
54
56
  `)
55
57
  .option('-n, --name <name>', 'Application name')
56
58
  .option('-d, --description <description>', 'Application description')
57
59
  .option('-p, --port <port>', 'Port number', '3000')
58
- .option('--protocol <protocol>', 'Protocol (http, https, tcp, udp)', 'http')
60
+ .option('--protocol <protocol>', 'Protocol (http, https, tcp, udp)', 'https')
59
61
  .option('--https-upgrade', 'Upgrade HTTP protocol to HTTPS automatically')
60
62
  .option('--device-id <id>', 'Serving device ID')
61
- .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs')
63
+ .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs (omit to use Edgible managed gateway)')
62
64
  .option('--hostnames <hostnames>', 'Comma-separated additional hostnames to route to this app')
63
- .option('--no-interactive', 'Run in non-interactive mode')
65
+ .option('--auth-modes <modes>', 'Auth modes: none, org, api-key (comma-separated for multiple)')
66
+ .option('--allowed-orgs <ids>', 'Comma-separated organization IDs allowed (when org auth is used)')
67
+ .option('--non-interactive', 'Run in non-interactive mode')
64
68
  .action((0, command_wrapper_1.wrapCommand)(async (options) => {
65
69
  await (0, create_existing_1.handleApplicationCreateExisting)(options);
66
70
  }, {
@@ -73,16 +77,18 @@ Examples:
73
77
  .addHelpText('after', `
74
78
  Examples:
75
79
  $ edgible application create docker-compose --name myapp --compose-file ./docker-compose.yml
76
- $ edgible application create docker-compose --name myapp
77
- $ edgible application create docker-compose --no-interactive --name myapp --compose-file ./docker-compose.yml
80
+ $ edgible application create docker-compose --name myapp --auth-modes org --device-id <serving-device>
81
+ $ edgible application create docker-compose --non-interactive --name myapp --compose-file ./docker-compose.yml --device-id <serving-device>
78
82
  `)
79
83
  .option('-n, --name <name>', 'Application name')
80
84
  .option('-d, --description <description>', 'Application description')
81
85
  .option('--compose-file <file>', 'Path to docker-compose.yml file')
82
86
  .option('--device-id <id>', 'Serving device ID')
83
- .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs')
87
+ .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs (omit to use Edgible managed gateway)')
84
88
  .option('--hostnames <hostnames>', 'Comma-separated additional hostnames to route to this app')
85
- .option('--no-interactive', 'Run in non-interactive mode')
89
+ .option('--auth-modes <modes>', 'Auth modes: none, org, api-key (comma-separated for multiple)')
90
+ .option('--allowed-orgs <ids>', 'Comma-separated organization IDs allowed (when org auth is used)')
91
+ .option('--non-interactive', 'Run in non-interactive mode')
86
92
  .action((0, command_wrapper_1.wrapCommand)(async (options) => {
87
93
  await (0, create_docker_compose_1.handleApplicationCreateDockerCompose)(options);
88
94
  }, {
@@ -96,7 +102,8 @@ Examples:
96
102
  Examples:
97
103
  $ edgible application create managed-process --name myapp --command "node server.js" --port 3000
98
104
  $ edgible application create managed-process --name myapp --command "python app.py" --port 8080 --working-dir /opt/myapp
99
- $ edgible application create managed-process --no-interactive --name myapp --command "npm start" --port 3000
105
+ $ edgible application create managed-process --name myapp --command "npm start" --port 3000 --auth-modes api-key
106
+ $ edgible application create managed-process --non-interactive --name myapp --command "npm start" --port 3000 --device-id <serving-device>
100
107
  `)
101
108
  .option('-n, --name <name>', 'Application name')
102
109
  .option('-d, --description <description>', 'Application description')
@@ -105,11 +112,13 @@ Examples:
105
112
  .option('--working-dir <dir>', 'Working directory for the process')
106
113
  .option('--env <vars>', 'Environment variables (format: KEY=VALUE,KEY2=VALUE2)')
107
114
  .option('--log-file <path>', 'Path to log file for stdout/stderr')
108
- .option('--protocol <protocol>', 'Protocol (http, https, tcp, udp)', 'http')
115
+ .option('--protocol <protocol>', 'Protocol (http, https, tcp, udp)', 'https')
109
116
  .option('--device-id <id>', 'Serving device ID')
110
- .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs')
117
+ .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs (omit to use Edgible managed gateway)')
111
118
  .option('--hostnames <hostnames>', 'Comma-separated additional hostnames')
112
- .option('--no-interactive', 'Run in non-interactive mode')
119
+ .option('--auth-modes <modes>', 'Auth modes: none, org, api-key (comma-separated for multiple)')
120
+ .option('--allowed-orgs <ids>', 'Comma-separated organization IDs allowed (when org auth is used)')
121
+ .option('--non-interactive', 'Run in non-interactive mode')
113
122
  .action((0, command_wrapper_1.wrapCommand)(async (options) => {
114
123
  await (0, create_managed_process_1.handleApplicationCreateManagedProcess)(options);
115
124
  }, {
@@ -125,13 +134,33 @@ Examples:
125
134
  requireAuth: false,
126
135
  requireOrganization: false,
127
136
  }));
128
- const createQemuCommand = new commander_1.Command('qemu')
129
- .description('Create application from QEMU VM (not implemented)')
130
- .action((0, command_wrapper_1.wrapCommand)(async () => {
131
- await (0, create_stubs_1.handleApplicationCreateQemu)();
137
+ const createVmCommand = new commander_1.Command('vm')
138
+ .description('Create a VM application (managed by the agent via QEMU or other backends)')
139
+ .addHelpText('after', `
140
+ Examples:
141
+ $ edgible application create vm --name my-vm --backend qemu --disk-image /var/lib/vms/ubuntu.qcow2 --device-id <id>
142
+ $ edgible application create vm --non-interactive --name my-vm --backend qemu --disk-image /path/to/disk.qcow2 --memory 1024 --cpus 2 --ssh-port 2222 --device-id <id>
143
+ `)
144
+ .option('-n, --name <name>', 'Application name')
145
+ .option('-d, --description <description>', 'Application description')
146
+ .option('--backend <backend>', 'VM backend (qemu)', 'qemu')
147
+ .option('--disk-image <path>', 'Disk image path or URL')
148
+ .option('--memory <mib>', 'Memory in MiB (default: 512)')
149
+ .option('--cpus <count>', 'Number of CPUs (default: 1)')
150
+ .option('--ssh-port <port>', 'Host port forwarded to VM port 22 (default: 2222)')
151
+ .option('--ssh-public-key <key>', 'SSH public key to inject via cloud-init')
152
+ .option('--arch <arch>', 'VM architecture: x86_64 or aarch64 (default: x86_64)')
153
+ .option('--device-id <id>', 'Serving device ID')
154
+ .option('--gateway-ids <ids>', 'Comma-separated gateway device IDs')
155
+ .option('--hostnames <hostnames>', 'Comma-separated additional hostnames')
156
+ .option('--auth-modes <modes>', 'Auth modes: none, org, api-key')
157
+ .option('--allowed-orgs <ids>', 'Comma-separated allowed organization IDs')
158
+ .option('--non-interactive', 'Run in non-interactive mode')
159
+ .action((0, command_wrapper_1.wrapCommand)(async (options) => {
160
+ await (0, create_vm_1.handleApplicationCreateVm)(options);
132
161
  }, {
133
- requireAuth: false,
134
- requireOrganization: false,
162
+ requireAuth: true,
163
+ requireOrganization: true,
135
164
  }));
136
165
  const createPodmanCommand = new commander_1.Command('podman')
137
166
  .description('Create application from Podman container (not implemented)')
@@ -146,7 +175,7 @@ Examples:
146
175
  createCommand.addCommand(createDockerComposeCommand);
147
176
  createCommand.addCommand(createManagedProcessCommand);
148
177
  createCommand.addCommand(createDockerCommand);
149
- createCommand.addCommand(createQemuCommand);
178
+ createCommand.addCommand(createVmCommand);
150
179
  createCommand.addCommand(createPodmanCommand);
151
180
  appCommand
152
181
  .command('get')
@@ -163,17 +192,24 @@ Examples:
163
192
  }));
164
193
  appCommand
165
194
  .command('update')
166
- .description('Update an existing application')
195
+ .description('Update an existing application (e.g. auth modes, name)')
167
196
  .option('-i, --app-id <id>', 'Application ID')
168
- .action(async (options) => {
197
+ .option('-n, --name <name>', 'Application name')
198
+ .option('--auth-modes <modes>', 'Auth modes: none, org, api-key (comma-separated for multiple)')
199
+ .option('--allowed-orgs <ids>', 'Comma-separated organization IDs allowed (when org auth is used)')
200
+ .action((0, command_wrapper_1.wrapCommand)(async (options) => {
169
201
  await (0, update_1.handleApplicationUpdate)(options);
170
- });
202
+ }, {
203
+ requireAuth: true,
204
+ requireOrganization: true,
205
+ }));
171
206
  appCommand
172
207
  .command('delete')
173
208
  .description('Delete an application')
174
209
  .option('-i, --app-id <id>', 'Application ID')
210
+ .option('-n, --name <name>', 'Application name (resolved to ID for deletion)')
175
211
  .option('-f, --force', 'Skip confirmation prompt')
176
- .option('--no-interactive', 'Run in non-interactive mode')
212
+ .option('--non-interactive', 'Run in non-interactive mode')
177
213
  .alias('rm')
178
214
  .action((0, command_wrapper_1.wrapCommand)(async (options) => {
179
215
  await (0, delete_1.handleApplicationDelete)(options);
@@ -279,5 +315,24 @@ Examples:
279
315
  requireAuth: true,
280
316
  requireOrganization: true,
281
317
  }));
318
+ appCommand
319
+ .command('ssh')
320
+ .description('Open an SSH session to a VM application')
321
+ .addHelpText('after', `
322
+ Examples:
323
+ $ edgible application ssh --id <app-id>
324
+ $ edgible application ssh --id <app-id> --user root --key ~/.ssh/id_ed25519
325
+ $ edgible application ssh --id <app-id> --command "uname -a"
326
+ `)
327
+ .requiredOption('-i, --id <id>', 'Application ID')
328
+ .option('-u, --user <username>', 'SSH username (default: ubuntu)')
329
+ .option('-k, --key <path>', 'Path to SSH private key')
330
+ .option('--command <cmd>', 'Run a single command instead of interactive session')
331
+ .action((0, command_wrapper_1.wrapCommand)(async (options) => {
332
+ await (0, ssh_1.handleApplicationSsh)(options);
333
+ }, {
334
+ requireAuth: true,
335
+ requireOrganization: true,
336
+ }));
282
337
  }
283
338
  //# sourceMappingURL=application.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmMxD"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAoNxD"}
@@ -55,9 +55,12 @@ function setupAuthCommands(program) {
55
55
  .addHelpText('after', `
56
56
  Examples:
57
57
  $ edgible auth login
58
+ $ edgible auth login --user-email user@example.com --user-password "YourPassword"
58
59
  $ edgible auth login --device --device-name mydevice --email user@example.com
59
60
  $ edgible auth login --device --device-name mydevice --email user@example.com --password "SecurePass123!"
60
61
  `)
62
+ .option('--user-email <email>', 'User email for non-interactive user login')
63
+ .option('--user-password <password>', 'User password for non-interactive user login')
61
64
  .option('--device', 'Login as a device')
62
65
  .option('--device-name <name>', 'Device name (required for device login)')
63
66
  .option('--device-type <type>', 'Device type: serving or gateway (default: serving)')
@@ -70,6 +73,11 @@ Examples:
70
73
  await handleDeviceLogin(instances_1.configManager, instances_1.authService, savedEmail, isFirstRun, options, instances_1.logger);
71
74
  return;
72
75
  }
76
+ // Non-interactive user login when both email and password provided
77
+ if (options.userEmail && options.userPassword) {
78
+ await handleUserLoginNonInteractive(instances_1.configManager, instances_1.authService, options.userEmail.trim().toLowerCase(), options.userPassword, instances_1.logger);
79
+ return;
80
+ }
73
81
  // Interactive mode (existing logic)
74
82
  if (isFirstRun) {
75
83
  console.log(chalk_1.default.blue.bold('\nšŸŽ‰ Welcome to Edgible CLI!'));
@@ -195,6 +203,42 @@ Examples:
195
203
  }
196
204
  }));
197
205
  }
206
+ async function handleUserLoginNonInteractive(configManager, authService, email, password, logger) {
207
+ if (!email.trim()) {
208
+ throw new Error('User email is required');
209
+ }
210
+ if (!(0, validation_1.validateEmail)(email)) {
211
+ throw new Error('Please provide a valid email address');
212
+ }
213
+ if (!password || !password.trim()) {
214
+ throw new Error('User password is required');
215
+ }
216
+ configManager.setEmail(email);
217
+ logger.info('Attempting user login (non-interactive)', { email });
218
+ await authService.loginUser(email, password);
219
+ console.log(chalk_1.default.green('āœ“ Login successful!'));
220
+ console.log(chalk_1.default.gray(`Welcome back, ${email}`));
221
+ try {
222
+ const userOrgs = await authService.getUserOrganizations(email);
223
+ const standardOrgs = userOrgs.organizations.filter((org) => org.organizationType !== 'billing');
224
+ if (standardOrgs.length > 0) {
225
+ configManager.updateConfig({ organizationId: standardOrgs[0].organizationId });
226
+ logger.info('Organization selected', { organizationId: standardOrgs[0].organizationId });
227
+ console.log(chalk_1.default.gray(`Using organization: ${standardOrgs[0].name}`));
228
+ }
229
+ else {
230
+ logger.warn('No standard organizations found for user', { email });
231
+ console.log(chalk_1.default.yellow('⚠ No standard organizations found for this user'));
232
+ }
233
+ }
234
+ catch (orgError) {
235
+ logger.warn('Could not fetch organizations', orgError);
236
+ console.log(chalk_1.default.yellow('⚠ Could not fetch organizations, but login was successful'));
237
+ }
238
+ configManager.setAccountStatus(true);
239
+ configManager.setFirstRunComplete();
240
+ console.log(chalk_1.default.gray('Use "edgible --help" to see available commands.'));
241
+ }
198
242
  async function handleUserLogin(configManager, authService, savedEmail, isFirstRun, logger) {
199
243
  // Check if we have a saved email
200
244
  let email;
@@ -139,7 +139,7 @@ function setupDebugCommands(program) {
139
139
  await (0, setup_1.handleAiSetup)({
140
140
  model: 'qwen:0.5b',
141
141
  autoInstall: true,
142
- noInteractive: true
142
+ nonInteractive: true
143
143
  });
144
144
  debugSections.push({
145
145
  title: 'AI Setup',
@@ -0,0 +1,7 @@
1
+ export declare function handleDeviceApplicationHealth(options: {
2
+ deviceId?: string;
3
+ name?: string;
4
+ json?: boolean;
5
+ nonInteractive?: boolean;
6
+ }): Promise<void>;
7
+ //# sourceMappingURL=application-health.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-health.d.ts","sourceRoot":"","sources":["../../../src/commands/device/application-health.ts"],"names":[],"mappings":"AAyEA,wBAAsB,6BAA6B,CAAC,OAAO,EAAE;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,IAAI,CAAC,CAwChB"}