@indigoai-us/hq-cli 5.103.2 → 5.103.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.
package/CHANGELOG.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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 —
|
|
39
|
-
*
|
|
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
|
|
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 —
|
|
39
|
-
*
|
|
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")
|
|
@@ -172,10 +174,11 @@ export function registerIntegrationsCommand(program) {
|
|
|
172
174
|
// A tool that ran but FAILED (`isError: true`) still has its payload
|
|
173
175
|
// printed — the error text is the useful part — but the command exits
|
|
174
176
|
// non-zero so a script or agent can tell failure from success without
|
|
175
|
-
// parsing output. The
|
|
176
|
-
//
|
|
177
|
+
// parsing output. The gateway double-wraps the provider result as a
|
|
178
|
+
// text-content string, so `isError` lands on the UNWRAPPED payload, not
|
|
179
|
+
// on the raw envelope; check both levels so either shape is caught.
|
|
177
180
|
printJson(payload);
|
|
178
|
-
if (gatewayResultIsError(message.result)) {
|
|
181
|
+
if (gatewayResultIsError(payload) || gatewayResultIsError(message.result)) {
|
|
179
182
|
process.exitCode = 1;
|
|
180
183
|
}
|
|
181
184
|
});
|
|
@@ -187,7 +190,7 @@ export function registerIntegrationsCommand(program) {
|
|
|
187
190
|
: "Reject a queued call (owner only)")
|
|
188
191
|
.option("--provider <slug>", "Connected app (e.g. linear)")
|
|
189
192
|
.option("--connection <id>", "Connection id (acct_…)")
|
|
190
|
-
.option("--company <slug>", "Company slug")
|
|
193
|
+
.option("--company <slug>", "Company slug, e.g. indigo")
|
|
191
194
|
.option("--json", "Machine-readable output")
|
|
192
195
|
.action(async (queueId, opts) => {
|
|
193
196
|
const token = await ensureCognitoIdToken();
|