chatroom-cli 1.65.7 → 1.65.9

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/dist/index.js CHANGED
@@ -36196,6 +36196,21 @@ var init_terminal_provider_error = __esm(() => {
36196
36196
  PROVIDER_ERROR_NAMES = ["ai_apicallerror", "ai_retryerror"];
36197
36197
  });
36198
36198
 
36199
+ // src/infrastructure/services/remote-agents/opencode-sdk/opencode-session-status.ts
36200
+ function isOpenCodeSessionStatus(value) {
36201
+ return typeof value === "string" && OPENCODE_SESSION_STATUSES.includes(value);
36202
+ }
36203
+ function parseOpenCodeSessionStatus(raw) {
36204
+ return isOpenCodeSessionStatus(raw) ? raw : null;
36205
+ }
36206
+ function assertNeverOpenCodeSessionStatus(value, context5) {
36207
+ throw new Error(`Unhandled OpenCode session status in ${context5}: ${String(value)}`);
36208
+ }
36209
+ var OPENCODE_SESSION_STATUSES;
36210
+ var init_opencode_session_status = __esm(() => {
36211
+ OPENCODE_SESSION_STATUSES = ["idle", "busy", "retry"];
36212
+ });
36213
+
36199
36214
  // src/infrastructure/services/remote-agents/opencode-sdk/session-event-forwarder.ts
36200
36215
  function formatLogLine(options, kind, payload) {
36201
36216
  return formatTimestampedLogLine(options.role, kind, payload, options.now);
@@ -36304,6 +36319,15 @@ function startSessionEventForwarder(client4, options) {
36304
36319
  cancelled = true;
36305
36320
  emitAgentEnd("provider_rate_limit");
36306
36321
  }
36322
+ function armTurnEnd() {
36323
+ if (terminalAbortRequested) {
36324
+ logLine(target, "status", "turn_arm_blocked_terminal");
36325
+ return;
36326
+ }
36327
+ clearRetryIdleTimeout();
36328
+ agentEndEmitted = false;
36329
+ lastStatus = undefined;
36330
+ }
36307
36331
  function resolvePartContent(delta, text) {
36308
36332
  return delta !== undefined && delta !== "" ? delta : text;
36309
36333
  }
@@ -36386,11 +36410,22 @@ function startSessionEventForwarder(client4, options) {
36386
36410
  logLine(target, "compacted");
36387
36411
  }
36388
36412
  async function handleSessionStatus(props) {
36389
- const currentStatus = props?.status?.type;
36390
- if (currentStatus !== lastStatus) {
36391
- lastStatus = currentStatus;
36392
- logLine(target, "status", currentStatus);
36393
- if (currentStatus === "retry") {
36413
+ const raw = props?.status?.type;
36414
+ const parsed = parseOpenCodeSessionStatus(raw);
36415
+ if (parsed === null) {
36416
+ const unknownKey = raw === undefined ? "undefined" : String(raw);
36417
+ if (unknownKey !== lastStatus) {
36418
+ lastStatus = unknownKey;
36419
+ logLine(target, "status", `unknown_session_status:${unknownKey}`);
36420
+ }
36421
+ return;
36422
+ }
36423
+ if (parsed === lastStatus)
36424
+ return;
36425
+ lastStatus = parsed;
36426
+ logLine(target, "status", parsed);
36427
+ switch (parsed) {
36428
+ case "retry": {
36394
36429
  if (terminalAbortRequested) {
36395
36430
  abortTerminalProviderError();
36396
36431
  return;
@@ -36398,7 +36433,18 @@ function startSessionEventForwarder(client4, options) {
36398
36433
  scheduleRetryIdleTimeout();
36399
36434
  return;
36400
36435
  }
36401
- clearRetryIdleTimeout();
36436
+ case "idle": {
36437
+ clearRetryIdleTimeout();
36438
+ await handleSessionIdle();
36439
+ return;
36440
+ }
36441
+ case "busy": {
36442
+ clearRetryIdleTimeout();
36443
+ return;
36444
+ }
36445
+ default: {
36446
+ assertNeverOpenCodeSessionStatus(parsed, "handleSessionStatus");
36447
+ }
36402
36448
  }
36403
36449
  }
36404
36450
  async function handleSessionError(props) {
@@ -36489,12 +36535,14 @@ function startSessionEventForwarder(client4, options) {
36489
36535
  onAgentEnd: (cb) => {
36490
36536
  agentEndCallbacks.push(cb);
36491
36537
  },
36492
- abortTerminalProviderError
36538
+ abortTerminalProviderError,
36539
+ armTurnEnd
36493
36540
  };
36494
36541
  }
36495
36542
  var RECENT_LOG_LINE_CAP = 20, DEFAULT_SESSION_RETRY_IDLE_TIMEOUT_MS;
36496
36543
  var init_session_event_forwarder = __esm(() => {
36497
36544
  init_terminal_provider_error();
36545
+ init_opencode_session_status();
36498
36546
  DEFAULT_SESSION_RETRY_IDLE_TIMEOUT_MS = 5 * 60 * 1000;
36499
36547
  });
36500
36548
 
@@ -37010,6 +37058,7 @@ var init_opencode_sdk_agent_service = __esm(() => {
37010
37058
  `);
37011
37059
  return;
37012
37060
  }
37061
+ this.forwarders.get(pid)?.armTurnEnd();
37013
37062
  const client4 = createOpencodeClient({ baseUrl: meta.baseUrl });
37014
37063
  const deferredSystem = meta.deferredSystemPrompt;
37015
37064
  const context5 = {
@@ -84676,7 +84725,7 @@ var init_featureFlags = __esm(() => {
84676
84725
  });
84677
84726
 
84678
84727
  // ../../services/backend/config/reliability.ts
84679
- var DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVATION_TTL_MS = 60000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SAFETY_POLL_MS = 30000, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS, CONNECTION_CLOSE_REQUEST_TTL_MS;
84728
+ var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, NATIVE_DELIVERY_RECONCILE_MS = 1e4, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVATION_TTL_MS = 60000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SAFETY_POLL_MS = 30000, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS, CONNECTION_CLOSE_REQUEST_TTL_MS;
84680
84729
  var init_reliability = __esm(() => {
84681
84730
  DAEMON_HEARTBEAT_INTERVAL_MS = 5 * 60000;
84682
84731
  DAEMON_HEARTBEAT_TTL_MS = 6 * DAEMON_HEARTBEAT_INTERVAL_MS;
@@ -84731,6 +84780,780 @@ var init_daemon_services = __esm(() => {
84731
84780
  };
84732
84781
  });
84733
84782
 
84783
+ // ../../services/backend/src/domain/entities/participant.ts
84784
+ var NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", NATIVE_HANDOFF_REMINDER = "Reminder: Use the handoff command to send your response to the team.", ONLINE_OR_STARTING_STATUSES;
84785
+ var init_participant = __esm(() => {
84786
+ ONLINE_OR_STARTING_STATUSES = new Set([
84787
+ "agent.waiting",
84788
+ "agent.requestStart",
84789
+ "agent.started",
84790
+ "task.acknowledged",
84791
+ "task.inProgress",
84792
+ "task.completed",
84793
+ "agent.requestStop",
84794
+ "agent.awaitingHandoff"
84795
+ ]);
84796
+ });
84797
+
84798
+ // src/commands/machine/daemon-start/native-ready-invariant.ts
84799
+ function isAgentReadyForNativeDelivery(task, slot) {
84800
+ return explainAgentReadyForNativeDeliveryBlock(task, slot) === null;
84801
+ }
84802
+ function explainAgentReadyForNativeDeliveryBlock(task, slot) {
84803
+ const { agentConfig } = task;
84804
+ if (!isNativeHarness(agentConfig.agentHarness)) {
84805
+ return `not_native_harness (harness=${agentConfig.agentHarness})`;
84806
+ }
84807
+ if (agentConfig.desiredState !== "running") {
84808
+ return `desired_state_not_running (desiredState=${agentConfig.desiredState})`;
84809
+ }
84810
+ if (agentConfig.spawnedAgentPid == null) {
84811
+ return "spawned_pid_missing";
84812
+ }
84813
+ if (!slot) {
84814
+ return `slot_missing (expectedPid=${agentConfig.spawnedAgentPid})`;
84815
+ }
84816
+ if (slot.state !== "running") {
84817
+ return `slot_not_running (slotState=${slot.state}, expectedPid=${agentConfig.spawnedAgentPid})`;
84818
+ }
84819
+ if (slot.pid !== agentConfig.spawnedAgentPid) {
84820
+ return `pid_mismatch (slotPid=${slot.pid ?? "none"}, snapshotPid=${agentConfig.spawnedAgentPid})`;
84821
+ }
84822
+ if (typeof slot.harnessSessionId !== "string" || slot.harnessSessionId.length === 0) {
84823
+ return "harness_session_missing";
84824
+ }
84825
+ const turnPhase = slot.nativeTurnPhase ?? "idle";
84826
+ if (turnPhase !== "idle") {
84827
+ return `turn_not_idle (nativeTurnPhase=${turnPhase})`;
84828
+ }
84829
+ return null;
84830
+ }
84831
+ function isDeliverableNativeTaskStatus(status3) {
84832
+ return status3 === "pending" || status3 === "acknowledged";
84833
+ }
84834
+ var init_native_ready_invariant = __esm(() => {
84835
+ init_types();
84836
+ });
84837
+
84838
+ // src/commands/machine/daemon-start/assigned-task-snapshot-store.ts
84839
+ function replaceAssignedTaskSnapshots(next4) {
84840
+ rows = [...next4];
84841
+ hasSnapshot = true;
84842
+ }
84843
+ function clearAssignedTaskSnapshots() {
84844
+ rows = [];
84845
+ hasSnapshot = false;
84846
+ }
84847
+ function hasAssignedTaskSnapshot() {
84848
+ return hasSnapshot;
84849
+ }
84850
+ function listAssignedTaskSnapshots() {
84851
+ return [...rows];
84852
+ }
84853
+ function listAssignedTaskSnapshotsForRole(chatroomId, role) {
84854
+ const roleLower = role.toLowerCase();
84855
+ return rows.filter((row) => row.chatroomId === chatroomId && row.agentConfig.role.toLowerCase() === roleLower);
84856
+ }
84857
+ var rows, hasSnapshot = false;
84858
+ var init_assigned_task_snapshot_store = __esm(() => {
84859
+ rows = [];
84860
+ });
84861
+
84862
+ // src/commands/machine/daemon-start/native-delivery-log.ts
84863
+ function logNativeDeliveryPrimary(role, chatroomId) {
84864
+ console.log(`[NativeDelivery:primary] turn idle ${role}@${chatroomId} — trying inject`);
84865
+ }
84866
+ function logNativeDeliveryFallback(reason, role, chatroomId, taskId) {
84867
+ const taskSuffix = taskId ? ` task ${taskId}` : "";
84868
+ console.log(`[NativeDelivery:fallback] ${reason} ${role}@${chatroomId}${taskSuffix} — reconcile`);
84869
+ }
84870
+ function logNativeDeliverySkip(role, chatroomId, taskId, reason) {
84871
+ console.log(`[NativeDelivery:skip] ${role}@${chatroomId} task ${taskId} — ${reason}`);
84872
+ }
84873
+ function logNativeDeliveryMutexSkip(role, chatroomId, taskId) {
84874
+ console.log(`[NativeDelivery:skip] ${role}@${chatroomId} task ${taskId} — delivery_mutex_busy (another inject in flight)`);
84875
+ }
84876
+ function logNativeDeliveryInjecting(role, chatroomId, taskId) {
84877
+ console.log(`[NativeDelivery:inject] ${role}@${chatroomId} task ${taskId} — starting injection`);
84878
+ }
84879
+ function logNativeDeliveryNoTasks(role, chatroomId) {
84880
+ console.log(`[NativeDelivery:skip] ${role}@${chatroomId} — no pending tasks for role`);
84881
+ }
84882
+
84883
+ // src/commands/machine/daemon-start/native-delivery-session-registry.ts
84884
+ function registerNativeDeliverySession(ctx) {
84885
+ registered = ctx;
84886
+ }
84887
+ function unregisterNativeDeliverySession() {
84888
+ registered = null;
84889
+ }
84890
+ function getNativeDeliverySession() {
84891
+ return registered;
84892
+ }
84893
+ var registered = null;
84894
+
84895
+ // src/domain/native-integration/predicates.ts
84896
+ function isStaleCliGetNextTaskWaiting(task) {
84897
+ const lastSeenAt = task.participant?.lastSeenAt ?? 0;
84898
+ return task.participant?.lastSeenAction === "get-next-task:started" && task.createdAt > lastSeenAt;
84899
+ }
84900
+ function isCliIdleNotListening(task, now, thresholdMs) {
84901
+ const lastSeenAt = task.participant?.lastSeenAt ?? 0;
84902
+ if (lastSeenAt === 0)
84903
+ return now - task.createdAt > thresholdMs;
84904
+ return now - lastSeenAt > thresholdMs;
84905
+ }
84906
+
84907
+ // src/infrastructure/services/remote-agents/spawn-prompt.ts
84908
+ function createSpawnPrompt(raw, opts) {
84909
+ if (opts?.nativeBootstrap) {
84910
+ return NATIVE_BOOTSTRAP_PROMPT;
84911
+ }
84912
+ const trimmed = raw?.trim();
84913
+ return trimmed && trimmed.length > 0 ? trimmed : DEFAULT_TRIGGER_PROMPT;
84914
+ }
84915
+ var DEFAULT_TRIGGER_PROMPT = "Please read your system prompt carefully and follow the Getting Started instructions.", NATIVE_BOOTSTRAP_PROMPT = "Focus on your role responsibilities. Complete each task via handoff.";
84916
+
84917
+ // src/domain/native-integration/spawn-policy.ts
84918
+ function shouldDeferInitialTurn(harness) {
84919
+ return isNativeHarness(harness);
84920
+ }
84921
+ function resolveNativeSpawnPolicy(harness, initMessage) {
84922
+ const deferInitialTurn = shouldDeferInitialTurn(harness);
84923
+ return {
84924
+ deferInitialTurn,
84925
+ prompt: createSpawnPrompt(initMessage, { nativeBootstrap: deferInitialTurn })
84926
+ };
84927
+ }
84928
+ var init_spawn_policy = __esm(() => {
84929
+ init_types();
84930
+ });
84931
+
84932
+ // src/domain/native-integration/index.ts
84933
+ var init_native_integration = __esm(() => {
84934
+ init_types();
84935
+ init_spawn_policy();
84936
+ });
84937
+
84938
+ // src/commands/machine/daemon-start/native-task-injector-logic.ts
84939
+ function explainNativeDeliveryBlock(task, opts) {
84940
+ if (!isDeliverableNativeTaskStatus(task.status)) {
84941
+ return `task_status_not_deliverable (status=${task.status})`;
84942
+ }
84943
+ if (task.status === "acknowledged") {
84944
+ const assignedTo = task.assignedTo?.toLowerCase();
84945
+ const role = task.agentConfig.role.toLowerCase();
84946
+ if (assignedTo !== role) {
84947
+ return `acknowledged_wrong_role (assignedTo=${assignedTo ?? "none"}, role=${role})`;
84948
+ }
84949
+ }
84950
+ return explainAgentReadyForNativeDeliveryBlock(task, opts.slot);
84951
+ }
84952
+ function buildNativeInjectionPrompt(params) {
84953
+ const { taskDeliveryOutput, augmentationMode } = params;
84954
+ if (augmentationMode === "compact") {
84955
+ return [
84956
+ "⚠️ Context was compacted. Run `chatroom get-system-prompt` only if role instructions are missing.",
84957
+ "",
84958
+ taskDeliveryOutput
84959
+ ].join(`
84960
+ `);
84961
+ }
84962
+ if (augmentationMode === "new_session") {
84963
+ return [
84964
+ "⚠️ Starting a new agent session. Run `chatroom get-system-prompt` to reload role instructions if needed.",
84965
+ "",
84966
+ taskDeliveryOutput
84967
+ ].join(`
84968
+ `);
84969
+ }
84970
+ return taskDeliveryOutput;
84971
+ }
84972
+ var init_native_task_injector_logic = __esm(() => {
84973
+ init_native_ready_invariant();
84974
+ init_native_integration();
84975
+ });
84976
+
84977
+ // ../../services/backend/src/domain/entities/team-agent-settings.ts
84978
+ function roleSupportsSessionAugmentation(role) {
84979
+ const normalized = role.toLowerCase();
84980
+ return SESSION_AUGMENTATION_ROLES.some((r) => r === normalized);
84981
+ }
84982
+ var SESSION_AUGMENTATION_ROLES;
84983
+ var init_team_agent_settings = __esm(() => {
84984
+ SESSION_AUGMENTATION_ROLES = ["builder"];
84985
+ });
84986
+
84987
+ // ../../services/backend/src/domain/handoff/parse-session-augmentation.ts
84988
+ function findSectionIndex(content, headings) {
84989
+ const indices = headings.map((heading) => content.indexOf(heading)).filter((idx) => idx !== -1);
84990
+ return indices.length === 0 ? -1 : Math.min(...indices);
84991
+ }
84992
+ function normalizeMode(raw) {
84993
+ return MODE_ALIASES[raw.toLowerCase()] ?? DEFAULT_MODE;
84994
+ }
84995
+ function extractSectionBody(content, sectionIdx) {
84996
+ const matchedHeading = SECTION_HEADINGS.find((h) => content.indexOf(h, sectionIdx) === sectionIdx) ?? SECTION_HEADINGS[0];
84997
+ const afterSection = content.slice(sectionIdx);
84998
+ const nextHeading = afterSection.slice(matchedHeading.length).search(/\n## /);
84999
+ return nextHeading === -1 ? afterSection : afterSection.slice(0, matchedHeading.length + nextHeading);
85000
+ }
85001
+ function parseSessionAugmentation(handoffContent) {
85002
+ const sectionIdx = findSectionIndex(handoffContent, SECTION_HEADINGS);
85003
+ if (sectionIdx === -1)
85004
+ return DEFAULT_MODE;
85005
+ const match17 = extractSectionBody(handoffContent, sectionIdx).match(DATA_TAG);
85006
+ if (!match17)
85007
+ return DEFAULT_MODE;
85008
+ return normalizeMode(match17[1]);
85009
+ }
85010
+ function resolveSessionAugmentationForRole(handoffContent, role) {
85011
+ if (!roleSupportsSessionAugmentation(role)) {
85012
+ return "none";
85013
+ }
85014
+ return parseSessionAugmentation(handoffContent);
85015
+ }
85016
+ function sessionAugmentationToWantResume(mode) {
85017
+ return mode === "none" || mode === "compact";
85018
+ }
85019
+ function sessionAugmentationNewSessionStarted(mode) {
85020
+ return mode === "new_session";
85021
+ }
85022
+ var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session", MODE_ALIASES;
85023
+ var init_parse_session_augmentation = __esm(() => {
85024
+ init_team_agent_settings();
85025
+ SECTION_HEADINGS = [
85026
+ "## Session Augmentation",
85027
+ "## Session Management",
85028
+ "## Restart new context"
85029
+ ];
85030
+ DATA_TAG = /\/\/\s*data:agent\.(?:session_augmentation|compress_context)=(none|compact|new_session|reset)\b/i;
85031
+ MODE_ALIASES = {
85032
+ reset: "new_session",
85033
+ none: "none",
85034
+ compact: "compact",
85035
+ new_session: "new_session"
85036
+ };
85037
+ });
85038
+
85039
+ // src/commands/machine/daemon-start/native-task-injector.ts
85040
+ async function emitTaskDeliveryFailed(deps, args2) {
85041
+ try {
85042
+ await deps.backend.mutation(api.machines.emitTaskDeliveryFailed, {
85043
+ sessionId: deps.sessionId,
85044
+ machineId: deps.machineId,
85045
+ chatroomId: args2.chatroomId,
85046
+ role: args2.role,
85047
+ taskId: args2.taskId,
85048
+ error: args2.error
85049
+ });
85050
+ } catch {}
85051
+ }
85052
+ function runNativeInjectionEffect(task, harnessSessionId, deps) {
85053
+ return exports_Effect.gen(function* () {
85054
+ const { chatroomId, taskId, taskContent, agentConfig, status: status3 } = task;
85055
+ const { role } = agentConfig;
85056
+ if (status3 === "pending") {
85057
+ const claimResult = yield* exports_Effect.tryPromise({
85058
+ try: () => deps.backend.mutation(api.tasks.claimTask, {
85059
+ sessionId: deps.sessionId,
85060
+ chatroomId,
85061
+ role,
85062
+ taskId
85063
+ }),
85064
+ catch: (err) => err
85065
+ }).pipe(exports_Effect.either);
85066
+ if (claimResult._tag === "Left") {
85067
+ yield* exports_Effect.tryPromise({
85068
+ try: () => emitTaskDeliveryFailed(deps, {
85069
+ chatroomId,
85070
+ role,
85071
+ taskId,
85072
+ error: getErrorMessage2(claimResult.left)
85073
+ }),
85074
+ catch: () => {
85075
+ return;
85076
+ }
85077
+ }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
85078
+ return yield* exports_Effect.fail(claimResult.left);
85079
+ }
85080
+ }
85081
+ const deliveryResult = yield* exports_Effect.tryPromise({
85082
+ try: () => deps.backend.query(api.messages.getTaskDeliveryPrompt, {
85083
+ sessionId: deps.sessionId,
85084
+ chatroomId,
85085
+ role,
85086
+ taskId,
85087
+ convexUrl: deps.convexUrl
85088
+ }),
85089
+ catch: (err) => err
85090
+ }).pipe(exports_Effect.either);
85091
+ if (deliveryResult._tag === "Left") {
85092
+ yield* exports_Effect.tryPromise({
85093
+ try: () => emitTaskDeliveryFailed(deps, {
85094
+ chatroomId,
85095
+ role,
85096
+ taskId,
85097
+ error: getErrorMessage2(deliveryResult.left)
85098
+ }),
85099
+ catch: () => {
85100
+ return;
85101
+ }
85102
+ }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
85103
+ return yield* exports_Effect.fail(deliveryResult.left);
85104
+ }
85105
+ const delivery = deliveryResult.right;
85106
+ const augmentationMode = resolveSessionAugmentationForRole(taskContent, role);
85107
+ const prompt = buildNativeInjectionPrompt({
85108
+ taskDeliveryOutput: delivery.fullCliOutput,
85109
+ augmentationMode
85110
+ });
85111
+ yield* exports_Effect.tryPromise({
85112
+ try: () => deps.backend.mutation(api.participants.join, {
85113
+ sessionId: deps.sessionId,
85114
+ chatroomId,
85115
+ role,
85116
+ action: NATIVE_TASK_INJECTED_ACTION,
85117
+ taskId
85118
+ }),
85119
+ catch: (err) => err
85120
+ });
85121
+ if (roleSupportsSessionAugmentation(role)) {
85122
+ yield* exports_Effect.tryPromise({
85123
+ try: () => deps.backend.mutation(api.machines.emitSessionAugmented, {
85124
+ sessionId: deps.sessionId,
85125
+ machineId: deps.machineId,
85126
+ chatroomId,
85127
+ role,
85128
+ taskId,
85129
+ mode: augmentationMode,
85130
+ newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode),
85131
+ harnessSessionId
85132
+ }),
85133
+ catch: (err) => err
85134
+ }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
85135
+ }
85136
+ const resumeResult = yield* exports_Effect.tryPromise({
85137
+ try: () => deps.agentMgr.resumeTurnForSlot({ chatroomId, role, prompt }),
85138
+ catch: (err) => err
85139
+ }).pipe(exports_Effect.either);
85140
+ if (resumeResult._tag === "Left") {
85141
+ const error = getErrorMessage2(resumeResult.left);
85142
+ console.warn(`[NativeTaskInjector] resumeTurn failed for ${role}@${chatroomId}: ${error}`);
85143
+ yield* exports_Effect.tryPromise({
85144
+ try: () => emitTaskDeliveryFailed(deps, {
85145
+ chatroomId,
85146
+ role,
85147
+ taskId,
85148
+ error
85149
+ }),
85150
+ catch: () => {
85151
+ return;
85152
+ }
85153
+ }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
85154
+ return;
85155
+ }
85156
+ yield* exports_Effect.tryPromise({
85157
+ try: () => deps.backend.mutation(api.machines.emitTaskDelivered, {
85158
+ sessionId: deps.sessionId,
85159
+ machineId: deps.machineId,
85160
+ chatroomId,
85161
+ role,
85162
+ taskId
85163
+ }),
85164
+ catch: (err) => err
85165
+ }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
85166
+ deps.onTaskDelivered?.({ chatroomId, role, taskId });
85167
+ });
85168
+ }
85169
+ var init_native_task_injector = __esm(() => {
85170
+ init_participant();
85171
+ init_team_agent_settings();
85172
+ init_parse_session_augmentation();
85173
+ init_esm();
85174
+ init_native_task_injector_logic();
85175
+ init_api3();
85176
+ init_convex_error();
85177
+ });
85178
+
85179
+ // src/commands/machine/daemon-start/role-delivery-state.ts
85180
+ function roleKey(chatroomId, role) {
85181
+ return `${chatroomId}:${role.toLowerCase()}`;
85182
+ }
85183
+
85184
+ class RoleDeliveryState {
85185
+ generation = new Map;
85186
+ inFlight = new Set;
85187
+ nativeNudgeFailures = new Map;
85188
+ getGeneration(chatroomId, role) {
85189
+ return this.generation.get(roleKey(chatroomId, role)) ?? 0;
85190
+ }
85191
+ resetDeliveryState(chatroomId, role) {
85192
+ const key = roleKey(chatroomId, role);
85193
+ const next4 = (this.generation.get(key) ?? 0) + 1;
85194
+ this.generation.set(key, next4);
85195
+ this.inFlight.delete(key);
85196
+ this.nativeNudgeFailures.delete(key);
85197
+ return next4;
85198
+ }
85199
+ tryAcquireDelivery(chatroomId, role) {
85200
+ const key = roleKey(chatroomId, role);
85201
+ if (this.inFlight.has(key))
85202
+ return false;
85203
+ this.inFlight.add(key);
85204
+ return true;
85205
+ }
85206
+ releaseDelivery(chatroomId, role) {
85207
+ this.inFlight.delete(roleKey(chatroomId, role));
85208
+ }
85209
+ recordNativeNudgeFailure(chatroomId, role) {
85210
+ const key = roleKey(chatroomId, role);
85211
+ const count3 = (this.nativeNudgeFailures.get(key) ?? 0) + 1;
85212
+ this.nativeNudgeFailures.set(key, count3);
85213
+ return count3;
85214
+ }
85215
+ clearNativeNudgeFailures(chatroomId, role) {
85216
+ this.nativeNudgeFailures.delete(roleKey(chatroomId, role));
85217
+ }
85218
+ getNativeNudgeFailures(chatroomId, role) {
85219
+ return this.nativeNudgeFailures.get(roleKey(chatroomId, role)) ?? 0;
85220
+ }
85221
+ }
85222
+ function getRoleDeliveryState() {
85223
+ shared ??= new RoleDeliveryState;
85224
+ return shared;
85225
+ }
85226
+ var shared;
85227
+
85228
+ // src/commands/machine/daemon-start/native-task-delivery-coordinator.ts
85229
+ class NativeTaskDeliveryCoordinator {
85230
+ onSessionLost(params) {
85231
+ getRoleDeliveryState().resetDeliveryState(params.chatroomId, params.role);
85232
+ }
85233
+ resetRoleDeliveryState(chatroomId, role) {
85234
+ getRoleDeliveryState().resetDeliveryState(chatroomId, role);
85235
+ }
85236
+ tryInjectNextForRole(chatroomId, role) {
85237
+ const session2 = getNativeDeliverySession();
85238
+ if (!session2)
85239
+ return;
85240
+ const { runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = session2;
85241
+ const tasks = listAssignedTaskSnapshotsForRole(chatroomId, role);
85242
+ if (tasks.length === 0) {
85243
+ logNativeDeliveryNoTasks(role, chatroomId);
85244
+ return;
85245
+ }
85246
+ this.reconcileAssignedTasks({
85247
+ tasks,
85248
+ runtime: runtime4,
85249
+ effectContext: effectContext2,
85250
+ agentMgr,
85251
+ sessionDeps,
85252
+ machineId
85253
+ });
85254
+ }
85255
+ reconcileAssignedTasks(params) {
85256
+ const { tasks, runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = params;
85257
+ const deliveryState = getRoleDeliveryState();
85258
+ const pendingFirst = [...tasks].sort((a, b) => {
85259
+ if (a.status === "pending" && b.status !== "pending")
85260
+ return -1;
85261
+ if (b.status === "pending" && a.status !== "pending")
85262
+ return 1;
85263
+ return a.createdAt - b.createdAt;
85264
+ });
85265
+ for (const row of pendingFirst) {
85266
+ const { role } = row.agentConfig;
85267
+ const slot = agentMgr.getSlot(row.chatroomId, role);
85268
+ const blockReason = explainNativeDeliveryBlock(row, { slot });
85269
+ if (blockReason) {
85270
+ if (row.status === "pending" || row.status === "acknowledged") {
85271
+ logNativeDeliverySkip(role, row.chatroomId, row.taskId, blockReason);
85272
+ }
85273
+ continue;
85274
+ }
85275
+ if (!deliveryState.tryAcquireDelivery(row.chatroomId, role)) {
85276
+ logNativeDeliveryMutexSkip(role, row.chatroomId, row.taskId);
85277
+ continue;
85278
+ }
85279
+ logNativeDeliveryInjecting(role, row.chatroomId, row.taskId);
85280
+ exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
85281
+ const full = yield* exports_Effect.tryPromise(() => sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
85282
+ sessionId: sessionDeps.sessionId,
85283
+ machineId,
85284
+ taskId: row.taskId,
85285
+ role: row.agentConfig.role
85286
+ }));
85287
+ if (!full) {
85288
+ console.warn(`[NativeDelivery:skip] ${role}@${row.chatroomId} task ${row.taskId} — task_hydrate_missing (deleted or not assigned)`);
85289
+ return;
85290
+ }
85291
+ const harnessSessionId = slot?.harnessSessionId;
85292
+ if (!harnessSessionId) {
85293
+ console.warn(`[NativeDelivery:skip] ${role}@${row.chatroomId} task ${row.taskId} — harness_session_missing (post-gate)`);
85294
+ return;
85295
+ }
85296
+ yield* runNativeInjectionEffect(full, harnessSessionId, {
85297
+ sessionId: sessionDeps.sessionId,
85298
+ machineId: sessionDeps.machineId,
85299
+ backend: sessionDeps.backend,
85300
+ agentMgr: {
85301
+ resumeTurnForSlot: (args2) => exports_Effect.runPromise(agentMgr.resumeTurnForSlot(args2))
85302
+ },
85303
+ convexUrl: sessionDeps.convexUrl,
85304
+ onTaskDelivered: ({ chatroomId, role: role2, taskId }) => {
85305
+ exports_Effect.runSync(agentMgr.setLastInFlightTask(chatroomId, role2, taskId));
85306
+ deliveryState.clearNativeNudgeFailures(chatroomId, role2);
85307
+ }
85308
+ });
85309
+ }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[NativeTaskDelivery] delivery failed for ${row.agentConfig.role}@${row.chatroomId}: ${getErrorMessage2(err)}`))), exports_Effect.ensuring(exports_Effect.sync(() => deliveryState.releaseDelivery(row.chatroomId, row.agentConfig.role)))));
85310
+ break;
85311
+ }
85312
+ }
85313
+ }
85314
+ function getNativeTaskDeliveryCoordinator() {
85315
+ coordinator ??= new NativeTaskDeliveryCoordinator;
85316
+ return coordinator;
85317
+ }
85318
+ function notifyNativeSessionLost(params) {
85319
+ getNativeTaskDeliveryCoordinator().onSessionLost(params);
85320
+ }
85321
+ function resetRoleDeliveryState(chatroomId, role) {
85322
+ getRoleDeliveryState().resetDeliveryState(chatroomId, role);
85323
+ }
85324
+ function notifyNativeTurnIdle(params) {
85325
+ logNativeDeliveryPrimary(params.role, params.chatroomId);
85326
+ getNativeTaskDeliveryCoordinator().tryInjectNextForRole(params.chatroomId, params.role);
85327
+ }
85328
+ var coordinator;
85329
+ var init_native_task_delivery_coordinator = __esm(() => {
85330
+ init_esm();
85331
+ init_assigned_task_snapshot_store();
85332
+ init_native_task_injector_logic();
85333
+ init_native_task_injector();
85334
+ init_api3();
85335
+ init_convex_error();
85336
+ });
85337
+
85338
+ // src/commands/machine/daemon-start/restart-orchestrator.ts
85339
+ async function emitPhase(deps, event, phase, detail) {
85340
+ await deps.session.backend.mutation(api.machines.emitRestartPhase, {
85341
+ sessionId: deps.session.sessionId,
85342
+ machineId: deps.session.machineId,
85343
+ chatroomId: event.chatroomId,
85344
+ role: event.role,
85345
+ correlationId: event.correlationId,
85346
+ phase,
85347
+ detail
85348
+ });
85349
+ }
85350
+ function sleep5(ms) {
85351
+ return new Promise((resolve4) => setTimeout(resolve4, ms));
85352
+ }
85353
+ async function waitForHarnessSessionId(deps, event, pid) {
85354
+ const initial = deps.agentMgr.getSlot(event.chatroomId, event.role);
85355
+ if (initial?.harnessSessionId) {
85356
+ return initial.harnessSessionId;
85357
+ }
85358
+ await deps.session.backend.mutation(api.machines.emitHarnessSessionAwaiting, {
85359
+ sessionId: deps.session.sessionId,
85360
+ machineId: deps.session.machineId,
85361
+ chatroomId: event.chatroomId,
85362
+ role: event.role,
85363
+ pid,
85364
+ timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS
85365
+ });
85366
+ const deadline = Date.now() + HARNESS_SESSION_READY_TIMEOUT_MS;
85367
+ while (Date.now() < deadline) {
85368
+ const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
85369
+ if (slot?.harnessSessionId) {
85370
+ return slot.harnessSessionId;
85371
+ }
85372
+ await sleep5(100);
85373
+ }
85374
+ await deps.session.backend.mutation(api.machines.emitHarnessSessionTimeout, {
85375
+ sessionId: deps.session.sessionId,
85376
+ machineId: deps.session.machineId,
85377
+ chatroomId: event.chatroomId,
85378
+ role: event.role,
85379
+ pid,
85380
+ timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS
85381
+ });
85382
+ await deps.agentMgr.stop({
85383
+ chatroomId: event.chatroomId,
85384
+ role: event.role,
85385
+ reason: "user.restart",
85386
+ pid
85387
+ });
85388
+ return null;
85389
+ }
85390
+ async function forceNativeWaiting(deps, event) {
85391
+ await deps.session.backend.mutation(api.participants.join, {
85392
+ sessionId: deps.session.sessionId,
85393
+ chatroomId: event.chatroomId,
85394
+ role: event.role,
85395
+ action: NATIVE_WAITING_ACTION
85396
+ });
85397
+ }
85398
+ async function listDeliverableSnapshots(deps, event) {
85399
+ await deps.session.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
85400
+ sessionId: deps.session.sessionId,
85401
+ machineId: deps.session.machineId
85402
+ });
85403
+ const result = await deps.session.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
85404
+ sessionId: deps.session.sessionId,
85405
+ machineId: deps.session.machineId
85406
+ });
85407
+ const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
85408
+ return (result.tasks ?? []).filter((t) => t.chatroomId === event.chatroomId && t.agentConfig.role.toLowerCase() === event.role.toLowerCase() && (t.status === "pending" || t.status === "acknowledged") && isAgentReadyForNativeDelivery(t, slot)).sort((a, b) => a.createdAt - b.createdAt);
85409
+ }
85410
+ async function deliverOneTask(deps, event, snapshot) {
85411
+ const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
85412
+ const harnessSessionId = slot?.harnessSessionId;
85413
+ if (!harnessSessionId)
85414
+ return false;
85415
+ const full = await deps.session.backend.query(api.machines.getAssignedTaskForAction, {
85416
+ sessionId: deps.session.sessionId,
85417
+ machineId: deps.session.machineId,
85418
+ taskId: snapshot.taskId,
85419
+ role: event.role
85420
+ });
85421
+ if (!full)
85422
+ return false;
85423
+ try {
85424
+ await exports_Effect.runPromise(runNativeInjectionEffect(full, harnessSessionId, {
85425
+ sessionId: deps.session.sessionId,
85426
+ machineId: deps.session.machineId,
85427
+ backend: deps.session.backend,
85428
+ convexUrl: deps.session.convexUrl,
85429
+ agentMgr: {
85430
+ resumeTurnForSlot: async (args2) => {
85431
+ await exports_Effect.runPromise(deps.agentMgr.resumeTurnForSlot(args2));
85432
+ }
85433
+ },
85434
+ onTaskDelivered: ({ chatroomId, role, taskId }) => {
85435
+ deps.agentMgr.setLastInFlightTask(chatroomId, role, taskId);
85436
+ }
85437
+ }));
85438
+ return true;
85439
+ } catch (err) {
85440
+ console.warn(`[RestartOrchestrator] deliver failed for task ${snapshot.taskId}: ${getErrorMessage2(err)}`);
85441
+ return false;
85442
+ }
85443
+ }
85444
+ async function deliverPendingTasks(deps, event) {
85445
+ const delivered = [];
85446
+ const snapshots = await listDeliverableSnapshots(deps, event);
85447
+ for (const snapshot of snapshots) {
85448
+ if (snapshot.status !== "pending")
85449
+ continue;
85450
+ const ok = await deliverOneTask(deps, event, snapshot);
85451
+ if (ok) {
85452
+ delivered.push(snapshot.taskId);
85453
+ }
85454
+ }
85455
+ return delivered;
85456
+ }
85457
+ async function runRestartOrchestrator(deps, event) {
85458
+ const { chatroomId, role } = event;
85459
+ try {
85460
+ await emitPhase(deps, event, "reset");
85461
+ resetRoleDeliveryState(chatroomId, role);
85462
+ await deps.agentMgr.stop({
85463
+ chatroomId,
85464
+ role,
85465
+ reason: "user.restart"
85466
+ });
85467
+ await emitPhase(deps, event, "spawn");
85468
+ const spawnResult = await exports_Effect.runPromise(deps.agentMgr.ensureRunning({
85469
+ chatroomId,
85470
+ role,
85471
+ agentHarness: event.agentHarness,
85472
+ model: event.model,
85473
+ workingDir: event.workingDir,
85474
+ reason: "user.restart",
85475
+ wantResume: event.wantResume ?? true
85476
+ }));
85477
+ if (!spawnResult.success || !spawnResult.pid) {
85478
+ await emitPhase(deps, event, "failed", spawnResult.error ?? "spawn failed");
85479
+ return;
85480
+ }
85481
+ await emitPhase(deps, event, "await_session");
85482
+ const harnessSessionId = await waitForHarnessSessionId(deps, event, spawnResult.pid);
85483
+ if (!harnessSessionId) {
85484
+ await emitPhase(deps, event, "failed", "harnessSessionId timeout");
85485
+ return;
85486
+ }
85487
+ await deps.session.backend.mutation(api.machines.emitHarnessSessionReady, {
85488
+ sessionId: deps.session.sessionId,
85489
+ machineId: deps.session.machineId,
85490
+ chatroomId,
85491
+ role,
85492
+ harnessSessionId,
85493
+ pid: spawnResult.pid
85494
+ });
85495
+ await forceNativeWaiting(deps, event);
85496
+ await emitPhase(deps, event, "ready");
85497
+ await emitPhase(deps, event, "deliver");
85498
+ const deliveredTaskIds = await deliverPendingTasks(deps, event);
85499
+ await deps.session.backend.mutation(api.machines.emitRestartCompleted, {
85500
+ sessionId: deps.session.sessionId,
85501
+ machineId: deps.session.machineId,
85502
+ chatroomId,
85503
+ role,
85504
+ correlationId: event.correlationId,
85505
+ deliveredTaskIds
85506
+ });
85507
+ await emitPhase(deps, event, "completed");
85508
+ } catch (err) {
85509
+ console.warn(`[RestartOrchestrator] failed for ${role}@${chatroomId}: ${getErrorMessage2(err)}`);
85510
+ await emitPhase(deps, event, "failed", getErrorMessage2(err));
85511
+ }
85512
+ }
85513
+ var init_restart_orchestrator = __esm(() => {
85514
+ init_reliability();
85515
+ init_participant();
85516
+ init_esm();
85517
+ init_native_ready_invariant();
85518
+ init_native_task_delivery_coordinator();
85519
+ init_native_task_injector();
85520
+ init_api3();
85521
+ init_convex_error();
85522
+ });
85523
+
85524
+ // src/events/daemon/agent/on-request-restart-agent.ts
85525
+ var onRequestRestartAgentEffect = (event) => exports_Effect.gen(function* () {
85526
+ if (Date.now() > event.deadline) {
85527
+ console.log(`[daemon] ⏰ Skipping expired agent.restart for role=${event.role} (deadline passed)`);
85528
+ return;
85529
+ }
85530
+ console.log(`[daemon] Processing agent.restart (correlationId=${event.correlationId}) for role=${event.role}`);
85531
+ const agentMgr = yield* DaemonAgentProcessManagerService;
85532
+ const session2 = yield* DaemonSessionService;
85533
+ yield* exports_Effect.tryPromise(() => runRestartOrchestrator({
85534
+ session: {
85535
+ sessionId: session2.sessionId,
85536
+ machineId: session2.machineId,
85537
+ convexUrl: session2.convexUrl,
85538
+ backend: session2.backend
85539
+ },
85540
+ agentMgr
85541
+ }, {
85542
+ chatroomId: event.chatroomId,
85543
+ role: event.role,
85544
+ agentHarness: event.agentHarness,
85545
+ model: event.model,
85546
+ workingDir: event.workingDir,
85547
+ correlationId: event.correlationId,
85548
+ wantResume: event.wantResume
85549
+ })).pipe(exports_Effect.catchAll(() => exports_Effect.void));
85550
+ });
85551
+ var init_on_request_restart_agent = __esm(() => {
85552
+ init_esm();
85553
+ init_daemon_services();
85554
+ init_restart_orchestrator();
85555
+ });
85556
+
84734
85557
  // src/events/daemon/agent/on-request-start-agent.ts
84735
85558
  function notifyAgentStartFailed(backend2, opts) {
84736
85559
  backend2.mutation(api.machines.emitAgentStartFailed, opts).catch((err) => {
@@ -85758,7 +86581,7 @@ var init_git = __esm(() => {
85758
86581
  });
85759
86582
 
85760
86583
  // src/infrastructure/local-actions/execute-local-action.ts
85761
- import { exec as exec2 } from "node:child_process";
86584
+ import { spawn as spawn5 } from "node:child_process";
85762
86585
  import { access as access3 } from "node:fs/promises";
85763
86586
  function escapeShellArg(arg) {
85764
86587
  return `"${arg.replace(/"/g, "\\\"")}"`;
@@ -85768,17 +86591,18 @@ function resolveWhichCommand(name) {
85768
86591
  }
85769
86592
  function isCliAvailable(cliName) {
85770
86593
  return new Promise((resolve4) => {
85771
- exec2(resolveWhichCommand(cliName), (err) => {
85772
- resolve4(!err);
85773
- });
86594
+ const child = spawn5(resolveWhichCommand(cliName), [], DETACHED_SHELL_SPAWN_OPTIONS);
86595
+ child.on("error", () => resolve4(false));
86596
+ child.on("close", (code2) => resolve4(code2 === 0));
86597
+ child.unref();
85774
86598
  });
85775
86599
  }
85776
86600
  function execFireAndForget(command, logTag) {
85777
- exec2(command, (err) => {
85778
- if (err) {
85779
- console.warn(`[${logTag}] exec failed: ${err.message}`);
85780
- }
86601
+ const child = spawn5(command, [], DETACHED_SHELL_SPAWN_OPTIONS);
86602
+ child.on("error", (err) => {
86603
+ console.warn(`[${logTag}] spawn failed: ${err.message}`);
85781
86604
  });
86605
+ child.unref();
85782
86606
  }
85783
86607
  function resolveOpenCommand(platform) {
85784
86608
  switch (platform) {
@@ -85869,9 +86693,14 @@ async function executeLocalAction(action, workingDir) {
85869
86693
  return handler(workingDir);
85870
86694
  return { success: false, error: `Unknown action: ${action}` };
85871
86695
  }
85872
- var actionHandlers;
86696
+ var DETACHED_SHELL_SPAWN_OPTIONS, actionHandlers;
85873
86697
  var init_execute_local_action = __esm(() => {
85874
86698
  init_git();
86699
+ DETACHED_SHELL_SPAWN_OPTIONS = {
86700
+ stdio: "ignore",
86701
+ detached: true,
86702
+ shell: true
86703
+ };
85875
86704
  actionHandlers = {
85876
86705
  "open-vscode": openVscode,
85877
86706
  "open-finder": openFinder,
@@ -86019,7 +86848,7 @@ function logWaitingForShutdown(pid) {
86019
86848
  function logDaemonAlreadyRunning(pid) {
86020
86849
  console.error(`❌ Daemon already running for ${getConvexUrl()} (PID: ${pid})`);
86021
86850
  }
86022
- async function waitForLockOrTimeout(deadline, intervalMs, sleep5) {
86851
+ async function waitForLockOrTimeout(deadline, intervalMs, sleep6) {
86023
86852
  let loggedWait = false;
86024
86853
  while (Date.now() < deadline) {
86025
86854
  if (tryAcquireLock()) {
@@ -86030,16 +86859,16 @@ async function waitForLockOrTimeout(deadline, intervalMs, sleep5) {
86030
86859
  logWaitingForShutdown(pid);
86031
86860
  loggedWait = true;
86032
86861
  }
86033
- await sleep5(intervalMs);
86862
+ await sleep6(intervalMs);
86034
86863
  }
86035
86864
  return false;
86036
86865
  }
86037
86866
  async function acquireLockWithRetry(options) {
86038
86867
  const intervalMs = options?.intervalMs ?? LOCK_RETRY_INTERVAL_MS;
86039
86868
  const maxWaitMs = options?.maxWaitMs ?? LOCK_RETRY_MAX_WAIT_MS;
86040
- const sleep5 = options?.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
86869
+ const sleep6 = options?.sleep ?? ((ms) => new Promise((resolve4) => setTimeout(resolve4, ms)));
86041
86870
  const deadline = Date.now() + maxWaitMs;
86042
- if (await waitForLockOrTimeout(deadline, intervalMs, sleep5)) {
86871
+ if (await waitForLockOrTimeout(deadline, intervalMs, sleep6)) {
86043
86872
  return true;
86044
86873
  }
86045
86874
  const { pid } = isDaemonRunning();
@@ -86890,7 +87719,7 @@ var init_opencode_session = __esm(() => {
86890
87719
  });
86891
87720
 
86892
87721
  // src/infrastructure/harnesses/opencode-sdk/opencode-harness.ts
86893
- import { spawn as spawn5 } from "node:child_process";
87722
+ import { spawn as spawn6 } from "node:child_process";
86894
87723
  function harnessEventSessionId(event) {
86895
87724
  const p = event.properties;
86896
87725
  if (!p)
@@ -87164,7 +87993,7 @@ class OpencodeSdkHarness {
87164
87993
  }
87165
87994
  }
87166
87995
  var OPENCODE_COMMAND3 = "opencode", SERVE_STARTUP_TIMEOUT_MS2 = 1e4, startOpencodeSdkHarness = async (config3) => {
87167
- const childProcess = spawn5(OPENCODE_COMMAND3, ["serve", "--print-logs", "--log-level", "WARN"], {
87996
+ const childProcess = spawn6(OPENCODE_COMMAND3, ["serve", "--print-logs", "--log-level", "WARN"], {
87168
87997
  cwd: config3.workingDir,
87169
87998
  stdio: ["pipe", "pipe", "pipe"],
87170
87999
  shell: false,
@@ -88955,9 +89784,9 @@ var init_file_content_fulfillment = __esm(() => {
88955
89784
  for (const request2 of requests) {
88956
89785
  const startTime = Date.now();
88957
89786
  const { workingDir, filePath } = request2;
88958
- const registered = yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => assertRegisteredWorkingDir(session2, workingDir)), () => exports_Effect.succeed({ ok: false, error: "Workspace check failed" }));
88959
- if (!registered.ok) {
88960
- console.warn(`[${formatTimestamp()}] ⚠️ Rejected unregistered workspace: ${workingDir} (${registered.error})`);
89787
+ const registered2 = yield* exports_Effect.catchAll(exports_Effect.tryPromise(() => assertRegisteredWorkingDir(session2, workingDir)), () => exports_Effect.succeed({ ok: false, error: "Workspace check failed" }));
89788
+ if (!registered2.ok) {
89789
+ console.warn(`[${formatTimestamp()}] ⚠️ Rejected unregistered workspace: ${workingDir} (${registered2.error})`);
88961
89790
  yield* fulfillGzippedContentEffect(session2, workingDir, filePath, "[Error: workspace not registered]", false);
88962
89791
  continue;
88963
89792
  }
@@ -91795,17 +92624,17 @@ var startFileTreeSubscriptionEffect = (wsClient2) => exports_Effect.gen(function
91795
92624
  });
91796
92625
  coordinators.set(normalized, coordinatorPromise);
91797
92626
  }
91798
- return coordinatorPromise.then(async (coordinator) => {
92627
+ return coordinatorPromise.then(async (coordinator2) => {
91799
92628
  const checkpoint = await session2.backend.query(api.workspaceFiles.getFileTreeCheckpoint, {
91800
92629
  sessionId: session2.sessionId,
91801
92630
  machineId: session2.machineId,
91802
92631
  workingDir: normalized
91803
92632
  });
91804
92633
  if (checkpoint === null)
91805
- await coordinator.checkpoint();
92634
+ await coordinator2.checkpoint();
91806
92635
  if (forceReconcile)
91807
- await coordinator.reconcile();
91808
- return coordinator;
92636
+ await coordinator2.reconcile();
92637
+ return coordinator2;
91809
92638
  });
91810
92639
  };
91811
92640
  const unsubscribe = wsClient2.onUpdate(api.workspaceFiles.getPendingFileTreeRequests, { sessionId: session2.sessionId, machineId: session2.machineId }, (requests) => {
@@ -91835,7 +92664,7 @@ var startFileTreeSubscriptionEffect = (wsClient2) => exports_Effect.gen(function
91835
92664
  return {
91836
92665
  stop: () => {
91837
92666
  unsubscribe();
91838
- Promise.all([...coordinators.values()].map((coordinator) => coordinator.then((handle) => handle.stop()).catch(() => {
92667
+ Promise.all([...coordinators.values()].map((coordinator2) => coordinator2.then((handle) => handle.stop()).catch(() => {
91839
92668
  return;
91840
92669
  })));
91841
92670
  coordinators.clear();
@@ -91920,11 +92749,11 @@ async function writePayloadToDisk(absolutePath, operation, content) {
91920
92749
  async function fulfillOneFileWriteRequest(session2, request2) {
91921
92750
  const startTime = Date.now();
91922
92751
  const { workingDir, filePath, operation } = request2;
91923
- const registered = await assertRegisteredWorkingDir(session2, workingDir);
91924
- if (!registered.ok) {
92752
+ const registered2 = await assertRegisteredWorkingDir(session2, workingDir);
92753
+ if (!registered2.ok) {
91925
92754
  await completeWriteRequest(session2, request2._id, {
91926
92755
  status: "error",
91927
- errorMessage: registered.error
92756
+ errorMessage: registered2.error
91928
92757
  });
91929
92758
  return;
91930
92759
  }
@@ -93095,21 +93924,6 @@ var init_crash_loop_tracker = __esm(() => {
93095
93924
  ];
93096
93925
  });
93097
93926
 
93098
- // ../../services/backend/src/domain/entities/participant.ts
93099
- var PARTICIPANT_EXITED_ACTION = "exited", NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", NATIVE_HANDOFF_REMINDER = "Reminder: Use the handoff command to send your response to the team.", ONLINE_OR_STARTING_STATUSES;
93100
- var init_participant = __esm(() => {
93101
- ONLINE_OR_STARTING_STATUSES = new Set([
93102
- "agent.waiting",
93103
- "agent.requestStart",
93104
- "agent.started",
93105
- "task.acknowledged",
93106
- "task.inProgress",
93107
- "task.completed",
93108
- "agent.requestStop",
93109
- "agent.awaitingHandoff"
93110
- ]);
93111
- });
93112
-
93113
93927
  // src/infrastructure/services/agent-process-manager/turn-completed-backend.ts
93114
93928
  function createTurnCompletedBackend(deps) {
93115
93929
  return {
@@ -93142,386 +93956,6 @@ class TurnEndQueue {
93142
93956
  }
93143
93957
  }
93144
93958
 
93145
- // src/commands/machine/daemon-start/native-delivery-ledger.ts
93146
- class NativeDeliveryLedger {
93147
- delivered = new Set;
93148
- inFlight = new Set;
93149
- deliveryKey(taskId, harnessSessionId) {
93150
- return `${taskId}\x00${harnessSessionId}`;
93151
- }
93152
- isDelivered(taskId, harnessSessionId) {
93153
- return this.delivered.has(this.deliveryKey(taskId, harnessSessionId));
93154
- }
93155
- tryAcquire(taskId, harnessSessionId) {
93156
- const key = this.deliveryKey(taskId, harnessSessionId);
93157
- if (this.delivered.has(key) || this.inFlight.has(key)) {
93158
- return false;
93159
- }
93160
- this.inFlight.add(key);
93161
- return true;
93162
- }
93163
- markDelivered(taskId, harnessSessionId) {
93164
- const key = this.deliveryKey(taskId, harnessSessionId);
93165
- this.inFlight.delete(key);
93166
- this.delivered.add(key);
93167
- }
93168
- clearDelivery(taskId, harnessSessionId) {
93169
- const key = this.deliveryKey(taskId, harnessSessionId);
93170
- this.inFlight.delete(key);
93171
- this.delivered.delete(key);
93172
- }
93173
- clearSession(harnessSessionId) {
93174
- const suffix = `\x00${harnessSessionId}`;
93175
- for (const key of [...this.delivered, ...this.inFlight]) {
93176
- if (key.endsWith(suffix)) {
93177
- this.delivered.delete(key);
93178
- this.inFlight.delete(key);
93179
- }
93180
- }
93181
- }
93182
- }
93183
-
93184
- // src/domain/native-integration/predicates.ts
93185
- function isNativeInjectableAliveRunning(task) {
93186
- const { agentConfig, status: status3 } = task;
93187
- if (!isNativeHarness(agentConfig.agentHarness))
93188
- return false;
93189
- if (agentConfig.spawnedAgentPid == null || agentConfig.desiredState !== "running") {
93190
- return false;
93191
- }
93192
- if (status3 === "pending")
93193
- return true;
93194
- if (status3 === "acknowledged") {
93195
- const assignedTo = task.assignedTo?.toLowerCase();
93196
- return assignedTo === agentConfig.role.toLowerCase();
93197
- }
93198
- return false;
93199
- }
93200
- function isInjectableNativeAction(action) {
93201
- if (action == null)
93202
- return true;
93203
- return action === NATIVE_WAITING_ACTION || action === PARTICIPANT_EXITED_ACTION;
93204
- }
93205
- function isNativePendingRedeliveryAfterRelease(task) {
93206
- return task.status === "pending" && task.participant?.lastSeenAction === NATIVE_TASK_INJECTED_ACTION;
93207
- }
93208
- function isNativeIdleAfterTaskComplete(participant) {
93209
- return participant.lastSeenAction === NATIVE_TASK_INJECTED_ACTION && participant.lastStatus === "task.completed";
93210
- }
93211
- function isNativeAcknowledgedInjectionRetry(task) {
93212
- if (task.status !== "acknowledged")
93213
- return false;
93214
- const assignedTo = task.assignedTo?.toLowerCase();
93215
- if (assignedTo !== task.agentConfig.role.toLowerCase())
93216
- return false;
93217
- return task.participant?.lastSeenAction === NATIVE_TASK_INJECTED_ACTION;
93218
- }
93219
- function isStaleCliGetNextTaskWaiting(task) {
93220
- const lastSeenAt = task.participant?.lastSeenAt ?? 0;
93221
- return task.participant?.lastSeenAction === "get-next-task:started" && task.createdAt > lastSeenAt;
93222
- }
93223
- function isCliIdleNotListening(task, now, thresholdMs) {
93224
- const lastSeenAt = task.participant?.lastSeenAt ?? 0;
93225
- if (lastSeenAt === 0)
93226
- return now - task.createdAt > thresholdMs;
93227
- return now - lastSeenAt > thresholdMs;
93228
- }
93229
- var init_predicates = __esm(() => {
93230
- init_types();
93231
- init_participant();
93232
- });
93233
-
93234
- // src/infrastructure/services/remote-agents/spawn-prompt.ts
93235
- function createSpawnPrompt(raw, opts) {
93236
- if (opts?.nativeBootstrap) {
93237
- return NATIVE_BOOTSTRAP_PROMPT;
93238
- }
93239
- const trimmed = raw?.trim();
93240
- return trimmed && trimmed.length > 0 ? trimmed : DEFAULT_TRIGGER_PROMPT;
93241
- }
93242
- var DEFAULT_TRIGGER_PROMPT = "Please read your system prompt carefully and follow the Getting Started instructions.", NATIVE_BOOTSTRAP_PROMPT = "Focus on your role responsibilities. Complete each task via handoff.";
93243
-
93244
- // src/domain/native-integration/spawn-policy.ts
93245
- function shouldDeferInitialTurn(harness) {
93246
- return isNativeHarness(harness);
93247
- }
93248
- function resolveNativeSpawnPolicy(harness, initMessage) {
93249
- const deferInitialTurn = shouldDeferInitialTurn(harness);
93250
- return {
93251
- deferInitialTurn,
93252
- prompt: createSpawnPrompt(initMessage, { nativeBootstrap: deferInitialTurn })
93253
- };
93254
- }
93255
- var init_spawn_policy = __esm(() => {
93256
- init_types();
93257
- });
93258
-
93259
- // src/domain/native-integration/index.ts
93260
- var init_native_integration = __esm(() => {
93261
- init_types();
93262
- init_predicates();
93263
- init_spawn_policy();
93264
- });
93265
-
93266
- // src/commands/machine/daemon-start/native-task-injector-logic.ts
93267
- function shouldDeliverNativeTask(task, opts) {
93268
- if (!isNativeInjectableAliveRunning(task))
93269
- return false;
93270
- if (!opts.harnessSessionId)
93271
- return false;
93272
- if (opts.ledger.isDelivered(task.taskId, opts.harnessSessionId) && task.status !== "pending") {
93273
- return false;
93274
- }
93275
- return isInjectableNativeAction(task.participant?.lastSeenAction) || isNativeIdleAfterTaskComplete(task.participant ?? {}) || isNativeAcknowledgedInjectionRetry(task) || isNativePendingRedeliveryAfterRelease(task);
93276
- }
93277
- function buildNativeInjectionPrompt(params) {
93278
- const { taskDeliveryOutput, augmentationMode } = params;
93279
- if (augmentationMode === "compact") {
93280
- return [
93281
- "⚠️ Context was compacted. Run `chatroom get-system-prompt` only if role instructions are missing.",
93282
- "",
93283
- taskDeliveryOutput
93284
- ].join(`
93285
- `);
93286
- }
93287
- if (augmentationMode === "new_session") {
93288
- return [
93289
- "⚠️ Starting a new agent session. Run `chatroom get-system-prompt` to reload role instructions if needed.",
93290
- "",
93291
- taskDeliveryOutput
93292
- ].join(`
93293
- `);
93294
- }
93295
- return taskDeliveryOutput;
93296
- }
93297
- var init_native_task_injector_logic = __esm(() => {
93298
- init_predicates();
93299
- init_native_integration();
93300
- });
93301
-
93302
- // ../../services/backend/src/domain/entities/team-agent-settings.ts
93303
- function roleSupportsSessionAugmentation(role) {
93304
- const normalized = role.toLowerCase();
93305
- return SESSION_AUGMENTATION_ROLES.some((r) => r === normalized);
93306
- }
93307
- var SESSION_AUGMENTATION_ROLES;
93308
- var init_team_agent_settings = __esm(() => {
93309
- SESSION_AUGMENTATION_ROLES = ["builder"];
93310
- });
93311
-
93312
- // ../../services/backend/src/domain/handoff/parse-session-augmentation.ts
93313
- function findSectionIndex(content, headings) {
93314
- const indices = headings.map((heading) => content.indexOf(heading)).filter((idx) => idx !== -1);
93315
- return indices.length === 0 ? -1 : Math.min(...indices);
93316
- }
93317
- function normalizeMode(raw) {
93318
- return MODE_ALIASES[raw.toLowerCase()] ?? DEFAULT_MODE;
93319
- }
93320
- function extractSectionBody(content, sectionIdx) {
93321
- const matchedHeading = SECTION_HEADINGS.find((h) => content.indexOf(h, sectionIdx) === sectionIdx) ?? SECTION_HEADINGS[0];
93322
- const afterSection = content.slice(sectionIdx);
93323
- const nextHeading = afterSection.slice(matchedHeading.length).search(/\n## /);
93324
- return nextHeading === -1 ? afterSection : afterSection.slice(0, matchedHeading.length + nextHeading);
93325
- }
93326
- function parseSessionAugmentation(handoffContent) {
93327
- const sectionIdx = findSectionIndex(handoffContent, SECTION_HEADINGS);
93328
- if (sectionIdx === -1)
93329
- return DEFAULT_MODE;
93330
- const match17 = extractSectionBody(handoffContent, sectionIdx).match(DATA_TAG);
93331
- if (!match17)
93332
- return DEFAULT_MODE;
93333
- return normalizeMode(match17[1]);
93334
- }
93335
- function resolveSessionAugmentationForRole(handoffContent, role) {
93336
- if (!roleSupportsSessionAugmentation(role)) {
93337
- return "none";
93338
- }
93339
- return parseSessionAugmentation(handoffContent);
93340
- }
93341
- function sessionAugmentationToWantResume(mode) {
93342
- return mode === "none" || mode === "compact";
93343
- }
93344
- function sessionAugmentationNewSessionStarted(mode) {
93345
- return mode === "new_session";
93346
- }
93347
- var SECTION_HEADINGS, DATA_TAG, DEFAULT_MODE = "new_session", MODE_ALIASES;
93348
- var init_parse_session_augmentation = __esm(() => {
93349
- init_team_agent_settings();
93350
- SECTION_HEADINGS = [
93351
- "## Session Augmentation",
93352
- "## Session Management",
93353
- "## Restart new context"
93354
- ];
93355
- DATA_TAG = /\/\/\s*data:agent\.(?:session_augmentation|compress_context)=(none|compact|new_session|reset)\b/i;
93356
- MODE_ALIASES = {
93357
- reset: "new_session",
93358
- none: "none",
93359
- compact: "compact",
93360
- new_session: "new_session"
93361
- };
93362
- });
93363
-
93364
- // src/commands/machine/daemon-start/native-task-injector.ts
93365
- function runNativeInjectionEffect(task, harnessSessionId, deps, ledger) {
93366
- return exports_Effect.gen(function* () {
93367
- if (!shouldDeliverNativeTask(task, { ledger, harnessSessionId })) {
93368
- return;
93369
- }
93370
- const { chatroomId, taskId, taskContent, agentConfig, status: status3 } = task;
93371
- const { role } = agentConfig;
93372
- if (!ledger.tryAcquire(taskId, harnessSessionId)) {
93373
- return;
93374
- }
93375
- if (status3 === "pending") {
93376
- const claimResult = yield* exports_Effect.tryPromise({
93377
- try: () => deps.backend.mutation(api.tasks.claimTask, {
93378
- sessionId: deps.sessionId,
93379
- chatroomId,
93380
- role,
93381
- taskId
93382
- }),
93383
- catch: (err) => err
93384
- }).pipe(exports_Effect.either);
93385
- if (claimResult._tag === "Left") {
93386
- ledger.clearDelivery(taskId, harnessSessionId);
93387
- return yield* exports_Effect.fail(claimResult.left);
93388
- }
93389
- }
93390
- const deliveryResult = yield* exports_Effect.tryPromise({
93391
- try: () => deps.backend.query(api.messages.getTaskDeliveryPrompt, {
93392
- sessionId: deps.sessionId,
93393
- chatroomId,
93394
- role,
93395
- taskId,
93396
- convexUrl: deps.convexUrl
93397
- }),
93398
- catch: (err) => err
93399
- }).pipe(exports_Effect.either);
93400
- if (deliveryResult._tag === "Left") {
93401
- ledger.clearDelivery(taskId, harnessSessionId);
93402
- return yield* exports_Effect.fail(deliveryResult.left);
93403
- }
93404
- const delivery = deliveryResult.right;
93405
- const augmentationMode = resolveSessionAugmentationForRole(taskContent, role);
93406
- const prompt = buildNativeInjectionPrompt({
93407
- taskDeliveryOutput: delivery.fullCliOutput,
93408
- augmentationMode
93409
- });
93410
- yield* exports_Effect.tryPromise({
93411
- try: () => deps.backend.mutation(api.participants.join, {
93412
- sessionId: deps.sessionId,
93413
- chatroomId,
93414
- role,
93415
- action: NATIVE_TASK_INJECTED_ACTION,
93416
- taskId
93417
- }),
93418
- catch: (err) => err
93419
- }).pipe(exports_Effect.tapError(() => exports_Effect.sync(() => ledger.clearDelivery(taskId, harnessSessionId))));
93420
- if (roleSupportsSessionAugmentation(role)) {
93421
- yield* exports_Effect.tryPromise({
93422
- try: () => deps.backend.mutation(api.machines.emitSessionAugmented, {
93423
- sessionId: deps.sessionId,
93424
- machineId: deps.machineId,
93425
- chatroomId,
93426
- role,
93427
- taskId,
93428
- mode: augmentationMode,
93429
- newSessionStarted: sessionAugmentationNewSessionStarted(augmentationMode),
93430
- harnessSessionId
93431
- }),
93432
- catch: (err) => err
93433
- }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
93434
- }
93435
- const resumeResult = yield* exports_Effect.tryPromise({
93436
- try: () => deps.agentMgr.resumeTurnForSlot({ chatroomId, role, prompt }),
93437
- catch: (err) => err
93438
- }).pipe(exports_Effect.either);
93439
- if (resumeResult._tag === "Left") {
93440
- ledger.clearDelivery(taskId, harnessSessionId);
93441
- console.warn(`[NativeTaskInjector] resumeTurn failed for ${role}@${chatroomId}: ${getErrorMessage2(resumeResult.left)}`);
93442
- return;
93443
- }
93444
- ledger.markDelivered(taskId, harnessSessionId);
93445
- deps.onTaskDelivered?.({ chatroomId, role, taskId });
93446
- });
93447
- }
93448
- var init_native_task_injector = __esm(() => {
93449
- init_participant();
93450
- init_team_agent_settings();
93451
- init_parse_session_augmentation();
93452
- init_esm();
93453
- init_native_task_injector_logic();
93454
- init_api3();
93455
- init_convex_error();
93456
- });
93457
-
93458
- // src/commands/machine/daemon-start/native-task-delivery-coordinator.ts
93459
- class NativeTaskDeliveryCoordinator {
93460
- ledger;
93461
- constructor(ledger = new NativeDeliveryLedger) {
93462
- this.ledger = ledger;
93463
- }
93464
- onSessionLost(params) {
93465
- if (params.harnessSessionId) {
93466
- this.ledger.clearSession(params.harnessSessionId);
93467
- }
93468
- }
93469
- reconcileAssignedTasks(params) {
93470
- const { tasks, runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = params;
93471
- const ledger = this.ledger;
93472
- for (const row of tasks) {
93473
- const slot = agentMgr.getSlot(row.chatroomId, row.agentConfig.role);
93474
- const harnessSessionId = slot?.harnessSessionId;
93475
- if (!shouldDeliverNativeTask(row, {
93476
- ledger,
93477
- harnessSessionId
93478
- })) {
93479
- continue;
93480
- }
93481
- if (!harnessSessionId) {
93482
- continue;
93483
- }
93484
- exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
93485
- const full = yield* exports_Effect.tryPromise(() => sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
93486
- sessionId: sessionDeps.sessionId,
93487
- machineId,
93488
- taskId: row.taskId,
93489
- role: row.agentConfig.role
93490
- }));
93491
- if (!full)
93492
- return;
93493
- yield* runNativeInjectionEffect(full, harnessSessionId, {
93494
- sessionId: sessionDeps.sessionId,
93495
- machineId: sessionDeps.machineId,
93496
- backend: sessionDeps.backend,
93497
- agentMgr: {
93498
- resumeTurnForSlot: (args2) => exports_Effect.runPromise(agentMgr.resumeTurnForSlot(args2))
93499
- },
93500
- convexUrl: sessionDeps.convexUrl,
93501
- onTaskDelivered: ({ chatroomId, role, taskId }) => {
93502
- exports_Effect.runSync(agentMgr.setLastInFlightTask(chatroomId, role, taskId));
93503
- }
93504
- }, ledger);
93505
- }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[NativeTaskDelivery] delivery failed for ${row.agentConfig.role}@${row.chatroomId}: ${getErrorMessage2(err)}`)))));
93506
- }
93507
- }
93508
- }
93509
- function getNativeTaskDeliveryCoordinator() {
93510
- coordinator ??= new NativeTaskDeliveryCoordinator;
93511
- return coordinator;
93512
- }
93513
- function notifyNativeSessionLost(params) {
93514
- getNativeTaskDeliveryCoordinator().onSessionLost(params);
93515
- }
93516
- var coordinator;
93517
- var init_native_task_delivery_coordinator = __esm(() => {
93518
- init_esm();
93519
- init_native_task_injector_logic();
93520
- init_native_task_injector();
93521
- init_api3();
93522
- init_convex_error();
93523
- });
93524
-
93525
93959
  // src/domain/agent-lifecycle/resolve-resumable-harness-session-id.ts
93526
93960
  function resolveResumableHarnessSessionId(snapshot) {
93527
93961
  return snapshot.resumableHarnessSessionId ?? snapshot.harnessSessionId;
@@ -93726,6 +94160,14 @@ var init_native_harness_session_exit = __esm(() => {
93726
94160
  init_agent_lifecycle();
93727
94161
  });
93728
94162
 
94163
+ // src/commands/machine/daemon-start/native-turn-phase.ts
94164
+ function defaultNativeTurnPhase() {
94165
+ return "idle";
94166
+ }
94167
+ function setNativeTurnPhase(slot, phase) {
94168
+ slot.nativeTurnPhase = phase;
94169
+ }
94170
+
93729
94171
  // src/domain/agent-lifecycle/policies/classify-resume-storm-reason.ts
93730
94172
  function classifyResumeStormReason(logLines) {
93731
94173
  const blob = logLines.join(`
@@ -94284,6 +94726,7 @@ class AgentProcessManager {
94284
94726
  slot.startedAt = undefined;
94285
94727
  slot.pendingOperation = undefined;
94286
94728
  slot.stoppingSince = undefined;
94729
+ slot.nativeTurnPhase = undefined;
94287
94730
  }
94288
94731
  bumpStopGeneration(slot) {
94289
94732
  slot.stopGeneration = (slot.stopGeneration ?? 0) + 1;
@@ -94319,7 +94762,14 @@ class AgentProcessManager {
94319
94762
  if (!service3?.resumeTurn) {
94320
94763
  throw new Error(`Harness ${slot.harness} does not support resumeTurn`);
94321
94764
  }
94322
- await service3.resumeTurn(slot.pid, args2.prompt);
94765
+ setNativeTurnPhase(slot, "injecting");
94766
+ try {
94767
+ await service3.resumeTurn(slot.pid, args2.prompt);
94768
+ setNativeTurnPhase(slot, "turn_in_flight");
94769
+ } catch (err) {
94770
+ setNativeTurnPhase(slot, defaultNativeTurnPhase());
94771
+ throw err;
94772
+ }
94323
94773
  }
94324
94774
  async injectHarnessReminder(chatroomId, role, prompt) {
94325
94775
  const key = agentKey3(chatroomId, role);
@@ -94329,7 +94779,13 @@ class AgentProcessManager {
94329
94779
  const service3 = this.deps.agentServices.get(slot.harness);
94330
94780
  if (!service3?.resumeTurn)
94331
94781
  return;
94332
- await service3.resumeTurn(slot.pid, prompt);
94782
+ setNativeTurnPhase(slot, "injecting");
94783
+ try {
94784
+ await service3.resumeTurn(slot.pid, prompt);
94785
+ setNativeTurnPhase(slot, "turn_in_flight");
94786
+ } catch {
94787
+ setNativeTurnPhase(slot, defaultNativeTurnPhase());
94788
+ }
94333
94789
  }
94334
94790
  async stop(opts) {
94335
94791
  const key = agentKey3(opts.chatroomId, opts.role);
@@ -94457,6 +94913,10 @@ class AgentProcessManager {
94457
94913
  console.log(`[AgentProcessManager] ⏩ Handoff reminder injected for ${opts.role}`);
94458
94914
  return;
94459
94915
  }
94916
+ if (slot) {
94917
+ setNativeTurnPhase(slot, defaultNativeTurnPhase());
94918
+ }
94919
+ notifyNativeTurnIdle({ chatroomId: opts.chatroomId, role: opts.role });
94460
94920
  console.log(`[AgentProcessManager] ✅ Native agent_end handled for ${opts.role}`);
94461
94921
  } catch (err) {
94462
94922
  console.log(` ⚠️ Failed native agent_end for ${opts.role}: ${err.message}`);
@@ -94542,6 +95002,7 @@ class AgentProcessManager {
94542
95002
  slot.pid = undefined;
94543
95003
  slot.startedAt = undefined;
94544
95004
  slot.pendingOperation = undefined;
95005
+ slot.nativeTurnPhase = undefined;
94545
95006
  }
94546
95007
  async emitExitEvent(slot, opts, ctx) {
94547
95008
  const stopReason = ctx.stopReason;
@@ -95322,6 +95783,9 @@ class AgentProcessManager {
95322
95783
  await this.deps.persistence.persistAgentPid(this.deps.machineId, opts.chatroomId, opts.role, pid, opts.agentHarness);
95323
95784
  } catch {}
95324
95785
  this.registerSpawnCallbacks(slot, opts, spawnResult, pid);
95786
+ if (getHarnessCapabilities(opts.agentHarness).supportsNativeIntegration) {
95787
+ setNativeTurnPhase(slot, defaultNativeTurnPhase());
95788
+ }
95325
95789
  await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
95326
95790
  }
95327
95791
  async emitNativeWaiting(chatroomId, role, harness) {
@@ -95357,11 +95821,11 @@ class AgentProcessManager {
95357
95821
  const initPrompt = await this.fetchInitPromptResult(opts, slot);
95358
95822
  if (!initPrompt.ok)
95359
95823
  return initPrompt.result;
95360
- const spawn6 = await this.spawnAgentForEnsureRunning(key, slot, opts, initPrompt, wantResume);
95361
- if (!spawn6.ok)
95362
- return spawn6.result;
95363
- await this.finalizeRunningSlot(key, slot, opts, spawn6.spawnResult, wantResume);
95364
- return { success: true, pid: spawn6.spawnResult.pid };
95824
+ const spawn7 = await this.spawnAgentForEnsureRunning(key, slot, opts, initPrompt, wantResume);
95825
+ if (!spawn7.ok)
95826
+ return spawn7.result;
95827
+ await this.finalizeRunningSlot(key, slot, opts, spawn7.spawnResult, wantResume);
95828
+ return { success: true, pid: spawn7.spawnResult.pid };
95365
95829
  } catch (e) {
95366
95830
  this.resetSlotIdle(slot);
95367
95831
  return { success: false, error: `Unexpected error: ${e.message}` };
@@ -109109,10 +109573,22 @@ function shouldNudgeCliPendingTask(task, now, pendingIdleThresholdMs) {
109109
109573
  }
109110
109574
  function shouldNudgePendingTask(task, now, pendingIdleThresholdMs = PENDING_IDLE_NUDGE_MS) {
109111
109575
  if (isNativeHarness(task.agentConfig.agentHarness)) {
109112
- return false;
109576
+ return shouldNudgeNativePendingTask(task, now, pendingIdleThresholdMs);
109113
109577
  }
109114
109578
  return shouldNudgeCliPendingTask(task, now, pendingIdleThresholdMs);
109115
109579
  }
109580
+ function shouldNudgeNativePendingTask(task, now, pendingIdleThresholdMs, slot) {
109581
+ if (!isPendingAliveRunningTask(task))
109582
+ return false;
109583
+ if (!isAgentReadyForNativeDelivery(task, slot))
109584
+ return false;
109585
+ const lastSeenAt = task.participant?.lastSeenAt ?? 0;
109586
+ const idleSince = lastSeenAt > 0 ? now - lastSeenAt : now - task.createdAt;
109587
+ return idleSince > pendingIdleThresholdMs;
109588
+ }
109589
+ function shouldEscalateNativeNudgeToRestart(chatroomId, role, failures3) {
109590
+ return failures3 >= NATIVE_NUDGE_ESCALATION_THRESHOLD;
109591
+ }
109116
109592
 
109117
109593
  class NudgeCooldown {
109118
109594
  cooldownMs;
@@ -109129,9 +109605,14 @@ class NudgeCooldown {
109129
109605
  this.lastNudgedAt.set(`${chatroomId}:${role}`, now);
109130
109606
  }
109131
109607
  }
109132
- function isTaskReadyForNudge(task, now, cooldown) {
109133
- if (!shouldNudgePendingTask(task, now))
109608
+ function isTaskReadyForNudge(task, now, cooldown, getSlot) {
109609
+ if (isNativeHarness(task.agentConfig.agentHarness)) {
109610
+ const slot = getSlot?.(task.chatroomId, task.agentConfig.role);
109611
+ if (!shouldNudgeNativePendingTask(task, now, PENDING_IDLE_NUDGE_MS, slot))
109612
+ return false;
109613
+ } else if (!shouldNudgePendingTask(task, now)) {
109134
109614
  return false;
109615
+ }
109135
109616
  const { chatroomId, agentConfig } = task;
109136
109617
  if (!cooldown.canNudge(chatroomId, agentConfig.role, now))
109137
109618
  return false;
@@ -109139,18 +109620,18 @@ function isTaskReadyForNudge(task, now, cooldown) {
109139
109620
  return false;
109140
109621
  return true;
109141
109622
  }
109142
- function listTasksReadyForNudge(tasks, now, cooldown) {
109623
+ function listTasksReadyForNudge(tasks, now, cooldown, getSlot) {
109143
109624
  return tasks.filter((task) => {
109144
- if (!isTaskReadyForNudge(task, now, cooldown))
109625
+ if (!isTaskReadyForNudge(task, now, cooldown, getSlot))
109145
109626
  return false;
109146
109627
  cooldown.recordNudge(task.chatroomId, task.agentConfig.role, now);
109147
109628
  return true;
109148
109629
  });
109149
109630
  }
109150
- var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000;
109631
+ var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000, NATIVE_NUDGE_ESCALATION_THRESHOLD = 2;
109151
109632
  var init_task_monitor_logic = __esm(() => {
109633
+ init_native_ready_invariant();
109152
109634
  init_native_task_injector_logic();
109153
- init_predicates();
109154
109635
  init_agent_process_manager();
109155
109636
  });
109156
109637
  // ../../services/backend/src/domain/usecase/machine/assigned-task-monitor-row.ts
@@ -109220,9 +109701,9 @@ class WorkingSnapshot {
109220
109701
  constructor(opts) {
109221
109702
  this.opts = opts;
109222
109703
  }
109223
- replaceAll(rows) {
109704
+ replaceAll(rows2) {
109224
109705
  this.rows.clear();
109225
- for (const row of rows) {
109706
+ for (const row of rows2) {
109226
109707
  this.rows.set(this.opts.rowKey(row), row);
109227
109708
  }
109228
109709
  }
@@ -109566,10 +110047,10 @@ var runIncrementalSubscribeLive = (opts) => exports_Effect.gen(function* () {
109566
110047
  }), runReconcilePollLive = (opts) => runReconcilePoll(opts).pipe(exports_Effect.provide(IntervalClockLive)), runDualChannelFeedLive = (opts) => exports_Effect.gen(function* () {
109567
110048
  const initial = yield* exports_Effect.tryPromise(() => opts.fetchReconcile()).pipe(exports_Effect.orElseSucceed(() => null));
109568
110049
  if (initial !== null) {
109569
- const rows = opts.extractReconcileRows(initial);
109570
- opts.snapshot.replaceAll(rows);
109571
- if (rows.length > 0) {
109572
- yield* opts.onReconcileRows(rows).pipe(exports_Effect.catchAll(() => exports_Effect.void));
110050
+ const rows2 = opts.extractReconcileRows(initial);
110051
+ opts.snapshot.replaceAll(rows2);
110052
+ if (rows2.length > 0) {
110053
+ yield* opts.onReconcileRows(rows2).pipe(exports_Effect.catchAll(() => exports_Effect.void));
109573
110054
  }
109574
110055
  }
109575
110056
  const seedKey = yield* exports_Effect.tryPromise(() => opts.seedCursor()).pipe(exports_Effect.orElseSucceed(() => null));
@@ -109602,9 +110083,9 @@ var runIncrementalSubscribeLive = (opts) => exports_Effect.gen(function* () {
109602
110083
  args: undefined,
109603
110084
  intervalMs: opts.reconcileIntervalMs,
109604
110085
  onResult: (result) => exports_Effect.gen(function* () {
109605
- const rows = opts.extractReconcileRows(result);
109606
- opts.snapshot.replaceAll(rows);
109607
- yield* opts.onReconcileRows(rows).pipe(exports_Effect.catchAll(() => exports_Effect.void));
110086
+ const rows2 = opts.extractReconcileRows(result);
110087
+ opts.snapshot.replaceAll(rows2);
110088
+ yield* opts.onReconcileRows(rows2).pipe(exports_Effect.catchAll(() => exports_Effect.void));
109608
110089
  })
109609
110090
  });
109610
110091
  return {
@@ -109801,8 +110282,42 @@ async function clearStuckStoppingSlotIfNeeded(agentMgr, chatroomId, role) {
109801
110282
  }
109802
110283
  }
109803
110284
  async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
109804
- for (const row of listTasksReadyForNudge(tasks, now, cooldown)) {
110285
+ const getSlot = (chatroomId, role) => agentMgr.getSlot(chatroomId, role);
110286
+ for (const row of listTasksReadyForNudge(tasks, now, cooldown, getSlot)) {
109805
110287
  await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
110288
+ if (isNativeHarness(row.agentConfig.agentHarness)) {
110289
+ const { chatroomId, agentConfig } = row;
110290
+ const { role } = agentConfig;
110291
+ const deliveryState = getRoleDeliveryState();
110292
+ const failures3 = deliveryState.recordNativeNudgeFailure(chatroomId, role);
110293
+ if (shouldEscalateNativeNudgeToRestart(chatroomId, role, failures3)) {
110294
+ const full2 = await fetchTaskForAction(sessionDeps, machineId, row);
110295
+ if (!full2)
110296
+ continue;
110297
+ console.log(`[TaskMonitor] native nudge escalate restart ${role}@${chatroomId} — pending task ${row.taskId}`);
110298
+ runCliNudgeEffect(full2, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
110299
+ deliveryState.clearNativeNudgeFailures(chatroomId, role);
110300
+ continue;
110301
+ }
110302
+ resetRoleDeliveryState(chatroomId, role);
110303
+ await sessionDeps.backend.mutation(api.participants.join, {
110304
+ sessionId: sessionDeps.sessionId,
110305
+ chatroomId,
110306
+ role,
110307
+ action: NATIVE_WAITING_ACTION
110308
+ });
110309
+ console.log(`[TaskMonitor] native light nudge ${role}@${chatroomId} — redeliver pending task ${row.taskId}`);
110310
+ logNativeDeliveryFallback("native-light-nudge", role, chatroomId, row.taskId);
110311
+ getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
110312
+ tasks: [row],
110313
+ runtime: runtime4,
110314
+ effectContext: effectContext2,
110315
+ agentMgr,
110316
+ sessionDeps,
110317
+ machineId
110318
+ });
110319
+ continue;
110320
+ }
109806
110321
  const full = await fetchTaskForAction(sessionDeps, machineId, row);
109807
110322
  if (!full)
109808
110323
  continue;
@@ -109827,6 +110342,10 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
109827
110342
  isPidAlive: (pid) => isProcessAlive((p) => process.kill(p, 0), pid)
109828
110343
  };
109829
110344
  await reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
110345
+ if (tasks.length > 0) {
110346
+ const first2 = tasks[0];
110347
+ logNativeDeliveryFallback("signal-presence", first2.agentConfig.role, first2.chatroomId, first2.taskId);
110348
+ }
109830
110349
  getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
109831
110350
  tasks,
109832
110351
  runtime: runtime4,
@@ -109837,6 +110356,44 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
109837
110356
  });
109838
110357
  await nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
109839
110358
  }
110359
+ function listDeliverablePendingFromStore(agentMgr) {
110360
+ if (!hasAssignedTaskSnapshot())
110361
+ return [];
110362
+ return listAssignedTaskSnapshots().filter((row) => {
110363
+ if (row.status !== "pending")
110364
+ return false;
110365
+ const slot = agentMgr.getSlot(row.chatroomId, row.agentConfig.role);
110366
+ return isAgentReadyForNativeDelivery(row, slot);
110367
+ });
110368
+ }
110369
+ function runLocalStoreReconcilePass(params) {
110370
+ const { stopped, monitorPassInFlight, agentMgr, runtime: runtime4, effectContext: effectContext2, sessionDeps, machineId } = params;
110371
+ if (stopped || monitorPassInFlight)
110372
+ return;
110373
+ const deliverable = listDeliverablePendingFromStore(agentMgr);
110374
+ if (deliverable.length === 0)
110375
+ return;
110376
+ const first2 = deliverable[0];
110377
+ logNativeDeliveryFallback("periodic-reconcile", first2.agentConfig.role, first2.chatroomId, first2.taskId);
110378
+ getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
110379
+ tasks: deliverable,
110380
+ runtime: runtime4,
110381
+ effectContext: effectContext2,
110382
+ agentMgr,
110383
+ sessionDeps,
110384
+ machineId
110385
+ });
110386
+ }
110387
+ function subscribeAssignedTaskSnapshotStore(wsClient2, args2, isStopped) {
110388
+ return wsClient2.onUpdate(api.machines.listMachineAssignedTaskSnapshots, args2, (result) => {
110389
+ if (isStopped())
110390
+ return;
110391
+ const tasks = parseAssignedTaskMonitorRows(result?.tasks ?? []);
110392
+ replaceAssignedTaskSnapshots(tasks);
110393
+ }, (err) => {
110394
+ console.warn(`[${formatTimestamp()}] ⚠️ Assigned-task snapshot subscription error: ${getErrorMessage2(err)}`);
110395
+ });
110396
+ }
109840
110397
  var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
109841
110398
  const session2 = yield* DaemonSessionService;
109842
110399
  const agentMgr = yield* DaemonAgentProcessManagerService;
@@ -109856,6 +110413,14 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
109856
110413
  query: (fn2, args2) => session2.backend.query(fn2, args2)
109857
110414
  }
109858
110415
  };
110416
+ registerNativeDeliverySession({
110417
+ runtime: runtime4,
110418
+ effectContext: effectContext2,
110419
+ agentMgr,
110420
+ sessionDeps,
110421
+ machineId: session2.machineId
110422
+ });
110423
+ const unsubscribeSnapshotStore = subscribeAssignedTaskSnapshotStore(wsClient2, { sessionId: session2.sessionId, machineId: session2.machineId }, () => stopped);
109859
110424
  const runMonitorPass = (tasks, pass) => {
109860
110425
  if (stopped || monitorPassInFlight || tasks.length === 0)
109861
110426
  return;
@@ -109864,6 +110429,17 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
109864
110429
  monitorPassInFlight = false;
109865
110430
  });
109866
110431
  };
110432
+ const reconcileTimer = setInterval(() => {
110433
+ runLocalStoreReconcilePass({
110434
+ stopped,
110435
+ monitorPassInFlight,
110436
+ agentMgr,
110437
+ runtime: runtime4,
110438
+ effectContext: effectContext2,
110439
+ sessionDeps,
110440
+ machineId: session2.machineId
110441
+ });
110442
+ }, NATIVE_DELIVERY_RECONCILE_MS);
109867
110443
  yield* exports_Effect.tryPromise(() => session2.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
109868
110444
  sessionId: session2.sessionId,
109869
110445
  machineId: session2.machineId
@@ -109918,6 +110494,10 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
109918
110494
  return {
109919
110495
  stop() {
109920
110496
  stopped = true;
110497
+ unsubscribeSnapshotStore();
110498
+ clearAssignedTaskSnapshots();
110499
+ unregisterNativeDeliverySession();
110500
+ clearInterval(reconcileTimer);
109921
110501
  exports_Effect.runPromise(signalHandle.stop());
109922
110502
  exports_Effect.runPromise(presenceHandle.stop());
109923
110503
  console.log(`[${formatTimestamp()}] \uD83D\uDCCB Task-monitor stopped`);
@@ -109925,12 +110505,17 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
109925
110505
  };
109926
110506
  });
109927
110507
  var init_task_monitor = __esm(() => {
110508
+ init_reliability();
110509
+ init_participant();
109928
110510
  init_team_agent_settings();
109929
110511
  init_parse_session_augmentation();
109930
110512
  init_assigned_task_monitor_contract();
109931
110513
  init_esm();
110514
+ init_assigned_task_snapshot_store();
109932
110515
  init_daemon_services();
110516
+ init_native_ready_invariant();
109933
110517
  init_native_task_delivery_coordinator();
110518
+ init_native_task_injector_logic();
109934
110519
  init_task_monitor_logic();
109935
110520
  init_task_monitor_snapshot();
109936
110521
  init_api3();
@@ -110027,6 +110612,15 @@ function handleRequestStartEffect(event, tracker) {
110027
110612
  tracker.commandIds.set(eventId, Date.now());
110028
110613
  });
110029
110614
  }
110615
+ function handleRequestRestartEffect(event, tracker) {
110616
+ return exports_Effect.gen(function* () {
110617
+ const eventId = event._id.toString();
110618
+ if (tracker.commandIds.has(eventId))
110619
+ return;
110620
+ yield* onRequestRestartAgentEffect(event);
110621
+ tracker.commandIds.set(eventId, Date.now());
110622
+ });
110623
+ }
110030
110624
  function handleRequestStopEffect(event, tracker) {
110031
110625
  return exports_Effect.gen(function* () {
110032
110626
  const eventId = event._id.toString();
@@ -110178,6 +110772,7 @@ var init_command_loop = __esm(() => {
110178
110772
  init_reliability();
110179
110773
  init_esm();
110180
110774
  init_api3();
110775
+ init_on_request_restart_agent();
110181
110776
  init_on_request_start_agent();
110182
110777
  init_on_request_stop_agent();
110183
110778
  init_on_daemon_shutdown();
@@ -110205,6 +110800,7 @@ var init_command_loop = __esm(() => {
110205
110800
  GIT_PUSH_ACTIONS = new Set(["git-pull", "git-push", "git-sync", "git-discard-all"]);
110206
110801
  commandEventHandlers = {
110207
110802
  "agent.requestStart": handleRequestStartEffect,
110803
+ "agent.restart": handleRequestRestartEffect,
110208
110804
  "agent.requestStop": handleRequestStopEffect,
110209
110805
  "daemon.ping": handlePingCommandEffect,
110210
110806
  "daemon.gitRefresh": handleGitRefreshCommandEffect,
@@ -110478,7 +111074,7 @@ async function harnessStatus() {
110478
111074
  };
110479
111075
  const program2 = exports_Effect.forEach(services, detectOne, { concurrency: "unbounded" });
110480
111076
  const results = await exports_Effect.runPromise(program2);
110481
- const rows = results.map(({ id: id3, displayName, result }) => {
111077
+ const rows2 = results.map(({ id: id3, displayName, result }) => {
110482
111078
  if (isInstalled(result)) {
110483
111079
  return { id: id3, displayName, status: "installed" };
110484
111080
  } else if (isNotInstalled(result)) {
@@ -110488,13 +111084,13 @@ async function harnessStatus() {
110488
111084
  }
110489
111085
  return { id: id3, displayName, status: "not-installed" };
110490
111086
  });
110491
- const idWidth = Math.max(4, ...rows.map((r) => r.id.length));
110492
- const nameWidth = Math.max(11, ...rows.map((r) => r.displayName.length));
111087
+ const idWidth = Math.max(4, ...rows2.map((r) => r.id.length));
111088
+ const nameWidth = Math.max(11, ...rows2.map((r) => r.displayName.length));
110493
111089
  const header = `${"ID".padEnd(idWidth)} ${"DISPLAY NAME".padEnd(nameWidth)} STATUS`;
110494
111090
  const divider = `${"-".repeat(idWidth)} ${"-".repeat(nameWidth)} ------`;
110495
111091
  console.log(header);
110496
111092
  console.log(divider);
110497
- for (const row of rows) {
111093
+ for (const row of rows2) {
110498
111094
  const statusIcon = row.status === "installed" ? "✅ installed" : row.status === "error" ? "⚠️ error" : "❌ not installed";
110499
111095
  const line = `${row.id.padEnd(idWidth)} ${row.displayName.padEnd(nameWidth)} ${statusIcon}`;
110500
111096
  console.log(line);
@@ -110503,8 +111099,8 @@ async function harnessStatus() {
110503
111099
  }
110504
111100
  }
110505
111101
  console.log("");
110506
- const installedCount = rows.filter((r) => r.status === "installed").length;
110507
- const totalCount = rows.length;
111102
+ const installedCount = rows2.filter((r) => r.status === "installed").length;
111103
+ const totalCount = rows2.length;
110508
111104
  console.log(`${installedCount}/${totalCount} harnesses available on this machine.`);
110509
111105
  }
110510
111106
  var init_harness_status = __esm(() => {
@@ -111471,4 +112067,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
111471
112067
  });
111472
112068
  program2.parse();
111473
112069
 
111474
- //# debugId=8E7C236B7CEE28C564756E2164756E21
112070
+ //# debugId=A68932632BD7E62C64756E2164756E21