@indigoai-us/hq-cli 5.345.165 → 5.345.166
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 +9 -0
- package/assets/scaffold/core/scripts/rebuild-all-indexes.sh +11 -0
- package/assets/scaffold/core/scripts/rebuild-orchestrator-index.sh +11 -0
- package/assets/scaffold/core/scripts/rebuild-public-knowledge-index.sh +11 -0
- package/assets/scaffold/core/scripts/rebuild-reports-index.sh +11 -0
- package/assets/scaffold/core/scripts/rebuild-social-drafts-index.sh +11 -0
- package/assets/scaffold/core/scripts/rebuild-threads-index.sh +11 -0
- package/assets/scaffold/core/scripts/rebuild-workers-index.sh +11 -0
- package/dist/commands/integrations-api.d.ts +15 -0
- package/dist/commands/integrations-api.js +27 -0
- package/dist/commands/integrations-manage.js +4 -2
- package/dist/commands/integrations.js +9 -5
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +210 -197
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/lib/doctor/checks/sync-runtime.d.ts +7 -2
- package/dist/lib/doctor/checks/sync-runtime.js +1 -3
- package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
- package/dist/lib/flag-registry-worker-source.generated.js +1 -1
- package/dist/lib/index-render/index.d.ts +5 -0
- package/dist/lib/index-render/index.js +22 -1
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.166] — 2026-10-24
|
|
6
|
+
- `hq integrations approve` now says why an approved call did not run. When an app refuses it, the CLI prints the app's own reason, such as Slack's refusal to send into a Slack Connect channel. Before this it printed only "failed (rejected)". With an older server it prints the rejection code instead. `hq integrations pending --history` adds a `Why:` line for decided calls that did not run. The approve command printed after a queued call keeps `--company` when you passed it. Before printing, the reason is cleaned of terminal escape codes, credentials and credential-bearing links, and it is capped at 500 characters. Feedback 15e7593c-50e5-4e6a-ae3a-342d618363c0.
|
|
7
|
+
- The bundled sync engine now uses hq-cloud 6.18.101, the current npm `latest`.
|
|
8
|
+
A 403 from the flags endpoint (for example a stale company in the local
|
|
9
|
+
manifest) is now held as `false` for an hour instead of being re-read and
|
|
10
|
+
logged on every telemetry pass (hq-cloud #1046).
|
|
11
|
+
- `hq doctor` no longer counts runner telemetry errors as sync receiver permission refusals. A failed outcome-flag read ("hq-flags: resolve returned 403") for a company you are not a member of used to inflate `sync.runtime.receiver-permission`; only the receiver's own events are counted now.
|
|
12
|
+
- The bundled shell fallbacks for `rebuild-index` all, orchestrator, public-knowledge, reports, social-drafts, threads, and workers now print the same usage as the native command for `--help`/`-h` and exit without writing. Before, they ignored the flag and rebuilt the index, which failed the published core command parity check.
|
|
13
|
+
|
|
5
14
|
## [5.345.165] — 2026-10-23
|
|
6
15
|
- `hq billing sponsor grant <email|prs_id> --company <slug>` lets a company owner or admin put a member's personal plan on the company bill without a request first; `--all-members` does it for every active member and reports each person as covered, already covered, or skipped. `hq billing sponsor ungrant <email|prs_id>` takes it off again. hq-pro checks the owner/admin role and active membership.
|
|
7
16
|
- `hq scan secrets <files...>` takes `--repo <dir>`, which applies that repo's committed `.gitleaks.toml` allowlists to a file scan, matching each file by its path relative to the repo, as a staged scan does. `--snapshot-root <dir>` (with `--repo`) matches files laid out as `<dir>/<commit>/<repo path>`, the history copies `commit-secret-scan.sh pr-check` writes, as `<repo path>`. Findings still name the files as given. Before this, a file scan ignored the repo's allowlists, so pr-check failed on false positives the commit gate already allowed. Without `--repo` a file scan is unchanged.
|
|
@@ -11,6 +11,17 @@
|
|
|
11
11
|
|
|
12
12
|
set -uo pipefail
|
|
13
13
|
|
|
14
|
+
# Help must never write: print the same usage as `hq core rebuild-index all --help`.
|
|
15
|
+
for arg in "$@"; do
|
|
16
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
17
|
+
printf '%s\n' \
|
|
18
|
+
'Usage: hq core rebuild-index all [--accept]' \
|
|
19
|
+
'' \
|
|
20
|
+
'Regenerate every INDEX.md across the HQ tree. Help performs no writes.'
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
done
|
|
24
|
+
|
|
14
25
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
15
26
|
cd "$HQ_ROOT"
|
|
16
27
|
|
|
@@ -12,6 +12,17 @@
|
|
|
12
12
|
|
|
13
13
|
set -euo pipefail
|
|
14
14
|
|
|
15
|
+
# Help must never write: print the same usage as `hq core rebuild-index orchestrator --help`.
|
|
16
|
+
for arg in "$@"; do
|
|
17
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
18
|
+
printf '%s\n' \
|
|
19
|
+
'Usage: hq core rebuild-index orchestrator [--accept]' \
|
|
20
|
+
'' \
|
|
21
|
+
'Regenerate the orchestrator workspace INDEX.md. Help performs no writes.'
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
done
|
|
25
|
+
|
|
15
26
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
16
27
|
cd "$HQ_ROOT"
|
|
17
28
|
|
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
|
|
10
|
+
# Help must never write: print the same usage as `hq core rebuild-index public-knowledge --help`.
|
|
11
|
+
for arg in "$@"; do
|
|
12
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
13
|
+
printf '%s\n' \
|
|
14
|
+
'Usage: hq core rebuild-index public-knowledge [--accept]' \
|
|
15
|
+
'' \
|
|
16
|
+
'Regenerate core/knowledge/public/INDEX.md. Help performs no writes.'
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
done
|
|
20
|
+
|
|
10
21
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
11
22
|
cd "$HQ_ROOT"
|
|
12
23
|
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
set -euo pipefail
|
|
10
10
|
|
|
11
|
+
# Help must never write: print the same usage as `hq core rebuild-index reports --help`.
|
|
12
|
+
for arg in "$@"; do
|
|
13
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
14
|
+
printf '%s\n' \
|
|
15
|
+
'Usage: hq core rebuild-index reports [--accept]' \
|
|
16
|
+
'' \
|
|
17
|
+
'Regenerate the reports INDEX.md. Help performs no writes.'
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
done
|
|
21
|
+
|
|
11
22
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
12
23
|
cd "$HQ_ROOT"
|
|
13
24
|
|
|
@@ -8,6 +8,17 @@
|
|
|
8
8
|
|
|
9
9
|
set -euo pipefail
|
|
10
10
|
|
|
11
|
+
# Help must never write: print the same usage as `hq core rebuild-index social-drafts --help`.
|
|
12
|
+
for arg in "$@"; do
|
|
13
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
14
|
+
printf '%s\n' \
|
|
15
|
+
'Usage: hq core rebuild-index social-drafts [--accept]' \
|
|
16
|
+
'' \
|
|
17
|
+
'Regenerate workspace/social-drafts/INDEX.md. Help performs no writes.'
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
done
|
|
21
|
+
|
|
11
22
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
12
23
|
# shellcheck source=core/scripts/lib/portable.sh
|
|
13
24
|
. "$HQ_ROOT/core/scripts/lib/portable.sh"
|
|
@@ -11,6 +11,17 @@
|
|
|
11
11
|
|
|
12
12
|
set -euo pipefail
|
|
13
13
|
|
|
14
|
+
# Help must never write: print the same usage as `hq core rebuild-index threads --help`.
|
|
15
|
+
for arg in "$@"; do
|
|
16
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
17
|
+
printf '%s\n' \
|
|
18
|
+
'Usage: hq core rebuild-index threads [--accept]' \
|
|
19
|
+
'' \
|
|
20
|
+
'Regenerate the session-threads INDEX.md. Help performs no writes.'
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
done
|
|
24
|
+
|
|
14
25
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
15
26
|
cd "$HQ_ROOT"
|
|
16
27
|
|
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
|
|
8
8
|
set -euo pipefail
|
|
9
9
|
|
|
10
|
+
# Help must never write: print the same usage as `hq core rebuild-index workers --help`.
|
|
11
|
+
for arg in "$@"; do
|
|
12
|
+
if [[ "$arg" == "--help" || "$arg" == "-h" ]]; then
|
|
13
|
+
printf '%s\n' \
|
|
14
|
+
'Usage: hq core rebuild-index workers [--accept]' \
|
|
15
|
+
'' \
|
|
16
|
+
'Regenerate the workers INDEX.md. Help performs no writes.'
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
done
|
|
20
|
+
|
|
10
21
|
HQ_ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
11
22
|
cd "$HQ_ROOT"
|
|
12
23
|
|
|
@@ -292,6 +292,10 @@ export interface PendingApproval {
|
|
|
292
292
|
status?: string;
|
|
293
293
|
/** Owner-facing outcome projected by hq-pro for decided rows. */
|
|
294
294
|
outcome?: string;
|
|
295
|
+
/** Closed rejection code for a rejected row (e.g. provider_tool_error); older servers omit it. */
|
|
296
|
+
rejectionReason?: string | null;
|
|
297
|
+
/** Plain reason a decided row did not run, such as the app's own refusal text; older servers omit it. */
|
|
298
|
+
failureMessage?: string | null;
|
|
295
299
|
}
|
|
296
300
|
/**
|
|
297
301
|
* Read open approvals from hq-pro's confirm-queue state (not the audit feed).
|
|
@@ -307,4 +311,15 @@ export declare function mutateConnectionAccess(token: string, companyUid: string
|
|
|
307
311
|
granteeId?: string;
|
|
308
312
|
permission?: Permission;
|
|
309
313
|
}): Promise<ConnectionAccess>;
|
|
314
|
+
/** Same cap the server applies to a failure reason; the CLI enforces it for older or malformed responses. */
|
|
315
|
+
export declare const TERMINAL_REASON_MAX_CHARS = 500;
|
|
316
|
+
/**
|
|
317
|
+
* Server-supplied text that reaches the terminal (a failure reason quoting an
|
|
318
|
+
* app's error). ANSI escapes, control and invisible formatting characters are
|
|
319
|
+
* removed, then the same credential-redaction chain the gateway diagnostics use
|
|
320
|
+
* (`redactErrorText`: credential URLs, bearer values, token assignments, known
|
|
321
|
+
* token shapes) is applied, and the result is capped. The server redacts too;
|
|
322
|
+
* this keeps an older or misbehaving server from printing a secret.
|
|
323
|
+
*/
|
|
324
|
+
export declare function terminalSafeText(text: string): string;
|
|
310
325
|
//# sourceMappingURL=integrations-api.d.ts.map
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* is optional and read defensively.
|
|
9
9
|
*/
|
|
10
10
|
import { vaultApiFetch } from "../utils/vault-api.js";
|
|
11
|
+
import { redactErrorText } from "../utils/redact-error-text.js";
|
|
11
12
|
import { IntegrationsCliError, raiseForResponse, } from "./integrations-core.js";
|
|
12
13
|
export async function listCatalog(token, companyUid, opts = {}) {
|
|
13
14
|
const query = {
|
|
@@ -188,4 +189,30 @@ export async function mutateConnectionAccess(token, companyUid, action, input) {
|
|
|
188
189
|
}
|
|
189
190
|
return (await res.json());
|
|
190
191
|
}
|
|
192
|
+
// eslint-disable-next-line no-control-regex
|
|
193
|
+
const TERMINAL_ESCAPES = /\u001b\[[0-?]*[ -/]*[@-~]|\u001b\][^\u0007\u001b]*(?:\u0007|\u001b\\)?|\u001b[@-_]/g;
|
|
194
|
+
// eslint-disable-next-line no-control-regex
|
|
195
|
+
const TERMINAL_CONTROL_CHARS = /[\u0000-\u0008\u000b-\u001f\u007f-\u009f]/g;
|
|
196
|
+
/** Bidirectional overrides, isolates, marks and zero-width characters, which can reorder or hide text. */
|
|
197
|
+
const TERMINAL_INVISIBLE_FORMAT_CHARS = /[\u200b-\u200f\u202a-\u202e\u2060-\u2069\ufeff]/g;
|
|
198
|
+
/** Same cap the server applies to a failure reason; the CLI enforces it for older or malformed responses. */
|
|
199
|
+
export const TERMINAL_REASON_MAX_CHARS = 500;
|
|
200
|
+
/**
|
|
201
|
+
* Server-supplied text that reaches the terminal (a failure reason quoting an
|
|
202
|
+
* app's error). ANSI escapes, control and invisible formatting characters are
|
|
203
|
+
* removed, then the same credential-redaction chain the gateway diagnostics use
|
|
204
|
+
* (`redactErrorText`: credential URLs, bearer values, token assignments, known
|
|
205
|
+
* token shapes) is applied, and the result is capped. The server redacts too;
|
|
206
|
+
* this keeps an older or misbehaving server from printing a secret.
|
|
207
|
+
*/
|
|
208
|
+
export function terminalSafeText(text) {
|
|
209
|
+
const visible = text
|
|
210
|
+
.replace(TERMINAL_ESCAPES, "")
|
|
211
|
+
.replace(TERMINAL_CONTROL_CHARS, "")
|
|
212
|
+
.replace(TERMINAL_INVISIBLE_FORMAT_CHARS, "");
|
|
213
|
+
const redacted = redactErrorText(visible);
|
|
214
|
+
return redacted.length > TERMINAL_REASON_MAX_CHARS
|
|
215
|
+
? `${redacted.slice(0, TERMINAL_REASON_MAX_CHARS - 1)}…`
|
|
216
|
+
: redacted;
|
|
217
|
+
}
|
|
191
218
|
//# sourceMappingURL=integrations-api.js.map
|
|
@@ -18,7 +18,7 @@ import { ensureCognitoIdToken } from "../utils/cognito-session.js";
|
|
|
18
18
|
import { getCompanyUid } from "../utils/vault-api.js";
|
|
19
19
|
import { redactSensitiveUrl, redactUrlsInText } from "../utils/redact-url.js";
|
|
20
20
|
import { IntegrationsCliError, bareProvider, printHealthNotice, fetchConnections, fetchAdminSurface, fetchAuditPage, AUDIT_PAGE_MAX, printJson, revokedConnectionDetails, resolveConnection, selectConnection, } from "./integrations-core.js";
|
|
21
|
-
import { fetchPendingApprovals, getConnectionAccess, mutateConnectionAccess, purgeConnection, setReadSafe, uninstallIntegration, updateGovernance, } from "./integrations-api.js";
|
|
21
|
+
import { fetchPendingApprovals, getConnectionAccess, mutateConnectionAccess, purgeConnection, setReadSafe, terminalSafeText, uninstallIntegration, updateGovernance, } from "./integrations-api.js";
|
|
22
22
|
const WRITE_POLICIES = ["auto-allow", "confirm", "deny"];
|
|
23
23
|
const PERMISSIONS = ["read", "write", "admin"];
|
|
24
24
|
/** Plain-English gloss for each write policy, used in every policy readout. */
|
|
@@ -617,9 +617,11 @@ export function registerManageCommands(integrations) {
|
|
|
617
617
|
console.log(`${chalk.bold(label)} ${chalk.dim(`${who} · ${row.createdAt}`)}`);
|
|
618
618
|
if (opts.history) {
|
|
619
619
|
console.log(chalk.dim(` ${row.queueId} · ${row.status ?? row.outcome ?? "status unavailable"}`));
|
|
620
|
+
if (row.failureMessage)
|
|
621
|
+
console.log(chalk.dim(` Why: ${terminalSafeText(row.failureMessage)}`));
|
|
620
622
|
}
|
|
621
623
|
else {
|
|
622
|
-
console.log(chalk.dim(` hq integrations approve ${row.queueId}${row.provider ? ` --provider ${bareProvider(row.provider)}` : ""}`));
|
|
624
|
+
console.log(chalk.dim(` hq integrations approve ${row.queueId}${row.provider ? ` --provider ${bareProvider(row.provider)}` : ""}${opts.company ? ` --company ${opts.company}` : ""}`));
|
|
623
625
|
}
|
|
624
626
|
}
|
|
625
627
|
});
|
|
@@ -61,7 +61,7 @@ import { registerConnectCommands } from "./integrations-connect.js";
|
|
|
61
61
|
import { registerImportCommands } from "./integrations-import.js";
|
|
62
62
|
import { registerManageCommands } from "./integrations-manage.js";
|
|
63
63
|
import { registerSlackCommands } from "./integrations-slack.js";
|
|
64
|
-
import { fetchPendingApprovals } from "./integrations-api.js";
|
|
64
|
+
import { fetchPendingApprovals, terminalSafeText } from "./integrations-api.js";
|
|
65
65
|
const CALL_ARGS_EXAMPLE = `--args '{"assignee":"me"}' or --args-file args.json`;
|
|
66
66
|
function readStream(stream) {
|
|
67
67
|
return new Promise((resolve, reject) => {
|
|
@@ -533,7 +533,7 @@ export function registerIntegrationsCommand(program) {
|
|
|
533
533
|
return;
|
|
534
534
|
}
|
|
535
535
|
console.log(chalk.yellow("Queued for approval — this call can change the app, so a company owner decides first."));
|
|
536
|
-
console.log(`Approve with:\n hq integrations approve ${queued.queueId} --provider ${bareProvider(connection.provider)}`);
|
|
536
|
+
console.log(`Approve with:\n hq integrations approve ${queued.queueId} --provider ${bareProvider(connection.provider)}${opts.company ? ` --company ${opts.company}` : ""}`);
|
|
537
537
|
if (queued.expiresAt) {
|
|
538
538
|
console.log(chalk.dim(`Expires ${queued.expiresAt}`));
|
|
539
539
|
}
|
|
@@ -606,7 +606,9 @@ export function registerIntegrationsCommand(program) {
|
|
|
606
606
|
const unknown = terminal.status === "write_unknown" || terminal.outcome === "unknown";
|
|
607
607
|
console.log(chalk.red(unknown
|
|
608
608
|
? `The provider outcome is unknown for ${queueId}. Check the provider before taking any action; ${historyCommand} shows the latest queue state.`
|
|
609
|
-
:
|
|
609
|
+
: terminal.failureMessage
|
|
610
|
+
? `The approved call did not run: ${terminalSafeText(terminal.failureMessage)}`
|
|
611
|
+
: `The approved call failed (${terminal.rejectionReason ?? terminal.status ?? terminal.outcome}). See ${historyCommand} for its status.`));
|
|
610
612
|
}
|
|
611
613
|
else if (terminal.status === "resumed" || terminal.status === "completed" || terminal.outcome === "ran") {
|
|
612
614
|
console.log(chalk.green("Approved — the call completed."));
|
|
@@ -614,7 +616,7 @@ export function registerIntegrationsCommand(program) {
|
|
|
614
616
|
printJson(unwrapGatewayResult(stored.result));
|
|
615
617
|
}
|
|
616
618
|
else if (ran) {
|
|
617
|
-
console.log(chalk.yellow(`The call's result could not be read back. Run \`hq integrations approve ${queueId}\` again to fetch it; the call will not run twice.`));
|
|
619
|
+
console.log(chalk.yellow(`The call's result could not be read back. Run \`hq integrations approve ${queueId} --provider ${bareProvider(connection.provider)}${opts.company ? ` --company ${opts.company}` : ""}\` again to fetch it; the call will not run twice.`));
|
|
618
620
|
}
|
|
619
621
|
}
|
|
620
622
|
else {
|
|
@@ -649,7 +651,9 @@ export function registerIntegrationsCommand(program) {
|
|
|
649
651
|
if (failed) {
|
|
650
652
|
const reason = body.rejectionReason ??
|
|
651
653
|
(toolError ? "provider_tool_error" : body.outcome ?? body.status ?? "failed");
|
|
652
|
-
console.log(chalk.red(
|
|
654
|
+
console.log(chalk.red(body.failureMessage
|
|
655
|
+
? `The approved call did not run: ${terminalSafeText(body.failureMessage)}`
|
|
656
|
+
: `The approved call failed at the provider (${reason}).`));
|
|
653
657
|
}
|
|
654
658
|
else if (body.status === "resumed" || body.status === "completed" || body.outcome === "ran") {
|
|
655
659
|
console.log(chalk.green(`Approved — the call ran (status: ${body.status ?? body.outcome}).`));
|