@bussolabs/closeyourit-cli 0.0.22 → 0.0.27

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 (66) hide show
  1. package/README.md +22 -0
  2. package/dist/base.d.ts +14 -2
  3. package/dist/base.js +33 -11
  4. package/dist/commands/environments/create.d.ts +3 -0
  5. package/dist/commands/environments/create.js +11 -0
  6. package/dist/commands/environments/update.d.ts +3 -0
  7. package/dist/commands/environments/update.js +11 -0
  8. package/dist/commands/projects/set-environment-capabilities.d.ts +13 -0
  9. package/dist/commands/projects/set-environment-capabilities.js +39 -0
  10. package/dist/commands/run.d.ts +12 -0
  11. package/dist/commands/run.js +33 -0
  12. package/dist/commands/secrets/assets/archive.d.ts +11 -0
  13. package/dist/commands/secrets/assets/archive.js +17 -0
  14. package/dist/commands/secrets/assets/delegate.d.ts +10 -0
  15. package/dist/commands/secrets/assets/delegate.js +17 -0
  16. package/dist/commands/secrets/assets/download.d.ts +14 -0
  17. package/dist/commands/secrets/assets/download.js +25 -0
  18. package/dist/commands/secrets/assets/list.d.ts +10 -0
  19. package/dist/commands/secrets/assets/list.js +18 -0
  20. package/dist/commands/secrets/assets/purge.d.ts +12 -0
  21. package/dist/commands/secrets/assets/purge.js +22 -0
  22. package/dist/commands/secrets/assets/rollback.d.ts +11 -0
  23. package/dist/commands/secrets/assets/rollback.js +17 -0
  24. package/dist/commands/secrets/assets/shared-list.d.ts +5 -0
  25. package/dist/commands/secrets/assets/shared-list.js +15 -0
  26. package/dist/commands/secrets/assets/shared-upload.d.ts +11 -0
  27. package/dist/commands/secrets/assets/shared-upload.js +24 -0
  28. package/dist/commands/secrets/assets/undelegate.d.ts +10 -0
  29. package/dist/commands/secrets/assets/undelegate.js +17 -0
  30. package/dist/commands/secrets/assets/upload.d.ts +12 -0
  31. package/dist/commands/secrets/assets/upload.js +25 -0
  32. package/dist/commands/secrets/assets/versions.d.ts +10 -0
  33. package/dist/commands/secrets/assets/versions.js +18 -0
  34. package/dist/commands/secrets/delete.d.ts +13 -0
  35. package/dist/commands/secrets/delete.js +26 -0
  36. package/dist/commands/secrets/download.d.ts +12 -0
  37. package/dist/commands/secrets/download.js +41 -0
  38. package/dist/commands/secrets/get.d.ts +13 -0
  39. package/dist/commands/secrets/get.js +30 -0
  40. package/dist/commands/secrets/import.d.ts +22 -0
  41. package/dist/commands/secrets/import.js +71 -0
  42. package/dist/commands/secrets/list.d.ts +10 -0
  43. package/dist/commands/secrets/list.js +32 -0
  44. package/dist/commands/secrets/set.d.ts +15 -0
  45. package/dist/commands/secrets/set.js +36 -0
  46. package/dist/commands/secrets/sync.d.ts +9 -0
  47. package/dist/commands/secrets/sync.js +20 -0
  48. package/dist/commands/service-accounts/create.d.ts +15 -0
  49. package/dist/commands/service-accounts/create.js +46 -0
  50. package/dist/commands/service-accounts/delete.d.ts +12 -0
  51. package/dist/commands/service-accounts/delete.js +25 -0
  52. package/dist/commands/service-accounts/list.d.ts +9 -0
  53. package/dist/commands/service-accounts/list.js +25 -0
  54. package/dist/commands/service-accounts/tokens/create.d.ts +10 -0
  55. package/dist/commands/service-accounts/tokens/create.js +27 -0
  56. package/dist/commands/service-accounts/tokens/revoke.d.ts +13 -0
  57. package/dist/commands/service-accounts/tokens/revoke.js +26 -0
  58. package/dist/lib/api.js +6 -0
  59. package/dist/lib/config.js +10 -1
  60. package/dist/lib/stdin.d.ts +3 -0
  61. package/dist/lib/stdin.js +11 -0
  62. package/dist/lib/subprocess.d.ts +6 -0
  63. package/dist/lib/subprocess.js +16 -0
  64. package/oclif.manifest.json +4050 -2662
  65. package/opencli.json +142 -1
  66. package/package.json +4 -1
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../../base';
2
+ export default class SecretsAssetsUndelegate extends BaseCommand {
3
+ static args: {
4
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static flags: {
7
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../../base");
5
+ class SecretsAssetsUndelegate extends base_1.BaseCommand {
6
+ static args = { id: core_1.Args.string({ required: true }) };
7
+ static flags = { project: core_1.Flags.string({ char: 'p', required: true }) };
8
+ async run() {
9
+ const { args, flags } = await this.parse(SecretsAssetsUndelegate);
10
+ const projectId = await this.resolveProjectId(flags.project);
11
+ await this.api.delete(`/cli/v1/shared_secret_assets/${encodeURIComponent(args.id)}/undelegate?project_id=${encodeURIComponent(projectId)}`);
12
+ if (!this.jsonEnabled())
13
+ this.log(`Removed shared-asset delegation from ${flags.project}`);
14
+ return { undelegated: true, project_id: projectId };
15
+ }
16
+ }
17
+ exports.default = SecretsAssetsUndelegate;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../../base';
2
+ export default class SecretsAssetsUpload extends BaseCommand {
3
+ static description: string;
4
+ static flags: {
5
+ file: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
6
+ name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<unknown>;
12
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const promises_1 = require("node:fs/promises");
4
+ const node_path_1 = require("node:path");
5
+ const core_1 = require("@oclif/core");
6
+ const base_1 = require("../../../base");
7
+ class SecretsAssetsUpload extends base_1.BaseCommand {
8
+ static description = 'Encrypt and upload a mobile CI secret file (never prints its contents)';
9
+ static flags = { ...base_1.projectFlag, file: core_1.Flags.string({ required: true }), name: core_1.Flags.string({ required: true }), environment: core_1.Flags.string(), description: core_1.Flags.string() };
10
+ async run() {
11
+ const { flags } = await this.parse(SecretsAssetsUpload);
12
+ const info = await (0, promises_1.stat)(flags.file).catch(() => undefined);
13
+ if (!info?.isFile())
14
+ this.error(`File not found or unreadable: ${flags.file}`, { exit: 2 });
15
+ if (info.size > 10 * 1024 * 1024)
16
+ this.error('Secret file exceeds 10 MiB', { exit: 2 });
17
+ const projectId = await this.resolveProjectId(flags.project);
18
+ const data = await (0, promises_1.readFile)(flags.file);
19
+ const res = await this.api.upload('POST', `/cli/v1/projects/${encodeURIComponent(projectId)}/secret_assets`, [{ field: 'file', filename: (0, node_path_1.basename)(flags.file), data: new Blob([data]) }], { body: { name: flags.name, environment: flags.environment, description: flags.description } });
20
+ if (!this.jsonEnabled())
21
+ this.log(`Encrypted and uploaded ${flags.name}`);
22
+ return res;
23
+ }
24
+ }
25
+ exports.default = SecretsAssetsUpload;
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../../base';
2
+ export default class SecretsAssetsVersions extends BaseCommand {
3
+ static args: {
4
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static flags: {
7
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../../base");
5
+ const output_1 = require("../../../lib/output");
6
+ class SecretsAssetsVersions extends base_1.BaseCommand {
7
+ static args = { id: core_1.Args.string({ required: true }) };
8
+ static flags = { ...base_1.projectFlag };
9
+ async run() {
10
+ const { args, flags } = await this.parse(SecretsAssetsVersions);
11
+ const projectId = await this.resolveProjectId(flags.project);
12
+ const res = await this.api.get(`/cli/v1/projects/${encodeURIComponent(projectId)}/secret_assets/${encodeURIComponent(args.id)}/versions`);
13
+ if (!this.jsonEnabled())
14
+ this.log((0, output_1.renderTable)(['VERSION', 'FILENAME', 'BYTES', 'CREATED'], (res.data ?? []).map((v) => [String(v.number ?? ''), String(v.filename ?? ''), String(v.byte_size ?? ''), String(v.created_at ?? '')])));
15
+ return res;
16
+ }
17
+ }
18
+ exports.default = SecretsAssetsVersions;
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class SecretsDelete extends BaseCommand {
3
+ static args: {
4
+ name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<unknown>;
13
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ class SecretsDelete extends base_1.BaseCommand {
6
+ static args = {
7
+ name: core_1.Args.string({ description: 'Secret name', required: true }),
8
+ };
9
+ static description = 'Delete a secret from a project environment';
10
+ static examples = ['<%= config.bin %> secrets delete -p acme-api -e production API_KEY'];
11
+ static flags = {
12
+ ...base_1.projectFlag,
13
+ ...base_1.environmentFlag,
14
+ };
15
+ async run() {
16
+ const { args, flags } = await this.parse(SecretsDelete);
17
+ const projectId = await this.resolveProjectId(flags.project);
18
+ const name = args.name.toUpperCase();
19
+ await this.api.delete(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets/${encodeURIComponent(name)}?environment=${encodeURIComponent(flags.environment)}`);
20
+ if (!this.jsonEnabled()) {
21
+ this.log(`Secret ${name} deleted (${flags.environment}).`);
22
+ }
23
+ return { deleted: name };
24
+ }
25
+ }
26
+ exports.default = SecretsDelete;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class SecretsDownload extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ format: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ out: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ };
11
+ run(): Promise<unknown>;
12
+ }
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const promises_1 = require("node:fs/promises");
4
+ const core_1 = require("@oclif/core");
5
+ const base_1 = require("../../base");
6
+ class SecretsDownload extends base_1.BaseCommand {
7
+ static description = 'Download all secrets of an environment as .env or JSON (to a file or stdout). Values with newlines: use --format json. Prefer `cyi run` to avoid writing plaintext to disk.';
8
+ static examples = [
9
+ '<%= config.bin %> secrets download -p acme-api -e production --out .env',
10
+ '<%= config.bin %> secrets download -p acme-api -e production --format json',
11
+ ];
12
+ static flags = {
13
+ ...base_1.projectFlag,
14
+ ...base_1.environmentFlag,
15
+ format: core_1.Flags.string({ default: 'env', description: 'Output format', options: ['env', 'json'] }),
16
+ out: core_1.Flags.string({ description: 'Write to this file instead of stdout' }),
17
+ };
18
+ async run() {
19
+ const { flags } = await this.parse(SecretsDownload);
20
+ const projectId = await this.resolveProjectId(flags.project);
21
+ const res = await this.api.get(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets/bundle?environment=${encodeURIComponent(flags.environment)}`);
22
+ const map = res.data ?? {};
23
+ const body = flags.format === 'json'
24
+ ? JSON.stringify(map, null, 2)
25
+ : Object.entries(map)
26
+ .map(([key, value]) => `${key}=${value}`)
27
+ .join('\n');
28
+ if (flags.out) {
29
+ await (0, promises_1.writeFile)(flags.out, `${body}\n`);
30
+ if (!this.jsonEnabled()) {
31
+ this.log(`Wrote ${Object.keys(map).length} secrets → ${flags.out}`);
32
+ this.warn('The file contains plaintext secrets. Prefer `cyi run` to inject them without touching disk.');
33
+ }
34
+ }
35
+ else if (!this.jsonEnabled()) {
36
+ this.log(body);
37
+ }
38
+ return { count: Object.keys(map).length, format: flags.format, out: flags.out ?? null };
39
+ }
40
+ }
41
+ exports.default = SecretsDownload;
@@ -0,0 +1,13 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class SecretsGet extends BaseCommand {
3
+ static args: {
4
+ name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ };
12
+ run(): Promise<unknown>;
13
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ class SecretsGet extends base_1.BaseCommand {
6
+ static args = {
7
+ name: core_1.Args.string({ description: 'Secret name', required: true }),
8
+ };
9
+ static description = 'Print the value of a single secret (pipeable). Requires the secrets.read permission.';
10
+ static examples = ['<%= config.bin %> secrets get -p acme-api -e production DATABASE_URL'];
11
+ static flags = {
12
+ ...base_1.projectFlag,
13
+ ...base_1.environmentFlag,
14
+ };
15
+ async run() {
16
+ const { args, flags } = await this.parse(SecretsGet);
17
+ const projectId = await this.resolveProjectId(flags.project);
18
+ const res = await this.api.get(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets/bundle?environment=${encodeURIComponent(flags.environment)}`);
19
+ const map = res.data ?? {};
20
+ const key = args.name.toUpperCase();
21
+ if (!(key in map)) {
22
+ this.error(`Secret not found: ${key} (${flags.environment})`, { exit: 1 });
23
+ }
24
+ if (!this.jsonEnabled()) {
25
+ this.log(map[key]);
26
+ }
27
+ return { name: key, value: map[key] };
28
+ }
29
+ }
30
+ exports.default = SecretsGet;
@@ -0,0 +1,22 @@
1
+ import { BaseCommand } from '../../base';
2
+ interface Entry {
3
+ name: string;
4
+ value: string;
5
+ description?: string;
6
+ }
7
+ /** Parse a .env text into entries: `KEY=VALUE` lines, skipping blanks and `#` comments. */
8
+ export declare function parseEnv(text: string): Entry[];
9
+ /** Parse JSON: either `{ "NAME": "value" }` or `[{ "name", "value", "description" }]`. */
10
+ export declare function parseJson(text: string): Entry[];
11
+ export default class SecretsImport extends BaseCommand {
12
+ static description: string;
13
+ static examples: string[];
14
+ static flags: {
15
+ 'from-file': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ format: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
17
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
18
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
19
+ };
20
+ run(): Promise<unknown>;
21
+ }
22
+ export {};
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseEnv = parseEnv;
4
+ exports.parseJson = parseJson;
5
+ const promises_1 = require("node:fs/promises");
6
+ const core_1 = require("@oclif/core");
7
+ const base_1 = require("../../base");
8
+ const stdin_1 = require("../../lib/stdin");
9
+ /** Parse a .env text into entries: `KEY=VALUE` lines, skipping blanks and `#` comments. */
10
+ function parseEnv(text) {
11
+ const entries = [];
12
+ for (const raw of text.split('\n')) {
13
+ const line = raw.trim();
14
+ if (line.length === 0 || line.startsWith('#'))
15
+ continue;
16
+ const eq = line.indexOf('=');
17
+ if (eq === -1)
18
+ continue;
19
+ entries.push({ name: line.slice(0, eq).trim(), value: line.slice(eq + 1) });
20
+ }
21
+ return entries;
22
+ }
23
+ /** Parse JSON: either `{ "NAME": "value" }` or `[{ "name", "value", "description" }]`. */
24
+ function parseJson(text) {
25
+ const data = JSON.parse(text);
26
+ if (Array.isArray(data)) {
27
+ return data.map((row) => {
28
+ const item = row;
29
+ return { name: String(item.name ?? ''), value: String(item.value ?? ''), description: item.description };
30
+ });
31
+ }
32
+ return Object.entries(data).map(([name, value]) => ({ name, value: String(value) }));
33
+ }
34
+ class SecretsImport extends base_1.BaseCommand {
35
+ static description = 'Import many secrets at once (all-or-nothing) from a .env or JSON file';
36
+ static examples = [
37
+ '<%= config.bin %> secrets import -p acme-api -e production --from-file .env',
38
+ '<%= config.bin %> secrets import -p acme-api -e production --format json --from-file secrets.json',
39
+ 'doppler secrets download --config production --no-file --format json | <%= config.bin %> secrets import -p acme-api -e production --format json',
40
+ ];
41
+ static flags = {
42
+ ...base_1.projectFlag,
43
+ ...base_1.environmentFlag,
44
+ 'from-file': core_1.Flags.string({ description: 'Path to a .env or JSON file (default: read from stdin)' }),
45
+ format: core_1.Flags.string({ default: 'env', description: 'Input format', options: ['env', 'json'] }),
46
+ };
47
+ async run() {
48
+ const { flags } = await this.parse(SecretsImport);
49
+ const projectId = await this.resolveProjectId(flags.project);
50
+ let text;
51
+ if (flags['from-file']) {
52
+ text = await (0, promises_1.readFile)(flags['from-file'], 'utf8');
53
+ }
54
+ else {
55
+ if (process.stdin.isTTY) {
56
+ this.error('Provide --from-file or pipe the input via stdin (e.g. `doppler secrets download --format json | cyi secrets import --format json`)', { exit: 1 });
57
+ }
58
+ text = await (0, stdin_1.readStream)();
59
+ }
60
+ const variables = flags.format === 'json' ? parseJson(text) : parseEnv(text);
61
+ if (variables.length === 0) {
62
+ this.error('No variables found in the input', { exit: 1 });
63
+ }
64
+ const res = await this.api.post(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets/import`, { environment: flags.environment, variables });
65
+ if (!this.jsonEnabled()) {
66
+ this.log(`Imported ${res.data?.imported ?? variables.length} secrets (${flags.environment}).`);
67
+ }
68
+ return res;
69
+ }
70
+ }
71
+ exports.default = SecretsImport;
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class SecretsList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ };
9
+ run(): Promise<unknown>;
10
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ const output_1 = require("../../lib/output");
6
+ class SecretsList extends base_1.BaseCommand {
7
+ static description = 'List secret names for a project (optionally filtered by environment). Never prints values.';
8
+ static examples = [
9
+ '<%= config.bin %> secrets list -p acme-api',
10
+ '<%= config.bin %> secrets list -p acme-api -e production',
11
+ ];
12
+ static flags = {
13
+ ...base_1.projectFlag,
14
+ environment: core_1.Flags.string({ char: 'e', description: 'Filter by environment code or id' }),
15
+ };
16
+ async run() {
17
+ const { flags } = await this.parse(SecretsList);
18
+ const projectId = await this.resolveProjectId(flags.project);
19
+ const query = flags.environment ? `?environment=${encodeURIComponent(flags.environment)}` : '';
20
+ const res = await this.api.get(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets${query}`);
21
+ if (!this.jsonEnabled()) {
22
+ const rows = (res.data ?? []).map((secret) => [
23
+ String(secret.name ?? ''),
24
+ String(secret.environment?.code ?? ''),
25
+ String(secret.description ?? ''),
26
+ ]);
27
+ this.log((0, output_1.renderTable)(['NAME', 'ENVIRONMENT', 'DESCRIPTION'], rows));
28
+ }
29
+ return res;
30
+ }
31
+ }
32
+ exports.default = SecretsList;
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class SecretsSet extends BaseCommand {
3
+ static args: {
4
+ assignment: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ value: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ description: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ environment: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
12
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<unknown>;
15
+ }
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ class SecretsSet extends base_1.BaseCommand {
6
+ static args = {
7
+ assignment: core_1.Args.string({ description: 'NAME=VALUE, or just NAME with --value', required: true }),
8
+ };
9
+ static description = 'Set (create or update) a secret for a project environment';
10
+ static examples = [
11
+ '<%= config.bin %> secrets set -p acme-api -e production DATABASE_URL=postgres://user:pass@host/db',
12
+ '<%= config.bin %> secrets set -p acme-api -e production API_KEY --value s3cr3t --description "Stripe key"',
13
+ ];
14
+ static flags = {
15
+ ...base_1.projectFlag,
16
+ ...base_1.environmentFlag,
17
+ value: core_1.Flags.string({ description: 'Secret value (use when the arg is just NAME)' }),
18
+ description: core_1.Flags.string({ description: 'Optional description' }),
19
+ };
20
+ async run() {
21
+ const { args, flags } = await this.parse(SecretsSet);
22
+ const projectId = await this.resolveProjectId(flags.project);
23
+ const eq = args.assignment.indexOf('=');
24
+ const name = eq === -1 ? args.assignment : args.assignment.slice(0, eq);
25
+ const value = eq === -1 ? flags.value : args.assignment.slice(eq + 1);
26
+ if (value === undefined) {
27
+ this.error('Provide a value: use NAME=VALUE or pass --value', { exit: 1 });
28
+ }
29
+ const res = await this.api.post(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets`, { environment: flags.environment, name, value, description: flags.description });
30
+ if (!this.jsonEnabled()) {
31
+ this.log(`Secret ${String(name).toUpperCase()} saved (${flags.environment}).`);
32
+ }
33
+ return res;
34
+ }
35
+ }
36
+ exports.default = SecretsSet;
@@ -0,0 +1,9 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class SecretsSync extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ };
8
+ run(): Promise<unknown>;
9
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_1 = require("../../base");
4
+ class SecretsSync extends base_1.BaseCommand {
5
+ static description = "Push the project's vault secrets to its connected GitHub repo Environment secrets (enqueues a background sync). Requires the github.manage permission.";
6
+ static examples = ['<%= config.bin %> secrets sync -p acme-api'];
7
+ static flags = {
8
+ ...base_1.projectFlag,
9
+ };
10
+ async run() {
11
+ const { flags } = await this.parse(SecretsSync);
12
+ const projectId = await this.resolveProjectId(flags.project);
13
+ const res = await this.api.post(`/cli/v1/projects/${encodeURIComponent(projectId)}/secrets/sync`);
14
+ if (!this.jsonEnabled()) {
15
+ this.log(`Secret sync enqueued for project ${flags.project}.`);
16
+ }
17
+ return res;
18
+ }
19
+ }
20
+ exports.default = SecretsSync;
@@ -0,0 +1,15 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class ServiceAccountsCreate extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ name: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ handle: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
8
+ project: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
9
+ group: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
10
+ role: import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
11
+ 'grant-secrets': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
12
+ 'secret-environment': import("@oclif/core/lib/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
13
+ };
14
+ run(): Promise<unknown>;
15
+ }
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ class ServiceAccountsCreate extends base_1.BaseCommand {
6
+ static description = 'Create a service account (AI member, CLI-only)';
7
+ static examples = [
8
+ '<%= config.bin %> service-accounts create --name "Deploy bot" --project CYI --grant-secrets --secret-environment staging',
9
+ ];
10
+ static flags = {
11
+ name: core_1.Flags.string({ description: 'Display name', required: true }),
12
+ handle: core_1.Flags.string({ description: 'Handle (a-z, 0-9, underscore); derived from name if omitted' }),
13
+ project: core_1.Flags.string({ description: 'Grant visibility on a project key/id (repeatable)', multiple: true }),
14
+ group: core_1.Flags.string({ description: 'Grant visibility on a group name/id (repeatable)', multiple: true }),
15
+ role: core_1.Flags.string({ description: 'Assign a role name/id (repeatable)', multiple: true }),
16
+ 'grant-secrets': core_1.Flags.boolean({ description: 'Grant read+write secrets on the visible projects', default: false }),
17
+ 'secret-environment': core_1.Flags.string({
18
+ description: 'Restrict secret access to these environment codes (repeatable; empty = all environments)',
19
+ multiple: true,
20
+ }),
21
+ };
22
+ async run() {
23
+ const { flags } = await this.parse(ServiceAccountsCreate);
24
+ const projectIds = await Promise.all((flags.project ?? []).map((value) => this.resolveProjectId(value)));
25
+ const groupIds = await Promise.all((flags.group ?? []).map((value) => this.resolveGroupId(value)));
26
+ const roleIds = await Promise.all((flags.role ?? []).map((value) => this.resolveRoleId(value)));
27
+ const body = {
28
+ name: flags.name,
29
+ project_ids: projectIds,
30
+ group_ids: groupIds,
31
+ role_ids: roleIds,
32
+ grant_secrets: flags['grant-secrets'],
33
+ secret_environment_codes: flags['secret-environment'] ?? [],
34
+ };
35
+ if (flags.handle)
36
+ body.handle = flags.handle;
37
+ const res = await this.api.post('/cli/v1/service/accounts', body);
38
+ if (!this.jsonEnabled()) {
39
+ const id = res.data?.id ?? '<id>';
40
+ this.log(`Created service account ${id} (@${res.data?.handle ?? ''}).`);
41
+ this.log(`Mint a token with: service-accounts tokens create ${id} <name>`);
42
+ }
43
+ return res;
44
+ }
45
+ }
46
+ exports.default = ServiceAccountsCreate;
@@ -0,0 +1,12 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class ServiceAccountsDelete extends BaseCommand {
3
+ static args: {
4
+ id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
8
+ static flags: {
9
+ confirm: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
10
+ };
11
+ run(): Promise<unknown>;
12
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const base_1 = require("../../base");
5
+ class ServiceAccountsDelete extends base_1.BaseCommand {
6
+ static args = {
7
+ id: core_1.Args.string({ description: 'Service account id', required: true }),
8
+ };
9
+ static description = 'Delete a service account (revokes its tokens + removes org access; the secrets audit trail is kept)';
10
+ static examples = ['<%= config.bin %> service-accounts delete <id> --confirm'];
11
+ static flags = {
12
+ confirm: core_1.Flags.boolean({ description: 'Required: confirm the deletion' }),
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(ServiceAccountsDelete);
16
+ if (!flags.confirm) {
17
+ this.error('Refusing to delete without --confirm.', { exit: 2 });
18
+ }
19
+ await this.api.delete(`/cli/v1/service/accounts/${encodeURIComponent(args.id)}`);
20
+ if (!this.jsonEnabled())
21
+ this.log(`Deleted service account ${args.id}`);
22
+ return { deleted: args.id };
23
+ }
24
+ }
25
+ exports.default = ServiceAccountsDelete;
@@ -0,0 +1,9 @@
1
+ import { BaseCommand } from '../../base';
2
+ export default class ServiceAccountsList extends BaseCommand {
3
+ static description: string;
4
+ static examples: string[];
5
+ static flags: {
6
+ page: import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
7
+ };
8
+ run(): Promise<unknown>;
9
+ }
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const base_1 = require("../../base");
4
+ const output_1 = require("../../lib/output");
5
+ class ServiceAccountsList extends base_1.BaseCommand {
6
+ static description = 'List the service accounts (AI members, CLI-only) in your organization';
7
+ static examples = ['<%= config.bin %> service-accounts list', '<%= config.bin %> service-accounts list --json'];
8
+ static flags = { ...base_1.pageFlag };
9
+ async run() {
10
+ const { flags } = await this.parse(ServiceAccountsList);
11
+ const res = await this.api.get(`/cli/v1/service/accounts?page=${flags.page}`);
12
+ const accounts = res.data ?? [];
13
+ if (!this.jsonEnabled()) {
14
+ this.log((0, output_1.renderTable)(['NAME', 'HANDLE', 'SECRET ENVS', 'TOKENS', 'ID'], accounts.map((account) => [
15
+ String(account.name ?? ''),
16
+ String(account.handle ?? ''),
17
+ (account.secret_environment_codes ?? []).join(',') || 'all',
18
+ String(account.active_tokens_count ?? 0),
19
+ String(account.id ?? ''),
20
+ ])));
21
+ }
22
+ return res;
23
+ }
24
+ }
25
+ exports.default = ServiceAccountsList;
@@ -0,0 +1,10 @@
1
+ import { BaseCommand } from '../../../base';
2
+ export default class ServiceAccountsTokensCreate extends BaseCommand {
3
+ static args: {
4
+ account: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
5
+ name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
6
+ };
7
+ static description: string;
8
+ static examples: string[];
9
+ run(): Promise<unknown>;
10
+ }