@indigoai-us/hq-cli 5.345.187 → 5.345.188
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 +14 -0
- package/dist/commands/agent-inbox.js +43 -11
- package/dist/commands/agent-mcp.js +5 -2
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +34414 -49801
- package/dist/hq-cloud-sync-runner/package.json +1 -1
- package/dist/lib/agent-kit/inbox-fetch.d.ts +92 -0
- package/dist/lib/agent-kit/inbox-fetch.js +135 -0
- package/dist/lib/agent-kit/mcp/tools.d.ts +11 -2
- package/dist/lib/agent-kit/mcp/tools.js +17 -3
- package/dist/utils/cognito-session.d.ts +1 -1
- package/dist/utils/cognito-session.js +16 -4
- package/package.json +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.188] — 2026-10-30
|
|
6
|
+
- `hq agent inbox` and the `hq_inbox_read` MCP tool now bound the server read (token mint plus GET) at 30 s
|
|
7
|
+
(`HQ_AGENT_INBOX_TIMEOUT_MS`, floor 1000) and retry it once after a short delay, honouring the server's
|
|
8
|
+
numeric `Retry-After` up to 5 s, when the token mint is held by another process, the request times out or
|
|
9
|
+
fails in transport, or the server answers 408, 425, 429, 500, 502 or 503. A 504 is left to the existing
|
|
10
|
+
single retry inside the API client, and a 401, 403, 404 or an invalid 200 body is not retried. The
|
|
11
|
+
deadline now reaches the hq-cloud mint, so a retry no longer queues behind a first mint that is still
|
|
12
|
+
waiting on another process's lock. The list command sets `HQ_MACHINE_CREDS_FILE`,
|
|
13
|
+
`HQ_REQUIRE_MACHINE_IDENTITY` and `HQ_VAULT_API_URL` before minting, as `hq agent inbox done` already did.
|
|
14
|
+
The JSON output gains `stale: true|false` next to `source`; whenever a retry happened, including one that
|
|
15
|
+
succeeded, it also carries `attempts: 2`, and a note that still reports a fallback ends with
|
|
16
|
+
"(after 2 attempts)", so automation can tell a hard failure from a single blip (DEV-4065).
|
|
17
|
+
- Keep downloaded revisions current and retry locally deleted files until the cloud confirms their removal.
|
|
18
|
+
|
|
5
19
|
## [5.345.187] — 2026-10-30
|
|
6
20
|
- The HQ Anywhere person gate now follows the desktop Settings key `hq-anywhere-opt-out`. Turning HQ Anywhere on in the app enables `hq mcp serve` without a separate `hq-anywhere` write. Older servers that only have `hq-anywhere` still work.
|
|
7
21
|
|
|
@@ -8,6 +8,7 @@ import chalk from "chalk";
|
|
|
8
8
|
import * as os from "node:os";
|
|
9
9
|
import { ensureCognitoToken } from "../utils/cognito-session.js";
|
|
10
10
|
import { vaultApiFetch } from "../utils/vault-api.js";
|
|
11
|
+
import { annotateInboxAttempts, fetchServerInboxWithRetry, parseRetryAfterSeconds, resolveAgentInboxTimeoutMs } from "../lib/agent-kit/inbox-fetch.js";
|
|
11
12
|
import { redactAgentInboxItem } from "../lib/agent-kit/inbox-redact.js";
|
|
12
13
|
import { markInboxDone, mergeAgentInbox, readDoneIds, summarizeInboxEntry } from "../lib/agent-kit/inbox-state.js";
|
|
13
14
|
import { agentKitPaths } from "../lib/agent-kit/paths.js";
|
|
@@ -23,25 +24,56 @@ export function registerAgentInboxCommand(agent) {
|
|
|
23
24
|
const paths = agentKitPaths(os.homedir(), process.env);
|
|
24
25
|
const creds = requireExternalCreds(paths);
|
|
25
26
|
const done = readDoneIds(paths);
|
|
27
|
+
// Pin the enrolled machine identity and API, as `done` does below, so the
|
|
28
|
+
// mint cannot fall through to a person session or another API base.
|
|
29
|
+
process.env.HQ_MACHINE_CREDS_FILE = paths.machineCredsPath;
|
|
30
|
+
process.env.HQ_REQUIRE_MACHINE_IDENTITY = "1";
|
|
31
|
+
process.env.HQ_VAULT_API_URL = creds.apiBaseUrl;
|
|
26
32
|
// Merged with the server, never the local mirror alone: a dead kit
|
|
27
33
|
// poller would otherwise make this command answer confidently with
|
|
28
|
-
// yesterday's mail and no sign anything was wrong.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
// yesterday's mail and no sign anything was wrong. The server read is
|
|
35
|
+
// bounded and retried once (inbox-fetch.ts) so a shared-lock mint, a
|
|
36
|
+
// 503 with Retry-After or a hung socket does not become a fallback.
|
|
37
|
+
let attempts = 1;
|
|
38
|
+
const merged = await mergeAgentInbox(paths, async () => {
|
|
39
|
+
const outcome = await fetchServerInboxWithRetry({
|
|
40
|
+
timeoutMs: resolveAgentInboxTimeoutMs(process.env),
|
|
41
|
+
mint: (signal) => ensureCognitoToken({ tokenSource: "machine", interactive: false, signal }),
|
|
42
|
+
fetch: async (token, signal) => {
|
|
43
|
+
const res = await vaultApiFetch({
|
|
44
|
+
token,
|
|
45
|
+
baseUrl: creds.apiBaseUrl,
|
|
46
|
+
path: `/v1/agents/${encodeURIComponent(creds.entityUid)}/inbox`,
|
|
47
|
+
signal,
|
|
48
|
+
});
|
|
49
|
+
const retryAfterSeconds = parseRetryAfterSeconds(res.headers?.get?.("retry-after"));
|
|
50
|
+
// Preserve a decode failure as an invalid body for mergeAgentInbox to
|
|
51
|
+
// classify. Parser errors can contain response bytes: do not echo them.
|
|
52
|
+
return {
|
|
53
|
+
status: res.status,
|
|
54
|
+
body: await res.json().catch(() => undefined),
|
|
55
|
+
...(retryAfterSeconds !== undefined ? { retryAfterSeconds } : {}),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
35
58
|
});
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
59
|
+
attempts = outcome.attempts;
|
|
60
|
+
if (!outcome.ok)
|
|
61
|
+
throw outcome.error;
|
|
62
|
+
return outcome.response;
|
|
39
63
|
});
|
|
64
|
+
const { entries, note, source, stale, attempts: attemptsMade } = annotateInboxAttempts(merged, attempts);
|
|
40
65
|
const rows = entries
|
|
41
66
|
.filter((e) => opts.all || !done.has(e.id))
|
|
42
67
|
.map((e) => summarizeInboxEntry(redactAgentInboxItem(e), done.has(e.id)));
|
|
43
68
|
if (opts.json) {
|
|
44
|
-
console.log(JSON.stringify({
|
|
69
|
+
console.log(JSON.stringify({
|
|
70
|
+
count: rows.length,
|
|
71
|
+
source,
|
|
72
|
+
stale,
|
|
73
|
+
...(attemptsMade !== undefined ? { attempts: attemptsMade } : {}),
|
|
74
|
+
messages: rows,
|
|
75
|
+
...(note ? { note } : {}),
|
|
76
|
+
}, null, 2));
|
|
45
77
|
return;
|
|
46
78
|
}
|
|
47
79
|
if (note)
|
|
@@ -13,6 +13,7 @@ import * as os from "node:os";
|
|
|
13
13
|
import { CLI_VERSION } from "../cli-version.js";
|
|
14
14
|
import { ensureCognitoToken } from "../utils/cognito-session.js";
|
|
15
15
|
import { getCompanyUid, vaultApiFetch } from "../utils/vault-api.js";
|
|
16
|
+
import { parseRetryAfterSeconds } from "../lib/agent-kit/inbox-fetch.js";
|
|
16
17
|
import { McpServer } from "../lib/agent-kit/mcp/jsonrpc.js";
|
|
17
18
|
import { createVaultObjectDownloader } from "../lib/agent-kit/attachment-download.js";
|
|
18
19
|
import { buildAgentMcpTools } from "../lib/agent-kit/mcp/tools.js";
|
|
@@ -59,7 +60,7 @@ export function defaultMcpClients(creds, credsPath, paths = agentKitPaths(os.hom
|
|
|
59
60
|
HQ_VAULT_API_URL: creds.apiBaseUrl,
|
|
60
61
|
NO_COLOR: "1",
|
|
61
62
|
};
|
|
62
|
-
const getToken = () => ensureCognitoToken({ tokenSource: "machine", interactive: false });
|
|
63
|
+
const getToken = (signal) => ensureCognitoToken({ tokenSource: "machine", interactive: false, signal });
|
|
63
64
|
let companyUid;
|
|
64
65
|
return {
|
|
65
66
|
creds,
|
|
@@ -89,9 +90,11 @@ export function defaultMcpClients(creds, credsPath, paths = agentKitPaths(os.hom
|
|
|
89
90
|
method: init?.method,
|
|
90
91
|
body: init?.body,
|
|
91
92
|
query: init?.query,
|
|
93
|
+
signal: init?.signal,
|
|
92
94
|
});
|
|
93
95
|
const body = await res.json().catch(() => ({}));
|
|
94
|
-
|
|
96
|
+
const retryAfterSeconds = parseRetryAfterSeconds(res.headers.get("retry-after"));
|
|
97
|
+
return { status: res.status, body, ...(retryAfterSeconds !== undefined ? { retryAfterSeconds } : {}) };
|
|
95
98
|
},
|
|
96
99
|
};
|
|
97
100
|
}
|