@indigoai-us/hq-cli 5.101.7 → 5.103.0

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,63 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.103.0] — 2026-08-18
6
+
7
+ ### Added
8
+
9
+ - `hq doctor` now checks the AI runtimes themselves, not just their hook
10
+ wiring. A new "AI runtime health" family verifies the `claude`, `codex`, and
11
+ `grok` CLIs are on PATH (a pure filesystem scan — the default run stays
12
+ offline; a missing CLI is WARN, never FAIL). A new `--live-runtimes` flag
13
+ additionally reads each installed CLI's version and sends it a one-line
14
+ prompt from a temp directory, proving the full binary → login → subscription
15
+ → response path; without the flag those checks report UNTESTED, so a
16
+ logged-out or broken runtime can no longer hide behind green wiring checks.
17
+
18
+ ## [5.102.0] — 2026-08-17
19
+
20
+ ### Added
21
+
22
+ - **`hq integrations` now covers the whole lifecycle**, not just using an
23
+ already-connected app. Previously the CLI could `list` / `tools` / `call` /
24
+ `approve` / `reject`, and everything else had to happen on the console.
25
+
26
+ Find and add:
27
+ - `hq integrations catalog [query]` (alias `search`) — browse or search
28
+ connectable apps, showing each one's sign-in style and provenance.
29
+ - `hq integrations inspect <app>` — surfaces, credentials, and warnings for
30
+ an app before you commit to it.
31
+ - `hq integrations discover <docsUrl>` — find a connectable server from a
32
+ documentation page.
33
+ - `hq integrations connect <app>` (alias `add`) — connect by domain, catalog
34
+ entry (`--entry-id`), docs page (`--docs-url`), or a raw endpoint
35
+ (`--mcp-url`). Auth mode is detected rather than declared: no-auth installs
36
+ directly, API-key apps read the key from `--token-stdin` / a hidden prompt
37
+ / `--token`, and OAuth apps run a browser sign-in. If hq-pro answers
38
+ `INTEGRATION_FACTORY_OAUTH_REQUIRED` to a direct install, the browser flow
39
+ starts automatically.
40
+ - `hq integrations reconnect [app]` — re-authenticate an app whose stored
41
+ credentials stopped working.
42
+
43
+ Govern and remove:
44
+ - `hq integrations show [app]` — one connection in full.
45
+ - `hq integrations policy [app] [--set auto-allow|confirm|deny]`.
46
+ - `hq integrations grants|grant|ungrant` — per-tool approval exceptions.
47
+ - `hq integrations access|share|unshare` — who in the company may use an app.
48
+ - `hq integrations audit` / `pending` — recent activity and queued approvals.
49
+ - `hq integrations disconnect [app]` (alias `remove`) — deletes stored
50
+ credentials; confirms first, and refuses non-interactively without `--yes`.
51
+
52
+ OAuth sign-in uses an RFC 8252 §7.3 loopback listener (`127.0.0.1`, ephemeral
53
+ port, pinned callback path), so the code never leaves the machine and the
54
+ PKCE verifier stays server-side in hq-pro. Against a backend that does not
55
+ admit a loopback callback, connect degrades to printing the sign-in URL for
56
+ the console to finish, and says so rather than reporting a false success.
57
+
58
+ Requires hq-pro with `INTEGRATION_FACTORY_OAUTH_LOOPBACK_ENABLED` for the
59
+ fully CLI-native OAuth path; every other verb works against any current
60
+ deployment.
61
+
5
62
  ## [5.101.7] — 2026-08-17
6
63
 
7
64
  ### Changed
@@ -15,6 +15,9 @@
15
15
  * hq agents start|stop <uid> — EC2 start/stop
16
16
  * hq agents retry <uid> — resume setup from first non-done step
17
17
  * hq agents rm <uid> --yes — deprovision (destructive; flag-guarded)
18
+ * hq agents jobs list <uid> — off-box job roster (schedule + rate)
19
+ * hq agents jobs pause <uid> <jobId> — flip schedule State=DISABLED
20
+ * hq agents jobs cancel <uid> <jobId> — delete schedule + drop the job
18
21
  *
19
22
  * Agents are company-scoped. `--company <slug>` may sit on the group
20
23
  * (`hq agents --company acme list`) or on a subcommand
@@ -204,6 +207,46 @@ export declare function deprovisionAgent(token: string, agentUid: string): Promi
204
207
  setupState?: string;
205
208
  terminal?: boolean;
206
209
  }>;
210
+ /** EventBridge Scheduler State as the operator list/pause surface reports it. */
211
+ export type JobScheduleState = "ENABLED" | "DISABLED";
212
+ /** One operator list row from `GET /v1/agents/{uid}/jobs`. */
213
+ export interface AgentJobView {
214
+ jobId: string;
215
+ scheduleState: JobScheduleState | string;
216
+ rate: string;
217
+ lastRunOutcome: string | null;
218
+ status?: string;
219
+ nextRunAt?: string | null;
220
+ lastRunAt?: string | null;
221
+ prompt?: string;
222
+ }
223
+ export interface PauseJobResult {
224
+ ok: true;
225
+ jobId: string;
226
+ scheduleState: "DISABLED" | string;
227
+ changed: boolean;
228
+ previousState?: string;
229
+ }
230
+ export interface CancelJobResult {
231
+ ok: true;
232
+ jobId: string;
233
+ }
234
+ export declare function listAgentJobs(token: string, agentUid: string): Promise<AgentJobView[]>;
235
+ export declare function pauseAgentJob(token: string, agentUid: string, jobId: string): Promise<PauseJobResult>;
236
+ export declare function cancelAgentJob(token: string, agentUid: string, jobId: string): Promise<CancelJobResult>;
237
+ /**
238
+ * Map a jobs-control HTTP error to a single operator-facing line. Pure so the
239
+ * status/code → copy mapping is unit-tested without a process exit.
240
+ *
241
+ * 404 without `JOB_NOT_FOUND` is also the deploy-order-safe path: hq-cli
242
+ * shipped before the hq-pro endpoints exist (or the agents flag is OFF, or
243
+ * the agent is cross-company) must print a clear message and exit non-zero,
244
+ * never throw a stack trace.
245
+ */
246
+ export declare function formatJobsHttpError(err: AgentsHttpError, jobId?: string): string;
247
+ /** Stable padEnd table: jobId, scheduleState, rate, lastRunOutcome, status. */
248
+ export declare function formatJobsTable(jobs: AgentJobView[]): string;
249
+ export declare function formatPauseResult(result: PauseJobResult): string;
207
250
  /** Human-readable "hot-applied to the running box" vs "saved for next launch". */
208
251
  export declare function appliedHint(applied: boolean): string;
209
252
  /** One message in a DM thread, as returned by `GET /v1/notify/thread`. */
@@ -15,6 +15,9 @@
15
15
  * hq agents start|stop <uid> — EC2 start/stop
16
16
  * hq agents retry <uid> — resume setup from first non-done step
17
17
  * hq agents rm <uid> --yes — deprovision (destructive; flag-guarded)
18
+ * hq agents jobs list <uid> — off-box job roster (schedule + rate)
19
+ * hq agents jobs pause <uid> <jobId> — flip schedule State=DISABLED
20
+ * hq agents jobs cancel <uid> <jobId> — delete schedule + drop the job
18
21
  *
19
22
  * Agents are company-scoped. `--company <slug>` may sit on the group
20
23
  * (`hq agents --company acme list`) or on a subcommand
@@ -309,6 +312,79 @@ export async function deprovisionAgent(token, agentUid) {
309
312
  method: "DELETE",
310
313
  });
311
314
  }
315
+ export async function listAgentJobs(token, agentUid) {
316
+ const data = await agentsRequest({
317
+ token,
318
+ path: `/v1/agents/${encodeURIComponent(agentUid)}/jobs`,
319
+ });
320
+ return data.jobs ?? [];
321
+ }
322
+ export async function pauseAgentJob(token, agentUid, jobId) {
323
+ return agentsRequest({
324
+ token,
325
+ path: `/v1/agents/${encodeURIComponent(agentUid)}/jobs/${encodeURIComponent(jobId)}/pause`,
326
+ method: "POST",
327
+ });
328
+ }
329
+ export async function cancelAgentJob(token, agentUid, jobId) {
330
+ return agentsRequest({
331
+ token,
332
+ path: `/v1/agents/${encodeURIComponent(agentUid)}/jobs/${encodeURIComponent(jobId)}/cancel`,
333
+ method: "POST",
334
+ });
335
+ }
336
+ /**
337
+ * Map a jobs-control HTTP error to a single operator-facing line. Pure so the
338
+ * status/code → copy mapping is unit-tested without a process exit.
339
+ *
340
+ * 404 without `JOB_NOT_FOUND` is also the deploy-order-safe path: hq-cli
341
+ * shipped before the hq-pro endpoints exist (or the agents flag is OFF, or
342
+ * the agent is cross-company) must print a clear message and exit non-zero,
343
+ * never throw a stack trace.
344
+ */
345
+ export function formatJobsHttpError(err, jobId) {
346
+ if (err.status === 401)
347
+ return "Not authenticated — run `hq login`.";
348
+ if (err.status === 403)
349
+ return "You need owner/admin on this company.";
350
+ if (err.status === 404 && err.code === "JOB_NOT_FOUND") {
351
+ const id = jobId ?? extractQuotedJobId(err.message) ?? "unknown";
352
+ return `Job '${id}' not found.`;
353
+ }
354
+ if (err.status === 404)
355
+ return "Agent not found or not accessible.";
356
+ if (err.code === "JOBS_SCHEDULER_UNAVAILABLE" ||
357
+ err.code === "SCHEDULE_DELETE_FAILED") {
358
+ return `${err.code}: ${err.message}`;
359
+ }
360
+ return err.message;
361
+ }
362
+ function extractQuotedJobId(message) {
363
+ const m = message.match(/Job '([^']+)'/i);
364
+ return m?.[1];
365
+ }
366
+ /** Stable padEnd table: jobId, scheduleState, rate, lastRunOutcome, status. */
367
+ export function formatJobsTable(jobs) {
368
+ if (jobs.length === 0)
369
+ return "No jobs.";
370
+ const cols = ["JOB_ID", "STATE", "RATE", "LAST_RUN", "STATUS"];
371
+ const rows = jobs.map((j) => [
372
+ j.jobId,
373
+ String(j.scheduleState ?? ""),
374
+ j.rate ?? "",
375
+ j.lastRunOutcome ?? "-",
376
+ j.status ?? "",
377
+ ]);
378
+ const widths = cols.map((c, i) => Math.max(c.length, ...rows.map((r) => r[i].length)));
379
+ const render = (cells) => cells.map((cell, i) => cell.padEnd(widths[i])).join(" ");
380
+ return [chalk.bold(render(cols)), ...rows.map(render)].join("\n");
381
+ }
382
+ export function formatPauseResult(result) {
383
+ if (!result.changed)
384
+ return "Already paused";
385
+ const from = result.previousState ?? "ENABLED";
386
+ return `Paused ${result.jobId} (${from} → ${result.scheduleState})`;
387
+ }
312
388
  /** Human-readable "hot-applied to the running box" vs "saved for next launch". */
313
389
  export function appliedHint(applied) {
314
390
  return applied
@@ -394,6 +470,13 @@ function fail(err) {
394
470
  }
395
471
  process.exit(1);
396
472
  }
473
+ function failJobs(err, jobId) {
474
+ if (err instanceof AgentsHttpError) {
475
+ console.error(chalk.red(formatJobsHttpError(err, jobId)));
476
+ process.exit(1);
477
+ }
478
+ fail(err);
479
+ }
397
480
  export function registerAgentsCommand(program) {
398
481
  const agents = program
399
482
  .command("agents")
@@ -842,5 +925,59 @@ export function registerAgentsCommand(program) {
842
925
  fail(err);
843
926
  }
844
927
  });
928
+ // Off-box job control (US-003). Nested group so `hq agents jobs --help`
929
+ // lists list|pause|cancel. Same vaultApiFetch + person JWT as the rest of
930
+ // this file; keyed HQ_API_KEY rewrites /v1/agents → /v1/keys/agents.
931
+ const jobs = agents
932
+ .command("jobs")
933
+ .description("List, pause, or cancel an agent's scheduled jobs");
934
+ jobs
935
+ .command("list <agentUid>")
936
+ .description("List an agent's scheduled jobs")
937
+ .option("--json", "Emit raw JSON")
938
+ .action(async (agentUid, opts) => {
939
+ try {
940
+ const token = (await resolveVaultCredential()).token;
941
+ const roster = await listAgentJobs(token, agentUid);
942
+ if (opts.json) {
943
+ process.stdout.write(JSON.stringify(roster, null, 2) + "\n");
944
+ return;
945
+ }
946
+ if (roster.length === 0) {
947
+ console.log(chalk.gray("No jobs."));
948
+ return;
949
+ }
950
+ console.log(formatJobsTable(roster));
951
+ }
952
+ catch (err) {
953
+ failJobs(err);
954
+ }
955
+ });
956
+ jobs
957
+ .command("pause <agentUid> <jobId>")
958
+ .description("Pause a job's schedule (reversible)")
959
+ .action(async (agentUid, jobId) => {
960
+ try {
961
+ const token = (await resolveVaultCredential()).token;
962
+ const result = await pauseAgentJob(token, agentUid, jobId);
963
+ console.log(chalk.green(formatPauseResult(result)));
964
+ }
965
+ catch (err) {
966
+ failJobs(err, jobId);
967
+ }
968
+ });
969
+ jobs
970
+ .command("cancel <agentUid> <jobId>")
971
+ .description("Cancel a job and delete its schedule")
972
+ .action(async (agentUid, jobId) => {
973
+ try {
974
+ const token = (await resolveVaultCredential()).token;
975
+ const result = await cancelAgentJob(token, agentUid, jobId);
976
+ console.log(chalk.green(`Cancelled ${result.jobId}.`));
977
+ }
978
+ catch (err) {
979
+ failJobs(err, jobId);
980
+ }
981
+ });
845
982
  }
846
983
  //# sourceMappingURL=agents.js.map
@@ -8,7 +8,9 @@
8
8
  * - Running outside any HQ tree exits non-zero with a message naming exactly
9
9
  * what it looked for — never a throw, never a false PASS.
10
10
  * - The command performs no network calls and needs no authentication; it is
11
- * purely a function of the on-disk shape of the tree.
11
+ * purely a function of the on-disk shape of the tree. `--live-runtimes` is
12
+ * the one opt-in exception: it probes the installed AI CLIs (claude, codex,
13
+ * grok) with a version read and a one-line prompt.
12
14
  *
13
15
  * US-015 adds reporting, `--json`, and the exit-code contract: the exit code is
14
16
  * 0 unless some result is FAIL or UNKNOWN (WARN/UNTESTED/NA/KNOWN-DEFECT never
@@ -77,6 +79,13 @@ export interface RunDoctorOptions {
77
79
  * does — so a plain `hq doctor` stays purely a function of the on-disk shape.
78
80
  */
79
81
  deepTest?: boolean;
82
+ /**
83
+ * Additionally probe each installed AI CLI (claude, codex, grok) with a
84
+ * version read and a one-line prompt (`--live-runtimes`). Off by default:
85
+ * this is the doctor's only networked tier, and without it the runtime-health
86
+ * family reports UNTESTED rather than spawning anything.
87
+ */
88
+ liveRuntimes?: boolean;
80
89
  }
81
90
  /** The outcome of a doctor run, returned rather than thrown so it is testable. */
82
91
  export interface RunDoctorResult {
@@ -8,7 +8,9 @@
8
8
  * - Running outside any HQ tree exits non-zero with a message naming exactly
9
9
  * what it looked for — never a throw, never a false PASS.
10
10
  * - The command performs no network calls and needs no authentication; it is
11
- * purely a function of the on-disk shape of the tree.
11
+ * purely a function of the on-disk shape of the tree. `--live-runtimes` is
12
+ * the one opt-in exception: it probes the installed AI CLIs (claude, codex,
13
+ * grok) with a version read and a one-line prompt.
12
14
  *
13
15
  * US-015 adds reporting, `--json`, and the exit-code contract: the exit code is
14
16
  * 0 unless some result is FAIL or UNKNOWN (WARN/UNTESTED/NA/KNOWN-DEFECT never
@@ -99,6 +101,7 @@ export async function runDoctor(options = {}) {
99
101
  hqRoot,
100
102
  platform: { id: platform.id, evidence: platform.evidence },
101
103
  sessionId: options.sessionId,
104
+ liveRuntimes: options.liveRuntimes === true,
102
105
  };
103
106
  const families = await registry.run(context);
104
107
  // `--deep-test` (US-008): after the read-only tiers, actually fire pure-guard
@@ -147,12 +150,13 @@ export async function runDoctor(options = {}) {
147
150
  export function registerDoctorCommand(program) {
148
151
  program
149
152
  .command("doctor")
150
- .description("Verify HQ hook guardrails are wired and firing (read-only, offline).")
153
+ .description("Verify HQ hook guardrails are wired and firing (read-only, offline; --live-runtimes adds networked AI CLI probes).")
151
154
  .option("--json", "Emit the machine-readable JSON document (no colour).")
152
155
  .option("--verbose", "Also print every PASS result in text output.")
153
156
  .option("--no-color", "Disable ANSI colour even on a TTY.")
154
157
  .option("--session-id <id>", "Scope the runtime probe's ledger check to this exact session.")
155
158
  .option("--deep-test", "Also fire pure-guard hooks through the real gate under all three profiles (sandboxed).")
159
+ .option("--live-runtimes", "Also probe each installed AI CLI (claude, codex, grok) with a one-line prompt to verify login and subscription (networked; uses your subscriptions).")
156
160
  .option("--fix", "Apply the allowlisted safe repairs (backs up first; read-only without this flag).")
157
161
  .option("--yes", "Skip the interactive --fix confirmation (non-interactive use).")
158
162
  .option("--force", "Let --fix run despite uncommitted changes under .claude/, .codex/, or .grok/.")
@@ -199,6 +203,7 @@ export function registerDoctorCommand(program) {
199
203
  platform,
200
204
  sessionId: opts.sessionId,
201
205
  deepTest: opts.deepTest === true,
206
+ liveRuntimes: opts.liveRuntimes === true,
202
207
  });
203
208
  // Set the exit code rather than calling process.exit, so the CLI's
204
209
  // normal shutdown (telemetry flush) still runs. Non-zero means either an
@@ -0,0 +1,216 @@
1
+ /**
2
+ * Typed client for hq-pro's integration-factory routes.
3
+ *
4
+ * One function per endpoint, each a thin `vaultApiFetch` + `raiseForResponse`
5
+ * pair. The wire shapes below MIRROR hq-pro (`src/vault-service/handlers/
6
+ * integrations-admin.ts`) rather than importing from it — hq-cli takes no
7
+ * cross-repo source dependency — so every field a newer backend might not emit
8
+ * is optional and read defensively.
9
+ */
10
+ import { type GranteeType, type Permission, type WriteAllowlistGrant, type WritePolicy } from "./integrations-core.js";
11
+ export interface CatalogEntry {
12
+ name: string;
13
+ domain: string;
14
+ description?: string;
15
+ /** True when the app is one-click connectable (has a remote MCP surface). */
16
+ mcpReady: boolean;
17
+ scope?: "company" | "global";
18
+ /**
19
+ * Provenance: `integrations.sh` is the curated third-party feed,
20
+ * `hq-recommended` is first-party, `hq-discovered` is a Community definition
21
+ * learned from a successful connect elsewhere.
22
+ */
23
+ source?: "hq-discovered" | "integrations.sh" | "hq-recommended";
24
+ authClass?: "none" | "key" | "oauth";
25
+ /** Opaque server-owned id; prefer it over echoing connection details back. */
26
+ entryId?: string;
27
+ }
28
+ export declare function listCatalog(token: string, companyUid: string, opts?: {
29
+ limit?: number;
30
+ query?: string;
31
+ }): Promise<CatalogEntry[]>;
32
+ export interface BlueprintSurface {
33
+ kind: string;
34
+ slug: string;
35
+ name: string;
36
+ url?: string;
37
+ docs?: string;
38
+ authStatus: "required" | "optional" | "none" | "unknown";
39
+ credentialIds: string[];
40
+ readiness: {
41
+ strategy: string;
42
+ score: number;
43
+ reason: string;
44
+ };
45
+ }
46
+ export interface Blueprint {
47
+ provider: string;
48
+ displayName: string;
49
+ domain: string;
50
+ summary?: string;
51
+ description?: string;
52
+ credentials: Array<{
53
+ id: string;
54
+ type: string;
55
+ label: string;
56
+ generateUrl?: string;
57
+ }>;
58
+ surfaces: BlueprintSurface[];
59
+ recommendedSurface?: BlueprintSurface;
60
+ warnings: Array<{
61
+ code: string;
62
+ message: string;
63
+ source?: string;
64
+ }>;
65
+ }
66
+ export declare function pullBlueprint(token: string, companyUid: string, input: {
67
+ domain?: string;
68
+ query?: string;
69
+ catalogEntryId?: string;
70
+ }): Promise<Blueprint>;
71
+ export interface DocsDiscovery {
72
+ docsUrl: string;
73
+ displayName: string;
74
+ provider: string;
75
+ mcpUrl: string;
76
+ authMode: "none" | "bearer" | "oauth";
77
+ transport: string;
78
+ verification: "verified" | "pending-auth";
79
+ confidence: "high" | "medium";
80
+ evidenceUrls: string[];
81
+ }
82
+ export interface DiscoverDocsResult {
83
+ /** Absent when hq-pro verified no MCP surface on the page. */
84
+ discovery?: DocsDiscovery;
85
+ /**
86
+ * Caller- and company-bound continuation token. Passing this to connect is
87
+ * what lets hq-pro trust the endpoint WITHOUT re-reading a URL the terminal
88
+ * echoed back at it. Short-lived (~15 min).
89
+ */
90
+ discoveryReceiptId?: string;
91
+ sourceTruncated?: boolean;
92
+ }
93
+ export declare function discoverDocs(token: string, companyUid: string, docsUrl: string): Promise<DiscoverDocsResult>;
94
+ export interface InstallResult {
95
+ connection: {
96
+ id: string;
97
+ provider: string;
98
+ status: string;
99
+ scopes?: string[];
100
+ };
101
+ installation: {
102
+ id: string;
103
+ displayName: string;
104
+ domain: string;
105
+ status: "installed" | "needs_credentials";
106
+ surface?: {
107
+ kind?: string;
108
+ url?: string;
109
+ authStatus?: string;
110
+ };
111
+ };
112
+ mcp?: {
113
+ tools?: Array<{
114
+ name: string;
115
+ description?: string;
116
+ mode?: string;
117
+ }>;
118
+ };
119
+ credential?: {
120
+ required: boolean;
121
+ configured: boolean;
122
+ authStatus?: string;
123
+ };
124
+ writeAllowlist?: WriteAllowlistGrant[];
125
+ }
126
+ export interface InstallInput {
127
+ domain?: string;
128
+ query?: string;
129
+ catalogEntryId?: string;
130
+ discoveryReceiptId?: string;
131
+ mcpUrl?: string;
132
+ provider?: string;
133
+ displayName?: string;
134
+ docsUrl?: string;
135
+ authMode?: "none" | "bearer";
136
+ bearerToken?: string;
137
+ }
138
+ export declare function installIntegration(token: string, companyUid: string, input: InstallInput): Promise<InstallResult>;
139
+ export declare function uninstallIntegration(token: string, companyUid: string, installationId: string): Promise<{
140
+ installationId: string;
141
+ connectionId: string;
142
+ }>;
143
+ export interface OAuthStartResult {
144
+ provider: string;
145
+ displayName: string;
146
+ /** The remote auth server's authorize URL — open this in a browser. */
147
+ authorizationUrl: string;
148
+ state: string;
149
+ expiresAt: string;
150
+ }
151
+ export interface OAuthStartInput {
152
+ mcpUrl?: string;
153
+ catalogEntryId?: string;
154
+ discoveryReceiptId?: string;
155
+ provider?: string;
156
+ displayName?: string;
157
+ domain?: string;
158
+ docsUrl?: string;
159
+ /**
160
+ * The native client's loopback callback. hq-pro accepts it only when its
161
+ * loopback flag is on and the URI matches the pinned RFC 8252 §7.3 shape;
162
+ * omitting it pins the console callback instead.
163
+ */
164
+ redirectUri?: string;
165
+ }
166
+ export declare function startOAuth(token: string, companyUid: string, input: OAuthStartInput): Promise<OAuthStartResult>;
167
+ export declare function completeOAuth(token: string, companyUid: string, input: {
168
+ state: string;
169
+ code: string;
170
+ }): Promise<InstallResult>;
171
+ export declare function updateGovernance(token: string, companyUid: string, input: {
172
+ connectionId: string;
173
+ writePolicy?: WritePolicy;
174
+ /**
175
+ * REPLACES the connection's whole per-tool allowlist — hq-pro has no
176
+ * add/remove verb. Callers must read the current list, merge, and send the
177
+ * full result, never a delta.
178
+ */
179
+ writeAllowlist?: WriteAllowlistGrant[];
180
+ }): Promise<{
181
+ writePolicy?: WritePolicy;
182
+ writeAllowlist: WriteAllowlistGrant[];
183
+ }>;
184
+ export interface ConnectionAccess {
185
+ connectionId: string;
186
+ provider: string;
187
+ creator: {
188
+ uid: string;
189
+ name?: string | null;
190
+ };
191
+ /** True when the connection predates access control and has no ACL row. */
192
+ grandfathered: boolean;
193
+ /** Whether THIS caller may grant/revoke. */
194
+ canManage: boolean;
195
+ access: {
196
+ mode: string;
197
+ grantCount: number;
198
+ };
199
+ entries: Array<{
200
+ granteeType: GranteeType;
201
+ granteeId: string;
202
+ granteeName?: string | null;
203
+ permission: Permission;
204
+ grantedBy: string;
205
+ grantedByName?: string | null;
206
+ grantedAt: string;
207
+ }>;
208
+ }
209
+ export declare function getConnectionAccess(token: string, companyUid: string, connectionId: string): Promise<ConnectionAccess>;
210
+ export declare function mutateConnectionAccess(token: string, companyUid: string, action: "grant" | "revoke", input: {
211
+ connectionId: string;
212
+ granteeType: GranteeType;
213
+ granteeId?: string;
214
+ permission?: Permission;
215
+ }): Promise<ConnectionAccess>;
216
+ //# sourceMappingURL=integrations-api.d.ts.map