@indigoai-us/hq-cli 5.103.3 → 5.103.5

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.103.5] — 2026-08-19
6
+
7
+ ## [5.103.4] — 2026-08-19
8
+
5
9
  ## [5.103.3] — 2026-08-19
6
10
 
7
11
  ## [5.103.2] — 2026-08-19
@@ -435,7 +435,7 @@ export function registerConnectCommands(integrations) {
435
435
  .command("catalog [query]")
436
436
  .alias("search")
437
437
  .description("Browse or search apps you can connect")
438
- .option("--company <slug>", "Company slug")
438
+ .option("--company <slug>", "Company slug, e.g. indigo")
439
439
  .option("--limit <n>", "How many entries to show (max 100)", "60")
440
440
  .option("--json", "Machine-readable output")
441
441
  .action(async (query, opts) => {
@@ -484,7 +484,7 @@ export function registerConnectCommands(integrations) {
484
484
  integrations
485
485
  .command("inspect <app>")
486
486
  .description("Show what an app exposes before you connect it")
487
- .option("--company <slug>", "Company slug")
487
+ .option("--company <slug>", "Company slug, e.g. indigo")
488
488
  .option("--json", "Machine-readable output")
489
489
  .action(async (app, opts) => {
490
490
  const token = await ensureCognitoIdToken();
@@ -511,7 +511,7 @@ export function registerConnectCommands(integrations) {
511
511
  integrations
512
512
  .command("discover <docsUrl>")
513
513
  .description("Find a connectable server from an app's documentation page")
514
- .option("--company <slug>", "Company slug")
514
+ .option("--company <slug>", "Company slug, e.g. indigo")
515
515
  .option("--json", "Machine-readable output")
516
516
  .action(async (docsUrl, opts) => {
517
517
  const token = await ensureCognitoIdToken();
@@ -536,7 +536,7 @@ export function registerConnectCommands(integrations) {
536
536
  .command("connect [app]")
537
537
  .alias("add")
538
538
  .description("Connect an app — by domain, catalog entry, docs page, or MCP URL")
539
- .option("--company <slug>", "Company slug")
539
+ .option("--company <slug>", "Company slug, e.g. indigo")
540
540
  .option("--entry-id <id>", "Catalog entry id (from `hq integrations catalog --json`)")
541
541
  .option("--mcp-url <url>", "Connect a specific MCP endpoint directly")
542
542
  .option("--docs-url <url>", "Find the endpoint from a documentation page first")
@@ -592,7 +592,7 @@ export function registerConnectCommands(integrations) {
592
592
  integrations
593
593
  .command("reconnect [app]")
594
594
  .description("Re-authenticate a connected app whose credentials stopped working")
595
- .option("--company <slug>", "Company slug")
595
+ .option("--company <slug>", "Company slug, e.g. indigo")
596
596
  .option("--provider <slug>", "Connected app (e.g. linear)")
597
597
  .option("--connection <id>", "Connection id (acct_…)")
598
598
  .option("--token <key>", "API key (prefer --token-stdin)")
@@ -26,6 +26,22 @@ const POLICY_BLURB = {
26
26
  confirm: "a company owner approves each change first",
27
27
  deny: "changes are refused",
28
28
  };
29
+ /**
30
+ * hq-pro seeds a connection's default write grant as a company-wide entry with
31
+ * granteeId `"*"` (seedFactoryWriteGrants), and its grant validation rejects an
32
+ * EMPTY granteeId even for company-wide. So a company-wide write grant must
33
+ * carry `"*"` — not `""`. Using `""` made `grant --to everyone` fail with
34
+ * "Invalid writeAllowlist entry" and `ungrant --from everyone` never match the
35
+ * seeded entry ("nothing to remove"). Person/group/email grantees carry a real
36
+ * id and are unaffected.
37
+ */
38
+ const COMPANY_WIDE_GRANTEE_ID = "*";
39
+ /** The write-allowlist granteeId for a principal (company-wide is the wildcard). */
40
+ function writeGrantGranteeId(principal) {
41
+ return principal.granteeType === "company-wide"
42
+ ? COMPANY_WIDE_GRANTEE_ID
43
+ : (principal.granteeId ?? "");
44
+ }
29
45
  /**
30
46
  * Parse a grantee from the one string a person would actually type.
31
47
  *
@@ -116,7 +132,7 @@ export function registerManageCommands(integrations) {
116
132
  integrations
117
133
  .command("show [app]")
118
134
  .description("Show one connected app in full")
119
- .option("--company <slug>", "Company slug")
135
+ .option("--company <slug>", "Company slug, e.g. indigo")
120
136
  .option("--provider <slug>", "Connected app (e.g. linear)")
121
137
  .option("--connection <id>", "Connection id (acct_…)")
122
138
  .option("--json", "Machine-readable output")
@@ -158,7 +174,7 @@ export function registerManageCommands(integrations) {
158
174
  integrations
159
175
  .command("policy [app]")
160
176
  .description("Show or change whether an app's changes need approval")
161
- .option("--company <slug>", "Company slug")
177
+ .option("--company <slug>", "Company slug, e.g. indigo")
162
178
  .option("--provider <slug>", "Connected app (e.g. linear)")
163
179
  .option("--connection <id>", "Connection id (acct_…)")
164
180
  .option("--set <mode>", "auto-allow, confirm, or deny")
@@ -205,7 +221,7 @@ export function registerManageCommands(integrations) {
205
221
  integrations
206
222
  .command("grants [app]")
207
223
  .description("Show who is authorized to run an app's change-making tools")
208
- .option("--company <slug>", "Company slug")
224
+ .option("--company <slug>", "Company slug, e.g. indigo")
209
225
  .option("--provider <slug>", "Connected app (e.g. linear)")
210
226
  .option("--connection <id>", "Connection id (acct_…)")
211
227
  .option("--json", "Machine-readable output")
@@ -245,7 +261,7 @@ export function registerManageCommands(integrations) {
245
261
  integrations
246
262
  .command("grant [app]")
247
263
  .description("Authorize someone to run one of an app's change-making tools")
248
- .option("--company <slug>", "Company slug")
264
+ .option("--company <slug>", "Company slug, e.g. indigo")
249
265
  .option("--provider <slug>", "Connected app (e.g. linear)")
250
266
  .option("--connection <id>", "Connection id (acct_…)")
251
267
  .requiredOption("--tool <name>", "The tool to authorize")
@@ -271,7 +287,7 @@ export function registerManageCommands(integrations) {
271
287
  const snapshot = connection.writeAllowlist ?? [];
272
288
  const merged = mergeGrant(snapshot, toolName, {
273
289
  granteeType: principal.granteeType,
274
- granteeId: principal.granteeId ?? "",
290
+ granteeId: writeGrantGranteeId(principal),
275
291
  permission: opts.permission,
276
292
  });
277
293
  const result = await patchAllowlistIfUnchanged(token, companyUid, connection.id, snapshot, merged);
@@ -284,7 +300,7 @@ export function registerManageCommands(integrations) {
284
300
  integrations
285
301
  .command("ungrant [app]")
286
302
  .description("Remove a per-tool authorization, leaving only the app's default access")
287
- .option("--company <slug>", "Company slug")
303
+ .option("--company <slug>", "Company slug, e.g. indigo")
288
304
  .option("--provider <slug>", "Connected app (e.g. linear)")
289
305
  .option("--connection <id>", "Connection id (acct_…)")
290
306
  .requiredOption("--tool <name>", "The tool to stop authorizing")
@@ -314,7 +330,7 @@ export function registerManageCommands(integrations) {
314
330
  integrations
315
331
  .command("access [app]")
316
332
  .description("Show who in the company can use a connected app")
317
- .option("--company <slug>", "Company slug")
333
+ .option("--company <slug>", "Company slug, e.g. indigo")
318
334
  .option("--provider <slug>", "Connected app (e.g. linear)")
319
335
  .option("--connection <id>", "Connection id (acct_…)")
320
336
  .option("--json", "Machine-readable output")
@@ -332,7 +348,7 @@ export function registerManageCommands(integrations) {
332
348
  integrations
333
349
  .command("share [app]")
334
350
  .description("Let someone in the company use a connected app")
335
- .option("--company <slug>", "Company slug")
351
+ .option("--company <slug>", "Company slug, e.g. indigo")
336
352
  .option("--provider <slug>", "Connected app (e.g. linear)")
337
353
  .option("--connection <id>", "Connection id (acct_…)")
338
354
  .requiredOption("--with <principal>", "Email, uid, or `everyone`")
@@ -362,7 +378,7 @@ export function registerManageCommands(integrations) {
362
378
  integrations
363
379
  .command("unshare [app]")
364
380
  .description("Stop someone from using a connected app")
365
- .option("--company <slug>", "Company slug")
381
+ .option("--company <slug>", "Company slug, e.g. indigo")
366
382
  .option("--provider <slug>", "Connected app (e.g. linear)")
367
383
  .option("--connection <id>", "Connection id (acct_…)")
368
384
  .requiredOption("--from <principal>", "Email, uid, or `everyone`")
@@ -387,7 +403,7 @@ export function registerManageCommands(integrations) {
387
403
  integrations
388
404
  .command("audit")
389
405
  .description("Recent activity across the company's connected apps")
390
- .option("--company <slug>", "Company slug")
406
+ .option("--company <slug>", "Company slug, e.g. indigo")
391
407
  .option("--provider <slug>", "Only this app")
392
408
  .option("--limit <n>", "How many events to show", "20")
393
409
  .option("--json", "Machine-readable output")
@@ -430,7 +446,7 @@ export function registerManageCommands(integrations) {
430
446
  integrations
431
447
  .command("pending")
432
448
  .description("Calls that were queued for an owner's approval")
433
- .option("--company <slug>", "Company slug")
449
+ .option("--company <slug>", "Company slug, e.g. indigo")
434
450
  .option("--json", "Machine-readable output")
435
451
  .action(async (opts) => {
436
452
  const token = await ensureCognitoIdToken();
@@ -470,7 +486,7 @@ export function registerManageCommands(integrations) {
470
486
  .command("disconnect [app]")
471
487
  .alias("remove")
472
488
  .description("Disconnect an app and delete its stored credentials")
473
- .option("--company <slug>", "Company slug")
489
+ .option("--company <slug>", "Company slug, e.g. indigo")
474
490
  .option("--provider <slug>", "Connected app (e.g. linear)")
475
491
  .option("--connection <id>", "Connection id (acct_…)")
476
492
  .option("--yes", "Skip the confirmation prompt")
@@ -557,7 +573,7 @@ export function mergeGrant(current, toolName, entry) {
557
573
  * dropped entirely rather than persisted as an empty rule.
558
574
  */
559
575
  export function removeGrant(current, toolName, principal) {
560
- const granteeId = principal.granteeId ?? "";
576
+ const granteeId = writeGrantGranteeId(principal);
561
577
  let removed = false;
562
578
  const next = [];
563
579
  for (const grant of current) {
@@ -16,7 +16,7 @@
16
16
  * hq integrations reconnect [app] Re-authenticate a broken app.
17
17
  *
18
18
  * Use:
19
- * hq integrations list Connected apps for the company.
19
+ * hq integrations list --company indigo Connected apps for a company.
20
20
  * hq integrations show [app] One app in full.
21
21
  * hq integrations tools --provider <p> What the connected app can do.
22
22
  * hq integrations call <tool> --provider <p> --args '<json>'
@@ -35,8 +35,10 @@
35
35
  * outcome is surfaced clearly with the exact approve command to run.
36
36
  *
37
37
  * Auth: Cognito ID token via the shared session cache (`hq auth refresh`
38
- * semantics); company resolves like every other command — `--company <slug>`
39
- * or the caller's single active membership. Never hardcoded.
38
+ * semantics); company resolves like every other command — pass a company SLUG
39
+ * with `--company <slug>` (e.g. `--company indigo`), which is preferred over a
40
+ * raw `cmp_…` uid, or rely on the caller's single active membership. Never
41
+ * hardcoded.
40
42
  *
41
43
  * Shared primitives (error taxonomy, HTTP guards, connection resolution) live
42
44
  * in `integrations-core.ts` and are re-exported below so existing importers
@@ -16,7 +16,7 @@
16
16
  * hq integrations reconnect [app] Re-authenticate a broken app.
17
17
  *
18
18
  * Use:
19
- * hq integrations list Connected apps for the company.
19
+ * hq integrations list --company indigo Connected apps for a company.
20
20
  * hq integrations show [app] One app in full.
21
21
  * hq integrations tools --provider <p> What the connected app can do.
22
22
  * hq integrations call <tool> --provider <p> --args '<json>'
@@ -35,8 +35,10 @@
35
35
  * outcome is surfaced clearly with the exact approve command to run.
36
36
  *
37
37
  * Auth: Cognito ID token via the shared session cache (`hq auth refresh`
38
- * semantics); company resolves like every other command — `--company <slug>`
39
- * or the caller's single active membership. Never hardcoded.
38
+ * semantics); company resolves like every other command — pass a company SLUG
39
+ * with `--company <slug>` (e.g. `--company indigo`), which is preferred over a
40
+ * raw `cmp_…` uid, or rely on the caller's single active membership. Never
41
+ * hardcoded.
40
42
  *
41
43
  * Shared primitives (error taxonomy, HTTP guards, connection resolution) live
42
44
  * in `integrations-core.ts` and are re-exported below so existing importers
@@ -58,7 +60,7 @@ export function registerIntegrationsCommand(program) {
58
60
  integrations
59
61
  .command("list")
60
62
  .description("List the company's connected apps")
61
- .option("--company <slug>", "Company slug (defaults to your single active company)")
63
+ .option("--company <slug>", "Company slug, e.g. indigo (defaults to your single active company)")
62
64
  .option("--json", "Machine-readable output")
63
65
  .action(async (opts) => {
64
66
  const token = await ensureCognitoIdToken();
@@ -90,7 +92,7 @@ export function registerIntegrationsCommand(program) {
90
92
  .description("List what a connected app can do")
91
93
  .option("--provider <slug>", "Connected app (e.g. linear)")
92
94
  .option("--connection <id>", "Connection id (acct_…)")
93
- .option("--company <slug>", "Company slug")
95
+ .option("--company <slug>", "Company slug, e.g. indigo")
94
96
  .option("--json", "Machine-readable output")
95
97
  .action(async (opts) => {
96
98
  const token = await ensureCognitoIdToken();
@@ -123,7 +125,7 @@ export function registerIntegrationsCommand(program) {
123
125
  .description("Call one of a connected app's tools (approval-gated when it changes things)")
124
126
  .option("--provider <slug>", "Connected app (e.g. linear)")
125
127
  .option("--connection <id>", "Connection id (acct_…)")
126
- .option("--company <slug>", "Company slug")
128
+ .option("--company <slug>", "Company slug, e.g. indigo")
127
129
  .option("--args <json>", "Tool arguments as JSON", "{}")
128
130
  .option("--idempotency-key <key>", "Stable key so retries execute at most once (default: generated)")
129
131
  .option("--json", "Machine-readable output")
@@ -188,7 +190,7 @@ export function registerIntegrationsCommand(program) {
188
190
  : "Reject a queued call (owner only)")
189
191
  .option("--provider <slug>", "Connected app (e.g. linear)")
190
192
  .option("--connection <id>", "Connection id (acct_…)")
191
- .option("--company <slug>", "Company slug")
193
+ .option("--company <slug>", "Company slug, e.g. indigo")
192
194
  .option("--json", "Machine-readable output")
193
195
  .action(async (queueId, opts) => {
194
196
  const token = await ensureCognitoIdToken();
@@ -368,10 +368,12 @@ async function resolveCompanyFromMemberships(token) {
368
368
  if (active.length === 1) {
369
369
  return active[0].companyUid;
370
370
  }
371
- const uids = active.map((m) => m.companyUid);
372
- throw new CompanySelectionError(`Multiple active companies found. Re-run with --company <slug-or-uid> to ` +
371
+ // Prefer the slug (the documented `--company` input) over the raw uid; fall
372
+ // back to the uid only when the server did not enrich a slug.
373
+ const picks = active.map((m) => ` --company ${m.companySlug ?? m.companyUid}`);
374
+ throw new CompanySelectionError(`Multiple active companies found. Re-run with --company <slug> to ` +
373
375
  `pick one:\n` +
374
- uids.map((u) => ` --company ${u}`).join('\n'));
376
+ picks.join('\n'));
375
377
  }
376
378
  export async function getCompanyUid(token, companySlug) {
377
379
  // Vault API keys are company-bound. Entity slug resolution has no keyed
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.103.3",
3
+ "version": "5.103.5",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {