@indigoai-us/hq-cli 5.345.1 → 5.345.3
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 +10 -0
- package/dist/commands/daemon.js +6 -2
- package/dist/commands/lanes-message.js +0 -3
- package/dist/commands/lanes-resume.js +0 -3
- package/dist/commands/lanes.js +1 -4
- package/dist/commands/mcp-serve.js +15 -5
- package/dist/hq-cloud-sync-runner/bin/sync-runner.js +135416 -0
- package/dist/hq-cloud-sync-runner/package.json +1 -0
- package/dist/index.js +2 -1
- package/dist/lib/daemon/hq-child-bootstrap-stage.d.ts +22 -0
- package/dist/lib/daemon/hq-child-bootstrap-stage.js +127 -0
- package/dist/lib/daemon/hq-child-bootstrap.d.mts +3 -0
- package/dist/lib/daemon/hq-child-bootstrap.mjs +208 -0
- package/dist/lib/daemon/hq-cloud.d.ts +5 -0
- package/dist/lib/daemon/hq-cloud.js +14 -0
- package/dist/lib/daemon/run.d.ts +28 -2
- package/dist/lib/daemon/run.js +139 -10
- package/dist/lib/daemon/sync-runner-bundle.d.ts +40 -0
- package/dist/lib/daemon/sync-runner-bundle.js +199 -0
- package/dist/lib/lanes/disk-guard.d.ts +3 -4
- package/dist/lib/lanes/disk-guard.js +7 -6
- package/dist/lib/lanes/reconcile.js +22 -28
- package/dist/lib/lanes/spawn.d.ts +0 -2
- package/dist/lib/lanes/spawn.js +21 -29
- package/dist/lib/lanes/watcher.js +6 -0
- package/dist/utils/package-use-lease.d.ts +6 -0
- package/dist/utils/package-use-lease.js +25 -2
- package/package.json +2 -2
package/dist/lib/lanes/spawn.js
CHANGED
|
@@ -36,7 +36,7 @@ import { MESSAGE_REPLAY_STATE_NAME } from "./message-replay.js";
|
|
|
36
36
|
import { markAnsweredQuestionsDelivered } from "./questions.js";
|
|
37
37
|
import { hasEarlierEligibleQueuedLane, laneAdmissionCapReason, withLaneAdmissionLock, } from "./admission.js";
|
|
38
38
|
import { resolveAdmissionHost } from "./admission-host.js";
|
|
39
|
-
import { checkLaneDiskSpace,
|
|
39
|
+
import { checkLaneDiskSpace, laneDiskAccount } from "./disk-guard.js";
|
|
40
40
|
import { LANE_ENVELOPE_JSON_SCHEMA, ENVELOPE_INVALID_REASON, parseLaneProvider, } from "./types.js";
|
|
41
41
|
export const LANES_RUNS_REL = path.join("workspace", "lanes-runs");
|
|
42
42
|
/** Written by reconcile before a resume spawn; the worker prompt names this path. */
|
|
@@ -606,7 +606,6 @@ export async function retryLaneOnAlternateAccount(hqRoot, lane, reason, writer =
|
|
|
606
606
|
return moved;
|
|
607
607
|
return spawnLaneWorker(hqRoot, moved, {
|
|
608
608
|
...deps,
|
|
609
|
-
lowDiskGuardEnabled: deps.lowDiskGuardEnabled ?? await lowDiskGuardEnabledForLane(hqRoot, moved),
|
|
610
609
|
});
|
|
611
610
|
});
|
|
612
611
|
}
|
|
@@ -1840,33 +1839,26 @@ export function spawnLaneWorker(hqRoot, lane, deps = {}, launch = {}) {
|
|
|
1840
1839
|
probe: modelDeps.probe ?? defaultProbe,
|
|
1841
1840
|
env,
|
|
1842
1841
|
};
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
const
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
},
|
|
1864
|
-
queued_at: current.queued_at ?? measuredAt,
|
|
1865
|
-
admission_reserved_at: undefined,
|
|
1866
|
-
terminal_reason: undefined,
|
|
1867
|
-
terminal_details: undefined,
|
|
1868
|
-
}));
|
|
1869
|
-
}
|
|
1842
|
+
const diskAccount = laneDiskAccount(config, existing.provider, existing.account);
|
|
1843
|
+
if (diskAccount !== undefined) {
|
|
1844
|
+
const free = checkLaneDiskSpace(hqRoot, effectiveAccountHome(diskAccount, hostname).home, deps.statfs, config.low_disk_min_free_bytes);
|
|
1845
|
+
if (free.low) {
|
|
1846
|
+
const measuredAt = (deps.now ?? (() => new Date()))().toISOString();
|
|
1847
|
+
return retryUpdateLane(hqRoot, lane.lane_id, "spawn", (current) => ({
|
|
1848
|
+
...current,
|
|
1849
|
+
state: "queued",
|
|
1850
|
+
queued_reason: "low_disk",
|
|
1851
|
+
queued_details: {
|
|
1852
|
+
reason: "low_disk",
|
|
1853
|
+
hq_free_bytes: free.hq.free_bytes,
|
|
1854
|
+
provider_free_bytes: free.provider.free_bytes,
|
|
1855
|
+
measured_at: measuredAt,
|
|
1856
|
+
},
|
|
1857
|
+
queued_at: current.queued_at ?? measuredAt,
|
|
1858
|
+
admission_reserved_at: undefined,
|
|
1859
|
+
terminal_reason: undefined,
|
|
1860
|
+
terminal_details: undefined,
|
|
1861
|
+
}));
|
|
1870
1862
|
}
|
|
1871
1863
|
}
|
|
1872
1864
|
let selection;
|
|
@@ -863,6 +863,12 @@ async function settleBlockerFreshness(hqRoot, lane, manifestTurnId, at, deps, me
|
|
|
863
863
|
retryUndeliverable = true;
|
|
864
864
|
escalationText = `Blocker freshness escalation for ${current.lane_id}: these blockers remain stale after consecutive turns: ${staleLabels.join(", ")}. Status file: ${resolution.statusPath}.`;
|
|
865
865
|
}
|
|
866
|
+
else if (failedFallback !== undefined) {
|
|
867
|
+
// If the senior inbox is still unavailable, retry the lane inbox fallback.
|
|
868
|
+
deliverFallback = true;
|
|
869
|
+
undeliverableReason = failedFallback.reason ?? prior?.undeliverable_reason ?? "The session senior inbox is unavailable";
|
|
870
|
+
escalationText = `Blocker freshness escalation for ${current.lane_id}: these blockers remain stale after consecutive turns: ${staleLabels.join(", ")}. Status file: ${resolution.statusPath}.`;
|
|
871
|
+
}
|
|
866
872
|
else if (prior !== undefined && blockerFreshnessFingerprint(prior.stale_keys.map((key, index) => ({ key, label: prior.stale_labels[index] ?? "" }))) !== fingerprint) {
|
|
867
873
|
escalatedFingerprint = undefined;
|
|
868
874
|
}
|
|
@@ -34,7 +34,13 @@ export declare function createPackageUseLeaseHandoff(lease: PackageUseLease, tim
|
|
|
34
34
|
export declare function createCurrentPackageUseLeaseHandoff(timeoutMs?: number): PackageUseLeaseHandoff | null;
|
|
35
35
|
/** Publish this process's lease identity to a parent waiting in the same prefix. */
|
|
36
36
|
export declare function publishPackageUseLeaseHandoff(lease: PackageUseLease, env?: NodeJS.ProcessEnv): boolean;
|
|
37
|
+
export declare function currentPackageUseLeaseInstall(): {
|
|
38
|
+
prefix: string;
|
|
39
|
+
version: string;
|
|
40
|
+
} | null;
|
|
37
41
|
export declare function acquireCurrentPackageUseLease(argv?: readonly string[]): PackageUseLease | null;
|
|
42
|
+
/** Let a daemon bootstrap drop its temporary lease after this process published its own. */
|
|
43
|
+
export declare function signalPackageUseLeaseBootstrapHandoff(lease?: PackageUseLease | null): void;
|
|
38
44
|
/** Release this process's package-use lease after a long-running command has loaded its package modules. */
|
|
39
45
|
export declare function releaseCurrentPackageUseLease(): void;
|
|
40
46
|
/** The lease remains held through command execution and is released on process exit. */
|
|
@@ -50,6 +50,7 @@ export function packageUseLeasePurposeForArgv(argv) {
|
|
|
50
50
|
return "command";
|
|
51
51
|
}
|
|
52
52
|
let currentPackageUseLease = null;
|
|
53
|
+
const BOOTSTRAP_HANDOFF_ENV = "HQ_CLI_PACKAGE_USE_HANDOFF_TOKEN";
|
|
53
54
|
function errorLabel(error) {
|
|
54
55
|
if (error && typeof error === "object") {
|
|
55
56
|
const value = error;
|
|
@@ -308,7 +309,7 @@ function exists(file) {
|
|
|
308
309
|
throw error;
|
|
309
310
|
}
|
|
310
311
|
}
|
|
311
|
-
export function
|
|
312
|
+
export function currentPackageUseLeaseInstall() {
|
|
312
313
|
const pkg = findCliPackage(path.dirname(fileURLToPath(import.meta.url)));
|
|
313
314
|
if (!pkg || isPnpmGlobal(pkg.root) || isBunGlobal(pkg.root))
|
|
314
315
|
return null;
|
|
@@ -321,11 +322,33 @@ export function acquireCurrentPackageUseLease(argv = process.argv) {
|
|
|
321
322
|
if (nodeModules > 0 && parts[nodeModules - 1] !== "lib")
|
|
322
323
|
return null;
|
|
323
324
|
}
|
|
324
|
-
|
|
325
|
+
return { prefix, version: pkg.version };
|
|
326
|
+
}
|
|
327
|
+
export function acquireCurrentPackageUseLease(argv = process.argv) {
|
|
328
|
+
const install = currentPackageUseLeaseInstall();
|
|
329
|
+
if (!install)
|
|
330
|
+
return null;
|
|
331
|
+
const lease = acquirePackageUseLease(install.prefix, install.version, undefined, packageUseLeasePurposeForArgv(argv));
|
|
325
332
|
currentPackageUseLease = lease;
|
|
326
333
|
publishPackageUseLeaseHandoff(lease);
|
|
327
334
|
return lease;
|
|
328
335
|
}
|
|
336
|
+
/** Let a daemon bootstrap drop its temporary lease after this process published its own. */
|
|
337
|
+
export function signalPackageUseLeaseBootstrapHandoff(lease = currentPackageUseLease) {
|
|
338
|
+
const token = process.env[BOOTSTRAP_HANDOFF_ENV];
|
|
339
|
+
if (token === undefined)
|
|
340
|
+
return;
|
|
341
|
+
delete process.env[BOOTSTRAP_HANDOFF_ENV];
|
|
342
|
+
if (!lease || !/^[a-f0-9]{32}$/.test(token))
|
|
343
|
+
return;
|
|
344
|
+
const markerPath = path.join(path.dirname(lease.leasePath), `handoff-${process.pid}-${token}.handoff`);
|
|
345
|
+
try {
|
|
346
|
+
writeFileSync(markerPath, `${process.pid}\n`, { flag: "wx", mode: 0o600 });
|
|
347
|
+
}
|
|
348
|
+
catch (error) {
|
|
349
|
+
process.stderr.write(`hq-cli package-use lease handoff signal failed (${errorLabel(error)})\n`);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
329
352
|
/** Release this process's package-use lease after a long-running command has loaded its package modules. */
|
|
330
353
|
export function releaseCurrentPackageUseLease() {
|
|
331
354
|
currentPackageUseLease?.release();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@indigoai-us/hq-cli",
|
|
3
|
-
"version": "5.345.
|
|
3
|
+
"version": "5.345.3",
|
|
4
4
|
"description": "HQ by Indigo management CLI — modules and cloud sync",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"scripts/mesh-daemon-if-stale.mjs"
|
|
25
25
|
],
|
|
26
26
|
"scripts": {
|
|
27
|
-
"build": "node scripts/generate-dsn.mjs && node scripts/build-flag-registry-worker.mjs && tsc && node scripts/generate-command-catalog.mjs --check && node scripts/copy-schemas.mjs && node scripts/chmod-bins.mjs",
|
|
27
|
+
"build": "node scripts/generate-dsn.mjs && node scripts/build-flag-registry-worker.mjs && tsc && node scripts/generate-command-catalog.mjs --check && node scripts/copy-schemas.mjs && node scripts/chmod-bins.mjs && node scripts/bundle-sync-runner.mjs",
|
|
28
28
|
"prepublishOnly": "npm run build",
|
|
29
29
|
"pretypecheck": "node scripts/generate-dsn.mjs && node scripts/build-flag-registry-worker.mjs",
|
|
30
30
|
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.typetest.json",
|