@indigoai-us/hq-cli 5.342.12 → 5.342.13
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 +13 -0
- package/dist/commands/agent-kit.d.ts +2 -0
- package/dist/commands/agent-kit.js +23 -17
- package/dist/commands/agent-mcp.d.ts +2 -0
- package/dist/commands/agent-mcp.js +21 -15
- package/dist/commands/lanes-message.d.ts +20 -2
- package/dist/commands/lanes-message.js +99 -38
- package/dist/commands/lanes-shared.d.ts +1 -0
- package/dist/commands/lanes.d.ts +4 -0
- package/dist/commands/lanes.js +24 -30
- package/dist/commands/mesh.js +2 -1
- package/dist/commands/monitor.d.ts +14 -1
- package/dist/commands/monitor.js +43 -14
- package/dist/lib/doctor/checks/anywhere.js +11 -6
- 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/lanes/keep-alive-audit.d.ts +3 -0
- package/dist/lib/lanes/keep-alive-audit.js +59 -11
- package/dist/lib/lanes/reconcile.js +46 -3
- package/dist/lib/lanes/types.d.ts +2 -1
- package/dist/utils/resident-package-preload.d.ts +8 -1
- package/dist/utils/resident-package-preload.js +68 -0
- package/docs/anywhere-runtime.md +3 -1
- package/package.json +4 -4
- package/dist/lib/db/remote-engine.d.ts +0 -58
- package/dist/lib/db/remote-engine.js +0 -87
- package/dist/lib/db/remote-sql.d.ts +0 -22
- package/dist/lib/db/remote-sql.js +0 -36
package/dist/commands/monitor.js
CHANGED
|
@@ -10,6 +10,9 @@ import { appendDropboxMessageAtPath, drainDropboxAtPath, formatDropboxMessages }
|
|
|
10
10
|
import { dispatchLaneDelivery } from "../lib/lanes/delivery-core.js";
|
|
11
11
|
import { MONITOR_FLAG, MONITOR_FLAG_DEFAULT, MONITOR_DEFAULT_CHECKIN_MS, MONITOR_DEFAULT_TIMEOUT_MS, MONITOR_POLL_INTERVAL_MS, MONITOR_BATCH_WINDOW_MS, MONITOR_MAX_EVENTS_PER_WINDOW, MONITOR_MAX_FLOOD_WINDOWS, MONITOR_RATE_WINDOW_MS, MONITOR_SCHEMA_VERSION, monitorDir, monitorSessionDir, monitorSessionHasActiveMarkerForOwner, monitorSessionHasActiveMarkers, monitorSessionHasWork, monitorSessionInboxHasEvents, monitorTargetKey, assertMonitorTimeoutCompatibility, parseMonitorDuration, parseMonitorTarget, detectMonitorTarget, findNearestMonitorRuntime, makeMonitorId, recordMonitorTargetDelivery, recordMonitorTargetActivity, recordMonitorTargetDeliveryAtPath, runMonitorCheckinTick, readMonitorPidLiveness, recordHookSessionMapping, resolveMappedSessionId, parseHookSessionId, withMonitorTargetLock, nextMonitorEventSequence, recordMonitorEventState, requestMonitorStop, nextMonitorTimeoutDelay } from "../lib/monitor.js";
|
|
12
12
|
import { readProcStarttime } from "../lib/lanes/spawn.js";
|
|
13
|
+
import { createMonitorLaneMessageApi } from "./lanes.js";
|
|
14
|
+
import { releaseCurrentPackageUseLease, releasePackageUseLeaseAfterResidentPreload } from "../utils/package-use-lease.js";
|
|
15
|
+
import { preloadResidentPackageModules, reportResidentPackagePreloadFailure, runResidentCommandWithPackageLease, } from "../utils/resident-package-preload.js";
|
|
13
16
|
const RUNTIME_ENV = {
|
|
14
17
|
claude: "CLAUDE_CODE_SESSION_ID",
|
|
15
18
|
codex: "CODEX_THREAD_ID",
|
|
@@ -418,7 +421,7 @@ function removeActiveMarker(hqRoot, meta) {
|
|
|
418
421
|
return;
|
|
419
422
|
fs.rmSync(path.join(monitorSessionDir(hqRoot, meta.target.provider, meta.target.sessionId), "active", meta.monitor_id), { force: true });
|
|
420
423
|
}
|
|
421
|
-
async function deliverLaneEvent(hqRoot, meta, sequence, text) {
|
|
424
|
+
async function deliverLaneEvent(hqRoot, meta, sequence, text, inProcess) {
|
|
422
425
|
if (meta.target.kind !== "lane")
|
|
423
426
|
throw new LanesError("monitor_lane_target_required", "Lane delivery requires a lane target.");
|
|
424
427
|
const lane = tryReadLane(hqRoot, meta.target.laneId);
|
|
@@ -427,8 +430,8 @@ async function deliverLaneEvent(hqRoot, meta, sequence, text) {
|
|
|
427
430
|
let dispatched;
|
|
428
431
|
try {
|
|
429
432
|
dispatched = await dispatchLaneDelivery(lane, {
|
|
430
|
-
dropbox: () => invokeLaneMonitorMessage(hqRoot, meta, sequence, text),
|
|
431
|
-
resume: () => invokeLaneMonitorMessage(hqRoot, meta, sequence, text),
|
|
433
|
+
dropbox: () => invokeLaneMonitorMessage(hqRoot, meta, sequence, text, inProcess),
|
|
434
|
+
resume: () => invokeLaneMonitorMessage(hqRoot, meta, sequence, text, inProcess),
|
|
432
435
|
});
|
|
433
436
|
}
|
|
434
437
|
catch (err) {
|
|
@@ -438,9 +441,24 @@ async function deliverLaneEvent(hqRoot, meta, sequence, text) {
|
|
|
438
441
|
}
|
|
439
442
|
return { ...dispatched.value, outcome: `${dispatched.mechanism}:${dispatched.value.outcome}` };
|
|
440
443
|
}
|
|
441
|
-
function invokeLaneMonitorMessage(hqRoot, meta, sequence, text) {
|
|
444
|
+
export function invokeLaneMonitorMessage(hqRoot, meta, sequence, text, inProcess) {
|
|
442
445
|
if (meta.target.kind !== "lane")
|
|
443
446
|
throw new LanesError("monitor_lane_target_required", "Lane delivery requires a lane target.");
|
|
447
|
+
if (inProcess) {
|
|
448
|
+
return inProcess(meta.target.laneId, { text, monitor_id: meta.monitor_id, description: meta.description, sequence })
|
|
449
|
+
.then((result) => {
|
|
450
|
+
if (!result.ok)
|
|
451
|
+
return { delivered: false, outcome: result.errorCode };
|
|
452
|
+
const response = result.response;
|
|
453
|
+
if (response === undefined) {
|
|
454
|
+
throw new LanesError("monitor_lane_delivery_invalid_response", "The lane delivery command returned invalid JSON: Unexpected end of JSON input.", {});
|
|
455
|
+
}
|
|
456
|
+
return {
|
|
457
|
+
delivered: response.accepted === true,
|
|
458
|
+
outcome: String(response.delivery_status ?? response.delivery ?? "accepted"),
|
|
459
|
+
};
|
|
460
|
+
});
|
|
461
|
+
}
|
|
444
462
|
const cliEntrypoint = process.argv[1];
|
|
445
463
|
if (!cliEntrypoint)
|
|
446
464
|
throw new LanesError("monitor_cli_path_missing", "Could not locate the hq CLI entry point for lane delivery.");
|
|
@@ -488,16 +506,16 @@ function deliverSessionEvent(hqRoot, meta, sequence, text) {
|
|
|
488
506
|
});
|
|
489
507
|
return { delivered: true, outcome: "session_inbox" };
|
|
490
508
|
}
|
|
491
|
-
async function deliverTargetEvent(hqRoot, meta, sequence, text) {
|
|
509
|
+
async function deliverTargetEvent(hqRoot, meta, sequence, text, inProcess) {
|
|
492
510
|
return meta.target.kind === "lane"
|
|
493
|
-
? deliverLaneEvent(hqRoot, meta, sequence, text)
|
|
511
|
+
? deliverLaneEvent(hqRoot, meta, sequence, text, inProcess)
|
|
494
512
|
: deliverSessionEvent(hqRoot, meta, sequence, text);
|
|
495
513
|
}
|
|
496
|
-
export async function deliverNormalEvent(hqRoot, meta, state, rawText) {
|
|
514
|
+
export async function deliverNormalEvent(hqRoot, meta, state, rawText, inProcess) {
|
|
497
515
|
return withMonitorTargetLock(hqRoot, meta.target_key, async (activityPath) => {
|
|
498
516
|
const current = readJson(statePath(hqRoot, meta.monitor_id)) ?? state;
|
|
499
517
|
const sequence = nextMonitorEventSequence(current);
|
|
500
|
-
const outcome = await deliverTargetEvent(hqRoot, meta, sequence, rawText);
|
|
518
|
+
const outcome = await deliverTargetEvent(hqRoot, meta, sequence, rawText, inProcess);
|
|
501
519
|
const event = { seq: sequence, at: new Date().toISOString(), text: rawText, delivery: outcome.delivered ? "delivered" : `undeliverable:${outcome.outcome}` };
|
|
502
520
|
const next = appendEventRecord(hqRoot, meta.monitor_id, current, event);
|
|
503
521
|
if (outcome.delivered)
|
|
@@ -512,7 +530,7 @@ function targetEnded(hqRoot, meta) {
|
|
|
512
530
|
const lane = tryReadLane(hqRoot, meta.target.laneId);
|
|
513
531
|
return !lane || ["killed", "cancelled", "failed"].includes(lane.state);
|
|
514
532
|
}
|
|
515
|
-
async function monitorCheckin(hqRoot, meta, state) {
|
|
533
|
+
async function monitorCheckin(hqRoot, meta, state, inProcess) {
|
|
516
534
|
await runMonitorCheckinTick(hqRoot, meta.target_key, {
|
|
517
535
|
now: () => new Date(),
|
|
518
536
|
isWakeable: async (targetKey) => {
|
|
@@ -540,7 +558,7 @@ async function monitorCheckin(hqRoot, meta, state) {
|
|
|
540
558
|
return { delivered: false, outcome: "no_live_monitor" };
|
|
541
559
|
const monitorState = readJson(statePath(hqRoot, monitor.monitor_id)) ?? state;
|
|
542
560
|
const sequence = nextMonitorEventSequence(monitorState);
|
|
543
|
-
const outcome = await deliverTargetEvent(hqRoot, monitor, sequence, text);
|
|
561
|
+
const outcome = await deliverTargetEvent(hqRoot, monitor, sequence, text, inProcess);
|
|
544
562
|
const event = { seq: sequence, at: new Date().toISOString(), text, delivery: outcome.delivered ? "delivered" : `undeliverable:${outcome.outcome}` };
|
|
545
563
|
appendEventRecord(hqRoot, monitor.monitor_id, monitorState, event);
|
|
546
564
|
return outcome;
|
|
@@ -557,6 +575,16 @@ function activeTargetMeta(hqRoot, targetKey) {
|
|
|
557
575
|
return meta?.target_key === targetKey && state?.status === "running" && state.pid !== null && readMonitorPidLiveness(state.pid, state.starttime) ? [meta] : [];
|
|
558
576
|
});
|
|
559
577
|
}
|
|
578
|
+
export async function preloadMonitorLaneMessageApi(hqRoot, meta, deps = {}) {
|
|
579
|
+
if (meta.target.kind !== "lane")
|
|
580
|
+
return undefined;
|
|
581
|
+
let laneMessageApi;
|
|
582
|
+
await releasePackageUseLeaseAfterResidentPreload(async () => {
|
|
583
|
+
await (deps.preloadResidentModules ?? (() => preloadResidentPackageModules("monitor-run")))();
|
|
584
|
+
laneMessageApi = (deps.createLaneMessageApi ?? createMonitorLaneMessageApi)(hqRoot, meta.cwd, process.env);
|
|
585
|
+
}, deps.reportPreloadFailure ?? reportResidentPackagePreloadFailure, deps.releasePackageUseLease ?? releaseCurrentPackageUseLease);
|
|
586
|
+
return laneMessageApi;
|
|
587
|
+
}
|
|
560
588
|
export async function runSupervisor(id, deps = {}) {
|
|
561
589
|
const hqRoot = (deps.resolveRoot ?? resolveLanesHqRoot)();
|
|
562
590
|
const dir = monitorDir(hqRoot, id);
|
|
@@ -569,6 +597,7 @@ export async function runSupervisor(id, deps = {}) {
|
|
|
569
597
|
removeActiveMarker(hqRoot, meta);
|
|
570
598
|
return;
|
|
571
599
|
}
|
|
600
|
+
const laneMessageApi = await preloadMonitorLaneMessageApi(hqRoot, meta, deps);
|
|
572
601
|
let state = { ...stateAtStart, status: "running", pid: process.pid, starttime: readProcStarttime(process.pid), started_at: new Date().toISOString() };
|
|
573
602
|
writeJsonAtomic(statePath(hqRoot, id), state);
|
|
574
603
|
let commandChild = null;
|
|
@@ -587,7 +616,7 @@ export async function runSupervisor(id, deps = {}) {
|
|
|
587
616
|
let suppressed = 0;
|
|
588
617
|
let floodWindows = 0;
|
|
589
618
|
let checkinRunning = false;
|
|
590
|
-
const deliver = deps.deliver ?? deliverNormalEvent;
|
|
619
|
+
const deliver = deps.deliver ?? ((root, metadata, current, text) => deliverNormalEvent(root, metadata, current, text, laneMessageApi));
|
|
591
620
|
const perWindowCap = (() => {
|
|
592
621
|
const candidate = Number.parseInt(process.env.HQ_MONITOR_MAX_EVENTS_PER_WINDOW ?? "", 10);
|
|
593
622
|
return Number.isInteger(candidate) && candidate > 0 ? candidate : MONITOR_MAX_EVENTS_PER_WINDOW;
|
|
@@ -711,7 +740,7 @@ export async function runSupervisor(id, deps = {}) {
|
|
|
711
740
|
}
|
|
712
741
|
if (!checkinRunning) {
|
|
713
742
|
checkinRunning = true;
|
|
714
|
-
void monitorCheckin(hqRoot, meta, state)
|
|
743
|
+
void monitorCheckin(hqRoot, meta, state, laneMessageApi)
|
|
715
744
|
.then((next) => { state = next; })
|
|
716
745
|
.catch((err) => writeStderr(`check-in failed: ${errorPath(err)}\n`))
|
|
717
746
|
.finally(() => { checkinRunning = false; });
|
|
@@ -966,11 +995,11 @@ export function registerMonitorCommand(parent) {
|
|
|
966
995
|
});
|
|
967
996
|
monitor.command("wait", { hidden: true }).requiredOption("--provider <provider>")
|
|
968
997
|
.action(async (options) => {
|
|
969
|
-
const result = await runMonitorHookSafely("wait", async () => {
|
|
998
|
+
const result = await runResidentCommandWithPackageLease("monitor-wait", () => runMonitorHookSafely("wait", async () => {
|
|
970
999
|
if (options.provider !== "claude")
|
|
971
1000
|
throw new LanesError("monitor_wait_provider_unsupported", "Only Claude Stop hooks can wait for session monitor events.", { provider: options.provider });
|
|
972
1001
|
return waitForSession(options.provider);
|
|
973
|
-
});
|
|
1002
|
+
}));
|
|
974
1003
|
if (result.stdout)
|
|
975
1004
|
process.stdout.write(result.stdout);
|
|
976
1005
|
process.exitCode = result.exitCode;
|
|
@@ -99,12 +99,15 @@ export async function runAnywhereChecks(context, deps = {}) {
|
|
|
99
99
|
health = unreachableHealth(socketPath);
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
const healthCheck = runtimeHealthCheck(health, healthUnsupported);
|
|
103
|
-
if (!runtimeEnabled)
|
|
104
|
-
return [healthCheck];
|
|
105
102
|
const claude = claudeTargets(home);
|
|
106
103
|
const codex = codexTargets(home);
|
|
107
104
|
const installed = [claude.hqPointer, claude.stateFile, codex.stateFile].some((p) => fs.existsSync(p));
|
|
105
|
+
const serviceState = runtimeEnabled && installed
|
|
106
|
+
? (deps.serviceState ?? (() => defaultServiceState(home)))()
|
|
107
|
+
: undefined;
|
|
108
|
+
const healthCheck = runtimeHealthCheck(health, healthUnsupported, serviceState);
|
|
109
|
+
if (!runtimeEnabled)
|
|
110
|
+
return [healthCheck];
|
|
108
111
|
const remoteModes = [
|
|
109
112
|
result("WARN", "chatgpt-mode", `ChatGPT integration mode: ${CHATGPT_MODE}; host connector setup is managed in ChatGPT`, "hq install --global --runtime chatgpt"),
|
|
110
113
|
result("WARN", "grok-mode", `Grok integration mode: ${GROK_MODE}; host connector setup is managed in Grok`, "hq install --global --runtime grok"),
|
|
@@ -117,7 +120,7 @@ export async function runAnywhereChecks(context, deps = {}) {
|
|
|
117
120
|
out.push(checkInstallMode(claude.stateFile));
|
|
118
121
|
out.push(checkPointer(claude.hqPointer));
|
|
119
122
|
out.push(checkRegistry(registryFile(registryDir(home, env))));
|
|
120
|
-
const service =
|
|
123
|
+
const service = serviceState;
|
|
121
124
|
if (!service.installed)
|
|
122
125
|
out.push(result("FAIL", "daemon-installed", `daemon service is not installed (${service.detail})`, REMEDIATION.daemonInstall));
|
|
123
126
|
else if (!service.loaded)
|
|
@@ -162,7 +165,7 @@ function unreachableHealth(socketPath) {
|
|
|
162
165
|
socket: { path: socketPath, transport: process.platform === "win32" ? "windows_named_pipe" : "unix_socket", mode: null, ownerMatchesUser: null, userOnly: null },
|
|
163
166
|
};
|
|
164
167
|
}
|
|
165
|
-
function runtimeHealthCheck(health, healthUnsupported = false) {
|
|
168
|
+
function runtimeHealthCheck(health, healthUnsupported = false, serviceState) {
|
|
166
169
|
const { flag, resolution, socket } = health;
|
|
167
170
|
const age = flag.lastSuccessfulReadAgeMs === null
|
|
168
171
|
? "unknown"
|
|
@@ -189,7 +192,9 @@ function runtimeHealthCheck(health, healthUnsupported = false) {
|
|
|
189
192
|
const message = health.reachable
|
|
190
193
|
? `hqd reachable; version ${health.version ?? "unknown"}; uptime ${health.uptimeMs === null ? "unknown" : `${new Intl.NumberFormat("en-US").format(health.uptimeMs)} ms`}; runtime flag ${flagLabel}; last successful flag read ${age} ago; held through read error: ${flag.heldThroughReadError ? "yes" : "no"}; cwd binding ${binding}; socket ${socket.path}; ${socketSecurity}${warningNotes.length ? `; ${warningNotes.join("; ")}` : ""}`
|
|
191
194
|
: unreachableMessage;
|
|
192
|
-
const remediation =
|
|
195
|
+
const remediation = !health.reachable && socket.transport === "unix_socket" && serviceState
|
|
196
|
+
? serviceState.installed ? REMEDIATION.daemonRestart : REMEDIATION.daemonInstall
|
|
197
|
+
: healthUnsupported || socketNotUserOnly ? REMEDIATION.daemonRestart : undefined;
|
|
193
198
|
return {
|
|
194
199
|
status: health.reachable && warningNotes.length === 0 ? "PASS" : "WARN",
|
|
195
200
|
checkId: "anywhere.runtime-health",
|