@indigoai-us/hq-cli 5.47.10 → 5.47.11

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.
@@ -1,11 +1,12 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="b2b63537-b45f-59d6-8783-172b7edcacd6")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="40f5379c-742e-5cd5-aba2-931856dc7dd3")}catch(e){}}();
3
3
  import chalk from "chalk";
4
4
  import { ensureCognitoToken } from "../utils/cognito-session.js";
5
5
  import { vaultApiFetch, getCompanyUid } from "../utils/vault-api.js";
6
6
  const EMAIL_PATTERN = /^[^\s]+@[^\s]+$/;
7
7
  const PERSON_UID_PATTERN = /^prs_[A-Za-z0-9_-]+$/;
8
8
  export const VALID_ROLES = new Set(["owner", "admin", "member", "guest"]);
9
+ const VALID_MEMBER_SET_ROLES = new Set(["admin", "member"]);
9
10
  export function detectTarget(target) {
10
11
  if (EMAIL_PATTERN.test(target)) {
11
12
  return { type: "email", value: target.trim().toLowerCase() };
@@ -250,11 +251,46 @@ export async function revokeInvite(token, tokenOrKey, companyUid) {
250
251
  throw new InviteHttpError(res.status, err.message ?? err.error ?? res.statusText, err.code);
251
252
  }
252
253
  }
254
+ async function setMemberRole(token, companyUid, membershipKey, newRole) {
255
+ if (!VALID_MEMBER_SET_ROLES.has(newRole)) {
256
+ throw new Error(`Invalid role '${newRole}': must be one of admin, member`);
257
+ }
258
+ const res = await vaultApiFetch({
259
+ token,
260
+ path: "/membership/role",
261
+ method: "POST",
262
+ body: { companyUid, membershipKey, newRole },
263
+ });
264
+ if (!res.ok) {
265
+ const err = (await res.json().catch(() => ({})));
266
+ throw new InviteHttpError(res.status, err.message ?? err.error ?? res.statusText, err.code);
267
+ }
268
+ }
253
269
  export function registerMembersCommand(program) {
254
270
  const members = program
255
271
  .command("members")
256
272
  .description("Manage company memberships and invites")
257
273
  .option("--company <slug>", "Company slug (resolves to companyUid)");
274
+ members
275
+ .command("set-role <membershipKey> <role>")
276
+ .description("Change a member or agent role to admin or member")
277
+ .action(async (membershipKey, role) => {
278
+ try {
279
+ const token = await ensureCognitoToken();
280
+ const companySlug = members.opts().company;
281
+ const companyUid = await getCompanyUid(token, companySlug);
282
+ await setMemberRole(token, companyUid, membershipKey, role);
283
+ console.log(chalk.green(`Updated role for '${membershipKey}' to ${role}`));
284
+ }
285
+ catch (err) {
286
+ if (err instanceof InviteHttpError) {
287
+ console.error(chalk.red(err.message));
288
+ process.exit(1);
289
+ }
290
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
291
+ process.exit(1);
292
+ }
293
+ });
258
294
  members
259
295
  .command("invite <target>")
260
296
  .description("Invite a person to the company by email or personUid (sends an invitation email by default)")
@@ -461,4 +497,4 @@ export function registerMembersCommand(program) {
461
497
  });
462
498
  }
463
499
  //# sourceMappingURL=members.js.map
464
- //# debugId=b2b63537-b45f-59d6-8783-172b7edcacd6
500
+ //# debugId=40f5379c-742e-5cd5-aba2-931856dc7dd3
@@ -1,19 +1,36 @@
1
1
 
2
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a1b39bbf-1f26-59e7-af70-6ecf01f2ce7e")}catch(e){}}();
2
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="26bb7e02-3864-5c66-8232-3abc8fc17dc1")}catch(e){}}();
3
3
  import { spawn } from 'node:child_process';
4
4
  import * as path from 'node:path';
5
5
  import * as fs from 'node:fs';
6
6
  import { internal } from 'varlock';
7
7
  import { ensureCognitoToken } from '../utils/cognito-session.js';
8
+ import { computeSha256 } from '../utils/integrity.js';
8
9
  import { vaultApiFetch, getCompanyUid } from '../utils/vault-api.js';
9
10
  import { discoverSchemas } from '../run/discover-schemas.js';
10
11
  import { installHqPlugin, prewarmHqSecrets } from '../run/hq-plugin.js';
12
+ async function buildRunUsage(scriptPath) {
13
+ if (!scriptPath) {
14
+ return undefined;
15
+ }
16
+ const resolvedPath = path.resolve(scriptPath);
17
+ return {
18
+ channel: 'run',
19
+ script: {
20
+ scriptId: resolvedPath,
21
+ path: resolvedPath,
22
+ sha256: await computeSha256(resolvedPath),
23
+ attestationLevel: 'self-asserted-hash',
24
+ },
25
+ };
26
+ }
11
27
  export function registerRunCommand(program) {
12
28
  program
13
29
  .command('run')
14
30
  .description('Load secrets from .env.schema and run a command with them injected')
15
31
  .option('--company <slug>', 'Company slug (overrides @hqCompany in schema)')
16
32
  .option('--schema <path>', 'Explicit schema path (skips walk-up discovery)')
33
+ .option('--script <path>', 'Attach local script identity for script-locked secrets')
17
34
  .option('--check', 'Resolve schema and validate vars without executing the command')
18
35
  .allowUnknownOption(true)
19
36
  .action(async (opts) => {
@@ -53,22 +70,34 @@ export function registerRunCommand(program) {
53
70
  }
54
71
  const token = await ensureCognitoToken();
55
72
  const uid = await getCompanyUid(token, slug);
56
- const fetchBatch = async (companyUid, names) => {
73
+ const usage = await buildRunUsage(opts.script);
74
+ const fetchBatch = async (companyUid, names, requestUsage) => {
57
75
  const res = await vaultApiFetch({
58
76
  token,
59
77
  path: `/secrets/${encodeURIComponent(companyUid)}/load`,
60
78
  method: 'POST',
61
- body: { names },
79
+ body: requestUsage ? { names, usage: requestUsage } : { names },
62
80
  });
63
81
  if (!res.ok) {
64
82
  const body = await res.json().catch(() => ({}));
65
- throw new Error(`Failed to batch-load secrets: ${body.error ?? res.statusText}`);
83
+ const message = typeof body.message === 'string'
84
+ ? body.message
85
+ : typeof body.error === 'string'
86
+ ? body.error
87
+ : res.statusText;
88
+ if (res.status >= 400 &&
89
+ res.status < 500 &&
90
+ typeof body.code === 'string') {
91
+ throw new Error(message);
92
+ }
93
+ throw new Error(`Failed to batch-load secrets: ${message}`);
66
94
  }
67
95
  return res.json();
68
96
  };
69
97
  const pluginOpts = {
70
98
  companyOverride: opts.company,
71
99
  resolveCompanyUid: async () => uid,
100
+ usage,
72
101
  fetchBatch,
73
102
  };
74
103
  // LAST entry = highest precedence; .env.local files trail .env.schema files so any .env.local beats any schema regardless of depth.
@@ -116,4 +145,4 @@ export function registerRunCommand(program) {
116
145
  });
117
146
  }
118
147
  //# sourceMappingURL=run.js.map
119
- //# debugId=a1b39bbf-1f26-59e7-af70-6ecf01f2ce7e
148
+ //# debugId=26bb7e02-3864-5c66-8232-3abc8fc17dc1
@@ -2,6 +2,40 @@ import { Command } from "commander";
2
2
  import { vaultApiFetch, getCompanyUid, getEntityUid } from "../utils/vault-api.js";
3
3
  export type { VaultApiOptions } from "../utils/vault-api.js";
4
4
  export { vaultApiFetch, getCompanyUid, getEntityUid };
5
- export declare function loadRevealedSecrets(token: string, companyUid: string, keys: string[]): Promise<Map<string, string>>;
5
+ export type SecretTier = "standard" | "sensitive" | "nuclear";
6
+ export type SecretScriptLockMode = "off" | "enforced";
7
+ export type SecretUsageChannel = "run" | "exec" | "env" | "reveal" | "submit-link";
8
+ export interface SecretScriptUsage {
9
+ scriptId: string;
10
+ path: string;
11
+ sha256: string;
12
+ attestationLevel: string;
13
+ }
14
+ export interface SecretUsage {
15
+ channel: SecretUsageChannel;
16
+ reason?: string;
17
+ script?: SecretScriptUsage;
18
+ }
19
+ export interface SecretMetadata {
20
+ tier?: SecretTier;
21
+ scriptLock?: {
22
+ mode?: SecretScriptLockMode;
23
+ requiredAttestation?: string;
24
+ };
25
+ cacheTtlMs?: number;
26
+ }
27
+ export interface SecretLoadSuccessRow extends SecretMetadata {
28
+ name: string;
29
+ value?: string;
30
+ }
31
+ export interface SecretLoadResponse {
32
+ secrets: SecretLoadSuccessRow[];
33
+ errors: Array<{
34
+ name: string;
35
+ code: string;
36
+ message?: string;
37
+ }>;
38
+ }
39
+ export declare function loadRevealedSecrets(token: string, companyUid: string, keys: string[], usage?: SecretUsage): Promise<Map<string, string>>;
6
40
  export declare function registerSecretsCommand(program: Command): void;
7
41
  //# sourceMappingURL=secrets.d.ts.map