@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 +57 -0
- package/dist/commands/agents.d.ts +43 -0
- package/dist/commands/agents.js +137 -0
- package/dist/commands/doctor.d.ts +10 -1
- package/dist/commands/doctor.js +7 -2
- package/dist/commands/integrations-api.d.ts +216 -0
- package/dist/commands/integrations-api.js +135 -0
- package/dist/commands/integrations-connect.d.ts +30 -0
- package/dist/commands/integrations-connect.js +583 -0
- package/dist/commands/integrations-core.d.ts +216 -0
- package/dist/commands/integrations-core.js +320 -0
- package/dist/commands/integrations-manage.d.ts +50 -0
- package/dist/commands/integrations-manage.js +556 -0
- package/dist/commands/integrations-oauth.d.ts +43 -0
- package/dist/commands/integrations-oauth.js +159 -0
- package/dist/commands/integrations.d.ts +32 -69
- package/dist/commands/integrations.js +42 -262
- package/dist/commands/reindex.js +1 -1
- package/dist/lib/doctor/checks/runtime-health.d.ts +100 -0
- package/dist/lib/doctor/checks/runtime-health.js +336 -0
- package/dist/lib/doctor/registry.js +6 -0
- package/dist/lib/doctor/types.d.ts +7 -0
- package/dist/utils/self-update.d.ts +2 -2
- package/dist/utils/self-update.js +19 -3
- package/dist/utils/version-gate.d.ts +34 -3
- package/dist/utils/version-gate.js +61 -4
- package/package.json +1 -1
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`. */
|
package/dist/commands/agents.js
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
|
|
@@ -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 {
|
package/dist/commands/doctor.js
CHANGED
|
@@ -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
|