@layr-labs/ecloud-cli 0.1.0-dev.1 → 0.1.0-dev.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/README.md +6 -4
  2. package/VERSION +2 -2
  3. package/dist/commands/auth/generate.js +184 -46
  4. package/dist/commands/auth/generate.js.map +1 -1
  5. package/dist/commands/auth/login.js +234 -93
  6. package/dist/commands/auth/login.js.map +1 -1
  7. package/dist/commands/auth/logout.js +170 -30
  8. package/dist/commands/auth/logout.js.map +1 -1
  9. package/dist/commands/auth/migrate.js +216 -76
  10. package/dist/commands/auth/migrate.js.map +1 -1
  11. package/dist/commands/auth/whoami.js +145 -17
  12. package/dist/commands/auth/whoami.js.map +1 -1
  13. package/dist/commands/billing/cancel.js +164 -30
  14. package/dist/commands/billing/cancel.js.map +1 -1
  15. package/dist/commands/billing/status.js +213 -80
  16. package/dist/commands/billing/status.js.map +1 -1
  17. package/dist/commands/billing/subscribe.js +179 -45
  18. package/dist/commands/billing/subscribe.js.map +1 -1
  19. package/dist/commands/compute/app/create.js +148 -20
  20. package/dist/commands/compute/app/create.js.map +1 -1
  21. package/dist/commands/compute/app/deploy.js +244 -146
  22. package/dist/commands/compute/app/deploy.js.map +1 -1
  23. package/dist/commands/compute/app/info.js +2 -1
  24. package/dist/commands/compute/app/info.js.map +1 -1
  25. package/dist/commands/compute/app/list.js +194 -111
  26. package/dist/commands/compute/app/list.js.map +1 -1
  27. package/dist/commands/compute/app/logs.js +105 -20
  28. package/dist/commands/compute/app/logs.js.map +1 -1
  29. package/dist/commands/compute/app/profile/set.js +153 -64
  30. package/dist/commands/compute/app/profile/set.js.map +1 -1
  31. package/dist/commands/compute/app/start.js +132 -43
  32. package/dist/commands/compute/app/start.js.map +1 -1
  33. package/dist/commands/compute/app/stop.js +132 -43
  34. package/dist/commands/compute/app/stop.js.map +1 -1
  35. package/dist/commands/compute/app/terminate.js +131 -44
  36. package/dist/commands/compute/app/terminate.js.map +1 -1
  37. package/dist/commands/compute/app/upgrade.js +210 -109
  38. package/dist/commands/compute/app/upgrade.js.map +1 -1
  39. package/dist/commands/compute/environment/list.js +104 -12
  40. package/dist/commands/compute/environment/list.js.map +1 -1
  41. package/dist/commands/compute/environment/set.js +103 -18
  42. package/dist/commands/compute/environment/set.js.map +1 -1
  43. package/dist/commands/compute/environment/show.js +122 -30
  44. package/dist/commands/compute/environment/show.js.map +1 -1
  45. package/dist/commands/compute/undelegate.js +113 -13
  46. package/dist/commands/compute/undelegate.js.map +1 -1
  47. package/dist/commands/telemetry.js +213 -0
  48. package/dist/commands/telemetry.js.map +1 -0
  49. package/dist/commands/upgrade.js +159 -19
  50. package/dist/commands/upgrade.js.map +1 -1
  51. package/dist/commands/version.js +163 -23
  52. package/dist/commands/version.js.map +1 -1
  53. package/package.json +2 -2
@@ -5,7 +5,7 @@ import { Command, Args } from "@oclif/core";
5
5
 
6
6
  // src/client.ts
7
7
  import {
8
- createAppModule,
8
+ createComputeModule,
9
9
  createBillingModule,
10
10
  getEnvironmentConfig as getEnvironmentConfig2,
11
11
  requirePrivateKey,
@@ -52,6 +52,7 @@ import * as path from "path";
52
52
  import * as os from "os";
53
53
  import { load as loadYaml, dump as dumpYaml } from "js-yaml";
54
54
  import { getBuildType } from "@layr-labs/ecloud-sdk";
55
+ import * as crypto from "crypto";
55
56
  var GLOBAL_CONFIG_FILE = "config.yaml";
56
57
  var PROFILE_CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
57
58
  function getGlobalConfigDir() {
@@ -98,6 +99,10 @@ function getDefaultEnvironment() {
98
99
  const config = loadGlobalConfig();
99
100
  return config.default_environment;
100
101
  }
102
+ function getGlobalTelemetryPreference() {
103
+ const config = loadGlobalConfig();
104
+ return config.telemetry_enabled;
105
+ }
101
106
  function getProfileCache(environment) {
102
107
  const config = loadGlobalConfig();
103
108
  const cacheEntry = config.profile_cache?.[environment];
@@ -121,6 +126,24 @@ function setProfileCache(environment, profiles) {
121
126
  };
122
127
  saveGlobalConfig(config);
123
128
  }
129
+ function getOrCreateUserUUID() {
130
+ const config = loadGlobalConfig();
131
+ if (config.user_uuid) {
132
+ return config.user_uuid;
133
+ }
134
+ const uuid = generateUUID();
135
+ config.user_uuid = uuid;
136
+ config.first_run = false;
137
+ saveGlobalConfig(config);
138
+ return uuid;
139
+ }
140
+ function generateUUID() {
141
+ const bytes = crypto.randomBytes(16);
142
+ bytes[6] = bytes[6] & 15 | 64;
143
+ bytes[8] = bytes[8] & 63 | 128;
144
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0"));
145
+ return hex.slice(0, 4).join("") + hex.slice(4, 6).join("") + "-" + hex.slice(6, 8).join("") + "-" + hex.slice(8, 10).join("") + "-" + hex.slice(10, 12).join("") + "-" + hex.slice(12, 16).join("");
146
+ }
124
147
 
125
148
  // src/utils/appNames.ts
126
149
  import * as fs2 from "fs";
@@ -168,7 +191,7 @@ function listApps(environment) {
168
191
 
169
192
  // src/utils/version.ts
170
193
  function getCliVersion() {
171
- return true ? "0.1.0-dev.1" : "0.0.0";
194
+ return true ? "0.1.0-dev.3" : "0.0.0";
172
195
  }
173
196
  function getClientId() {
174
197
  return `ecloud-cli/v${getCliVersion()}`;
@@ -585,7 +608,7 @@ async function validateCommonFlags(flags) {
585
608
  }
586
609
 
587
610
  // src/client.ts
588
- async function createAppClient(flags) {
611
+ async function createComputeClient(flags) {
589
612
  flags = await validateCommonFlags(flags);
590
613
  const environment = flags.environment;
591
614
  const environmentConfig = getEnvironmentConfig2(environment);
@@ -596,12 +619,14 @@ async function createAppClient(flags) {
596
619
  if (flags.verbose) {
597
620
  console.log(`Using private key from: ${source}`);
598
621
  }
599
- return createAppModule({
622
+ return createComputeModule({
600
623
  verbose: flags.verbose,
601
624
  privateKey,
602
625
  rpcUrl,
603
626
  environment,
604
- clientId: getClientId()
627
+ clientId: getClientId(),
628
+ skipTelemetry: true
629
+ // CLI already has telemetry, skip SDK telemetry
605
630
  });
606
631
  }
607
632
 
@@ -613,6 +638,66 @@ import {
613
638
  isMainnet
614
639
  } from "@layr-labs/ecloud-sdk";
615
640
  import chalk from "chalk";
641
+
642
+ // src/telemetry.ts
643
+ import {
644
+ createTelemetryClient,
645
+ createAppEnvironment,
646
+ createMetricsContext,
647
+ addMetric,
648
+ addMetricWithDimensions,
649
+ emitMetrics,
650
+ getBuildType as getBuildType2
651
+ } from "@layr-labs/ecloud-sdk";
652
+ function createCLITelemetryClient() {
653
+ const userUUID = getOrCreateUserUUID();
654
+ const environment = createAppEnvironment(userUUID);
655
+ const telemetryEnabled = getGlobalTelemetryPreference();
656
+ return createTelemetryClient(environment, "ecloud-cli", {
657
+ telemetryEnabled: telemetryEnabled === true
658
+ // Only enabled if explicitly set to true
659
+ });
660
+ }
661
+ async function withTelemetry(command, action) {
662
+ const client = createCLITelemetryClient();
663
+ const metrics = createMetricsContext();
664
+ metrics.properties["source"] = "ecloud-cli";
665
+ metrics.properties["command"] = command.id || command.constructor.name;
666
+ const environment = getDefaultEnvironment() || "sepolia";
667
+ metrics.properties["environment"] = environment;
668
+ const buildType = getBuildType2() || "prod";
669
+ metrics.properties["build_type"] = buildType;
670
+ const cliVersion = command.config.version;
671
+ if (cliVersion) {
672
+ metrics.properties["cli_version"] = cliVersion;
673
+ }
674
+ addMetric(metrics, "Count", 1);
675
+ let actionError;
676
+ let result;
677
+ try {
678
+ result = await action();
679
+ return result;
680
+ } catch (err) {
681
+ actionError = err instanceof Error ? err : new Error(String(err));
682
+ throw err;
683
+ } finally {
684
+ const resultValue = actionError ? "Failure" : "Success";
685
+ const dimensions = {};
686
+ if (actionError) {
687
+ dimensions["error"] = actionError.message;
688
+ }
689
+ addMetricWithDimensions(metrics, resultValue, 1, dimensions);
690
+ const duration = Date.now() - metrics.startTime.getTime();
691
+ addMetric(metrics, "DurationMilliseconds", duration);
692
+ try {
693
+ await emitMetrics(client, metrics);
694
+ await client.close();
695
+ } catch {
696
+ }
697
+ }
698
+ }
699
+
700
+ // src/commands/compute/app/stop.ts
616
701
  var AppLifecycleStop = class _AppLifecycleStop extends Command {
617
702
  static description = "Stop running app (stop GCP instance)";
618
703
  static args = {
@@ -625,48 +710,52 @@ var AppLifecycleStop = class _AppLifecycleStop extends Command {
625
710
  ...commonFlags
626
711
  };
627
712
  async run() {
628
- const { args, flags } = await this.parse(_AppLifecycleStop);
629
- const app = await createAppClient(flags);
630
- const environment = flags.environment || "sepolia";
631
- const environmentConfig = getEnvironmentConfig3(environment);
632
- const rpcUrl = flags.rpcUrl || environmentConfig.defaultRPCURL;
633
- const privateKey = flags["private-key"] || await getPrivateKeyInteractive(environment);
634
- const appId = await getOrPromptAppID({
635
- appID: args["app-id"],
636
- environment: flags["environment"],
637
- privateKey,
638
- rpcUrl,
639
- action: "stop"
640
- });
641
- const callData = encodeStopAppData(appId);
642
- const estimate = await estimateTransactionGas({
643
- privateKey,
644
- rpcUrl,
645
- environmentConfig,
646
- to: environmentConfig.appControllerAddress,
647
- data: callData
648
- });
649
- if (isMainnet(environmentConfig)) {
650
- const confirmed = await confirm(`This will cost up to ${estimate.maxCostEth} ETH. Continue?`);
651
- if (!confirmed) {
652
- this.log(`
713
+ return withTelemetry(this, async () => {
714
+ const { args, flags } = await this.parse(_AppLifecycleStop);
715
+ const compute = await createComputeClient(flags);
716
+ const environment = flags.environment || "sepolia";
717
+ const environmentConfig = getEnvironmentConfig3(environment);
718
+ const rpcUrl = flags.rpcUrl || environmentConfig.defaultRPCURL;
719
+ const privateKey = flags["private-key"] || await getPrivateKeyInteractive(environment);
720
+ const appId = await getOrPromptAppID({
721
+ appID: args["app-id"],
722
+ environment: flags["environment"],
723
+ privateKey,
724
+ rpcUrl,
725
+ action: "stop"
726
+ });
727
+ const callData = encodeStopAppData(appId);
728
+ const estimate = await estimateTransactionGas({
729
+ privateKey,
730
+ rpcUrl,
731
+ environmentConfig,
732
+ to: environmentConfig.appControllerAddress,
733
+ data: callData
734
+ });
735
+ if (isMainnet(environmentConfig)) {
736
+ const confirmed = await confirm(
737
+ `This will cost up to ${estimate.maxCostEth} ETH. Continue?`
738
+ );
739
+ if (!confirmed) {
740
+ this.log(`
653
741
  ${chalk.gray(`Stop cancelled`)}`);
654
- return;
655
- }
656
- }
657
- const res = await app.stop(appId, {
658
- gas: {
659
- maxFeePerGas: estimate.maxFeePerGas,
660
- maxPriorityFeePerGas: estimate.maxPriorityFeePerGas
742
+ return;
743
+ }
661
744
  }
662
- });
663
- if (!res.tx) {
664
- this.log(`
745
+ const res = await compute.app.stop(appId, {
746
+ gas: {
747
+ maxFeePerGas: estimate.maxFeePerGas,
748
+ maxPriorityFeePerGas: estimate.maxPriorityFeePerGas
749
+ }
750
+ });
751
+ if (!res.tx) {
752
+ this.log(`
665
753
  ${chalk.gray(`Stop failed`)}`);
666
- } else {
667
- this.log(`
754
+ } else {
755
+ this.log(`
668
756
  \u2705 ${chalk.green(`App stopped successfully`)}`);
669
- }
757
+ }
758
+ });
670
759
  }
671
760
  };
672
761
  export {