@indigoai-us/hq-cli 5.5.2 → 5.5.4

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 (123) hide show
  1. package/dist/bin/hq-auth-refresh.js +26 -13
  2. package/dist/commands/_patterns.d.ts +3 -0
  3. package/dist/commands/_patterns.js +6 -0
  4. package/dist/commands/add.js +4 -1
  5. package/dist/commands/auth.js +4 -1
  6. package/dist/commands/cloud.js +4 -1
  7. package/dist/commands/groups.d.ts +3 -0
  8. package/dist/commands/groups.js +344 -0
  9. package/dist/commands/list.js +4 -1
  10. package/dist/commands/login.js +4 -1
  11. package/dist/commands/logout.js +4 -1
  12. package/dist/commands/onboard.js +4 -1
  13. package/dist/commands/pack-install.js +4 -1
  14. package/dist/commands/pkg-install.js +4 -1
  15. package/dist/commands/pkg-list.js +4 -1
  16. package/dist/commands/pkg-remove.js +4 -1
  17. package/dist/commands/pkg-update.js +4 -1
  18. package/dist/commands/secrets.d.ts +9 -0
  19. package/dist/commands/secrets.js +263 -25
  20. package/dist/commands/sync.js +4 -1
  21. package/dist/commands/team-sync.js +4 -1
  22. package/dist/commands/update.js +4 -1
  23. package/dist/commands/whoami.js +4 -1
  24. package/dist/index.js +21 -2
  25. package/dist/sentry-before-send.d.ts +3 -0
  26. package/dist/sentry-before-send.js +219 -0
  27. package/dist/sentry-dsn.generated.d.ts +2 -0
  28. package/dist/sentry-dsn.generated.js +5 -0
  29. package/dist/sentry.d.ts +4 -0
  30. package/dist/sentry.js +22 -0
  31. package/dist/strategies/link.js +4 -1
  32. package/dist/strategies/merge.js +4 -1
  33. package/dist/types.js +4 -1
  34. package/dist/utils/cognito-session.d.ts +1 -1
  35. package/dist/utils/cognito-session.js +8 -5
  36. package/dist/utils/git.js +4 -1
  37. package/dist/utils/hq-root.js +4 -1
  38. package/dist/utils/integrity.js +4 -1
  39. package/dist/utils/manifest.js +4 -1
  40. package/dist/utils/registry-client.js +4 -1
  41. package/dist/utils/registry.js +4 -1
  42. package/dist/utils/secrets-cache.js +6 -2
  43. package/package.json +4 -3
  44. package/scripts/generate-dsn.mjs +26 -0
  45. package/src/bin/hq-auth-refresh.ts +23 -16
  46. package/src/commands/_patterns.ts +2 -0
  47. package/src/commands/groups.ts +357 -0
  48. package/src/commands/secrets.ts +306 -26
  49. package/src/index.ts +17 -1
  50. package/src/sentry-before-send.test.ts +359 -0
  51. package/src/sentry-before-send.ts +221 -0
  52. package/src/sentry.test.ts +24 -0
  53. package/src/sentry.ts +19 -0
  54. package/src/utils/cognito-session.ts +4 -4
  55. package/src/utils/secrets-cache.ts +2 -1
  56. package/dist/bin/hq-auth-refresh.d.ts.map +0 -1
  57. package/dist/bin/hq-auth-refresh.js.map +0 -1
  58. package/dist/commands/add.d.ts.map +0 -1
  59. package/dist/commands/add.js.map +0 -1
  60. package/dist/commands/auth.d.ts.map +0 -1
  61. package/dist/commands/auth.js.map +0 -1
  62. package/dist/commands/cloud.d.ts.map +0 -1
  63. package/dist/commands/cloud.js.map +0 -1
  64. package/dist/commands/list.d.ts.map +0 -1
  65. package/dist/commands/list.js.map +0 -1
  66. package/dist/commands/login.d.ts.map +0 -1
  67. package/dist/commands/login.js.map +0 -1
  68. package/dist/commands/logout.d.ts.map +0 -1
  69. package/dist/commands/logout.js.map +0 -1
  70. package/dist/commands/onboard.d.ts.map +0 -1
  71. package/dist/commands/onboard.js.map +0 -1
  72. package/dist/commands/pack-install.d.ts.map +0 -1
  73. package/dist/commands/pack-install.js.map +0 -1
  74. package/dist/commands/pkg-install.d.ts.map +0 -1
  75. package/dist/commands/pkg-install.js.map +0 -1
  76. package/dist/commands/pkg-list.d.ts.map +0 -1
  77. package/dist/commands/pkg-list.js.map +0 -1
  78. package/dist/commands/pkg-remove.d.ts.map +0 -1
  79. package/dist/commands/pkg-remove.js.map +0 -1
  80. package/dist/commands/pkg-update.d.ts.map +0 -1
  81. package/dist/commands/pkg-update.js.map +0 -1
  82. package/dist/commands/secrets.d.ts.map +0 -1
  83. package/dist/commands/secrets.js.map +0 -1
  84. package/dist/commands/sync.d.ts.map +0 -1
  85. package/dist/commands/sync.js.map +0 -1
  86. package/dist/commands/team-sync.d.ts.map +0 -1
  87. package/dist/commands/team-sync.js.map +0 -1
  88. package/dist/commands/update.d.ts.map +0 -1
  89. package/dist/commands/update.js.map +0 -1
  90. package/dist/commands/whoami.d.ts.map +0 -1
  91. package/dist/commands/whoami.js.map +0 -1
  92. package/dist/index.d.ts.map +0 -1
  93. package/dist/index.js.map +0 -1
  94. package/dist/strategies/link.d.ts.map +0 -1
  95. package/dist/strategies/link.js.map +0 -1
  96. package/dist/strategies/merge.d.ts.map +0 -1
  97. package/dist/strategies/merge.js.map +0 -1
  98. package/dist/types.d.ts.map +0 -1
  99. package/dist/types.js.map +0 -1
  100. package/dist/utils/auth.d.ts +0 -27
  101. package/dist/utils/auth.d.ts.map +0 -1
  102. package/dist/utils/auth.js +0 -155
  103. package/dist/utils/auth.js.map +0 -1
  104. package/dist/utils/cognito-session.d.ts.map +0 -1
  105. package/dist/utils/cognito-session.js.map +0 -1
  106. package/dist/utils/git.d.ts.map +0 -1
  107. package/dist/utils/git.js.map +0 -1
  108. package/dist/utils/hq-root.d.ts.map +0 -1
  109. package/dist/utils/hq-root.js.map +0 -1
  110. package/dist/utils/integrity.d.ts.map +0 -1
  111. package/dist/utils/integrity.js.map +0 -1
  112. package/dist/utils/manifest.d.ts.map +0 -1
  113. package/dist/utils/manifest.js.map +0 -1
  114. package/dist/utils/registry-client.d.ts.map +0 -1
  115. package/dist/utils/registry-client.js.map +0 -1
  116. package/dist/utils/registry.d.ts.map +0 -1
  117. package/dist/utils/registry.js.map +0 -1
  118. package/dist/utils/secrets-cache.d.ts.map +0 -1
  119. package/dist/utils/secrets-cache.js.map +0 -1
  120. package/dist/utils/token-store.d.ts +0 -28
  121. package/dist/utils/token-store.d.ts.map +0 -1
  122. package/dist/utils/token-store.js +0 -68
  123. package/dist/utils/token-store.js.map +0 -1
@@ -9,19 +9,32 @@
9
9
  * Exit 0 on refresh, exit 1 if no cached session or refresh failed.
10
10
  * Writes the refreshed tokens to ~/.hq/cognito-tokens.json.
11
11
  */
12
+
13
+ !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]="28774b80-becb-5fb9-b676-dee74c26d73d")}catch(e){}}();
14
+ import { initSentry, Sentry } from "../sentry.js";
12
15
  import { refreshCachedSession } from "../utils/cognito-session.js";
13
- async function main() {
14
- const result = await refreshCachedSession();
15
- if (result.refreshed) {
16
- process.exit(0);
16
+ initSentry();
17
+ (async () => {
18
+ let exitCode = 1;
19
+ try {
20
+ const result = await refreshCachedSession();
21
+ if (result.refreshed) {
22
+ exitCode = 0;
23
+ }
24
+ else {
25
+ if (result.reason) {
26
+ process.stderr.write(`hq-auth-refresh: ${result.reason}\n`);
27
+ }
28
+ }
17
29
  }
18
- if (result.reason) {
19
- process.stderr.write(`hq-auth-refresh: ${result.reason}\n`);
30
+ catch (err) {
31
+ Sentry.captureException(err);
32
+ process.stderr.write(`hq-auth-refresh: ${err instanceof Error ? err.message : String(err)}\n`);
20
33
  }
21
- process.exit(1);
22
- }
23
- main().catch((err) => {
24
- process.stderr.write(`hq-auth-refresh: ${err instanceof Error ? err.message : String(err)}\n`);
25
- process.exit(1);
26
- });
27
- //# sourceMappingURL=hq-auth-refresh.js.map
34
+ finally {
35
+ await Sentry.flush(2000);
36
+ process.exit(exitCode);
37
+ }
38
+ })();
39
+ //# sourceMappingURL=hq-auth-refresh.js.map
40
+ //# debugId=28774b80-becb-5fb9-b676-dee74c26d73d
@@ -0,0 +1,3 @@
1
+ export declare const SECRET_NAME_PATTERN: RegExp;
2
+ export declare const GROUP_ID_PATTERN: RegExp;
3
+ //# sourceMappingURL=_patterns.d.ts.map
@@ -0,0 +1,6 @@
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]="61b178c5-2bd1-5503-bbee-ecb98a9d72f5")}catch(e){}}();
3
+ export const SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*(?:\/[A-Z][A-Z0-9_]+)*$/;
4
+ export const GROUP_ID_PATTERN = /^grp_[A-Za-z0-9_-]+$/;
5
+ //# sourceMappingURL=_patterns.js.map
6
+ //# debugId=61b178c5-2bd1-5503-bbee-ecb98a9d72f5
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * hq modules add command (US-003)
3
3
  */
4
+
5
+ !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]="4b8dd2fb-2564-590a-b294-7deeff926e4b")}catch(e){}}();
4
6
  import { findHqRoot, addModule, parseRepoName, isValidRepoUrl } from '../utils/manifest.js';
5
7
  export function registerAddCommand(program) {
6
8
  program
@@ -58,4 +60,5 @@ export function registerAddCommand(program) {
58
60
  }
59
61
  });
60
62
  }
61
- //# sourceMappingURL=add.js.map
63
+ //# sourceMappingURL=add.js.map
64
+ //# debugId=4b8dd2fb-2564-590a-b294-7deeff926e4b
@@ -13,6 +13,8 @@
13
13
  * session is kept fresh by `hq auth refresh` / `hq-auth-refresh` and consumed
14
14
  * by the deploy + sync skills.
15
15
  */
16
+
17
+ !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]="a4a30b14-55b3-5206-9148-48aff1a8cdd4")}catch(e){}}();
16
18
  import chalk from "chalk";
17
19
  import { browserLogin, clearCachedTokens, loadCachedTokens, isExpiring, CognitoAuthError, } from "@indigoai-us/hq-cloud";
18
20
  import { DEFAULT_COGNITO, refreshCachedSession, } from "../utils/cognito-session.js";
@@ -107,4 +109,5 @@ export function registerAuthCommands(program) {
107
109
  : chalk.green(`${label}HQ session valid (expiresAt=${cached.expiresAt})`));
108
110
  });
109
111
  }
110
- //# sourceMappingURL=auth.js.map
112
+ //# sourceMappingURL=auth.js.map
113
+ //# debugId=a4a30b14-55b3-5206-9148-48aff1a8cdd4
@@ -12,6 +12,8 @@
12
12
  * hq sync pull — pull all permitted files from the vault
13
13
  * hq sync status — show local journal summary
14
14
  */
15
+
16
+ !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]="a3524c87-f874-56f4-92b3-9c33467b4f95")}catch(e){}}();
15
17
  import chalk from "chalk";
16
18
  import * as fs from "fs";
17
19
  import * as path from "path";
@@ -135,4 +137,5 @@ function formatBytes(bytes) {
135
137
  const value = bytes / Math.pow(1024, exponent);
136
138
  return `${value.toFixed(value >= 100 || exponent === 0 ? 0 : 1)} ${units[exponent]}`;
137
139
  }
138
- //# sourceMappingURL=cloud.js.map
140
+ //# sourceMappingURL=cloud.js.map
141
+ //# debugId=a3524c87-f874-56f4-92b3-9c33467b4f95
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare function registerGroupsCommand(program: Command): void;
3
+ //# sourceMappingURL=groups.d.ts.map
@@ -0,0 +1,344 @@
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]="e84b2c37-90d0-559c-ace0-2b08fb69eec5")}catch(e){}}();
3
+ import chalk from "chalk";
4
+ import { ensureCognitoToken } from "../utils/cognito-session.js";
5
+ import { vaultApiFetch, getCompanyUid } from "./secrets.js";
6
+ import { GROUP_ID_PATTERN } from "./_patterns.js";
7
+ const EMAIL_PATTERN = /^[^\s]+@[^\s]+$/;
8
+ const PERSON_UID_PATTERN = /^prs_[A-Za-z0-9_-]+$/;
9
+ function detectPrincipalType(principal) {
10
+ if (EMAIL_PATTERN.test(principal)) {
11
+ // Server normalizes email again; we normalize here so local validation /
12
+ // cache keys agree with the server-side canonicalization.
13
+ return { granteeType: "email", granteeId: principal.trim().toLowerCase() };
14
+ }
15
+ if (PERSON_UID_PATTERN.test(principal)) {
16
+ return { granteeType: "person", granteeId: principal };
17
+ }
18
+ return null;
19
+ }
20
+ function shortDate(iso) {
21
+ return iso.slice(0, 10);
22
+ }
23
+ export function registerGroupsCommand(program) {
24
+ const groups = program
25
+ .command("groups")
26
+ .description("Manage groups in HQ vault")
27
+ .option("--company <slug>", "Company slug (resolves to companyUid)");
28
+ groups
29
+ .command("create <groupId>")
30
+ .description("Create a new group")
31
+ .requiredOption("--name <name>", "Human-readable group name")
32
+ .option("--description <desc>", "Optional description")
33
+ .action(async (groupId, opts) => {
34
+ try {
35
+ if (!GROUP_ID_PATTERN.test(groupId)) {
36
+ console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
37
+ process.exit(1);
38
+ }
39
+ const token = await ensureCognitoToken();
40
+ const companySlug = groups.opts().company;
41
+ const companyUid = await getCompanyUid(token, companySlug);
42
+ const body = { groupId, name: opts.name };
43
+ if (opts.description)
44
+ body.description = opts.description;
45
+ const res = await vaultApiFetch({
46
+ token,
47
+ path: `/secrets/${encodeURIComponent(companyUid)}/groups`,
48
+ method: "POST",
49
+ body,
50
+ });
51
+ if (!res.ok) {
52
+ const err = await res.json().catch(() => ({}));
53
+ if (res.status === 401) {
54
+ console.error(chalk.red("Not authenticated — please run `hq login`"));
55
+ }
56
+ else if (res.status === 403) {
57
+ console.error(chalk.red("Not authorized — owner or admin role required"));
58
+ }
59
+ else if (res.status === 409) {
60
+ console.error(chalk.red(`Group already exists: ${groupId}`));
61
+ }
62
+ else if (res.status >= 500) {
63
+ console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
64
+ }
65
+ else {
66
+ console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
67
+ }
68
+ process.exit(1);
69
+ }
70
+ console.log(chalk.green(`Group '${groupId}' (${opts.name}) created`));
71
+ }
72
+ catch (err) {
73
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
74
+ process.exit(1);
75
+ }
76
+ });
77
+ groups
78
+ .command("delete <groupId>")
79
+ .description("Delete a group")
80
+ .action(async (groupId) => {
81
+ try {
82
+ if (!GROUP_ID_PATTERN.test(groupId)) {
83
+ console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
84
+ process.exit(1);
85
+ }
86
+ const token = await ensureCognitoToken();
87
+ const companySlug = groups.opts().company;
88
+ const companyUid = await getCompanyUid(token, companySlug);
89
+ const res = await vaultApiFetch({
90
+ token,
91
+ path: `/secrets/${encodeURIComponent(companyUid)}/groups`,
92
+ method: "DELETE",
93
+ query: { groupId },
94
+ });
95
+ if (!res.ok) {
96
+ const err = await res.json().catch(() => ({}));
97
+ if (res.status === 401) {
98
+ console.error(chalk.red("Not authenticated — please run `hq login`"));
99
+ }
100
+ else if (res.status === 403) {
101
+ console.error(chalk.red("Not authorized — owner or admin role required"));
102
+ }
103
+ else if (res.status === 404) {
104
+ console.error(chalk.red(`Group not found: ${groupId}`));
105
+ }
106
+ else if (res.status >= 500) {
107
+ console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
108
+ }
109
+ else {
110
+ console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
111
+ }
112
+ process.exit(1);
113
+ }
114
+ console.log(chalk.green(`Group '${groupId}' deleted`));
115
+ }
116
+ catch (err) {
117
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
118
+ process.exit(1);
119
+ }
120
+ });
121
+ groups
122
+ .command("add <groupId> <principal>")
123
+ .description("Add a person to a group (principal: email or personUid)")
124
+ .action(async (groupId, principal) => {
125
+ try {
126
+ if (!GROUP_ID_PATTERN.test(groupId)) {
127
+ console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
128
+ process.exit(1);
129
+ }
130
+ const detected = detectPrincipalType(principal);
131
+ if (!detected) {
132
+ console.error(chalk.red(`Invalid principal '${principal}': must be an email address or a personUid matching prs_<alphanumeric>`));
133
+ process.exit(1);
134
+ }
135
+ const token = await ensureCognitoToken();
136
+ const companySlug = groups.opts().company;
137
+ const companyUid = await getCompanyUid(token, companySlug);
138
+ const res = await vaultApiFetch({
139
+ token,
140
+ path: `/secrets/${encodeURIComponent(companyUid)}/groups/members`,
141
+ method: "POST",
142
+ body: { groupId, granteeType: detected.granteeType, granteeId: detected.granteeId },
143
+ });
144
+ if (!res.ok) {
145
+ const err = await res.json().catch(() => ({}));
146
+ if (res.status === 401) {
147
+ console.error(chalk.red("Not authenticated — please run `hq login`"));
148
+ }
149
+ else if (res.status === 403) {
150
+ console.error(chalk.red("Not authorized — owner/admin role or group creator required"));
151
+ }
152
+ else if (res.status === 404) {
153
+ // Server provides a helpful message (email not found vs group not found)
154
+ console.error(chalk.red(err.error ?? `Not found`));
155
+ }
156
+ else if (res.status >= 500) {
157
+ console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
158
+ }
159
+ else {
160
+ console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
161
+ }
162
+ process.exit(1);
163
+ }
164
+ console.log(chalk.green(`Added ${principal} to group '${groupId}'`));
165
+ }
166
+ catch (err) {
167
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
168
+ process.exit(1);
169
+ }
170
+ });
171
+ groups
172
+ .command("remove <groupId> <principal>")
173
+ .description("Remove a person from a group (principal: email or personUid)")
174
+ .action(async (groupId, principal) => {
175
+ try {
176
+ if (!GROUP_ID_PATTERN.test(groupId)) {
177
+ console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
178
+ process.exit(1);
179
+ }
180
+ const detected = detectPrincipalType(principal);
181
+ if (!detected) {
182
+ console.error(chalk.red(`Invalid principal '${principal}': must be an email address or a personUid matching prs_<alphanumeric>`));
183
+ process.exit(1);
184
+ }
185
+ const token = await ensureCognitoToken();
186
+ const companySlug = groups.opts().company;
187
+ const companyUid = await getCompanyUid(token, companySlug);
188
+ const res = await vaultApiFetch({
189
+ token,
190
+ path: `/secrets/${encodeURIComponent(companyUid)}/groups/members`,
191
+ method: "DELETE",
192
+ query: {
193
+ groupId,
194
+ granteeType: detected.granteeType,
195
+ granteeId: detected.granteeId,
196
+ },
197
+ });
198
+ if (!res.ok) {
199
+ const err = await res.json().catch(() => ({}));
200
+ if (res.status === 401) {
201
+ console.error(chalk.red("Not authenticated — please run `hq login`"));
202
+ }
203
+ else if (res.status === 403) {
204
+ console.error(chalk.red("Not authorized — owner/admin role or group creator required"));
205
+ }
206
+ else if (res.status === 404) {
207
+ console.error(chalk.red(err.error ?? `Not found`));
208
+ }
209
+ else if (res.status >= 500) {
210
+ console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
211
+ }
212
+ else {
213
+ console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
214
+ }
215
+ process.exit(1);
216
+ }
217
+ console.log(chalk.green(`Removed ${principal} from group '${groupId}'`));
218
+ }
219
+ catch (err) {
220
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
221
+ process.exit(1);
222
+ }
223
+ });
224
+ groups
225
+ .command("list")
226
+ .description("List all groups in the company")
227
+ .action(async () => {
228
+ try {
229
+ const token = await ensureCognitoToken();
230
+ const companySlug = groups.opts().company;
231
+ const companyUid = await getCompanyUid(token, companySlug);
232
+ const res = await vaultApiFetch({
233
+ token,
234
+ path: `/secrets/${encodeURIComponent(companyUid)}/groups`,
235
+ });
236
+ if (!res.ok) {
237
+ const err = await res.json().catch(() => ({}));
238
+ if (res.status === 401) {
239
+ console.error(chalk.red("Not authenticated — please run `hq login`"));
240
+ }
241
+ else if (res.status === 403) {
242
+ console.error(chalk.red("Not authorized to list groups"));
243
+ }
244
+ else if (res.status >= 500) {
245
+ console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
246
+ }
247
+ else {
248
+ console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
249
+ }
250
+ process.exit(1);
251
+ }
252
+ const data = await res.json();
253
+ if (data.groups.length === 0) {
254
+ console.log(chalk.gray("No groups in this company yet."));
255
+ return;
256
+ }
257
+ const idW = Math.max(8, ...data.groups.map((g) => g.groupId.length));
258
+ const nameW = Math.max(4, ...data.groups.map((g) => g.name.length));
259
+ const descW = Math.max(11, ...data.groups.map((g) => (g.description ?? "").length));
260
+ console.log(chalk.bold([
261
+ "GROUP_ID".padEnd(idW),
262
+ "NAME".padEnd(nameW),
263
+ "DESCRIPTION".padEnd(descW),
264
+ "CREATED_AT",
265
+ ].join(" ")));
266
+ for (const g of data.groups) {
267
+ console.log([
268
+ g.groupId.padEnd(idW),
269
+ g.name.padEnd(nameW),
270
+ (g.description ?? "").padEnd(descW),
271
+ shortDate(g.createdAt),
272
+ ].join(" "));
273
+ }
274
+ }
275
+ catch (err) {
276
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
277
+ process.exit(1);
278
+ }
279
+ });
280
+ groups
281
+ .command("members <groupId>")
282
+ .description("List members of a group")
283
+ .action(async (groupId) => {
284
+ try {
285
+ if (!GROUP_ID_PATTERN.test(groupId)) {
286
+ console.error(chalk.red(`Invalid group id '${groupId}': must match grp_<alphanumeric>`));
287
+ process.exit(1);
288
+ }
289
+ const token = await ensureCognitoToken();
290
+ const companySlug = groups.opts().company;
291
+ const companyUid = await getCompanyUid(token, companySlug);
292
+ const res = await vaultApiFetch({
293
+ token,
294
+ path: `/secrets/${encodeURIComponent(companyUid)}/groups/members`,
295
+ query: { groupId },
296
+ });
297
+ if (!res.ok) {
298
+ const err = await res.json().catch(() => ({}));
299
+ if (res.status === 401) {
300
+ console.error(chalk.red("Not authenticated — please run `hq login`"));
301
+ }
302
+ else if (res.status === 403) {
303
+ console.error(chalk.red("Not authorized to view group members"));
304
+ }
305
+ else if (res.status === 404) {
306
+ console.error(chalk.red(`Group not found: ${groupId}`));
307
+ }
308
+ else if (res.status >= 500) {
309
+ console.error(chalk.red(`Server error: ${err.error ?? res.statusText}`));
310
+ }
311
+ else {
312
+ console.error(chalk.red(err.message ?? err.error ?? "Invalid request"));
313
+ }
314
+ process.exit(1);
315
+ }
316
+ const data = await res.json();
317
+ console.log(`Members of '${groupId}':`);
318
+ if (data.members.length === 0) {
319
+ console.log(chalk.gray("No members yet — use 'hq groups add' to add."));
320
+ return;
321
+ }
322
+ const uidW = Math.max(10, ...data.members.map((m) => m.personUid.length));
323
+ const byW = Math.max(8, ...data.members.map((m) => m.addedBy.length));
324
+ console.log(chalk.bold([
325
+ "PERSON_UID".padEnd(uidW),
326
+ "ADDED_BY".padEnd(byW),
327
+ "ADDED_AT",
328
+ ].join(" ")));
329
+ for (const m of data.members) {
330
+ console.log([
331
+ m.personUid.padEnd(uidW),
332
+ m.addedBy.padEnd(byW),
333
+ shortDate(m.addedAt),
334
+ ].join(" "));
335
+ }
336
+ }
337
+ catch (err) {
338
+ console.error(chalk.red("Error:"), err instanceof Error ? err.message : String(err));
339
+ process.exit(1);
340
+ }
341
+ });
342
+ }
343
+ //# sourceMappingURL=groups.js.map
344
+ //# debugId=e84b2c37-90d0-559c-ace0-2b08fb69eec5
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * hq modules list command (US-005)
3
3
  */
4
+
5
+ !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]="0ed2bacf-8934-5b52-a841-1eaa2bbcd8b8")}catch(e){}}();
4
6
  import * as path from 'path';
5
7
  import { findHqRoot, readManifest, readLock, getModulesDir } from '../utils/manifest.js';
6
8
  import { isRepo, getCurrentCommit, isBehindRemote } from '../utils/git.js';
@@ -69,4 +71,5 @@ export function registerListCommand(program) {
69
71
  }
70
72
  });
71
73
  }
72
- //# sourceMappingURL=list.js.map
74
+ //# sourceMappingURL=list.js.map
75
+ //# debugId=0ed2bacf-8934-5b52-a841-1eaa2bbcd8b8
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * hq login — opens browser for Cognito auth via Google OAuth
3
3
  */
4
+
5
+ !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]="31735154-208b-5544-85a4-22f8f0fbe415")}catch(e){}}();
4
6
  import chalk from 'chalk';
5
7
  import { browserLogin, loadCachedTokens, isExpiring } from '@indigoai-us/hq-cloud';
6
8
  import { DEFAULT_COGNITO } from '../utils/cognito-session.js';
@@ -41,4 +43,5 @@ export function registerLoginCommand(program) {
41
43
  }
42
44
  });
43
45
  }
44
- //# sourceMappingURL=login.js.map
46
+ //# sourceMappingURL=login.js.map
47
+ //# debugId=31735154-208b-5544-85a4-22f8f0fbe415
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * hq logout — clears cached Cognito session
3
3
  */
4
+
5
+ !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]="120038e8-9b88-59c3-821a-da21ccb1c365")}catch(e){}}();
4
6
  import chalk from 'chalk';
5
7
  import { clearCachedTokens, loadCachedTokens } from '@indigoai-us/hq-cloud';
6
8
  export function registerLogoutCommand(program) {
@@ -23,4 +25,5 @@ export function registerLogoutCommand(program) {
23
25
  }
24
26
  });
25
27
  }
26
- //# sourceMappingURL=logout.js.map
28
+ //# sourceMappingURL=logout.js.map
29
+ //# debugId=120038e8-9b88-59c3-821a-da21ccb1c365
@@ -18,6 +18,8 @@
18
18
  * If the cached token is missing or expired beyond the refresh window, the
19
19
  * browser-OAuth flow opens automatically.
20
20
  */
21
+
22
+ !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]="38856701-42d8-587b-9969-8da51ede7cd4")}catch(e){}}();
21
23
  import chalk from "chalk";
22
24
  import { runOnboardCli } from "@indigoai-us/hq-onboarding";
23
25
  import { DEFAULT_HQ_ROOT, ensureCognitoToken, buildVaultConfig, } from "../utils/cognito-session.js";
@@ -139,4 +141,5 @@ export function registerOnboardCommand(program) {
139
141
  }
140
142
  });
141
143
  }
142
- //# sourceMappingURL=onboard.js.map
144
+ //# sourceMappingURL=onboard.js.map
145
+ //# debugId=38856701-42d8-587b-9969-8da51ede7cd4
@@ -30,6 +30,8 @@
30
30
  * 7. Append entry to modules.yaml with strategy: package
31
31
  * 8. Run scan-packages.sh to wire contributions into host paths
32
32
  */
33
+
34
+ !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]="9c0fc9f1-9a26-5a3f-a795-7254534316d5")}catch(e){}}();
33
35
  import * as fs from 'fs';
34
36
  import * as os from 'os';
35
37
  import * as path from 'path';
@@ -510,4 +512,5 @@ export async function installPack(source, opts = {}) {
510
512
  fs.rmSync(tmpDir, { recursive: true, force: true });
511
513
  }
512
514
  }
513
- //# sourceMappingURL=pack-install.js.map
515
+ //# sourceMappingURL=pack-install.js.map
516
+ //# debugId=9c0fc9f1-9a26-5a3f-a795-7254534316d5
@@ -12,6 +12,8 @@
12
12
  * 8. Update packages/registry.yaml
13
13
  * 9. Print next-step message
14
14
  */
15
+
16
+ !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]="874fe8a4-2348-5f03-8600-c545cac13fc9")}catch(e){}}();
15
17
  import * as fs from 'fs';
16
18
  import * as os from 'os';
17
19
  import * as path from 'path';
@@ -153,4 +155,5 @@ async function installPackage(slug, company) {
153
155
  }
154
156
  }
155
157
  }
156
- //# sourceMappingURL=pkg-install.js.map
158
+ //# sourceMappingURL=pkg-install.js.map
159
+ //# debugId=874fe8a4-2348-5f03-8600-c545cac13fc9
@@ -3,6 +3,8 @@
3
3
  *
4
4
  * Graceful offline: if registry is unreachable, show cached data with a note.
5
5
  */
6
+
7
+ !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]="ce4886ce-109a-5ace-b8d9-4e5bed61978a")}catch(e){}}();
6
8
  import chalk from 'chalk';
7
9
  import { findHqRoot } from '../utils/hq-root.js';
8
10
  import { readRegistry } from '../utils/registry.js';
@@ -67,4 +69,5 @@ async function listPackages() {
67
69
  console.log(chalk.yellow('Note: Could not reach registry — showing cached data only.'));
68
70
  }
69
71
  }
70
- //# sourceMappingURL=pkg-list.js.map
72
+ //# sourceMappingURL=pkg-list.js.map
73
+ //# debugId=ce4886ce-109a-5ace-b8d9-4e5bed61978a
@@ -5,6 +5,8 @@
5
5
  * 2. Remove entry from packages/registry.yaml
6
6
  * 3. Print next-step message
7
7
  */
8
+
9
+ !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]="b54529d6-de12-595e-b1c7-ab50b9f22eb5")}catch(e){}}();
8
10
  import * as fs from 'fs';
9
11
  import * as path from 'path';
10
12
  import chalk from 'chalk';
@@ -50,4 +52,5 @@ async function removePackage(slug) {
50
52
  console.log(chalk.green(`\nRemoved ${slug}.`));
51
53
  console.log(chalk.cyan('Run /package-remove ' + slug + ' in Claude to clean up merged content.'));
52
54
  }
53
- //# sourceMappingURL=pkg-remove.js.map
55
+ //# sourceMappingURL=pkg-remove.js.map
56
+ //# debugId=b54529d6-de12-595e-b1c7-ab50b9f22eb5
@@ -4,6 +4,8 @@
4
4
  * If no slug: check all installed packages for updates.
5
5
  * If slug given: update only that package.
6
6
  */
7
+
8
+ !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]="3ef2968d-eb65-594b-a506-4314b70dd3dc")}catch(e){}}();
7
9
  import * as fs from 'fs';
8
10
  import * as os from 'os';
9
11
  import * as path from 'path';
@@ -121,4 +123,5 @@ async function updatePackages(slug) {
121
123
  }
122
124
  console.log(`\n${updatedCount} package(s) updated${updatedCount > 0 ? '.' : ' — everything is current.'}`);
123
125
  }
124
- //# sourceMappingURL=pkg-update.js.map
126
+ //# sourceMappingURL=pkg-update.js.map
127
+ //# debugId=3ef2968d-eb65-594b-a506-4314b70dd3dc
@@ -1,3 +1,12 @@
1
1
  import { Command } from "commander";
2
+ export interface VaultApiOptions {
3
+ token: string;
4
+ path: string;
5
+ method?: string;
6
+ body?: Record<string, unknown>;
7
+ query?: Record<string, string>;
8
+ }
9
+ export declare function vaultApiFetch(opts: VaultApiOptions): Promise<Response>;
10
+ export declare function getCompanyUid(token: string, companySlug: string | undefined): Promise<string>;
2
11
  export declare function registerSecretsCommand(program: Command): void;
3
12
  //# sourceMappingURL=secrets.d.ts.map