@indigoai-us/hq-cli 5.344.0 → 5.344.1
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,9 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.344.1] — 2026-10-05
|
|
6
|
+
- Release the MCP server's package lease after its resident modules preload and record a bounded command purpose on CLI package leases.
|
|
7
|
+
|
|
5
8
|
## [5.344.0] — 2026-10-04
|
|
6
9
|
- Include a bounded reason in sync-failure client-health reports.
|
|
7
10
|
- Add an explicit opt-in to count usage from HQ sessions with no company toward the default company: `hq mesh context default set` asks in a terminal (default No), takes `--count-usage` / `--no-count-usage`, and writes `usageAttribution` (company and signed-in person) to the work-context config. Changing or clearing the default, logging out, or signing in as another account withdraws it; `get` shows it; an automatic default never opts in.
|
|
@@ -73,11 +73,12 @@ export async function runMcpServe(opts = {}) {
|
|
|
73
73
|
process.emitWarning("hq-cli resident package preload completion failed (class=Error, module=unknown)");
|
|
74
74
|
});
|
|
75
75
|
};
|
|
76
|
+
// Release before the stdio read can remain open indefinitely. The request
|
|
77
|
+
// handlers and their declared lazy modules are loaded before this point.
|
|
78
|
+
startResidentPreload();
|
|
76
79
|
const send = (msg) => {
|
|
77
80
|
const response = `${JSON.stringify({ jsonrpc: "2.0", ...msg })}\n`;
|
|
78
|
-
|
|
79
|
-
return output.write(response);
|
|
80
|
-
return output.write(response, startResidentPreload);
|
|
81
|
+
return output.write(response);
|
|
81
82
|
};
|
|
82
83
|
const reply = (id, result) => send({ id, result });
|
|
83
84
|
const replyError = (id, code, message) => send({ id, error: { code, message } });
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare const PACKAGE_USE_LEASE_HANDOFF_ENV = "HQ_CLI_PACKAGE_USE_LEASE_HANDOFF";
|
|
2
|
+
export declare const PACKAGE_USE_LEASE_PURPOSES: readonly ["command", "resident-preload", "mcp-serve", "hook", "daemon"];
|
|
3
|
+
export type PackageUseLeasePurpose = (typeof PACKAGE_USE_LEASE_PURPOSES)[number];
|
|
2
4
|
export declare class PackageUseUpdatePendingError extends Error {
|
|
3
5
|
constructor(message: string);
|
|
4
6
|
}
|
|
@@ -10,7 +12,10 @@ export interface PackageUseLeaseRecord {
|
|
|
10
12
|
pid: number;
|
|
11
13
|
start_time_ms: number;
|
|
12
14
|
hq_version: string;
|
|
15
|
+
purpose?: PackageUseLeasePurpose;
|
|
13
16
|
}
|
|
17
|
+
/** Map only fixed command words to a bounded lease purpose; never persist argv values. */
|
|
18
|
+
export declare function packageUseLeasePurposeForArgv(argv: readonly string[]): PackageUseLeasePurpose;
|
|
14
19
|
export interface PackageUseLeaseHandoff {
|
|
15
20
|
readonly envValue: string;
|
|
16
21
|
waitForChild(pid: number, childAlive: () => boolean): Promise<boolean>;
|
|
@@ -20,7 +25,7 @@ export declare function npmPrefix(root: string, platform?: NodeJS.Platform): str
|
|
|
20
25
|
export declare function packageUseLeaseDirectory(prefix: string, stateDirectory?: string): string;
|
|
21
26
|
export declare function packageUseUpdateRequestPath(prefix: string, stateDirectory?: string): string;
|
|
22
27
|
declare function waitForUpdateRequest(requestPath: string, timeoutMs: number): void;
|
|
23
|
-
export declare function acquirePackageUseLease(prefix: string, hqVersion: string, stateDirectory?: string): PackageUseLease;
|
|
28
|
+
export declare function acquirePackageUseLease(prefix: string, hqVersion: string, stateDirectory?: string, purpose?: PackageUseLeasePurpose): PackageUseLease;
|
|
24
29
|
/**
|
|
25
30
|
* Create a bounded, per-reexec rendezvous in the current lease directory.
|
|
26
31
|
* The child confirms readiness only after publishing its own atomic lease.
|
|
@@ -29,7 +34,7 @@ export declare function createPackageUseLeaseHandoff(lease: PackageUseLease, tim
|
|
|
29
34
|
export declare function createCurrentPackageUseLeaseHandoff(timeoutMs?: number): PackageUseLeaseHandoff | null;
|
|
30
35
|
/** Publish this process's lease identity to a parent waiting in the same prefix. */
|
|
31
36
|
export declare function publishPackageUseLeaseHandoff(lease: PackageUseLease, env?: NodeJS.ProcessEnv): boolean;
|
|
32
|
-
export declare function acquireCurrentPackageUseLease(): PackageUseLease | null;
|
|
37
|
+
export declare function acquireCurrentPackageUseLease(argv?: readonly string[]): PackageUseLease | null;
|
|
33
38
|
/** Release this process's package-use lease after a long-running command has loaded its package modules. */
|
|
34
39
|
export declare function releaseCurrentPackageUseLease(): void;
|
|
35
40
|
/** The lease remains held through command execution and is released on process exit. */
|
|
@@ -8,12 +8,47 @@ const CLI_NAME = "@indigoai-us/hq-cli";
|
|
|
8
8
|
const UPDATE_REQUEST = "update.pending.json";
|
|
9
9
|
export const PACKAGE_USE_LEASE_HANDOFF_ENV = "HQ_CLI_PACKAGE_USE_LEASE_HANDOFF";
|
|
10
10
|
const HANDOFF_TIMEOUT_MS = 2_000;
|
|
11
|
+
export const PACKAGE_USE_LEASE_PURPOSES = [
|
|
12
|
+
"command",
|
|
13
|
+
"resident-preload",
|
|
14
|
+
"mcp-serve",
|
|
15
|
+
"hook",
|
|
16
|
+
"daemon",
|
|
17
|
+
];
|
|
11
18
|
export class PackageUseUpdatePendingError extends Error {
|
|
12
19
|
constructor(message) {
|
|
13
20
|
super(message);
|
|
14
21
|
this.name = "PackageUseUpdatePendingError";
|
|
15
22
|
}
|
|
16
23
|
}
|
|
24
|
+
/** Map only fixed command words to a bounded lease purpose; never persist argv values. */
|
|
25
|
+
export function packageUseLeasePurposeForArgv(argv) {
|
|
26
|
+
const args = argv.slice(2);
|
|
27
|
+
if (args[0] === "mcp" && args[1] === "serve")
|
|
28
|
+
return "mcp-serve";
|
|
29
|
+
if ((args[0] === "daemon" && args[1] === "run") ||
|
|
30
|
+
(args[0] === "mesh" && args[1] === "daemon" && args[2] === "run"))
|
|
31
|
+
return "daemon";
|
|
32
|
+
if (args[0] === "core" && ["hq-session", "checkpoint-stop-gate"].includes(args[1] ?? "")) {
|
|
33
|
+
return "hook";
|
|
34
|
+
}
|
|
35
|
+
const hasOption = (...options) => options.some((option) => args.includes(option));
|
|
36
|
+
if (args[0] === "login" ||
|
|
37
|
+
(args[0] === "auth" && args[1] === "login") ||
|
|
38
|
+
(args[0] === "agents" && ["kit", "mcp"].includes(args[1] ?? "")) ||
|
|
39
|
+
(args[0] === "agents" && ["terminal", "message"].includes(args[1] ?? "") &&
|
|
40
|
+
(args[1] === "terminal" || hasOption("--wait"))) ||
|
|
41
|
+
(args[0] === "bot" && (args[1] === "run" || (args[1] === "logs" && hasOption("--follow", "-f")))) ||
|
|
42
|
+
(args[0] === "daemon" && args[1] === "logs" && hasOption("--follow", "-f")) ||
|
|
43
|
+
(args[0] === "integrations" && args[1] === "connect") ||
|
|
44
|
+
(args[0] === "lanes" && ["watch", "message", "resume"].includes(args[1] ?? "")) ||
|
|
45
|
+
(args[0] === "monitor" && ["wait", "_run"].includes(args[1] ?? "")) ||
|
|
46
|
+
(args[0] === "pack" && args[1] === "install") ||
|
|
47
|
+
(args[0] === "pkg" && args[1] === "update") ||
|
|
48
|
+
(args[0] === "secrets" && args[1] === "sandbox"))
|
|
49
|
+
return "resident-preload";
|
|
50
|
+
return "command";
|
|
51
|
+
}
|
|
17
52
|
let currentPackageUseLease = null;
|
|
18
53
|
function errorLabel(error) {
|
|
19
54
|
if (error && typeof error === "object") {
|
|
@@ -131,7 +166,7 @@ function waitForUpdateRequest(requestPath, timeoutMs) {
|
|
|
131
166
|
Atomics.wait(sleeper, 0, 0, 100);
|
|
132
167
|
}
|
|
133
168
|
}
|
|
134
|
-
export function acquirePackageUseLease(prefix, hqVersion, stateDirectory) {
|
|
169
|
+
export function acquirePackageUseLease(prefix, hqVersion, stateDirectory, purpose = "command") {
|
|
135
170
|
const directory = packageUseLeaseDirectory(prefix, stateDirectory);
|
|
136
171
|
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
137
172
|
const requestPath = path.join(directory, UPDATE_REQUEST);
|
|
@@ -139,6 +174,7 @@ export function acquirePackageUseLease(prefix, hqVersion, stateDirectory) {
|
|
|
139
174
|
pid: process.pid,
|
|
140
175
|
start_time_ms: Math.floor(performance.timeOrigin),
|
|
141
176
|
hq_version: hqVersion,
|
|
177
|
+
purpose,
|
|
142
178
|
};
|
|
143
179
|
const leasePath = path.join(directory, `${record.pid}-${record.start_time_ms}.json`);
|
|
144
180
|
const tempPath = `${leasePath}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
@@ -272,7 +308,7 @@ function exists(file) {
|
|
|
272
308
|
throw error;
|
|
273
309
|
}
|
|
274
310
|
}
|
|
275
|
-
export function acquireCurrentPackageUseLease() {
|
|
311
|
+
export function acquireCurrentPackageUseLease(argv = process.argv) {
|
|
276
312
|
const pkg = findCliPackage(path.dirname(fileURLToPath(import.meta.url)));
|
|
277
313
|
if (!pkg || isPnpmGlobal(pkg.root) || isBunGlobal(pkg.root))
|
|
278
314
|
return null;
|
|
@@ -285,7 +321,7 @@ export function acquireCurrentPackageUseLease() {
|
|
|
285
321
|
if (nodeModules > 0 && parts[nodeModules - 1] !== "lib")
|
|
286
322
|
return null;
|
|
287
323
|
}
|
|
288
|
-
const lease = acquirePackageUseLease(prefix, pkg.version);
|
|
324
|
+
const lease = acquirePackageUseLease(prefix, pkg.version, undefined, packageUseLeasePurposeForArgv(argv));
|
|
289
325
|
currentPackageUseLease = lease;
|
|
290
326
|
publishPackageUseLeaseHandoff(lease);
|
|
291
327
|
return lease;
|