@indigoai-us/hq-cli 5.342.11 → 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.
Files changed (36) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/command-catalog.generated.d.ts +1 -1
  3. package/dist/command-catalog.generated.js +1 -1
  4. package/dist/commands/agent-kit.d.ts +2 -0
  5. package/dist/commands/agent-kit.js +23 -17
  6. package/dist/commands/agent-mcp.d.ts +2 -0
  7. package/dist/commands/agent-mcp.js +21 -15
  8. package/dist/commands/lanes-keep-alive-audit.js +1 -1
  9. package/dist/commands/lanes-message.d.ts +20 -2
  10. package/dist/commands/lanes-message.js +99 -38
  11. package/dist/commands/lanes-shared.d.ts +1 -0
  12. package/dist/commands/lanes.d.ts +4 -0
  13. package/dist/commands/lanes.js +24 -30
  14. package/dist/commands/mesh.js +2 -1
  15. package/dist/commands/monitor.d.ts +14 -1
  16. package/dist/commands/monitor.js +43 -14
  17. package/dist/lib/doctor/checks/anywhere.js +11 -6
  18. package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
  19. package/dist/lib/flag-registry-worker-source.generated.js +1 -1
  20. package/dist/lib/lanes/keep-alive-audit.d.ts +5 -1
  21. package/dist/lib/lanes/keep-alive-audit.js +132 -19
  22. package/dist/lib/lanes/reconcile.js +46 -3
  23. package/dist/lib/lanes/spawn.js +79 -0
  24. package/dist/lib/lanes/types.d.ts +2 -1
  25. package/dist/utils/package-use-lease.d.ts +15 -0
  26. package/dist/utils/package-use-lease.js +94 -1
  27. package/dist/utils/resident-package-preload.d.ts +8 -1
  28. package/dist/utils/resident-package-preload.js +68 -0
  29. package/dist/utils/self-update.d.ts +5 -0
  30. package/dist/utils/self-update.js +100 -12
  31. package/docs/anywhere-runtime.md +3 -1
  32. package/package.json +4 -4
  33. package/dist/lib/db/remote-engine.d.ts +0 -58
  34. package/dist/lib/db/remote-engine.js +0 -87
  35. package/dist/lib/db/remote-sql.d.ts +0 -22
  36. package/dist/lib/db/remote-sql.js +0 -36
package/CHANGELOG.md CHANGED
@@ -2,6 +2,25 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.342.13] — 2026-10-04
6
+ - Run independent core migration differential cases with bounded parallel child processes while preserving per-case reports and failures.
7
+
8
+ - Keep resident monitor lane delivery in-process and release the supervisor package lease after its lane-message modules preload.
9
+ - Show `hq daemon install` or `hq daemon restart --daemon` in the runtime-health row when the Unix hqd socket is unreachable, based on whether its service is installed.
10
+ - Run shared typecheck and lint once on pull requests while retaining the Node 20 build and test coverage leg.
11
+ - Honor blocked lead `next_check_at` values behind the existing blocked-resume flag, and report due blocked checks in the keep-alive audit.
12
+ - Release package-use leases for agent kit, agent MCP, mesh daemon, lanes watch and wait, and monitor hook wait only after each resident import graph loads.
13
+ - Share one Node 22 CLI build artifact across the four e2e shards to reduce repeated build work.
14
+ - Remove the unused remote vault database helpers. No command called them.
15
+ - Updated semver and its type definitions, and pinned esbuild to 0.28.2.
16
+ - Combine the live Windows pipe DACL and current-user SID inspection in one PowerShell process in the integration test.
17
+
18
+ ## [5.342.12] — 2026-10-04
19
+
20
+ - Record every lane worker resume with its launch time and trigger, and classify watcher, monitor-event, and pending-work wakes separately from keep-alive timer accuracy.
21
+
22
+ - Hand off the package-use lease through a non-JSON marker after a re-executed CLI publishes its matching lease, and forward parent-only stop signals to the child.
23
+
5
24
  ## [5.342.11] — 2026-10-04
6
25
  - Release the CLI package-use lease before interactive login waits after resident modules preload.
7
26
  - Show the cached version update nudge after interactive commands when a newer cached release remains and its feature flag is enabled; avoid waiting for registry readiness when there is no nudge to show or repeating guidance after the updater already reported its result.
@@ -11147,7 +11147,7 @@ export declare const COMMAND_CATALOG: readonly [{
11147
11147
  readonly subcommands: readonly [];
11148
11148
  }, {
11149
11149
  readonly name: "keep-alive-audit";
11150
- readonly description: "Audit lead lane keep-alive timing. A later envelope proves another turn ran and may reclassify an expired stop as restarted_untimed when no launch record remains; late_restarts_after_window counts known launches after the grace window.";
11150
+ readonly description: "Audit lead lane keep-alive timing. Durable worker-resume events retain launch time and trigger after bounded lane history rolls over; late_restarts_after_window counts known launches after the grace window.";
11151
11151
  readonly aliases: readonly [];
11152
11152
  readonly hidden: false;
11153
11153
  readonly helpOption: true;
@@ -13537,7 +13537,7 @@ export const COMMAND_CATALOG = [
13537
13537
  },
13538
13538
  {
13539
13539
  "name": "keep-alive-audit",
13540
- "description": "Audit lead lane keep-alive timing. A later envelope proves another turn ran and may reclassify an expired stop as restarted_untimed when no launch record remains; late_restarts_after_window counts known launches after the grace window.",
13540
+ "description": "Audit lead lane keep-alive timing. Durable worker-resume events retain launch time and trigger after bounded lane history rolls over; late_restarts_after_window counts known launches after the grace window.",
13541
13541
  "aliases": [],
13542
13542
  "hidden": false,
13543
13543
  "helpOption": true,
@@ -24,6 +24,7 @@ import { type KitLogger } from "../lib/agent-kit/log.js";
24
24
  import { type AgentKitPaths } from "../lib/agent-kit/paths.js";
25
25
  import { type KitService } from "../lib/agent-kit/services.js";
26
26
  import { type CronRunner, type RebootCronResult, type DetachedSpawn, type KillFn } from "../lib/agent-kit/fallback.js";
27
+ import { type ResidentCommandLeaseOptions } from "../utils/resident-package-preload.js";
27
28
  import { type ServiceHostPaths, type ServiceManagerDeps, type ServiceSetResult } from "../lib/service-manager/index.js";
28
29
  import type { HeartbeatCredsSource } from "../lib/heartbeat-identity.js";
29
30
  export declare class KitError extends Error {
@@ -83,5 +84,6 @@ export declare function runKitService(service: KitService, rt: KitRuntime): Prom
83
84
  /** `kit run all`: supervise the kit services as child processes with restart backoff. */
84
85
  export declare function runAllKitServices(rt: KitRuntime, host: ServiceHostPaths): Promise<void>;
85
86
  export declare function formatFallbackStatus(paths: AgentKitPaths, kill?: KillFn): string[] | null;
87
+ export declare function runAgentKitWithPackageLease<T>(run: () => Promise<T>, options?: ResidentCommandLeaseOptions): Promise<T>;
86
88
  export declare function registerAgentKitCommand(agent: Command): void;
87
89
  //# sourceMappingURL=agent-kit.d.ts.map
@@ -33,6 +33,7 @@ import { runInboxLoop } from "../lib/agent-kit/run/inbox.js";
33
33
  import { superviseKitServices } from "../lib/agent-kit/run/supervisor.js";
34
34
  import { fallbackStatus, rebootCrontabLine, ensureRebootCrontab, shouldUseFallback, startFallback, stopFallback, } from "../lib/agent-kit/fallback.js";
35
35
  import { serviceLogPath } from "../lib/agent-kit/paths.js";
36
+ import { runResidentCommandWithPackageLease } from "../utils/resident-package-preload.js";
36
37
  import { spawn } from "node:child_process";
37
38
  import { pendingInbox } from "../lib/agent-kit/inbox-state.js";
38
39
  import { buildWakeNotice, clearWakeConfig, currentWakeState, DEFAULT_WAKE_RETRY_MS, describeWake, fireWake, readWakeConfig, validateWakeUrl, writeWakeConfig, } from "../lib/agent-kit/wake.js";
@@ -242,6 +243,9 @@ function fail(err) {
242
243
  console.error(chalk.red(err instanceof Error ? err.message : String(err)));
243
244
  process.exit(1);
244
245
  }
246
+ export function runAgentKitWithPackageLease(run, options) {
247
+ return runResidentCommandWithPackageLease("agent-kit", run, options);
248
+ }
245
249
  export function registerAgentKitCommand(agent) {
246
250
  const kit = agent
247
251
  .command("kit")
@@ -453,28 +457,30 @@ export function registerAgentKitCommand(agent) {
453
457
  .command("run <service>")
454
458
  .description(`Run one kit service in the foreground (${KIT_SERVICES.join("|")}), or \`all\` to supervise every service in one process`)
455
459
  .action(async (service) => {
456
- if (service === "all") {
460
+ if (service !== "all" && !isKitService(service)) {
461
+ console.error(chalk.red(`Unknown kit service "${service}". Expected one of: all, ${KIT_SERVICES.join(", ")}`));
462
+ process.exit(1);
463
+ }
464
+ await runAgentKitWithPackageLease(async () => {
465
+ if (service === "all") {
466
+ try {
467
+ const paths = agentKitPaths(os.homedir(), process.env);
468
+ const rt = buildKitRuntime("all");
469
+ await runAllKitServices(rt, resolveServiceHost(paths));
470
+ process.exit(0);
471
+ }
472
+ catch (err) {
473
+ fail(err);
474
+ }
475
+ }
457
476
  try {
458
- const paths = agentKitPaths(os.homedir(), process.env);
459
- const rt = buildKitRuntime("all");
460
- await runAllKitServices(rt, resolveServiceHost(paths));
461
- process.exit(0);
477
+ const rt = buildKitRuntime(service);
478
+ await runKitService(service, rt);
462
479
  }
463
480
  catch (err) {
464
481
  fail(err);
465
482
  }
466
- }
467
- if (!isKitService(service)) {
468
- console.error(chalk.red(`Unknown kit service "${service}". Expected one of: all, ${KIT_SERVICES.join(", ")}`));
469
- process.exit(1);
470
- }
471
- try {
472
- const rt = buildKitRuntime(service);
473
- await runKitService(service, rt);
474
- }
475
- catch (err) {
476
- fail(err);
477
- }
483
+ });
478
484
  });
479
485
  }
480
486
  //# sourceMappingURL=agent-kit.js.map
@@ -13,6 +13,7 @@ import { McpServer } from "../lib/agent-kit/mcp/jsonrpc.js";
13
13
  import { type HqRunResult, type McpToolClients } from "../lib/agent-kit/mcp/tools.js";
14
14
  import { type AgentKitPaths } from "../lib/agent-kit/paths.js";
15
15
  import type { ExternalMachineCreds } from "../lib/agent-kit/creds.js";
16
+ import { type ResidentCommandLeaseOptions } from "../utils/resident-package-preload.js";
16
17
  export { readBounded } from "../lib/agent-kit/attachment-download.js";
17
18
  export declare const AGENT_MCP_SERVER_NAME = "hq-agent";
18
19
  export declare const AGENT_MCP_INSTRUCTIONS: string;
@@ -20,5 +21,6 @@ export declare const HQ_SUBPROCESS_TIMEOUT_MS = 120000;
20
21
  export declare function defaultRunHq(nodeBinary: string, hqBinary: string, env: NodeJS.ProcessEnv): (args: string[]) => Promise<HqRunResult>;
21
22
  export declare function defaultMcpClients(creds: ExternalMachineCreds, credsPath: string, paths?: Pick<AgentKitPaths, "inboxDir" | "attachmentsDir">): McpToolClients;
22
23
  export declare function createAgentMcpServer(clients: McpToolClients): McpServer;
24
+ export declare function runAgentMcpWithPackageLease<T>(run: () => Promise<T>, options?: ResidentCommandLeaseOptions): Promise<T>;
23
25
  export declare function registerAgentMcpCommand(agent: Command): void;
24
26
  //# sourceMappingURL=agent-mcp.d.ts.map
@@ -19,6 +19,7 @@ import { buildAgentMcpTools } from "../lib/agent-kit/mcp/tools.js";
19
19
  import { readKitConfig } from "../lib/agent-kit/kit-config.js";
20
20
  import { agentKitPaths } from "../lib/agent-kit/paths.js";
21
21
  import { requireExternalCreds } from "./agent-kit.js";
22
+ import { runResidentCommandWithPackageLease } from "../utils/resident-package-preload.js";
22
23
  // Re-exported for callers that imported it from here before it moved.
23
24
  export { readBounded } from "../lib/agent-kit/attachment-download.js";
24
25
  export const AGENT_MCP_SERVER_NAME = "hq-agent";
@@ -102,26 +103,31 @@ export function createAgentMcpServer(clients) {
102
103
  tools: buildAgentMcpTools(clients),
103
104
  });
104
105
  }
106
+ export function runAgentMcpWithPackageLease(run, options) {
107
+ return runResidentCommandWithPackageLease("agent-mcp", run, options);
108
+ }
105
109
  export function registerAgentMcpCommand(agent) {
106
110
  agent
107
111
  .command("mcp")
108
112
  .description("Serve HQ as a stdio MCP server for the bot framework (whoami, search, files, secrets-exec, dm, inbox, work-mesh)")
109
113
  .action(async () => {
110
- const paths = agentKitPaths(os.homedir(), process.env);
111
- let creds;
112
- try {
113
- creds = requireExternalCreds(paths);
114
- }
115
- catch (err) {
116
- process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
117
- process.exit(1);
118
- }
119
- process.env.HQ_MACHINE_CREDS_FILE = paths.machineCredsPath;
120
- process.env.HQ_REQUIRE_MACHINE_IDENTITY = "1";
121
- process.env.HQ_VAULT_API_URL = creds.apiBaseUrl;
122
- const server = createAgentMcpServer(defaultMcpClients(creds, paths.machineCredsPath, paths));
123
- process.stderr.write(`hq agent mcp: serving as ${creds.entityUid} (${creds.companySlug})\n`);
124
- await server.serve(process.stdin, process.stdout);
114
+ await runAgentMcpWithPackageLease(async () => {
115
+ const paths = agentKitPaths(os.homedir(), process.env);
116
+ let creds;
117
+ try {
118
+ creds = requireExternalCreds(paths);
119
+ }
120
+ catch (err) {
121
+ process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
122
+ process.exit(1);
123
+ }
124
+ process.env.HQ_MACHINE_CREDS_FILE = paths.machineCredsPath;
125
+ process.env.HQ_REQUIRE_MACHINE_IDENTITY = "1";
126
+ process.env.HQ_VAULT_API_URL = creds.apiBaseUrl;
127
+ const server = createAgentMcpServer(defaultMcpClients(creds, paths.machineCredsPath, paths));
128
+ process.stderr.write(`hq agent mcp: serving as ${creds.entityUid} (${creds.companySlug})\n`);
129
+ await server.serve(process.stdin, process.stdout);
130
+ });
125
131
  });
126
132
  }
127
133
  //# sourceMappingURL=agent-mcp.js.map
@@ -2,7 +2,7 @@ import { buildKeepAliveAudit, formatKeepAliveAuditText } from "../lib/lanes/keep
2
2
  export function registerLaneKeepAliveAuditCommand(parent, deps) {
3
3
  parent
4
4
  .command("keep-alive-audit")
5
- .description("Audit lead lane keep-alive timing. A later envelope proves another turn ran and may reclassify an expired stop as restarted_untimed when no launch record remains; late_restarts_after_window counts known launches after the grace window.")
5
+ .description("Audit lead lane keep-alive timing. Durable worker-resume events retain launch time and trigger after bounded lane history rolls over; late_restarts_after_window counts known launches after the grace window.")
6
6
  .option("--since <iso>", "Include stopped turns at or after this ISO date-time")
7
7
  .option("--lane <id>", "Audit one exact lane id")
8
8
  .option("--json", "Print the report as JSON")
@@ -1,6 +1,24 @@
1
- import { type Ctx, type LaneMessageHandlerDeps, type LaneMessageOptions } from "./lanes-shared.js";
1
+ import { type Ctx, type LaneMessageHandlerDeps, type LaneMessageOptions, type LaneMessageResponse } from "./lanes-shared.js";
2
+ export interface MonitorLaneMessagePayload {
3
+ text: string;
4
+ monitor_id: string;
5
+ description: string;
6
+ sequence: number;
7
+ }
8
+ export type MonitorLaneMessageResult = {
9
+ ok: true;
10
+ response: LaneMessageResponse | undefined;
11
+ } | {
12
+ ok: false;
13
+ error: unknown;
14
+ errorCode: string;
15
+ message: string;
16
+ };
17
+ export declare function parseMonitorLaneMessagePayload(input: unknown): MonitorLaneMessagePayload;
18
+ export declare function deliverMonitorLaneMessage(ctx: Ctx, laneId: string, input: unknown, runMessage: (ctx: Ctx, laneId: string, options: LaneMessageOptions) => Promise<LaneMessageResponse | undefined>): Promise<MonitorLaneMessageResult>;
2
19
  export declare function createLaneMessageHandlers(deps: LaneMessageHandlerDeps): {
3
- runMessage: (ctx: Ctx, laneId: string, opts: LaneMessageOptions) => Promise<void>;
20
+ runMessage: (ctx: Ctx, laneId: string, opts: LaneMessageOptions) => Promise<LaneMessageResponse | undefined>;
21
+ deliverMonitorLaneMessage: (ctx: Ctx, laneId: string, input: unknown) => Promise<MonitorLaneMessageResult>;
4
22
  recoverQueuedMessages: (ctx: Ctx, laneId: string) => Promise<{
5
23
  action: "none" | "resumed" | "undeliverable";
6
24
  message_count: number;
@@ -1,7 +1,8 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import { appendCappedHistory, appendDropboxMessage, deliveryRefusalReason, dropboxInboxPath, laneAcceptsOperatorMessage, laneDeliveryMechanism, operatorMessageRefusalReason, providerSessionPortable, providerSupportsSessionResume, readLane, sessionNotPortableMessage, validateProjectStories, withLaneAdmissionLock } from "../lib/lanes/index.js";
4
- import { LanesError } from "../lib/lanes/errors.js";
4
+ import { isLanesError, LanesError } from "../lib/lanes/errors.js";
5
+ import { CompanySelectionError } from "../utils/company-selection-error.js";
5
6
  import { parseCliEffort } from "../lib/lanes/effort.js";
6
7
  import { parseOutpostHireGrantContext, sameHireGrantSenior } from "../lib/lanes/hire-grant-dispatch.js";
7
8
  import { dispatchLaneDelivery } from "../lib/lanes/delivery-core.js";
@@ -15,6 +16,60 @@ import { readLanesRegistryFlag } from "../lib/lanes/registry-flag.js";
15
16
  import { lowDiskGuardEnabledForLane } from "../lib/lanes/disk-guard.js";
16
17
  import { resolveLaneCompany } from "../lib/lanes/lane-company.js";
17
18
  import { accountMoveSummary, accountRequestKeepsCurrentLane, assertCurrentResumeAccountAvailable, callerMatchesSessionSenior, recordedResumeEffort, resetKeepAliveProgress, resolveResumeEffort } from "./lanes-shared.js";
19
+ export function parseMonitorLaneMessagePayload(input) {
20
+ let payload = input;
21
+ if (typeof input === "string") {
22
+ try {
23
+ payload = JSON.parse(input);
24
+ }
25
+ catch (err) {
26
+ throw new LanesError("monitor_lane_payload_invalid", `Monitor lane delivery payload is invalid JSON: ${err instanceof Error ? err.message : String(err)}.`, {});
27
+ }
28
+ }
29
+ if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
30
+ throw new LanesError("monitor_lane_payload_invalid", "Monitor lane delivery payload must be an object.", {});
31
+ }
32
+ const value = payload;
33
+ if (typeof value.text !== "string" ||
34
+ typeof value.monitor_id !== "string" ||
35
+ typeof value.description !== "string" ||
36
+ !Number.isInteger(value.sequence) ||
37
+ Number(value.sequence) < 1) {
38
+ throw new LanesError("monitor_lane_payload_invalid", "Monitor lane delivery payload is missing text, monitor metadata, or sequence.", {});
39
+ }
40
+ return {
41
+ text: value.text,
42
+ monitor_id: value.monitor_id,
43
+ description: value.description,
44
+ sequence: Number(value.sequence),
45
+ };
46
+ }
47
+ export async function deliverMonitorLaneMessage(ctx, laneId, input, runMessage) {
48
+ try {
49
+ const payload = parseMonitorLaneMessagePayload(input);
50
+ const response = await runMessage(ctx, laneId, {
51
+ text: payload.text,
52
+ monitorEvent: {
53
+ monitor_id: payload.monitor_id,
54
+ description: payload.description,
55
+ sequence: payload.sequence,
56
+ },
57
+ silent: true,
58
+ });
59
+ return { ok: true, response };
60
+ }
61
+ catch (error) {
62
+ const commandError = error instanceof CompanySelectionError
63
+ ? new LanesError("company_selection_failed", error.message)
64
+ : error;
65
+ return {
66
+ ok: false,
67
+ error: commandError,
68
+ errorCode: isLanesError(commandError) ? commandError.error : "internal",
69
+ message: commandError instanceof Error ? commandError.message : String(commandError),
70
+ };
71
+ }
72
+ }
18
73
  export function createLaneMessageHandlers(deps) {
19
74
  const { archiveResumeMessage, assertLaneRunsHereForAdmission, assertLaneRunsHereForOperatorMutation, assessLaneAdmission, casUpdateLane, dispatchOutpostLaneCommand, dispatchPrimaryLaneMessage, drainHookStatusFor, laneIsHostedHere, laneWithRecoveredProviderSession, loadAllLanes, mintMessageId, persistClaudeAccountSelection, prepareAccountMove, printJson, recordResumeSetup, resolveActiveQuestionCompany, resolveResumeProfile, selectAutomaticClaudeResumeAccount, validateResumeProfileModel, withResumeHireAdmission } = deps;
20
75
  function currentSuccessorOf(lane, lanes, lineageAware, companyForLane) {
@@ -843,43 +898,45 @@ export function createLaneMessageHandlers(deps) {
843
898
  ? `The worker has made no tool call since ${next.stalled_at ?? "an unknown time"} (${next.stalled_reason ?? "stalled"}); delivery waits on its next tool call.`
844
899
  : null,
845
900
  ].filter((message) => message !== undefined && message !== null).join(" ") || null;
901
+ const response = {
902
+ ok: true,
903
+ action: "message",
904
+ lane_id: laneId,
905
+ message_id: messageId,
906
+ accepted: true,
907
+ delivered: false,
908
+ delivery: mechanism,
909
+ delivered_to: { host: lane.host.id, lane_id: laneId, mechanism },
910
+ delivery_status: deliveryStatus,
911
+ ...(queuedOnQuotaHold ? {
912
+ queued_reason: "account_quota_held",
913
+ quota_hold: {
914
+ reason: "account_quota_held",
915
+ quota_reset_at: quotaHoldDeferred?.quota_reset_at ?? null,
916
+ model: quotaHoldDeferred?.model ?? null,
917
+ },
918
+ } : {}),
919
+ inbox_path: mechanism === "dropbox" ? dropboxInboxPath(hqRoot, laneId) : null,
920
+ drain_hook: drainHook,
921
+ warning,
922
+ ...(questionCancellation === null ? {} : {
923
+ cancelled_questions: questionCancellation.cancelled_question_ids,
924
+ question_cancellation_failures: questionCancellation.failures,
925
+ }),
926
+ resumed_session_id: resumed?.last_resume?.session_id ?? null,
927
+ compaction: resumed?.last_compaction && resumed.last_compaction.resume_at === resumed.last_resume?.at
928
+ ? resumed.last_compaction
929
+ : null,
930
+ account_move: move ? accountMoveSummary(move) : null,
931
+ project_id: next.project_id,
932
+ story_id: next.story_id,
933
+ stories: laneStories(next),
934
+ story_warning: storyWarning(next) ?? null,
935
+ lane: next,
936
+ };
846
937
  if (!opts.silent)
847
- printJson({
848
- ok: true,
849
- action: "message",
850
- lane_id: laneId,
851
- message_id: messageId,
852
- accepted: true,
853
- delivered: false,
854
- delivery: mechanism,
855
- delivered_to: { host: lane.host.id, lane_id: laneId, mechanism },
856
- delivery_status: deliveryStatus,
857
- ...(queuedOnQuotaHold ? {
858
- queued_reason: "account_quota_held",
859
- quota_hold: {
860
- reason: "account_quota_held",
861
- quota_reset_at: quotaHoldDeferred?.quota_reset_at ?? null,
862
- model: quotaHoldDeferred?.model ?? null,
863
- },
864
- } : {}),
865
- inbox_path: mechanism === "dropbox" ? dropboxInboxPath(hqRoot, laneId) : null,
866
- drain_hook: drainHook,
867
- warning,
868
- ...(questionCancellation === null ? {} : {
869
- cancelled_questions: questionCancellation.cancelled_question_ids,
870
- question_cancellation_failures: questionCancellation.failures,
871
- }),
872
- resumed_session_id: resumed?.last_resume?.session_id ?? null,
873
- compaction: resumed?.last_compaction && resumed.last_compaction.resume_at === resumed.last_resume?.at
874
- ? resumed.last_compaction
875
- : null,
876
- account_move: move ? accountMoveSummary(move) : null,
877
- project_id: next.project_id,
878
- story_id: next.story_id,
879
- stories: laneStories(next),
880
- story_warning: storyWarning(next) ?? null,
881
- lane: next,
882
- });
938
+ printJson(response);
939
+ return response;
883
940
  }
884
941
  catch (err) {
885
942
  if (storySwitchRollback !== undefined && !storySwitchDeliveryStarted) {
@@ -994,6 +1051,10 @@ export function createLaneMessageHandlers(deps) {
994
1051
  throw err;
995
1052
  }
996
1053
  }
997
- return { runMessage, recoverQueuedMessages };
1054
+ return {
1055
+ runMessage,
1056
+ deliverMonitorLaneMessage: (ctx, laneId, input) => deliverMonitorLaneMessage(ctx, laneId, input, runMessage),
1057
+ recoverQueuedMessages,
1058
+ };
998
1059
  }
999
1060
  //# sourceMappingURL=lanes-message.js.map
@@ -60,6 +60,7 @@ export interface LaneMessageOptions {
60
60
  /** Internal recovery claim is safe to archive once this callback runs. */
61
61
  onAccepted?: () => void;
62
62
  }
63
+ export type LaneMessageResponse = Record<string, unknown>;
63
64
  export interface LaneResumeOptions {
64
65
  text?: string;
65
66
  fromFailed?: boolean;
@@ -6,6 +6,7 @@
6
6
  * `watch` and the monitor reminder are the line-oriented text surfaces.
7
7
  */
8
8
  import { Command } from "commander";
9
+ import type { MonitorLaneMessagePayload, MonitorLaneMessageResult } from "./lanes-message.js";
9
10
  import { type LanesMesh, type OutpostRouteIdentity, type SpawnLoginResult } from "./lanes-shared.js";
10
11
  export type { LanesMesh, SpawnLoginResult } from "./lanes-shared.js";
11
12
  export { CLAUDE_ACCOUNT_BALANCE_SIGNALS_FLAG, LANE_OUTPOST_LOAD_BALANCING_FLAG } from "./lanes-shared.js";
@@ -105,6 +106,9 @@ export interface LanesCommandDeps {
105
106
  /** Test seam for the repository-merge-hold registry flag. */
106
107
  mergeHoldEnabled?: (company: LaneCompanyRef) => boolean | Promise<boolean>;
107
108
  }
109
+ export type MonitorLaneMessageApi = (laneId: string, payload: MonitorLaneMessagePayload) => Promise<MonitorLaneMessageResult>;
110
+ /** Build the same lane message handlers used by `hq lanes _monitor-message`, without a CLI process boundary. */
111
+ export declare function createMonitorLaneMessageApi(hqRoot: string, cwd: string, env?: NodeJS.ProcessEnv): MonitorLaneMessageApi;
108
112
  export declare function parseSeniorRef(raw: string): SeniorRef;
109
113
  export declare function parseQuestionBody(raw: unknown): QuestionBody | null;
110
114
  /**
@@ -10,7 +10,7 @@ import { randomBytes } from "node:crypto";
10
10
  import * as fs from "node:fs";
11
11
  import * as os from "node:os";
12
12
  import * as path from "node:path";
13
- import { Option } from "commander";
13
+ import { Command, Option } from "commander";
14
14
  import { createLaneAccountsHandlers } from "./lanes-accounts.js";
15
15
  import { createLaneMessageHandlers } from "./lanes-message.js";
16
16
  import { createLaneMoveHandlers } from "./lanes-move.js";
@@ -34,6 +34,7 @@ import { ensureCognitoToken } from "../utils/cognito-session.js";
34
34
  import { withCliFeatureUsed } from "../utils/cli-telemetry.js";
35
35
  import { resolveLanesHqRoot } from "../lib/lanes/hq-root.js";
36
36
  import { isSsmRunCommandProcess } from "../lib/lanes/ssm-command-context.js";
37
+ import { runResidentCommandWithPackageLease } from "../utils/resident-package-preload.js";
37
38
  import { readLanesFlagLocalOverride, readLanesRegistryFlag, readLanesRegistryFlagFailOff } from "../lib/lanes/registry-flag.js";
38
39
  import { LANE_HIRE_GRANT_FINISHED_LANES_FLAG, LANE_LIST_SKIP_REMOTE_REFRESH_FLAG, LANE_MESSAGE_ROUTE_OWNER_HOST_FLAG, LANE_ORPHANED_BARE_ID_DROPBOX_REPAIR_FLAG, LANE_REUSE_REFRESHES_PROFILE_FLAG, } from "../lib/lanes/flag-keys.js";
39
40
  import { CODEX_ROLLOUT_RETENTION_FLAG, configuredCodexRolloutHomes, lowDiskGuardEnabledForLane, retainCodexRollouts } from "../lib/lanes/disk-guard.js";
@@ -90,6 +91,20 @@ const REMOTE_MIRROR_REFRESH_BATCH_SIZE = 100;
90
91
  const REMOTE_LANE_NOT_FOUND_GRACE_MS = 15 * 60_000;
91
92
  /** The lane → mesh seam. Defined in lib/lanes/mesh-events.ts; the watcher shares it. */
92
93
  export { emitLaneDecisionEvents };
94
+ const monitorLaneMessageApis = new WeakMap();
95
+ /** Build the same lane message handlers used by `hq lanes _monitor-message`, without a CLI process boundary. */
96
+ export function createMonitorLaneMessageApi(hqRoot, cwd, env = process.env) {
97
+ const program = new Command();
98
+ registerLanesCommand(program, {
99
+ hqRoot: () => hqRoot,
100
+ cwd: () => cwd,
101
+ env: { ...env, HQ_ROOT: hqRoot },
102
+ });
103
+ const api = monitorLaneMessageApis.get(program);
104
+ if (!api)
105
+ throw new Error("Monitor lane message handler was not registered");
106
+ return api;
107
+ }
93
108
  function withoutProviderHome(value) {
94
109
  if (Array.isArray(value))
95
110
  return value.map(withoutProviderHome);
@@ -8390,6 +8405,7 @@ export function registerLanesCommand(parent, deps = {}) {
8390
8405
  withResumeHireAdmission,
8391
8406
  };
8392
8407
  const messageHandlers = createLaneMessageHandlers(messageHandlerDeps);
8408
+ monitorLaneMessageApis.set(parent, (laneId, payload) => messageHandlers.deliverMonitorLaneMessage(ctx, laneId, payload));
8393
8409
  const resumeHandlers = createLaneResumeHandlers({
8394
8410
  onLaneWorkerStarted: deps.onLaneWorkerStarted,
8395
8411
  archiveResumeMessage,
@@ -8681,13 +8697,13 @@ export function registerLanesCommand(parent, deps = {}) {
8681
8697
  .option("--for <change-type>", "envelope | question | state", collectRepeatable, [])
8682
8698
  .option("--timeout <seconds>", "Positive timeout in seconds")
8683
8699
  .option("--json", "JSON output")
8684
- .action(wrapText(async (opts) => watchHandlers.runWait(ctx, opts)));
8700
+ .action(wrapText(async (opts) => runResidentCommandWithPackageLease("lanes-watch", () => watchHandlers.runWait(ctx, opts))));
8685
8701
  lanes
8686
8702
  .command("watch")
8687
8703
  .description("Watch lane state and question changes until all lanes are terminal")
8688
8704
  .argument("<lane-id...>", "Lane ids to watch")
8689
8705
  .option("--interval-ms <ms>", "Polling interval, bounded to 100ms–30s", "5000")
8690
- .action(wrapText(async (laneIds, opts) => watchHandlers.runWatch(ctx, laneIds, opts)));
8706
+ .action(wrapText(async (laneIds, opts) => runResidentCommandWithPackageLease("lanes-watch", () => watchHandlers.runWatch(ctx, laneIds, opts))));
8691
8707
  lanes
8692
8708
  .command("monitor-check")
8693
8709
  .description("Check that active Claude senior lanes have live Monitor watch tasks")
@@ -8809,33 +8825,11 @@ export function registerLanesCommand(parent, deps = {}) {
8809
8825
  .command("_monitor-message", { hidden: true })
8810
8826
  .argument("<lane-id>", "Lane id")
8811
8827
  .action(wrap(async (laneId) => {
8812
- const input = ctx.readStdin();
8813
- let payload;
8814
- try {
8815
- payload = JSON.parse(input);
8816
- }
8817
- catch (err) {
8818
- throw new LanesError("monitor_lane_payload_invalid", `Monitor lane delivery payload is invalid JSON: ${err instanceof Error ? err.message : String(err)}.`, {});
8819
- }
8820
- if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
8821
- throw new LanesError("monitor_lane_payload_invalid", "Monitor lane delivery payload must be an object.", {});
8822
- }
8823
- const value = payload;
8824
- if (typeof value.text !== "string" ||
8825
- typeof value.monitor_id !== "string" ||
8826
- typeof value.description !== "string" ||
8827
- !Number.isInteger(value.sequence) ||
8828
- Number(value.sequence) < 1) {
8829
- throw new LanesError("monitor_lane_payload_invalid", "Monitor lane delivery payload is missing text, monitor metadata, or sequence.", {});
8830
- }
8831
- await messageHandlers.runMessage(ctx, laneId, {
8832
- text: value.text,
8833
- monitorEvent: {
8834
- monitor_id: value.monitor_id,
8835
- description: value.description,
8836
- sequence: Number(value.sequence),
8837
- },
8838
- });
8828
+ const result = await messageHandlers.deliverMonitorLaneMessage(ctx, laneId, ctx.readStdin());
8829
+ if (!result.ok)
8830
+ throw result.error;
8831
+ if (result.response !== undefined)
8832
+ printJson(result.response);
8839
8833
  }));
8840
8834
  lanes
8841
8835
  .command("resume")
@@ -56,6 +56,7 @@ import { deriveRemoteOwnerSlug, deriveRepoIdentityKey, } from "../lib/work-conte
56
56
  import { promptRepoCompany, } from "../lib/work-context/repo-prompt.js";
57
57
  import { requeueQuarantinedOutbox } from "../lib/work-context/outbox.js";
58
58
  import { handOffInstallHere } from "../lib/daemon/handoff.js";
59
+ import { runResidentCommandWithPackageLease } from "../utils/resident-package-preload.js";
59
60
  export function formatCheckLines(threads, company, projectId) {
60
61
  if (threads.length === 0) {
61
62
  return ["Work mesh: no active project threads found."];
@@ -2108,7 +2109,7 @@ export function registerMeshCommand(program) {
2108
2109
  .command("run")
2109
2110
  .description("Start the single-instance daemon (pid lock, spool watch, presence)")
2110
2111
  .option("--hq-root <path>", "HQ tree root (else HQ_ROOT / persisted trusted roots); the Windows task passes this explicitly")
2111
- .action((opts) => wrap(() => runDaemonRun(opts))());
2112
+ .action((opts) => wrap(() => runResidentCommandWithPackageLease("mesh-daemon", () => runDaemonRun(opts)))());
2112
2113
  daemon
2113
2114
  .command("install")
2114
2115
  .description("Install LaunchAgent (macOS), systemd user unit (Linux), or Scheduled Task (Windows)")
@@ -3,6 +3,7 @@ import { Command } from "commander";
3
3
  import { drainDropboxAtPath } from "../lib/lanes/dropbox.js";
4
4
  import { recordMonitorTargetActivity, type MonitorMetadata, type MonitorState, type MonitorTarget, type MonitorProcessEntry, type MonitorRuntimeIdentity } from "../lib/monitor.js";
5
5
  import type { LaneCompanyRef, LaneProvider } from "../lib/lanes/types.js";
6
+ import { createMonitorLaneMessageApi, type MonitorLaneMessageApi } from "./lanes.js";
6
7
  export declare function findSessionOwner(target: MonitorTarget, deps?: {
7
8
  env?: NodeJS.ProcessEnv;
8
9
  parentPid?: number;
@@ -21,13 +22,25 @@ export declare function runMonitorEnabledCommand(deps?: {
21
22
  }): Promise<number>;
22
23
  export declare function armText(meta: MonitorMetadata): string;
23
24
  export declare function resolveMonitorStartTarget(hqRoot: string, discovered: MonitorTarget, explicitlyProvided: boolean, runtime?: MonitorRuntimeIdentity): MonitorTarget;
24
- export declare function deliverNormalEvent(hqRoot: string, meta: MonitorMetadata, state: MonitorState, rawText: string): Promise<MonitorState>;
25
+ export declare function invokeLaneMonitorMessage(hqRoot: string, meta: MonitorMetadata, sequence: number, text: string, inProcess?: MonitorLaneMessageApi): {
26
+ delivered: boolean;
27
+ outcome: string;
28
+ } | Promise<{
29
+ delivered: boolean;
30
+ outcome: string;
31
+ }>;
32
+ export declare function deliverNormalEvent(hqRoot: string, meta: MonitorMetadata, state: MonitorState, rawText: string, inProcess?: MonitorLaneMessageApi): Promise<MonitorState>;
25
33
  export interface RunSupervisorDeps {
26
34
  resolveRoot?: () => string;
27
35
  monitorEnabled?: typeof monitorEnabled;
28
36
  deliver?: typeof deliverNormalEvent;
29
37
  spawn?: typeof spawn;
38
+ preloadResidentModules?: () => Promise<void>;
39
+ releasePackageUseLease?: () => void;
40
+ reportPreloadFailure?: (error: unknown) => void;
41
+ createLaneMessageApi?: typeof createMonitorLaneMessageApi;
30
42
  }
43
+ export declare function preloadMonitorLaneMessageApi(hqRoot: string, meta: MonitorMetadata, deps?: Pick<RunSupervisorDeps, "preloadResidentModules" | "releasePackageUseLease" | "reportPreloadFailure" | "createLaneMessageApi">): Promise<MonitorLaneMessageApi | undefined>;
31
44
  export declare function runSupervisor(id: string, deps?: RunSupervisorDeps): Promise<void>;
32
45
  interface MonitorHookResult {
33
46
  stdout: string;