hereya-cli 0.86.3 → 0.88.0

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 (44) hide show
  1. package/README.md +80 -130
  2. package/dist/backend/index.js +0 -24
  3. package/dist/commands/app/deploy/index.d.ts +0 -2
  4. package/dist/commands/app/deploy/index.js +0 -17
  5. package/dist/commands/app/deployments/index.d.ts +0 -4
  6. package/dist/commands/app/deployments/index.js +1 -20
  7. package/dist/commands/app/destroy/index.d.ts +0 -2
  8. package/dist/commands/app/destroy/index.js +0 -17
  9. package/dist/commands/app/env/index.d.ts +0 -2
  10. package/dist/commands/app/env/index.js +0 -17
  11. package/dist/commands/app/list/index.d.ts +0 -4
  12. package/dist/commands/app/list/index.js +1 -20
  13. package/dist/commands/app/status/index.d.ts +0 -2
  14. package/dist/commands/app/status/index.js +0 -17
  15. package/dist/commands/deploy/index.d.ts +0 -2
  16. package/dist/commands/deploy/index.js +56 -69
  17. package/dist/commands/init/index.d.ts +0 -2
  18. package/dist/commands/init/index.js +1 -18
  19. package/dist/commands/login/index.js +0 -5
  20. package/dist/commands/publish/index.d.ts +0 -2
  21. package/dist/commands/publish/index.js +0 -17
  22. package/dist/commands/run/index.d.ts +0 -2
  23. package/dist/commands/run/index.js +0 -17
  24. package/dist/commands/search/index.d.ts +0 -2
  25. package/dist/commands/search/index.js +21 -38
  26. package/dist/commands/undeploy/index.d.ts +0 -2
  27. package/dist/commands/undeploy/index.js +14 -27
  28. package/dist/commands/up/index.d.ts +0 -2
  29. package/dist/commands/up/index.js +1 -17
  30. package/dist/commands/workspace/executor/install/index.d.ts +0 -2
  31. package/dist/commands/workspace/executor/install/index.js +1 -17
  32. package/dist/commands/workspace/executor/token/index.d.ts +0 -2
  33. package/dist/commands/workspace/executor/token/index.js +0 -17
  34. package/dist/commands/workspace/executor/uninstall/index.d.ts +0 -2
  35. package/dist/commands/workspace/executor/uninstall/index.js +1 -17
  36. package/dist/executor/context.js +15 -12
  37. package/dist/lib/hereya-token.js +11 -10
  38. package/dist/lib/package/index.js +24 -20
  39. package/oclif.manifest.json +3 -133
  40. package/package.json +1 -1
  41. package/dist/lib/active-cloud.d.ts +0 -31
  42. package/dist/lib/active-cloud.js +0 -55
  43. package/dist/lib/ephemeral-token.d.ts +0 -45
  44. package/dist/lib/ephemeral-token.js +0 -89
@@ -2,8 +2,6 @@ import { Args, Command, Flags } from '@oclif/core';
2
2
  import { getBackend } from '../../backend/index.js';
3
3
  import { getConfigManager } from '../../lib/config/index.js';
4
4
  import { getEnvManager } from '../../lib/env/index.js';
5
- import { withEphemeralToken } from '../../lib/ephemeral-token.js';
6
- import { getDefaultLogger } from '../../lib/log.js';
7
5
  import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
8
6
  import { runShell } from '../../lib/shell.js';
9
7
  import { validateDevelopmentWorkspace } from '../../lib/workspace-validation.js';
@@ -21,10 +19,6 @@ export default class Run extends Command {
21
19
  description: 'directory to run command in',
22
20
  required: false,
23
21
  }),
24
- token: Flags.string({
25
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
26
- required: false,
27
- }),
28
22
  workspace: Flags.string({
29
23
  char: 'w',
30
24
  description: 'name of the workspace to run the command in',
@@ -33,17 +27,6 @@ export default class Run extends Command {
33
27
  };
34
28
  static strict = false;
35
29
  async run() {
36
- const { flags } = await this.parse(Run);
37
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
38
- if (flags.token) {
39
- if (process.env.HEREYA_TOKEN) {
40
- getDefaultLogger().debug('[run] --token flag overrides HEREYA_TOKEN environment variable.');
41
- }
42
- return withEphemeralToken(flags.token, () => this.runInner());
43
- }
44
- return this.runInner();
45
- }
46
- async runInner() {
47
30
  const { args, argv, flags } = await this.parse(Run);
48
31
  const projectRootDir = flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR;
49
32
  const configManager = getConfigManager();
@@ -9,9 +9,7 @@ export default class Search extends Command {
9
9
  chdir: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
10
10
  json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
11
  limit: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
12
- token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
12
  };
14
13
  run(): Promise<void>;
15
14
  private displayResults;
16
- private runInner;
17
15
  }
@@ -1,8 +1,6 @@
1
1
  import { Args, Command, Flags } from '@oclif/core';
2
2
  import chalk from 'chalk';
3
3
  import { getBackend } from '../../backend/index.js';
4
- import { withEphemeralToken } from '../../lib/ephemeral-token.js';
5
- import { getDefaultLogger } from '../../lib/log.js';
6
4
  export default class Search extends Command {
7
5
  static args = {
8
6
  query: Args.string({
@@ -32,44 +30,8 @@ export default class Search extends Command {
32
30
  default: 20,
33
31
  description: 'Maximum number of results to return',
34
32
  }),
35
- token: Flags.string({
36
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
37
- required: false,
38
- }),
39
33
  };
40
34
  async run() {
41
- const { flags } = await this.parse(Search);
42
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
43
- if (flags.token) {
44
- if (process.env.HEREYA_TOKEN) {
45
- getDefaultLogger().debug('[search] --token flag overrides HEREYA_TOKEN environment variable.');
46
- }
47
- return withEphemeralToken(flags.token, () => this.runInner());
48
- }
49
- return this.runInner();
50
- }
51
- displayResults(packages, hasMore) {
52
- if (packages.length === 0) {
53
- this.log(chalk.yellow('No packages found matching your query.'));
54
- return;
55
- }
56
- this.log(`Found ${chalk.bold(packages.length)} package(s):`);
57
- this.log();
58
- for (const pkg of packages) {
59
- const visibilityBadge = pkg.visibility === 'PUBLIC'
60
- ? chalk.green('PUBLIC')
61
- : chalk.yellow('PRIVATE');
62
- this.log(` ${chalk.cyan.bold(`${pkg.name}@${pkg.version}`)} ${visibilityBadge}`);
63
- if (pkg.description) {
64
- this.log(` ${chalk.gray(pkg.description)}`);
65
- }
66
- this.log();
67
- }
68
- if (hasMore) {
69
- this.log(chalk.dim('More results available. Use --limit to see more.'));
70
- }
71
- }
72
- async runInner() {
73
35
  const { args, flags } = await this.parse(Search);
74
36
  // Change to specified directory
75
37
  if (flags.chdir !== '.') {
@@ -104,4 +66,25 @@ export default class Search extends Command {
104
66
  this.error(error instanceof Error ? error.message : 'Failed to search packages');
105
67
  }
106
68
  }
69
+ displayResults(packages, hasMore) {
70
+ if (packages.length === 0) {
71
+ this.log(chalk.yellow('No packages found matching your query.'));
72
+ return;
73
+ }
74
+ this.log(`Found ${chalk.bold(packages.length)} package(s):`);
75
+ this.log();
76
+ for (const pkg of packages) {
77
+ const visibilityBadge = pkg.visibility === 'PUBLIC'
78
+ ? chalk.green('PUBLIC')
79
+ : chalk.yellow('PRIVATE');
80
+ this.log(` ${chalk.cyan.bold(`${pkg.name}@${pkg.version}`)} ${visibilityBadge}`);
81
+ if (pkg.description) {
82
+ this.log(` ${chalk.gray(pkg.description)}`);
83
+ }
84
+ this.log();
85
+ }
86
+ if (hasMore) {
87
+ this.log(chalk.dim('More results available. Use --limit to see more.'));
88
+ }
89
+ }
107
90
  }
@@ -6,10 +6,8 @@ export default class Undeploy extends Command {
6
6
  chdir: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
7
  debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
8
  local: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
- token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
9
  workspace: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
11
10
  };
12
11
  run(): Promise<void>;
13
- private runInner;
14
12
  private undeployRemotely;
15
13
  }
@@ -2,14 +2,13 @@ import { Command, Flags } from '@oclif/core';
2
2
  import { getRendererClass, Listr, ListrLogger, ListrLogLevels } from 'listr2';
3
3
  import path from 'node:path';
4
4
  import { CloudBackend } from '../../backend/cloud/cloud-backend.js';
5
+ import { getCloudCredentials, loadBackendConfig } from '../../backend/config.js';
5
6
  import { getBackend } from '../../backend/index.js';
6
7
  import { getExecutor } from '../../executor/index.js';
7
- import { getActiveCloudAuth } from '../../lib/active-cloud.js';
8
8
  import { getConfigManager } from '../../lib/config/index.js';
9
9
  import { getEnvManager } from '../../lib/env/index.js';
10
- import { withEphemeralToken } from '../../lib/ephemeral-token.js';
11
10
  import { gitUtils } from '../../lib/git-utils.js';
12
- import { getDefaultLogger, getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
11
+ import { getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
13
12
  import { getParameterManager } from '../../lib/parameter/index.js';
14
13
  import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
15
14
  import { pollExecutorJob } from '../../lib/remote-job-utils.js';
@@ -36,10 +35,6 @@ export default class Undeploy extends Command {
36
35
  default: false,
37
36
  description: 'force local execution (skip remote executor)',
38
37
  }),
39
- token: Flags.string({
40
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
41
- required: false,
42
- }),
43
38
  workspace: Flags.string({
44
39
  char: 'w',
45
40
  description: 'name of the workspace to undeploy the packages for',
@@ -47,17 +42,6 @@ export default class Undeploy extends Command {
47
42
  }),
48
43
  };
49
44
  async run() {
50
- const { flags } = await this.parse(Undeploy);
51
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
52
- if (flags.token) {
53
- if (process.env.HEREYA_TOKEN) {
54
- getDefaultLogger().debug('[undeploy] --token flag overrides HEREYA_TOKEN environment variable.');
55
- }
56
- return withEphemeralToken(flags.token, () => this.runInner());
57
- }
58
- return this.runInner();
59
- }
60
- async runInner() {
61
45
  const { flags } = await this.parse(Undeploy);
62
46
  setDebug(flags.debug);
63
47
  const projectRootDir = path.resolve(flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR || process.cwd());
@@ -338,18 +322,21 @@ See ${getLogPath()} for more details`);
338
322
  this.error(cleanCheck.reason);
339
323
  }
340
324
  myLogger.log(ListrLogLevels.STARTED, `Undeploying ${input.workspace} via remote executor (branch: ${input.gitBranch})`);
341
- // 2. Resolve cloud auth (ephemeral --token first, then persisted creds)
342
- // and build a CloudBackend for job submission + polling.
343
- const auth = await getActiveCloudAuth();
344
- if (!auth) {
345
- this.error('Remote undeployment requires cloud backend. Run `hereya login` or pass `--token <token>`.');
325
+ // 2. Build CloudBackend for job submission + polling
326
+ const backendConfig = await loadBackendConfig();
327
+ if (!backendConfig.cloud) {
328
+ this.error('Remote undeployment requires cloud backend. Run `hereya login` first.');
329
+ }
330
+ const credentials = await getCloudCredentials(backendConfig.cloud.clientId);
331
+ if (!credentials) {
332
+ this.error('Cloud credentials not found. Run `hereya login` first.');
346
333
  }
347
334
  const resolvedWorkspaceName = resolveWorkspaceName(input.workspace, input.project);
348
335
  const cloudBackend = new CloudBackend({
349
- accessToken: auth.accessToken,
350
- clientId: auth.clientId ?? '',
351
- refreshToken: auth.refreshToken ?? '',
352
- url: auth.cloudUrl,
336
+ accessToken: credentials.accessToken,
337
+ clientId: backendConfig.cloud.clientId,
338
+ refreshToken: credentials.refreshToken,
339
+ url: backendConfig.cloud.url,
353
340
  });
354
341
  // 3. Submit undeploy job
355
342
  const submitResult = await cloudBackend.submitExecutorJob({
@@ -7,9 +7,7 @@ export default class Up extends Command {
7
7
  debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
8
  deploy: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
9
  select: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
10
- token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
10
  workspace: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
11
  };
13
12
  run(): Promise<void>;
14
- private runInner;
15
13
  }
@@ -4,8 +4,7 @@ import { getBackend } from '../../backend/index.js';
4
4
  import { getExecutorForWorkspace } from '../../executor/context.js';
5
5
  import { getConfigManager } from '../../lib/config/index.js';
6
6
  import { getEnvManager } from '../../lib/env/index.js';
7
- import { withEphemeralToken } from '../../lib/ephemeral-token.js';
8
- import { getDefaultLogger, getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
7
+ import { getLogger, getLogPath, isDebug, setDebug } from '../../lib/log.js';
9
8
  import { getParameterManager } from '../../lib/parameter/index.js';
10
9
  import { getProfileFromWorkspace } from '../../lib/profile-utils.js';
11
10
  import { delay } from '../../lib/shell.js';
@@ -36,10 +35,6 @@ export default class Up extends Command {
36
35
  description: 'select the packages to provision',
37
36
  multiple: true,
38
37
  }),
39
- token: Flags.string({
40
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
41
- required: false,
42
- }),
43
38
  workspace: Flags.string({
44
39
  char: 'w',
45
40
  description: 'name of the workspace to install the packages for',
@@ -47,17 +42,6 @@ export default class Up extends Command {
47
42
  }),
48
43
  };
49
44
  async run() {
50
- const { flags } = await this.parse(Up);
51
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
52
- if (flags.token) {
53
- if (process.env.HEREYA_TOKEN) {
54
- getDefaultLogger().debug('[up] --token flag overrides HEREYA_TOKEN environment variable.');
55
- }
56
- return withEphemeralToken(flags.token, () => this.runInner());
57
- }
58
- return this.runInner();
59
- }
60
- async runInner() {
61
45
  const { flags } = await this.parse(Up);
62
46
  setDebug(flags.debug);
63
47
  const projectRootDir = flags.chdir || process.env.HEREYA_PROJECT_ROOT_DIR;
@@ -4,9 +4,7 @@ export default class WorkspaceExecutorInstall extends Command {
4
4
  static flags: {
5
5
  debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
6
  force: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
- token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
8
7
  workspace: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
8
  };
10
9
  run(): Promise<void>;
11
- private runInner;
12
10
  }
@@ -3,8 +3,7 @@ import { Listr, ListrLogger, ListrLogLevels } from 'listr2';
3
3
  import { CloudBackend } from '../../../../backend/cloud/cloud-backend.js';
4
4
  import { getBackend } from '../../../../backend/index.js';
5
5
  import { getExecutor } from '../../../../executor/index.js';
6
- import { withEphemeralToken } from '../../../../lib/ephemeral-token.js';
7
- import { getDefaultLogger, getLogger, getLogPath, isDebug, setDebug } from '../../../../lib/log.js';
6
+ import { getLogger, getLogPath, isDebug, setDebug } from '../../../../lib/log.js';
8
7
  import { delay } from '../../../../lib/shell.js';
9
8
  const DEFAULT_EXECUTOR_PACKAGE = 'hereya/remote-executor-aws';
10
9
  export default class WorkspaceExecutorInstall extends Command {
@@ -12,10 +11,6 @@ export default class WorkspaceExecutorInstall extends Command {
12
11
  static flags = {
13
12
  debug: Flags.boolean({ default: false, description: 'enable debug mode' }),
14
13
  force: Flags.boolean({ char: 'f', default: false, description: 'force reinstall even if executor is already installed' }),
15
- token: Flags.string({
16
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
17
- required: false,
18
- }),
19
14
  workspace: Flags.string({
20
15
  char: 'w',
21
16
  description: 'name of the workspace',
@@ -23,17 +18,6 @@ export default class WorkspaceExecutorInstall extends Command {
23
18
  }),
24
19
  };
25
20
  async run() {
26
- const { flags } = await this.parse(WorkspaceExecutorInstall);
27
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
28
- if (flags.token) {
29
- if (process.env.HEREYA_TOKEN) {
30
- getDefaultLogger().debug('[workspace executor install] --token flag overrides HEREYA_TOKEN environment variable.');
31
- }
32
- return withEphemeralToken(flags.token, () => this.runInner());
33
- }
34
- return this.runInner();
35
- }
36
- async runInner() {
37
21
  const { flags } = await this.parse(WorkspaceExecutorInstall);
38
22
  setDebug(flags.debug);
39
23
  const myLogger = new ListrLogger({ useIcons: false });
@@ -2,9 +2,7 @@ import { Command } from '@oclif/core';
2
2
  export default class WorkspaceExecutorToken extends Command {
3
3
  static description: string;
4
4
  static flags: {
5
- token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
5
  workspace: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
7
6
  };
8
7
  run(): Promise<void>;
9
- private runInner;
10
8
  }
@@ -1,15 +1,9 @@
1
1
  import { Command, Flags } from '@oclif/core';
2
2
  import { CloudBackend } from '../../../../backend/cloud/cloud-backend.js';
3
3
  import { getBackend } from '../../../../backend/index.js';
4
- import { withEphemeralToken } from '../../../../lib/ephemeral-token.js';
5
- import { getDefaultLogger } from '../../../../lib/log.js';
6
4
  export default class WorkspaceExecutorToken extends Command {
7
5
  static description = 'Generate a workspace-scoped executor token for the remote executor';
8
6
  static flags = {
9
- token: Flags.string({
10
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
11
- required: false,
12
- }),
13
7
  workspace: Flags.string({
14
8
  char: 'w',
15
9
  description: 'name of the workspace',
@@ -17,17 +11,6 @@ export default class WorkspaceExecutorToken extends Command {
17
11
  }),
18
12
  };
19
13
  async run() {
20
- const { flags } = await this.parse(WorkspaceExecutorToken);
21
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
22
- if (flags.token) {
23
- if (process.env.HEREYA_TOKEN) {
24
- getDefaultLogger().debug('[workspace executor token] --token flag overrides HEREYA_TOKEN environment variable.');
25
- }
26
- return withEphemeralToken(flags.token, () => this.runInner());
27
- }
28
- return this.runInner();
29
- }
30
- async runInner() {
31
14
  const { flags } = await this.parse(WorkspaceExecutorToken);
32
15
  const backend = await getBackend();
33
16
  if (!(backend instanceof CloudBackend)) {
@@ -3,9 +3,7 @@ export default class WorkspaceExecutorUninstall extends Command {
3
3
  static description: string;
4
4
  static flags: {
5
5
  debug: import("@oclif/core/interfaces").BooleanFlag<boolean>;
6
- token: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
7
6
  workspace: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
8
7
  };
9
8
  run(): Promise<void>;
10
- private runInner;
11
9
  }
@@ -3,18 +3,13 @@ import { Listr, ListrLogger, ListrLogLevels } from 'listr2';
3
3
  import { CloudBackend } from '../../../../backend/cloud/cloud-backend.js';
4
4
  import { getBackend } from '../../../../backend/index.js';
5
5
  import { getExecutor } from '../../../../executor/index.js';
6
- import { withEphemeralToken } from '../../../../lib/ephemeral-token.js';
7
- import { getDefaultLogger, getLogger, getLogPath, isDebug, setDebug } from '../../../../lib/log.js';
6
+ import { getLogger, getLogPath, isDebug, setDebug } from '../../../../lib/log.js';
8
7
  import { delay } from '../../../../lib/shell.js';
9
8
  const DEFAULT_EXECUTOR_PACKAGE = 'hereya/remote-executor-aws';
10
9
  export default class WorkspaceExecutorUninstall extends Command {
11
10
  static description = 'Uninstall the remote executor from a workspace';
12
11
  static flags = {
13
12
  debug: Flags.boolean({ default: false, description: 'enable debug mode' }),
14
- token: Flags.string({
15
- description: 'Ephemeral cloud access token used for this invocation only. Held in memory; never written to the keychain or `~/.hereya/secrets/`. Takes precedence over the HEREYA_TOKEN environment variable.',
16
- required: false,
17
- }),
18
13
  workspace: Flags.string({
19
14
  char: 'w',
20
15
  description: 'name of the workspace',
@@ -22,17 +17,6 @@ export default class WorkspaceExecutorUninstall extends Command {
22
17
  }),
23
18
  };
24
19
  async run() {
25
- const { flags } = await this.parse(WorkspaceExecutorUninstall);
26
- // Precedence: --token flag > HEREYA_TOKEN env var > keychain.
27
- if (flags.token) {
28
- if (process.env.HEREYA_TOKEN) {
29
- getDefaultLogger().debug('[workspace executor uninstall] --token flag overrides HEREYA_TOKEN environment variable.');
30
- }
31
- return withEphemeralToken(flags.token, () => this.runInner());
32
- }
33
- return this.runInner();
34
- }
35
- async runInner() {
36
20
  const { flags } = await this.parse(WorkspaceExecutorUninstall);
37
21
  setDebug(flags.debug);
38
22
  const myLogger = new ListrLogger({ useIcons: false });
@@ -1,17 +1,16 @@
1
- import { getBackend } from '../backend/index.js';
2
- import { getActiveCloudAuth } from '../lib/active-cloud.js';
1
+ import { getCloudCredentials, loadBackendConfig } from '../backend/config.js';
2
+ import { BackendType, getBackend } from '../backend/index.js';
3
3
  import { resolveWorkspaceName } from '../lib/workspace-utils.js';
4
4
  import { getExecutor } from './index.js';
5
5
  export async function getExecutorForWorkspace(workspaceName, project) {
6
6
  if (!workspaceName) {
7
7
  return getExecutor();
8
8
  }
9
- // Honors both `hereya login` (persisted on disk) and an in-scope
10
- // ephemeral `--token`. Without this, `--token` invocations silently
11
- // fell through to the local executor regardless of whether the
12
- // workspace actually has a remote executor.
13
- const auth = await getActiveCloudAuth();
14
- if (!auth) {
9
+ const backendConfig = await loadBackendConfig();
10
+ if (backendConfig.current !== BackendType.Cloud) {
11
+ return getExecutor();
12
+ }
13
+ if (!backendConfig.cloud) {
15
14
  return getExecutor();
16
15
  }
17
16
  const resolvedName = resolveWorkspaceName(workspaceName, project);
@@ -24,12 +23,16 @@ export async function getExecutorForWorkspace(workspaceName, project) {
24
23
  if (!workspace.hasExecutor) {
25
24
  return getExecutor();
26
25
  }
26
+ const credentials = await getCloudCredentials(backendConfig.cloud.clientId);
27
+ if (!credentials) {
28
+ return getExecutor();
29
+ }
27
30
  return getExecutor({
28
31
  cloudConfig: {
29
- accessToken: auth.accessToken,
30
- clientId: auth.clientId ?? '',
31
- refreshToken: auth.refreshToken ?? '',
32
- url: auth.cloudUrl,
32
+ accessToken: credentials.accessToken,
33
+ clientId: backendConfig.cloud.clientId,
34
+ refreshToken: credentials.refreshToken,
35
+ url: backendConfig.cloud.url,
33
36
  },
34
37
  workspace: resolvedName,
35
38
  });
@@ -1,21 +1,22 @@
1
- import { getActiveCloudAuth } from './active-cloud.js';
1
+ import { getCloudCredentials, loadBackendConfig } from '../backend/config.js';
2
2
  export const hereyaTokenUtils = {
3
3
  async generateHereyaToken(description) {
4
- // Honors both `hereya login` (persisted) and an in-scope ephemeral
5
- // `--token`. Note: workspace-scoped CLI tokens (kind:"cli") are
6
- // intentionally rejected by the cloud's /api/personal-tokens route —
7
- // only user-level tokens can mint long-lived personal tokens.
8
- const auth = await getActiveCloudAuth();
9
- if (!auth) {
4
+ const backendConfig = await loadBackendConfig();
5
+ if (!backendConfig.cloud) {
6
+ return null;
7
+ }
8
+ const { clientId, url } = backendConfig.cloud;
9
+ const credentials = await getCloudCredentials(clientId);
10
+ if (!credentials) {
10
11
  return null;
11
12
  }
12
13
  const formData = new FormData();
13
14
  formData.append('description', description);
14
15
  formData.append('expiresInDays', '365');
15
- const response = await fetch(`${auth.cloudUrl}/api/personal-tokens`, {
16
+ const response = await fetch(`${url}/api/personal-tokens`, {
16
17
  body: formData,
17
18
  headers: {
18
- Authorization: `Bearer ${auth.accessToken}`,
19
+ Authorization: `Bearer ${credentials.accessToken}`,
19
20
  },
20
21
  method: 'POST',
21
22
  });
@@ -23,6 +24,6 @@ export const hereyaTokenUtils = {
23
24
  return null;
24
25
  }
25
26
  const result = await response.json();
26
- return { cloudUrl: auth.cloudUrl, token: result.data.token };
27
+ return { cloudUrl: url, token: result.data.token };
27
28
  },
28
29
  };
@@ -1,9 +1,9 @@
1
1
  import * as yaml from 'yaml';
2
2
  import { z } from 'zod';
3
- import { getBackend } from '../../backend/index.js';
3
+ import { getCurrentBackendType } from '../../backend/config.js';
4
+ import { BackendType, getBackend } from '../../backend/index.js';
4
5
  import { IacType } from '../../iac/common.js';
5
6
  import { InfrastructureType } from '../../infrastructure/common.js';
6
- import { isCloudBackendActive } from '../active-cloud.js';
7
7
  import { CloudPackageManager } from './cloud.js';
8
8
  import { GitHubPackageManager } from './github.js';
9
9
  import { LocalPackageManager } from './local.js';
@@ -31,21 +31,23 @@ export async function resolvePackage(input) {
31
31
  return { found: false, reason: 'Invalid package format. Package name cannot contain dots (.) nor double dashes (--)' };
32
32
  }
33
33
  const isLocal = packageName.startsWith('local/');
34
- // Try cloud first if not local and backend is cloud (or an ephemeral
35
- // --token is in scope, which acts as Cloud regardless of on-disk config).
36
- if (!isLocal && await isCloudBackendActive()) {
37
- const result = await tryCloudResolution(input);
38
- if (result.found) {
39
- return result; // Success
34
+ // Try cloud first if not local and backend is cloud
35
+ if (!isLocal) {
36
+ const backendType = await getCurrentBackendType();
37
+ if (backendType === BackendType.Cloud) {
38
+ const result = await tryCloudResolution(input);
39
+ if (result.found) {
40
+ return result; // Success
41
+ }
42
+ // Failed - check if we should fallback to GitHub or return the error
43
+ if (!packageName.includes('/')) {
44
+ // Simple package names can't fallback to GitHub, return the detailed error
45
+ return result;
46
+ }
47
+ // For owner/repo format, we can fallback to GitHub
48
+ input.logger?.debug(`Package ${packageName} not found in registry, trying GitHub...`);
49
+ input.logger?.debug(`Registry error: ${result.reason}`);
40
50
  }
41
- // Failed - check if we should fallback to GitHub or return the error
42
- if (!packageName.includes('/')) {
43
- // Simple package names can't fallback to GitHub, return the detailed error
44
- return result;
45
- }
46
- // For owner/repo format, we can fallback to GitHub
47
- input.logger?.debug(`Package ${packageName} not found in registry, trying GitHub...`);
48
- input.logger?.debug(`Registry error: ${result.reason}`);
49
51
  }
50
52
  // Determine protocol for standard resolution
51
53
  const protocol = isLocal ? 'local' : '';
@@ -61,10 +63,12 @@ export async function downloadPackage(pkgUrl, destPath) {
61
63
  if (pkgUrl.startsWith('local/')) {
62
64
  protocol = 'local';
63
65
  }
64
- else if (pkgUrl.includes('#') && await isCloudBackendActive()) {
65
- // Registry package URLs contain commit SHA. Cloud branch fires when
66
- // backend.yaml says Cloud OR an ephemeral --token is in scope.
67
- protocol = 'cloud';
66
+ else if (pkgUrl.includes('#')) {
67
+ // Registry package URLs contain commit SHA
68
+ const backendType = await getCurrentBackendType();
69
+ if (backendType === BackendType.Cloud) {
70
+ protocol = 'cloud';
71
+ }
68
72
  }
69
73
  // Otherwise defaults to GitHub
70
74
  const packageManager = await getPackageManager(protocol);