@indigoai-us/hq-cli 5.342.12 → 5.342.14

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 (47) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/assets/scaffold/core/scripts/hq-delegate-grant.sh +9 -0
  3. package/assets/scaffold/core/scripts/hq-delegate-send.sh +9 -0
  4. package/assets/scaffold/core/scripts/hq-job-probe.sh +9 -0
  5. package/assets/scaffold/core/scripts/jobs-validate.sh +9 -0
  6. package/dist/commands/agent-kit.d.ts +2 -0
  7. package/dist/commands/agent-kit.js +23 -17
  8. package/dist/commands/agent-mcp.d.ts +2 -0
  9. package/dist/commands/agent-mcp.js +21 -15
  10. package/dist/commands/core-delegate-w1b.js +19 -10
  11. package/dist/commands/core-delegate.d.ts +2 -0
  12. package/dist/commands/core-delegate.js +16 -4
  13. package/dist/commands/core-job-probe-native.d.ts +4 -1
  14. package/dist/commands/core-job-probe-native.js +62 -14
  15. package/dist/commands/core-job-run-native.js +14 -2
  16. package/dist/commands/core-jobs-native.js +2 -1
  17. package/dist/commands/core-ontology-native.js +18 -2
  18. package/dist/commands/core-worker-share-native.js +2 -1
  19. package/dist/commands/lanes-message.d.ts +20 -2
  20. package/dist/commands/lanes-message.js +99 -38
  21. package/dist/commands/lanes-shared.d.ts +1 -0
  22. package/dist/commands/lanes.d.ts +4 -0
  23. package/dist/commands/lanes.js +24 -30
  24. package/dist/commands/mesh.js +2 -1
  25. package/dist/commands/monitor.d.ts +14 -1
  26. package/dist/commands/monitor.js +43 -14
  27. package/dist/lib/core-utils/shell-display-path.d.ts +3 -0
  28. package/dist/lib/core-utils/shell-display-path.js +12 -0
  29. package/dist/lib/doctor/checks/anywhere.js +11 -6
  30. package/dist/lib/flag-registry-worker-source.generated.d.ts +1 -1
  31. package/dist/lib/flag-registry-worker-source.generated.js +1 -1
  32. package/dist/lib/lanes/keep-alive-audit.d.ts +3 -0
  33. package/dist/lib/lanes/keep-alive-audit.js +59 -11
  34. package/dist/lib/lanes/reconcile.js +46 -3
  35. package/dist/lib/lanes/types.d.ts +2 -1
  36. package/dist/utils/resident-package-preload.d.ts +8 -1
  37. package/dist/utils/resident-package-preload.js +68 -0
  38. package/dist/utils/run-bundled-script.d.ts +2 -0
  39. package/dist/utils/run-bundled-script.js +1 -0
  40. package/dist/utils/windows-spawn.d.ts +2 -0
  41. package/dist/utils/windows-spawn.js +6 -0
  42. package/docs/anywhere-runtime.md +3 -1
  43. package/package.json +4 -4
  44. package/dist/lib/db/remote-engine.d.ts +0 -58
  45. package/dist/lib/db/remote-engine.js +0 -87
  46. package/dist/lib/db/remote-sql.d.ts +0 -22
  47. package/dist/lib/db/remote-sql.js +0 -36
@@ -3,8 +3,10 @@ import { createHash } from "node:crypto";
3
3
  import { spawnSync } from "node:child_process";
4
4
  import * as fs from "node:fs";
5
5
  import * as path from "node:path";
6
+ import { resolveWindowsExecutable } from "../lib/bot/runtime/windows.js";
6
7
  import { runBundledScript } from "../utils/run-bundled-script.js";
7
8
  import { resolveBundledAsset } from "../utils/hq-roots.js";
9
+ import { planResolvedCommandSpawn } from "../utils/windows-spawn.js";
8
10
  import { describeCoreCommand } from "./core-command-catalog.js";
9
11
  import { runKnowledgePrefs } from "./core-knowledge-prefs.js";
10
12
  const FLAG = "core-native-ontology";
@@ -55,10 +57,23 @@ export function runOntologyNativeFast(args, _stdin, cwd, hqRoot, commandName) {
55
57
  }
56
58
  function runHq(args, output = "capture") {
57
59
  const executable = process.env.HQ_BIN || "hq";
58
- const result = spawnSync(executable, args, {
60
+ const resolvedExecutable = process.platform === "win32" && !path.isAbsolute(executable) && !executable.includes(path.sep)
61
+ ? resolveWindowsExecutable(executable, process.env, (candidate) => {
62
+ try {
63
+ return fs.statSync(candidate).isFile();
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ }, process.cwd()) ?? executable
69
+ : executable;
70
+ const plan = planResolvedCommandSpawn(resolvedExecutable, args, process.env);
71
+ const result = spawnSync(plan.cmd, plan.args, {
59
72
  cwd: process.cwd(),
60
73
  env: process.env,
61
74
  encoding: "utf8",
75
+ shell: plan.shell,
76
+ ...(plan.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}),
62
77
  stdio: output === "ignore" ? ["ignore", "ignore", "ignore"] : ["ignore", "pipe", "ignore"],
63
78
  });
64
79
  return { status: result.status, stdout: typeof result.stdout === "string" ? result.stdout : "" };
@@ -522,7 +537,8 @@ export function gardenCommand(args, defaultRoot) {
522
537
  source_ref: JSON.stringify(fm.source_ref || ""), created_at: String(fm.created_at || isoNow()),
523
538
  }, body, dryRun);
524
539
  report.signals_promoted += 1;
525
- index.push({ signal_id: id, type, audience_key: key, path: path.relative(companyDir, outputFile) });
540
+ const outputPath = path.relative(companyDir, outputFile);
541
+ index.push({ signal_id: id, type, audience_key: key, path: process.platform === "win32" ? outputPath.replaceAll("\\", "/") : outputPath });
526
542
  if (key !== "company") {
527
543
  const audienceFile = path.join(scopeDirectory, "_audience.yaml");
528
544
  if (!fs.existsSync(audienceFile) && !dryRun) {
@@ -56,7 +56,8 @@ function isRegularFile(filePath, fileSystem) {
56
56
  }
57
57
  }
58
58
  function readLink(filePath, fileSystem) {
59
- return fileSystem.readlinkSync(filePath);
59
+ const target = fileSystem.readlinkSync(filePath);
60
+ return process.platform === "win32" ? target.replaceAll("\\", "/") : target;
60
61
  }
61
62
  function sameBytes(leftPath, rightPath, fileSystem) {
62
63
  try {
@@ -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;
@@ -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;
@@ -0,0 +1,3 @@
1
+ /** Render a native path with the path spelling used by the bundled Bash scripts. */
2
+ export declare function shellDisplayPath(value: string): string;
3
+ //# sourceMappingURL=shell-display-path.d.ts.map
@@ -0,0 +1,12 @@
1
+ import * as path from "node:path";
2
+ /** Render a native path with the path spelling used by the bundled Bash scripts. */
3
+ export function shellDisplayPath(value) {
4
+ if (process.platform !== "win32")
5
+ return value;
6
+ const absolute = path.win32.resolve(value);
7
+ const match = /^([A-Za-z]):[\\/](.*)$/.exec(absolute);
8
+ if (!match?.[1] || match[2] === undefined)
9
+ return value;
10
+ return `/${match[1].toLowerCase()}/${match[2].replaceAll("\\", "/")}`;
11
+ }
12
+ //# sourceMappingURL=shell-display-path.js.map