@layr-labs/ecloud-cli 0.2.0-dev → 0.2.0-dev.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/VERSION +2 -2
  2. package/dist/commands/auth/generate.js +4 -4
  3. package/dist/commands/auth/generate.js.map +1 -1
  4. package/dist/commands/auth/login.js +2 -2
  5. package/dist/commands/auth/login.js.map +1 -1
  6. package/dist/commands/auth/logout.js +2 -2
  7. package/dist/commands/auth/logout.js.map +1 -1
  8. package/dist/commands/auth/migrate.js +2 -2
  9. package/dist/commands/auth/migrate.js.map +1 -1
  10. package/dist/commands/auth/whoami.js +7 -5
  11. package/dist/commands/auth/whoami.js.map +1 -1
  12. package/dist/commands/billing/cancel.js +9 -7
  13. package/dist/commands/billing/cancel.js.map +1 -1
  14. package/dist/commands/billing/status.js +8 -5
  15. package/dist/commands/billing/status.js.map +1 -1
  16. package/dist/commands/billing/subscribe.js +14 -10
  17. package/dist/commands/billing/subscribe.js.map +1 -1
  18. package/dist/commands/compute/app/create.js +2 -2
  19. package/dist/commands/compute/app/create.js.map +1 -1
  20. package/dist/commands/compute/app/deploy.js +105 -105
  21. package/dist/commands/compute/app/deploy.js.map +1 -1
  22. package/dist/commands/compute/app/info.js +55 -8
  23. package/dist/commands/compute/app/info.js.map +1 -1
  24. package/dist/commands/compute/app/list.js +8 -9
  25. package/dist/commands/compute/app/list.js.map +1 -1
  26. package/dist/commands/compute/app/logs.js +58 -11
  27. package/dist/commands/compute/app/logs.js.map +1 -1
  28. package/dist/commands/compute/app/profile/set.js +147 -22
  29. package/dist/commands/compute/app/profile/set.js.map +1 -1
  30. package/dist/commands/compute/app/releases.js +110 -143
  31. package/dist/commands/compute/app/releases.js.map +1 -1
  32. package/dist/commands/compute/app/start.js +58 -11
  33. package/dist/commands/compute/app/start.js.map +1 -1
  34. package/dist/commands/compute/app/stop.js +58 -11
  35. package/dist/commands/compute/app/stop.js.map +1 -1
  36. package/dist/commands/compute/app/terminate.js +58 -11
  37. package/dist/commands/compute/app/terminate.js.map +1 -1
  38. package/dist/commands/compute/app/upgrade.js +121 -67
  39. package/dist/commands/compute/app/upgrade.js.map +1 -1
  40. package/dist/commands/compute/build/info.js +8 -9
  41. package/dist/commands/compute/build/info.js.map +1 -1
  42. package/dist/commands/compute/build/list.js +50 -131
  43. package/dist/commands/compute/build/list.js.map +1 -1
  44. package/dist/commands/compute/build/logs.js +9 -10
  45. package/dist/commands/compute/build/logs.js.map +1 -1
  46. package/dist/commands/compute/build/status.js +9 -10
  47. package/dist/commands/compute/build/status.js.map +1 -1
  48. package/dist/commands/compute/build/submit.js +8 -9
  49. package/dist/commands/compute/build/submit.js.map +1 -1
  50. package/dist/commands/compute/build/verify.js +59 -12
  51. package/dist/commands/compute/build/verify.js.map +1 -1
  52. package/dist/commands/compute/environment/list.js +2 -2
  53. package/dist/commands/compute/environment/list.js.map +1 -1
  54. package/dist/commands/compute/environment/set.js +2 -2
  55. package/dist/commands/compute/environment/set.js.map +1 -1
  56. package/dist/commands/compute/environment/show.js +2 -2
  57. package/dist/commands/compute/environment/show.js.map +1 -1
  58. package/dist/commands/compute/undelegate.js +8 -9
  59. package/dist/commands/compute/undelegate.js.map +1 -1
  60. package/dist/commands/{telemetry.js → telemetry/disable.js} +15 -64
  61. package/dist/commands/telemetry/disable.js.map +1 -0
  62. package/dist/commands/telemetry/enable.js +164 -0
  63. package/dist/commands/telemetry/enable.js.map +1 -0
  64. package/dist/commands/telemetry/status.js +159 -0
  65. package/dist/commands/telemetry/status.js.map +1 -0
  66. package/dist/commands/upgrade.js +2 -2
  67. package/dist/commands/upgrade.js.map +1 -1
  68. package/dist/commands/version.js +2 -2
  69. package/dist/commands/version.js.map +1 -1
  70. package/package.json +4 -2
  71. package/dist/commands/telemetry.js.map +0 -1
@@ -2,15 +2,7 @@
2
2
 
3
3
  // src/commands/compute/app/deploy.ts
4
4
  import { Command, Flags as Flags2 } from "@oclif/core";
5
- import {
6
- getEnvironmentConfig as getEnvironmentConfig3,
7
- UserApiClient as UserApiClient3,
8
- isMainnet,
9
- prepareDeploy,
10
- prepareDeployFromVerifiableBuild,
11
- executeDeploy,
12
- watchDeployment
13
- } from "@layr-labs/ecloud-sdk";
5
+ import { getEnvironmentConfig as getEnvironmentConfig3, UserApiClient as UserApiClient3, isMainnet } from "@layr-labs/ecloud-sdk";
14
6
 
15
7
  // src/telemetry.ts
16
8
  import {
@@ -72,6 +64,29 @@ function saveGlobalConfig(config) {
72
64
  const content = dumpYaml(config, { lineWidth: -1 });
73
65
  fs.writeFileSync(configPath, content, { mode: 420 });
74
66
  }
67
+ function normalizeDirectoryPath(directoryPath) {
68
+ const resolved = path.resolve(directoryPath);
69
+ try {
70
+ return fs.realpathSync(resolved);
71
+ } catch {
72
+ return resolved;
73
+ }
74
+ }
75
+ function setLinkedAppForDirectory(environment, directoryPath, appId) {
76
+ if (!directoryPath || !environment) {
77
+ return;
78
+ }
79
+ const config = loadGlobalConfig();
80
+ if (!config.directory_links) {
81
+ config.directory_links = {};
82
+ }
83
+ if (!config.directory_links[environment]) {
84
+ config.directory_links[environment] = {};
85
+ }
86
+ const normalizedPath = normalizeDirectoryPath(directoryPath);
87
+ config.directory_links[environment][normalizedPath] = appId.toLowerCase();
88
+ saveGlobalConfig(config);
89
+ }
75
90
  function getDefaultEnvironment() {
76
91
  const config = loadGlobalConfig();
77
92
  return config.default_environment;
@@ -117,8 +132,8 @@ function createCLITelemetryClient() {
117
132
  const environment = createAppEnvironment(userUUID);
118
133
  const telemetryEnabled = getGlobalTelemetryPreference();
119
134
  return createTelemetryClient(environment, "ecloud-cli", {
120
- telemetryEnabled: telemetryEnabled === true
121
- // Only enabled if explicitly set to true
135
+ telemetryEnabled: telemetryEnabled !== false
136
+ // Enabled by default, disabled only if explicitly set to false
122
137
  });
123
138
  }
124
139
  async function withTelemetry(command, action) {
@@ -162,6 +177,7 @@ async function withTelemetry(command, action) {
162
177
 
163
178
  // src/flags.ts
164
179
  import { Flags } from "@oclif/core";
180
+ import { getBuildType as getBuildType3 } from "@layr-labs/ecloud-sdk";
165
181
 
166
182
  // src/utils/prompts.ts
167
183
  import { input, select, password, confirm as inquirerConfirm } from "@inquirer/prompts";
@@ -257,7 +273,7 @@ function findAvailableName(environment, baseName) {
257
273
 
258
274
  // src/utils/version.ts
259
275
  function getCliVersion() {
260
- return true ? "0.2.0-dev" : "0.0.0";
276
+ return true ? "0.2.0-dev.1" : "0.0.0";
261
277
  }
262
278
  function getClientId() {
263
279
  return `ecloud-cli/v${getCliVersion()}`;
@@ -646,9 +662,9 @@ async function getImageReferenceInteractive(imageRef, buildFromDockerfile = fals
646
662
  });
647
663
  return imageRefInput;
648
664
  }
649
- async function getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName) {
650
- const baseName = suggestedBaseName || extractAppNameFromImage(imageRef);
651
- const suggestedName = findAvailableName(environment, baseName);
665
+ async function getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName, skipDefaultName) {
666
+ const baseName = skipDefaultName ? void 0 : suggestedBaseName || extractAppNameFromImage(imageRef);
667
+ const suggestedName = baseName ? findAvailableName(environment, baseName) : void 0;
652
668
  while (true) {
653
669
  console.log("\nApp name selection:");
654
670
  const name = await input({
@@ -671,16 +687,16 @@ async function getAvailableAppNameInteractive(environment, imageRef, suggestedBa
671
687
  console.log(`Suggested alternative: ${newSuggested}`);
672
688
  }
673
689
  }
674
- async function getOrPromptAppName(appName, environment, imageRef, suggestedBaseName) {
690
+ async function getOrPromptAppName(appName, environment, imageRef, suggestedBaseName, skipDefaultName) {
675
691
  if (appName) {
676
692
  validateAppName(appName);
677
693
  if (isAppNameAvailable(environment, appName)) {
678
694
  return appName;
679
695
  }
680
696
  console.log(`Warning: App name '${appName}' is already taken.`);
681
- return getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName);
697
+ return getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName, skipDefaultName);
682
698
  }
683
- return getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName);
699
+ return getAvailableAppNameInteractive(environment, imageRef, suggestedBaseName, skipDefaultName);
684
700
  }
685
701
  async function getEnvFileInteractive(envFilePath) {
686
702
  if (envFilePath && fs3.existsSync(envFilePath)) {
@@ -1109,7 +1125,8 @@ var commonFlags = {
1109
1125
  environment: Flags.string({
1110
1126
  required: false,
1111
1127
  description: "Deployment environment to use",
1112
- env: "ECLOUD_ENV"
1128
+ env: "ECLOUD_ENV",
1129
+ default: async () => getDefaultEnvironment() || (getBuildType3() === "dev" ? "sepolia-dev" : "sepolia")
1113
1130
  }),
1114
1131
  "private-key": Flags.string({
1115
1132
  required: false,
@@ -1128,9 +1145,6 @@ var commonFlags = {
1128
1145
  })
1129
1146
  };
1130
1147
  async function validateCommonFlags(flags, options) {
1131
- if (!flags["environment"]) {
1132
- flags["environment"] = getDefaultEnvironment();
1133
- }
1134
1148
  flags["environment"] = await getEnvironmentInteractive(flags["environment"]);
1135
1149
  if (options?.requirePrivateKey !== false) {
1136
1150
  flags["private-key"] = await getPrivateKeyInteractive(flags["private-key"]);
@@ -1138,9 +1152,6 @@ async function validateCommonFlags(flags, options) {
1138
1152
  return flags;
1139
1153
  }
1140
1154
 
1141
- // src/commands/compute/app/deploy.ts
1142
- import chalk from "chalk";
1143
-
1144
1155
  // src/client.ts
1145
1156
  import {
1146
1157
  createComputeModule,
@@ -1150,6 +1161,27 @@ import {
1150
1161
  requirePrivateKey,
1151
1162
  getPrivateKeyWithSource
1152
1163
  } from "@layr-labs/ecloud-sdk";
1164
+ async function createComputeClient(flags) {
1165
+ flags = await validateCommonFlags(flags);
1166
+ const environment = flags.environment;
1167
+ const environmentConfig = getEnvironmentConfig2(environment);
1168
+ const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
1169
+ const { key: privateKey, source } = await requirePrivateKey({
1170
+ privateKey: flags["private-key"]
1171
+ });
1172
+ if (flags.verbose) {
1173
+ console.log(`Using private key from: ${source}`);
1174
+ }
1175
+ return createComputeModule({
1176
+ verbose: flags.verbose,
1177
+ privateKey,
1178
+ rpcUrl,
1179
+ environment,
1180
+ clientId: getClientId(),
1181
+ skipTelemetry: true
1182
+ // CLI already has telemetry, skip SDK telemetry
1183
+ });
1184
+ }
1153
1185
  async function createBuildClient(flags) {
1154
1186
  flags = await validateCommonFlags(flags, { requirePrivateKey: false });
1155
1187
  return createBuildModule({
@@ -1162,6 +1194,9 @@ async function createBuildClient(flags) {
1162
1194
  });
1163
1195
  }
1164
1196
 
1197
+ // src/commands/compute/app/deploy.ts
1198
+ import chalk from "chalk";
1199
+
1165
1200
  // src/utils/build.ts
1166
1201
  function formatSourceLink(repoUrl, gitRef) {
1167
1202
  const normalizedRepo = repoUrl.replace(/\.git$/, "");
@@ -1424,16 +1459,11 @@ var AppDeploy = class _AppDeploy extends Command {
1424
1459
  async run() {
1425
1460
  return withTelemetry(this, async () => {
1426
1461
  const { flags } = await this.parse(_AppDeploy);
1427
- const logger = {
1428
- info: (msg) => this.log(msg),
1429
- warn: (msg) => this.warn(msg),
1430
- error: (msg) => this.error(msg),
1431
- debug: (msg) => flags.verbose && this.log(msg)
1432
- };
1433
- const environment = flags.environment || "sepolia";
1462
+ const compute = await createComputeClient(flags);
1463
+ const environment = flags.environment;
1434
1464
  const environmentConfig = getEnvironmentConfig3(environment);
1435
1465
  const rpcUrl = flags["rpc-url"] || environmentConfig.defaultRPCURL;
1436
- const privateKey = await getPrivateKeyInteractive(flags["private-key"]);
1466
+ const privateKey = flags["private-key"];
1437
1467
  let buildClient;
1438
1468
  const getBuildClient = async () => {
1439
1469
  if (buildClient) return buildClient;
@@ -1446,6 +1476,7 @@ var AppDeploy = class _AppDeploy extends Command {
1446
1476
  let verifiableImageUrl;
1447
1477
  let verifiableImageDigest;
1448
1478
  let suggestedAppBaseName;
1479
+ let skipDefaultAppName = false;
1449
1480
  let verifiableMode = "none";
1450
1481
  let envFilePath;
1451
1482
  const suggestAppBaseNameFromRepoUrl = (repoUrl) => {
@@ -1549,7 +1580,7 @@ var AppDeploy = class _AppDeploy extends Command {
1549
1580
  }
1550
1581
  verifiableImageUrl = imageRef2;
1551
1582
  verifiableImageDigest = digest;
1552
- suggestedAppBaseName = suggestAppBaseNameFromRepoUrl(verify.repoUrl);
1583
+ skipDefaultAppName = true;
1553
1584
  for (const line of formatVerifiableBuildSummary({
1554
1585
  buildId: verify.buildId,
1555
1586
  imageUrl: imageRef2,
@@ -1570,7 +1601,8 @@ var AppDeploy = class _AppDeploy extends Command {
1570
1601
  flags.name,
1571
1602
  environment,
1572
1603
  imageRef,
1573
- suggestedAppBaseName
1604
+ suggestedAppBaseName,
1605
+ skipDefaultAppName
1574
1606
  );
1575
1607
  envFilePath = envFilePath ?? await getEnvFileInteractive(flags["env-file"]);
1576
1608
  const availableTypes = await fetchAvailableInstanceTypes(
@@ -1591,37 +1623,23 @@ var AppDeploy = class _AppDeploy extends Command {
1591
1623
  flags["resource-usage-monitoring"]
1592
1624
  );
1593
1625
  const logVisibility = logSettings.publicLogs ? "public" : logSettings.logRedirect ? "private" : "off";
1594
- const { prepared, gasEstimate } = isVerifiable ? await prepareDeployFromVerifiableBuild(
1595
- {
1596
- privateKey,
1597
- rpcUrl,
1598
- environment,
1599
- imageRef,
1600
- imageDigest: verifiableImageDigest,
1601
- envFilePath,
1602
- appName,
1603
- instanceType,
1604
- logVisibility,
1605
- resourceUsageMonitoring,
1606
- skipTelemetry: true
1607
- },
1608
- logger
1609
- ) : await prepareDeploy(
1610
- {
1611
- privateKey,
1612
- rpcUrl,
1613
- environment,
1614
- dockerfilePath,
1615
- imageRef,
1616
- envFilePath,
1617
- appName,
1618
- instanceType,
1619
- logVisibility,
1620
- resourceUsageMonitoring,
1621
- skipTelemetry: true
1622
- },
1623
- logger
1624
- );
1626
+ const { prepared, gasEstimate } = isVerifiable ? await compute.app.prepareDeployFromVerifiableBuild({
1627
+ name: appName,
1628
+ imageRef,
1629
+ imageDigest: verifiableImageDigest,
1630
+ envFile: envFilePath,
1631
+ instanceType,
1632
+ logVisibility,
1633
+ resourceUsageMonitoring
1634
+ }) : await compute.app.prepareDeploy({
1635
+ name: appName,
1636
+ dockerfile: dockerfilePath,
1637
+ imageRef,
1638
+ envFile: envFilePath,
1639
+ instanceType,
1640
+ logVisibility,
1641
+ resourceUsageMonitoring
1642
+ });
1625
1643
  this.log(`
1626
1644
  Estimated transaction cost: ${chalk.cyan(gasEstimate.maxCostEth)} ETH`);
1627
1645
  if (isMainnet(environmentConfig)) {
@@ -1632,16 +1650,10 @@ ${chalk.gray(`Deployment cancelled`)}`);
1632
1650
  return;
1633
1651
  }
1634
1652
  }
1635
- const res = await executeDeploy(
1636
- prepared,
1637
- {
1638
- maxFeePerGas: gasEstimate.maxFeePerGas,
1639
- maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
1640
- },
1641
- logger,
1642
- true
1643
- // skipTelemetry
1644
- );
1653
+ const res = await compute.app.executeDeploy(prepared, {
1654
+ maxFeePerGas: gasEstimate.maxFeePerGas,
1655
+ maxPriorityFeePerGas: gasEstimate.maxPriorityFeePerGas
1656
+ });
1645
1657
  if (!flags["skip-profile"]) {
1646
1658
  const hasProfileFlags = flags.website || flags.description || flags["x-url"] || flags.image;
1647
1659
  let profile = null;
@@ -1660,47 +1672,35 @@ ${chalk.gray(`Deployment cancelled`)}`);
1660
1672
  try {
1661
1673
  profile = await getAppProfileInteractive(appName, true) || null;
1662
1674
  } catch {
1663
- logger.debug("Profile collection skipped or cancelled");
1675
+ if (flags.verbose) {
1676
+ this.log("Profile collection skipped or cancelled");
1677
+ }
1664
1678
  }
1665
1679
  }
1666
1680
  if (profile) {
1667
- logger.info("Uploading app profile...");
1681
+ this.log("Uploading app profile...");
1668
1682
  try {
1669
- const userApiClient = new UserApiClient3(
1670
- environmentConfig,
1671
- privateKey,
1672
- rpcUrl,
1673
- getClientId()
1674
- );
1675
- await userApiClient.uploadAppProfile(
1676
- res.appId,
1677
- profile.name,
1678
- profile.website,
1679
- profile.description,
1680
- profile.xURL,
1681
- profile.imagePath
1682
- );
1683
- logger.info("\u2713 Profile uploaded successfully");
1683
+ await compute.app.setProfile(res.appId, profile);
1684
+ this.log("\u2713 Profile uploaded successfully");
1684
1685
  try {
1685
1686
  invalidateProfileCache(environment);
1686
1687
  } catch (cacheErr) {
1687
- logger.debug(`Failed to invalidate profile cache: ${cacheErr.message}`);
1688
+ if (flags.verbose) {
1689
+ this.log(`Failed to invalidate profile cache: ${cacheErr.message}`);
1690
+ }
1688
1691
  }
1689
1692
  } catch (uploadErr) {
1690
- logger.warn(`Failed to upload profile: ${uploadErr.message}`);
1693
+ this.warn(`Failed to upload profile: ${uploadErr.message}`);
1691
1694
  }
1692
1695
  }
1693
1696
  }
1694
- const ipAddress = await watchDeployment(
1695
- res.appId,
1696
- privateKey,
1697
- rpcUrl,
1698
- environment,
1699
- logger,
1700
- getClientId(),
1701
- true
1702
- // skipTelemetry - CLI already has telemetry
1703
- );
1697
+ const ipAddress = await compute.app.watchDeployment(res.appId);
1698
+ try {
1699
+ const cwd = process.env.INIT_CWD || process.cwd();
1700
+ setLinkedAppForDirectory(environment, cwd, res.appId);
1701
+ } catch (err) {
1702
+ this.debug(`Failed to link directory to app: ${err.message}`);
1703
+ }
1704
1704
  this.log(
1705
1705
  `
1706
1706
  \u2705 ${chalk.green(`App deployed successfully ${chalk.bold(`(id: ${res.appId}, ip: ${ipAddress})`)}`)}`