chatroom-cli 1.98.5 → 1.98.7

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
@@ -83544,7 +83544,9 @@ var DaemonMachineService, DaemonMachineServiceLive = (ops) => exports_Layer.succ
83544
83544
  clearStuckStoppingSlot: (chatroomId, role) => exports_Effect.promise(() => mgr.clearStuckStoppingSlot(chatroomId, role)),
83545
83545
  whenTurnEndsIdle: () => exports_Effect.promise(() => mgr.whenTurnEndsIdle()),
83546
83546
  resumeTurnForSlot: (args2) => exports_Effect.promise(() => mgr.resumeTurnForSlot(args2)),
83547
- setLastInFlightTask: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.setLastInFlightTask(chatroomId, role, taskId))
83547
+ setLastInFlightTask: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.setLastInFlightTask(chatroomId, role, taskId)),
83548
+ clearLastInFlightTaskIfMatches: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.clearLastInFlightTaskIfMatches(chatroomId, role, taskId)),
83549
+ reconcileNativeTurnPhaseIdle: (chatroomId, role) => exports_Effect.sync(() => mgr.reconcileNativeTurnPhaseIdle(chatroomId, role))
83548
83550
  }), DaemonSessionService, DaemonMutableStateService;
83549
83551
  var init_daemon_services = __esm(() => {
83550
83552
  init_esm();
@@ -84012,8 +84014,76 @@ async function logDaemonAuditEvent(logEvent, event) {
84012
84014
  });
84013
84015
  }
84014
84016
 
84017
+ // src/daemon/infrastructure/inbox/task-snapshot-state.ts
84018
+ function snapshotKey(taskId, role) {
84019
+ return `${taskId}:${role.toLowerCase()}`;
84020
+ }
84021
+
84022
+ class MachineTaskSnapshotState {
84023
+ snapshots = new Map;
84024
+ replace(snapshots) {
84025
+ this.snapshots.clear();
84026
+ this.upsert(snapshots);
84027
+ }
84028
+ applySignalPage(signals, snapshots) {
84029
+ const snapshotsByKey = new Map(snapshots.map((snapshot) => [
84030
+ snapshotKey(snapshot.taskId, snapshot.agentConfig.role),
84031
+ snapshot
84032
+ ]));
84033
+ for (const signal of signals) {
84034
+ const key = snapshotKey(signal.taskId, signal.targetRole);
84035
+ const snapshot = snapshotsByKey.get(key);
84036
+ if (snapshot) {
84037
+ this.snapshots.set(key, snapshot);
84038
+ } else {
84039
+ this.snapshots.delete(key);
84040
+ }
84041
+ }
84042
+ }
84043
+ listForRole(chatroomId, role) {
84044
+ const roleLower = role.toLowerCase();
84045
+ return [...this.snapshots.values()].filter((snapshot) => snapshot.chatroomId === chatroomId && snapshot.agentConfig.role.toLowerCase() === roleLower);
84046
+ }
84047
+ listAll() {
84048
+ return [...this.snapshots.values()];
84049
+ }
84050
+ setDesiredState(chatroomId, role, desiredState) {
84051
+ const roleLower = role.toLowerCase();
84052
+ for (const [key, snapshot] of this.snapshots) {
84053
+ if (snapshot.chatroomId !== chatroomId || snapshot.agentConfig.role.toLowerCase() !== roleLower) {
84054
+ continue;
84055
+ }
84056
+ this.snapshots.set(key, {
84057
+ ...snapshot,
84058
+ agentConfig: { ...snapshot.agentConfig, desiredState }
84059
+ });
84060
+ }
84061
+ }
84062
+ upsert(snapshots) {
84063
+ for (const snapshot of snapshots) {
84064
+ this.snapshots.set(snapshotKey(snapshot.taskId, snapshot.agentConfig.role), snapshot);
84065
+ }
84066
+ }
84067
+ }
84068
+
84069
+ // src/daemon/entry/native-delivery/native-delivery-session-registry.ts
84070
+ function registerNativeDeliverySession(ctx) {
84071
+ registered = {
84072
+ ...ctx,
84073
+ taskSnapshotState: ctx.taskSnapshotState ?? new MachineTaskSnapshotState
84074
+ };
84075
+ }
84076
+ function unregisterNativeDeliverySession() {
84077
+ registered = null;
84078
+ }
84079
+ function getNativeDeliverySession() {
84080
+ return registered;
84081
+ }
84082
+ var registered = null;
84083
+ var init_native_delivery_session_registry = () => {};
84084
+
84015
84085
  // ../../services/backend/config/reliability.ts
84016
- 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, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SYNC_RECONCILE_MS, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
84086
+ var HARNESS_SESSION_READY_TIMEOUT_MS = 5000, DAEMON_HEARTBEAT_INTERVAL_MS, DAEMON_HEARTBEAT_TTL_MS, AGENT_REQUEST_DEADLINE_MS = 120000, OBSERVED_FULL_PUSH_INTERVAL_MS, OBSERVED_SYNC_RECONCILE_MS, WORKSPACE_RECENCY_WINDOW_MS, WORKSPACE_LIST_RECONCILE_MS, CONNECTION_CLOSE_REQUEST_TTL_MS, ENHANCER_TERMINAL_JOB_RETENTION_MS;
84017
84087
  var init_reliability = __esm(() => {
84018
84088
  DAEMON_HEARTBEAT_INTERVAL_MS = 5 * 60000;
84019
84089
  DAEMON_HEARTBEAT_TTL_MS = 6 * DAEMON_HEARTBEAT_INTERVAL_MS;
@@ -98686,40 +98756,18 @@ var init_convex_id = __esm(() => {
98686
98756
  init_zod();
98687
98757
  });
98688
98758
 
98689
- // ../../services/backend/src/domain/usecase/machine/assigned-task-monitor-contract.ts
98690
- function parseAssignedTaskSignal(raw) {
98691
- return assignedTaskSignalSchema.parse(raw);
98759
+ // ../../services/backend/src/domain/usecase/machine/assigned-task-snapshot-contract.ts
98760
+ function parseAssignedTaskSnapshotRow(raw) {
98761
+ return assignedTaskSnapshotRowSchema.parse(raw);
98692
98762
  }
98693
- function parseAssignedTaskPresenceSignal(raw) {
98694
- const full = assignedTaskPresenceSignalSchema.safeParse(raw);
98695
- if (full.success)
98696
- return full.data;
98697
- const delta = assignedTaskPresenceDeltaSchema.safeParse(raw);
98698
- if (delta.success) {
98699
- const presenceUpdatedAt = Number(delta.data.presenceKey.split(":")[0]);
98700
- const resolvedAt = Number.isFinite(presenceUpdatedAt) ? presenceUpdatedAt : 0;
98701
- return {
98702
- taskId: delta.data.taskId,
98703
- chatroomId: "",
98704
- role: delta.data.role,
98705
- lastSeenAt: resolvedAt,
98706
- presenceUpdatedAt: resolvedAt,
98707
- presenceKey: delta.data.presenceKey
98708
- };
98709
- }
98710
- return assignedTaskPresenceSignalSchema.parse(raw);
98711
- }
98712
- function parseAssignedTaskMonitorRow(raw) {
98713
- return assignedTaskMonitorRowSchema.parse(raw);
98714
- }
98715
- function parseAssignedTaskMonitorRows(raw) {
98763
+ function parseAssignedTaskSnapshotRows(raw) {
98716
98764
  if (!Array.isArray(raw)) {
98717
98765
  throw new Error("Expected hydrate tasks array");
98718
98766
  }
98719
- return raw.map((row) => parseAssignedTaskMonitorRow(row));
98767
+ return raw.map((row) => parseAssignedTaskSnapshotRow(row));
98720
98768
  }
98721
- var ACTIVE_TASK_STATUSES, activeTaskStatusSchema, ASSIGNED_TASK_SIGNAL_TYPES, assignedTaskSignalTypeSchema, SESSION_AUGMENTATION_MODES, sessionAugmentationSchema, AGENT_DESIRED_STATES, agentDesiredStateSchema, AGENT_CIRCUIT_STATES, agentCircuitStateSchema, chatroomTaskIdSchema, chatroomRoomIdSchema, assignedTaskAgentConfigSchema, assignedTaskParticipantSchema, assignedTaskSignalBootstrapFields, assignedTaskSignalSchema, assignedTaskPresenceSignalSchema, assignedTaskPresenceDeltaSchema, assignedTaskMonitorRowSchema;
98722
- var init_assigned_task_monitor_contract = __esm(() => {
98769
+ var ACTIVE_TASK_STATUSES, activeTaskStatusSchema, ASSIGNED_TASK_SIGNAL_TYPES, assignedTaskSignalTypeSchema, SESSION_AUGMENTATION_MODES, sessionAugmentationSchema, AGENT_DESIRED_STATES, agentDesiredStateSchema, AGENT_CIRCUIT_STATES, agentCircuitStateSchema, chatroomTaskIdSchema, chatroomRoomIdSchema, assignedTaskAgentConfigSchema, assignedTaskParticipantSchema, assignedTaskSignalBootstrapFields, assignedTaskSignalSchema, assignedTaskPresenceSignalSchema, assignedTaskPresenceDeltaSchema, assignedTaskSnapshotRowSchema;
98770
+ var init_assigned_task_snapshot_contract = __esm(() => {
98723
98771
  init_zod();
98724
98772
  init_convex_id();
98725
98773
  ACTIVE_TASK_STATUSES = ["pending", "acknowledged", "in_progress"];
@@ -98782,7 +98830,7 @@ var init_assigned_task_monitor_contract = __esm(() => {
98782
98830
  role: exports_external.string(),
98783
98831
  presenceKey: exports_external.string()
98784
98832
  });
98785
- assignedTaskMonitorRowSchema = exports_external.object({
98833
+ assignedTaskSnapshotRowSchema = exports_external.object({
98786
98834
  taskId: chatroomTaskIdSchema,
98787
98835
  chatroomId: chatroomRoomIdSchema,
98788
98836
  status: activeTaskStatusSchema,
@@ -98880,16 +98928,16 @@ function explainAgentReadyForNativeDeliveryBlock(task, slot) {
98880
98928
  if (!isAgentDesiredRunning(agentConfig.desiredState)) {
98881
98929
  return `desired_state_not_running (desiredState=${agentConfig.desiredState})`;
98882
98930
  }
98883
- if (agentConfig.spawnedAgentPid == null) {
98884
- return "spawned_pid_missing";
98885
- }
98886
98931
  if (!slot) {
98887
- return `slot_missing (expectedPid=${agentConfig.spawnedAgentPid})`;
98932
+ return agentConfig.spawnedAgentPid == null ? "spawned_pid_missing" : `slot_missing (expectedPid=${agentConfig.spawnedAgentPid})`;
98888
98933
  }
98889
98934
  if (!isSlotRunning(slot.state)) {
98890
- return `slot_not_running (slotState=${slot.state}, expectedPid=${agentConfig.spawnedAgentPid})`;
98935
+ return `slot_not_running (slotState=${slot.state}, expectedPid=${agentConfig.spawnedAgentPid ?? "none"})`;
98891
98936
  }
98892
- if (slot.pid !== agentConfig.spawnedAgentPid) {
98937
+ if (slot.pid == null) {
98938
+ return "slot_pid_missing";
98939
+ }
98940
+ if (agentConfig.spawnedAgentPid != null && slot.pid !== agentConfig.spawnedAgentPid) {
98893
98941
  return `pid_mismatch (slotPid=${slot.pid ?? "none"}, snapshotPid=${agentConfig.spawnedAgentPid})`;
98894
98942
  }
98895
98943
  if (typeof slot.harnessSessionId !== "string" || slot.harnessSessionId.length === 0) {
@@ -98931,17 +98979,18 @@ function logNativeDeliveryNoTasks(role, chatroomId) {
98931
98979
  console.log(`[NativeDelivery:skip] ${role}@${chatroomId} — no pending tasks for role`);
98932
98980
  }
98933
98981
 
98934
- // src/daemon/entry/native-delivery/native-delivery-session-registry.ts
98935
- function registerNativeDeliverySession(ctx) {
98936
- registered = ctx;
98937
- }
98938
- function unregisterNativeDeliverySession() {
98939
- registered = null;
98940
- }
98941
- function getNativeDeliverySession() {
98942
- return registered;
98982
+ // src/daemon/entry/native-delivery/native-stale-turn-phase.ts
98983
+ function isStaleTurnInFlightWhileWaiting(task, slot) {
98984
+ if (!slot || isTurnPhaseIdle(slot.nativeTurnPhase ?? "idle"))
98985
+ return false;
98986
+ if (task.status !== "pending")
98987
+ return false;
98988
+ return task.participant?.lastSeenAction === NATIVE_WAITING_ACTION;
98943
98989
  }
98944
- var registered = null;
98990
+ var init_native_stale_turn_phase = __esm(() => {
98991
+ init_participant();
98992
+ init_check_agent_slot();
98993
+ });
98945
98994
 
98946
98995
  // src/daemon/domain/native-integration/predicates.ts
98947
98996
  function isStaleCliGetNextTaskWaiting(task) {
@@ -99002,8 +99051,21 @@ function explainNativeDeliveryBlock(task, opts) {
99002
99051
  return `acknowledged_wrong_role (assignedTo=${assignedTo ?? "none"}, role=${role})`;
99003
99052
  }
99004
99053
  }
99054
+ const inFlightBlock = explainInFlightDeliveryBlock(task, opts.slot);
99055
+ if (inFlightBlock)
99056
+ return inFlightBlock;
99005
99057
  return explainAgentReadyForNativeDeliveryBlock(task, opts.slot);
99006
99058
  }
99059
+ function explainInFlightDeliveryBlock(task, slot) {
99060
+ if (!slot?.lastInFlightTaskId || slot.lastInFlightTaskId !== task.taskId)
99061
+ return null;
99062
+ if (task.status === "pending")
99063
+ return null;
99064
+ if (task.status === "acknowledged") {
99065
+ return "already_delivered_to_slot (lastInFlightTaskId match, status=acknowledged)";
99066
+ }
99067
+ return null;
99068
+ }
99007
99069
  function explainLedgerDeliveryBlock(taskId, harnessSessionId, ledger) {
99008
99070
  if (ledger.isDelivered(taskId, harnessSessionId)) {
99009
99071
  return "already_delivered_this_session";
@@ -99403,30 +99465,6 @@ function mapAssignedTaskSnapshotList(rows) {
99403
99465
  return rows.map(mapAssignedTaskSnapshot);
99404
99466
  }
99405
99467
 
99406
- // src/infrastructure/stores/assigned-task-snapshot-store.ts
99407
- function replaceAssignedTaskSnapshots(next4) {
99408
- rows = [...next4];
99409
- hasSnapshot = true;
99410
- }
99411
- function clearAssignedTaskSnapshots() {
99412
- rows = [];
99413
- hasSnapshot = false;
99414
- }
99415
- function hasAssignedTaskSnapshot() {
99416
- return hasSnapshot;
99417
- }
99418
- function listAssignedTaskSnapshots() {
99419
- return [...rows];
99420
- }
99421
- function listAssignedTaskSnapshotsForRole(chatroomId, role) {
99422
- const roleLower = role.toLowerCase();
99423
- return rows.filter((row) => row.chatroomId === chatroomId && row.agentConfig.role.toLowerCase() === roleLower);
99424
- }
99425
- var rows, hasSnapshot = false;
99426
- var init_assigned_task_snapshot_store = __esm(() => {
99427
- rows = [];
99428
- });
99429
-
99430
99468
  // src/daemon/entry/restart-orchestrator-in-flight.ts
99431
99469
  function roleKey(chatroomId, role) {
99432
99470
  return `${chatroomId}:${role.toLowerCase()}`;
@@ -99518,7 +99556,7 @@ class NativeTaskDeliveryCoordinator {
99518
99556
  if (!session2)
99519
99557
  return;
99520
99558
  const { runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = session2;
99521
- const tasks = listAssignedTaskSnapshotsForRole(chatroomId, role);
99559
+ const tasks = session2.taskSnapshotState?.listForRole(chatroomId, role) ?? [];
99522
99560
  if (tasks.length === 0) {
99523
99561
  logNativeDeliveryNoTasks(role, chatroomId);
99524
99562
  return;
@@ -99549,7 +99587,18 @@ class NativeTaskDeliveryCoordinator {
99549
99587
  for (const row of pendingFirst) {
99550
99588
  const { role } = row.agentConfig;
99551
99589
  const slot = agentMgr.getSlot(row.chatroomId, role);
99552
- const blockReason = explainNativeDeliveryBlock(row, { slot });
99590
+ if (row.status === "pending" && slot?.lastInFlightTaskId === row.taskId) {
99591
+ exports_Effect.runSync(agentMgr.clearLastInFlightTaskIfMatches(row.chatroomId, role, row.taskId));
99592
+ }
99593
+ if (isStaleTurnInFlightWhileWaiting(row, slot)) {
99594
+ if (agentMgr.reconcileNativeTurnPhaseIdle) {
99595
+ exports_Effect.runSync(agentMgr.reconcileNativeTurnPhaseIdle(row.chatroomId, role));
99596
+ }
99597
+ logNativeDeliveryFallback("stale-turn-phase", role, row.chatroomId, row.taskId);
99598
+ }
99599
+ const blockReason = explainNativeDeliveryBlock(row, {
99600
+ slot: agentMgr.getSlot(row.chatroomId, role)
99601
+ });
99553
99602
  if (blockReason) {
99554
99603
  if (isDeliverableTaskStatus(row.status)) {
99555
99604
  logNativeDeliverySkip(role, row.chatroomId, row.taskId, blockReason);
@@ -99638,11 +99687,12 @@ function notifyNativeTurnIdle(params) {
99638
99687
  var coordinator;
99639
99688
  var init_native_task_delivery_coordinator = __esm(() => {
99640
99689
  init_esm();
99690
+ init_native_delivery_session_registry();
99691
+ init_native_stale_turn_phase();
99641
99692
  init_native_task_injector_logic();
99642
99693
  init_native_task_injector();
99643
99694
  init_api3();
99644
99695
  init_assigned_task();
99645
- init_assigned_task_snapshot_store();
99646
99696
  init_convex_error();
99647
99697
  init_restart_orchestrator_in_flight();
99648
99698
  });
@@ -99718,7 +99768,7 @@ async function listDeliverableSnapshots(deps, event) {
99718
99768
  machineId: deps.session.machineId
99719
99769
  });
99720
99770
  const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
99721
- return mapAssignedTaskSnapshotList(parseAssignedTaskMonitorRows(result.tasks ?? [])).filter((t) => t.chatroomId === event.chatroomId && t.agentConfig.role.toLowerCase() === event.role.toLowerCase() && isDeliverableTaskStatus(t.status) && isAgentReadyForNativeDelivery(t, slot)).sort((a, b) => a.createdAt - b.createdAt);
99771
+ return mapAssignedTaskSnapshotList(parseAssignedTaskSnapshotRows(result.tasks ?? [])).filter((t) => t.chatroomId === event.chatroomId && t.agentConfig.role.toLowerCase() === event.role.toLowerCase() && isDeliverableTaskStatus(t.status) && isAgentReadyForNativeDelivery(t, slot)).sort((a, b) => a.createdAt - b.createdAt);
99722
99772
  }
99723
99773
  async function deliverOneTask(deps, event, snapshot) {
99724
99774
  const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
@@ -99740,6 +99790,11 @@ async function deliverOneTask(deps, event, snapshot) {
99740
99790
  console.warn(`[RestartOrchestrator] skip task ${snapshot.taskId} — ${ledgerBlock}`);
99741
99791
  return false;
99742
99792
  }
99793
+ const deliveryBlock = explainNativeDeliveryBlock(snapshot, { slot });
99794
+ if (deliveryBlock) {
99795
+ console.warn(`[RestartOrchestrator] skip task ${snapshot.taskId} — ${deliveryBlock}`);
99796
+ return false;
99797
+ }
99743
99798
  if (!ledger.tryAcquire(snapshot.taskId, harnessSessionId)) {
99744
99799
  console.warn(`[RestartOrchestrator] skip task ${snapshot.taskId} — delivery_ledger_busy`);
99745
99800
  return false;
@@ -99843,7 +99898,7 @@ var init_restart_orchestrator = __esm(() => {
99843
99898
  init_reliability();
99844
99899
  init_participant();
99845
99900
  init_build_agent_restart_event();
99846
- init_assigned_task_monitor_contract();
99901
+ init_assigned_task_snapshot_contract();
99847
99902
  init_esm();
99848
99903
  init_api3();
99849
99904
  init_native_ready_invariant();
@@ -99860,15 +99915,23 @@ var init_restart_orchestrator = __esm(() => {
99860
99915
  function createStartAgentDeps(agentMgr, session2) {
99861
99916
  return {
99862
99917
  agentProcessManager: {
99863
- ensureRunning: async (args2) => exports_Effect.runPromise(agentMgr.ensureRunning({
99864
- chatroomId: args2.chatroomId,
99865
- role: args2.role,
99866
- agentHarness: args2.agentHarness,
99867
- model: args2.model,
99868
- workingDir: args2.workingDir,
99869
- reason: args2.reason,
99870
- wantResume: args2.wantResume
99871
- }))
99918
+ ensureRunning: async (args2) => {
99919
+ const taskSnapshotState = getNativeDeliverySession()?.taskSnapshotState;
99920
+ taskSnapshotState?.setDesiredState(args2.chatroomId, args2.role, "running");
99921
+ const result = await exports_Effect.runPromise(agentMgr.ensureRunning({
99922
+ chatroomId: args2.chatroomId,
99923
+ role: args2.role,
99924
+ agentHarness: args2.agentHarness,
99925
+ model: args2.model,
99926
+ workingDir: args2.workingDir,
99927
+ reason: args2.reason,
99928
+ wantResume: args2.wantResume
99929
+ }));
99930
+ if (!result.success) {
99931
+ taskSnapshotState?.setDesiredState(args2.chatroomId, args2.role, "stopped");
99932
+ }
99933
+ return result;
99934
+ }
99872
99935
  },
99873
99936
  session: {
99874
99937
  sessionId: session2.sessionId,
@@ -99989,6 +100052,7 @@ function createRecoverAgentStateDeps(agentMgr, session2) {
99989
100052
  var init_agent_control_bridge = __esm(() => {
99990
100053
  init_esm();
99991
100054
  init_api3();
100055
+ init_native_delivery_session_registry();
99992
100056
  init_restart_orchestrator();
99993
100057
  });
99994
100058
 
@@ -101527,6 +101591,7 @@ class AgentProcessManager {
101527
101591
  }
101528
101592
  if (slot) {
101529
101593
  setNativeTurnPhase(slot, defaultNativeTurnPhase());
101594
+ this.clearLastInFlightTask(opts.chatroomId, opts.role);
101530
101595
  }
101531
101596
  notifyNativeTurnIdle({ chatroomId: opts.chatroomId, role: opts.role });
101532
101597
  console.log(`[AgentProcessManager] ✅ Native agent_end handled for ${opts.role}`);
@@ -101542,6 +101607,9 @@ class AgentProcessManager {
101542
101607
  }
101543
101608
  const stopReason = resolveStopReason(opts.code, opts.signal);
101544
101609
  const ctx = this.captureExitContext(slot, opts, stopReason);
101610
+ if (slot.harness && getHarnessCapabilities(slot.harness).supportsNativeIntegration) {
101611
+ setNativeTurnPhase(slot, defaultNativeTurnPhase());
101612
+ }
101545
101613
  this.maybeEmitProviderUnavailable(opts.chatroomId, opts.role, slot);
101546
101614
  notifyNativeHarnessSessionLostOnExit({
101547
101615
  chatroomId: opts.chatroomId,
@@ -101843,6 +101911,21 @@ class AgentProcessManager {
101843
101911
  const slot = this.getOrCreateSlot(agentKey3(chatroomId, role));
101844
101912
  slot.lastInFlightTaskId = taskId;
101845
101913
  }
101914
+ clearLastInFlightTaskIfMatches(chatroomId, role, taskId) {
101915
+ const slot = this.slots.get(agentKey3(chatroomId, role));
101916
+ if (slot?.lastInFlightTaskId === taskId)
101917
+ slot.lastInFlightTaskId = undefined;
101918
+ }
101919
+ reconcileNativeTurnPhaseIdle(chatroomId, role) {
101920
+ const slot = this.getSlot(chatroomId, role);
101921
+ if (slot)
101922
+ setNativeTurnPhase(slot, defaultNativeTurnPhase());
101923
+ }
101924
+ clearLastInFlightTask(chatroomId, role) {
101925
+ const slot = this.slots.get(agentKey3(chatroomId, role));
101926
+ if (slot)
101927
+ slot.lastInFlightTaskId = undefined;
101928
+ }
101846
101929
  listActive() {
101847
101930
  const result = [];
101848
101931
  for (const [key, slot] of this.slots) {
@@ -102512,6 +102595,9 @@ class AgentProcessManager {
102512
102595
  setNativeTurnPhase(slot, defaultNativeTurnPhase());
102513
102596
  }
102514
102597
  await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
102598
+ if (getHarnessCapabilities(opts.agentHarness).supportsNativeIntegration) {
102599
+ getNativeTaskDeliveryCoordinator().tryInjectNextForRole(opts.chatroomId, opts.role);
102600
+ }
102515
102601
  }
102516
102602
  async emitNativeWaiting(chatroomId, role, harness) {
102517
102603
  return emitNativeWaitingAfterSpawn({
@@ -114159,27 +114245,27 @@ function createFifoBatchedOutbox(o) {
114159
114245
  return running3;
114160
114246
  running3 = (async () => {
114161
114247
  while (true) {
114162
- const rows2 = o.store.claimNextBatch(o.deliveryKey, o.batchSize);
114163
- if (!rows2.length)
114248
+ const rows = o.store.claimNextBatch(o.deliveryKey, o.batchSize);
114249
+ if (!rows.length)
114164
114250
  break;
114165
114251
  try {
114166
- const results = await o.send(rows2.map((r) => o.deserialize(r.payloadJson)));
114252
+ const results = await o.send(rows.map((r) => o.deserialize(r.payloadJson)));
114167
114253
  let hasRetry = false;
114168
114254
  for (let i2 = 0;i2 < results.length; i2++) {
114169
- const item = o.deserialize(rows2[i2].payloadJson);
114255
+ const item = o.deserialize(rows[i2].payloadJson);
114170
114256
  const outcome = o.classifyOutcome?.(results[i2], item) ?? { kind: "success" };
114171
114257
  if (outcome.kind === "retry") {
114172
- o.store.updatePayload(rows2[i2].id, o.serialize(outcome.item));
114173
- o.store.markPending(rows2[i2].id);
114258
+ o.store.updatePayload(rows[i2].id, o.serialize(outcome.item));
114259
+ o.store.markPending(rows[i2].id);
114174
114260
  hasRetry = true;
114175
114261
  continue;
114176
114262
  }
114177
- o.store.markDone(rows2[i2].id);
114178
- waiters.get(rows2[i2].id)?.resolve(results[i2]);
114179
- waiters.delete(rows2[i2].id);
114263
+ o.store.markDone(rows[i2].id);
114264
+ waiters.get(rows[i2].id)?.resolve(results[i2]);
114265
+ waiters.delete(rows[i2].id);
114180
114266
  }
114181
- for (let i2 = results.length;i2 < rows2.length; i2++)
114182
- o.store.markPending(rows2[i2].id);
114267
+ for (let i2 = results.length;i2 < rows.length; i2++)
114268
+ o.store.markPending(rows[i2].id);
114183
114269
  if (hasRetry) {
114184
114270
  scheduleRetry();
114185
114271
  break;
@@ -114187,7 +114273,7 @@ function createFifoBatchedOutbox(o) {
114187
114273
  retryAttempt = 0;
114188
114274
  } catch (e) {
114189
114275
  o.onError?.(e);
114190
- for (const r of rows2)
114276
+ for (const r of rows)
114191
114277
  o.store.markPendingRetry(r.id, e);
114192
114278
  scheduleRetry();
114193
114279
  break;
@@ -115715,20 +115801,7 @@ var init_command_run_subscription = __esm(() => {
115715
115801
  dispatchedStop = new Set;
115716
115802
  });
115717
115803
 
115718
- // src/daemon/entry/assigned-task-monitor-registry.ts
115719
- function registerAssignedTaskMonitorHandler(h) {
115720
- handler6 = h;
115721
- }
115722
- function unregisterAssignedTaskMonitorHandler() {
115723
- handler6 = undefined;
115724
- }
115725
- async function dispatchAssignedTaskMonitorEvent(event) {
115726
- if (handler6)
115727
- await handler6(event);
115728
- }
115729
- var handler6;
115730
-
115731
- // src/daemon/entry/task-monitor/task-monitor-logic.ts
115804
+ // src/daemon/entry/task-delivery/task-delivery-logic.ts
115732
115805
  function isPendingAliveRunningTask(task) {
115733
115806
  const { agentConfig, status: status3 } = task;
115734
115807
  return status3 === "pending" && agentConfig.spawnedAgentPid != null && isAgentDesiredRunning(agentConfig.desiredState);
@@ -115754,7 +115827,7 @@ function isSlotUnavailableForPid(slot, pid, isPidAlive, now = Date.now()) {
115754
115827
  function isNativeRevivableTaskStatus(task) {
115755
115828
  const { status: status3 } = task;
115756
115829
  if (status3 === "pending") {
115757
- return task.agentConfig.spawnedAgentPid != null;
115830
+ return true;
115758
115831
  }
115759
115832
  if (status3 === "acknowledged") {
115760
115833
  return task.assignedTo?.toLowerCase() === task.agentConfig.role.toLowerCase();
@@ -115787,9 +115860,29 @@ function listNativeTasksNeedingRevive(tasks, health, now, cooldown) {
115787
115860
  const { chatroomId, agentConfig } = task;
115788
115861
  if (!agentConfig.workingDir)
115789
115862
  return false;
115790
- if (!cooldown.canNudge(chatroomId, agentConfig.role, now))
115863
+ if (!cooldown.canAttempt(chatroomId, agentConfig.role, "revive", now))
115864
+ return false;
115865
+ cooldown.recordAttempt(chatroomId, agentConfig.role, "revive", now);
115866
+ return true;
115867
+ });
115868
+ }
115869
+ function isNativePendingTaskNeedingWake(task) {
115870
+ if (!isNativeHarness(task.agentConfig.agentHarness))
115871
+ return false;
115872
+ if (task.status !== "pending")
115873
+ return false;
115874
+ if (isAgentDesiredRunning(task.agentConfig.desiredState))
115875
+ return false;
115876
+ return Boolean(task.agentConfig.workingDir);
115877
+ }
115878
+ function listNativePendingTasksNeedingWake(tasks, cooldown, now) {
115879
+ return tasks.filter((task) => {
115880
+ if (!isNativePendingTaskNeedingWake(task))
115881
+ return false;
115882
+ const { chatroomId, agentConfig } = task;
115883
+ if (!cooldown.canAttempt(chatroomId, agentConfig.role, "wake", now))
115791
115884
  return false;
115792
- cooldown.recordNudge(chatroomId, agentConfig.role, now);
115885
+ cooldown.recordAttempt(chatroomId, agentConfig.role, "wake", now);
115793
115886
  return true;
115794
115887
  });
115795
115888
  }
@@ -115813,23 +115906,20 @@ function shouldNudgeNativePendingTask(task, now, pendingIdleThresholdMs, slot) {
115813
115906
  const idleSince = lastSeenAt > 0 ? now - lastSeenAt : now - task.createdAt;
115814
115907
  return idleSince > pendingIdleThresholdMs;
115815
115908
  }
115816
- function shouldEscalateNativeNudgeToRestart(chatroomId, role, failures3) {
115817
- return failures3 >= NATIVE_NUDGE_ESCALATION_THRESHOLD;
115818
- }
115819
115909
 
115820
- class NudgeCooldown {
115910
+ class RecoveryCooldown {
115821
115911
  cooldownMs;
115822
- lastNudgedAt = new Map;
115912
+ lastAttemptAt = new Map;
115823
115913
  constructor(cooldownMs = NUDGE_COOLDOWN_MS) {
115824
115914
  this.cooldownMs = cooldownMs;
115825
115915
  }
115826
- canNudge(chatroomId, role, now) {
115827
- const key = `${chatroomId}:${role}`;
115828
- const last2 = this.lastNudgedAt.get(key);
115916
+ canAttempt(chatroomId, role, kind, now) {
115917
+ const key = `${kind}:${chatroomId}:${role}`;
115918
+ const last2 = this.lastAttemptAt.get(key);
115829
115919
  return last2 === undefined || now - last2 >= this.cooldownMs;
115830
115920
  }
115831
- recordNudge(chatroomId, role, now) {
115832
- this.lastNudgedAt.set(`${chatroomId}:${role}`, now);
115921
+ recordAttempt(chatroomId, role, kind, now) {
115922
+ this.lastAttemptAt.set(`${kind}:${chatroomId}:${role}`, now);
115833
115923
  }
115834
115924
  }
115835
115925
  function isTaskReadyForNudge(task, now, cooldown, getSlot) {
@@ -115841,7 +115931,7 @@ function isTaskReadyForNudge(task, now, cooldown, getSlot) {
115841
115931
  return false;
115842
115932
  }
115843
115933
  const { chatroomId, agentConfig } = task;
115844
- if (!cooldown.canNudge(chatroomId, agentConfig.role, now))
115934
+ if (!cooldown.canAttempt(chatroomId, agentConfig.role, "nudge", now))
115845
115935
  return false;
115846
115936
  if (!agentConfig.workingDir)
115847
115937
  return false;
@@ -115851,12 +115941,12 @@ function listTasksReadyForNudge(tasks, now, cooldown, getSlot) {
115851
115941
  return tasks.filter((task) => {
115852
115942
  if (!isTaskReadyForNudge(task, now, cooldown, getSlot))
115853
115943
  return false;
115854
- cooldown.recordNudge(task.chatroomId, task.agentConfig.role, now);
115944
+ cooldown.recordAttempt(task.chatroomId, task.agentConfig.role, "nudge", now);
115855
115945
  return true;
115856
115946
  });
115857
115947
  }
115858
- var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000, NATIVE_NUDGE_ESCALATION_THRESHOLD = 2;
115859
- var init_task_monitor_logic = __esm(() => {
115948
+ var PENDING_IDLE_NUDGE_MS = 15000, NUDGE_COOLDOWN_MS = 60000;
115949
+ var init_task_delivery_logic = __esm(() => {
115860
115950
  init_assigned_task();
115861
115951
  init_check_agent_slot();
115862
115952
  init_predicates();
@@ -115865,7 +115955,7 @@ var init_task_monitor_logic = __esm(() => {
115865
115955
  init_native_task_injector_logic();
115866
115956
  });
115867
115957
 
115868
- // src/daemon/entry/task-monitor-runtime.ts
115958
+ // src/daemon/entry/native-delivery/task-delivery-processor.ts
115869
115959
  function resolveTaskWantResume(task) {
115870
115960
  return sessionAugmentationToWantResume(resolveSessionAugmentationForTask({ content: task.taskContent ?? "", startInNewSession: task.startInNewSession }, task.agentConfig.role));
115871
115961
  }
@@ -115955,6 +116045,24 @@ function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
115955
116045
  });
115956
116046
  }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native revive failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
115957
116047
  }
116048
+ function runNativeWakeEffect(task, runtime4, effectContext2, agentMgr) {
116049
+ const ctx = resolveTaskRunnerContextFromFull(task);
116050
+ if (!ctx)
116051
+ return;
116052
+ const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
116053
+ console.log(`[TaskMonitor] native wake ${role}@${chatroomId} — desiredState=stopped with pending task ${task.taskId}`);
116054
+ exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
116055
+ yield* agentMgr.ensureRunning({
116056
+ chatroomId,
116057
+ role,
116058
+ agentHarness: agentConfig.agentHarness,
116059
+ model: agentConfig.model,
116060
+ workingDir,
116061
+ reason: "platform.pending_task_wake",
116062
+ wantResume
116063
+ });
116064
+ }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native wake failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
116065
+ }
115958
116066
  async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
115959
116067
  const result = await sessionDeps.backend.query(api.machines.getAssignedTaskForAction, {
115960
116068
  sessionId: sessionDeps.sessionId,
@@ -115976,43 +116084,9 @@ async function clearStuckStoppingSlotIfNeeded(agentMgr, chatroomId, role) {
115976
116084
  }
115977
116085
  async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
115978
116086
  const getSlot = (chatroomId, role) => agentMgr.getSlot(chatroomId, role);
115979
- for (const row of listTasksReadyForNudge(tasks, now, cooldown, getSlot)) {
116087
+ const cliTasks = tasks.filter((task) => !isNativeHarness(task.agentConfig.agentHarness));
116088
+ for (const row of listTasksReadyForNudge(cliTasks, now, cooldown, getSlot)) {
115980
116089
  await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
115981
- if (isNativeHarness(row.agentConfig.agentHarness)) {
115982
- const { chatroomId, agentConfig } = row;
115983
- const { role } = agentConfig;
115984
- if (!isTeamAgentRole(role))
115985
- continue;
115986
- const deliveryState = getRoleDeliveryState();
115987
- const failures3 = deliveryState.recordNativeNudgeFailure(chatroomId, role);
115988
- if (shouldEscalateNativeNudgeToRestart(chatroomId, role, failures3)) {
115989
- const full2 = await fetchTaskForAction(sessionDeps, machineId, row);
115990
- if (!full2)
115991
- continue;
115992
- console.log(`[TaskMonitor] native nudge escalate restart ${role}@${chatroomId} — pending task ${row.taskId}`);
115993
- runCliNudgeEffect(full2, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
115994
- deliveryState.clearNativeNudgeFailures(chatroomId, role);
115995
- continue;
115996
- }
115997
- resetRoleDeliveryState(chatroomId, role);
115998
- await sessionDeps.backend.mutation(api.participants.join, {
115999
- sessionId: sessionDeps.sessionId,
116000
- chatroomId,
116001
- role,
116002
- action: NATIVE_WAITING_ACTION
116003
- });
116004
- console.log(`[TaskMonitor] native light nudge ${role}@${chatroomId} — redeliver pending task ${row.taskId}`);
116005
- logNativeDeliveryFallback("native-light-nudge", role, chatroomId, row.taskId);
116006
- getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
116007
- tasks: [row],
116008
- runtime: runtime4,
116009
- effectContext: effectContext2,
116010
- agentMgr,
116011
- sessionDeps,
116012
- machineId
116013
- });
116014
- continue;
116015
- }
116016
116090
  const full = await fetchTaskForAction(sessionDeps, machineId, row);
116017
116091
  if (!full)
116018
116092
  continue;
@@ -116030,7 +116104,19 @@ async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, ef
116030
116104
  runNativeReviveEffect(full, runtime4, effectContext2, agentMgr);
116031
116105
  }
116032
116106
  }
116033
- async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps, machineId, _pass) {
116107
+ async function wakeStoppedAgentsForPendingTasks(tasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
116108
+ for (const row of listNativePendingTasksNeedingWake(tasks, cooldown, now)) {
116109
+ if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
116110
+ continue;
116111
+ await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
116112
+ const full = await fetchTaskForAction(sessionDeps, machineId, row);
116113
+ if (!full)
116114
+ continue;
116115
+ runNativeWakeEffect(full, runtime4, effectContext2, agentMgr);
116116
+ }
116117
+ }
116118
+ async function processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, machineId, _pass, options) {
116119
+ const tasks = [...options.snapshots];
116034
116120
  const filteredTasks = filterSnapshotsExcludingRestartInFlight(tasks);
116035
116121
  if (filteredTasks.length === 0)
116036
116122
  return;
@@ -116039,10 +116125,11 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
116039
116125
  getSlot: (chatroomId, role) => agentMgr.getSlot(chatroomId, role),
116040
116126
  isPidAlive: (pid) => isProcessAlive((p) => process.kill(p, 0), pid)
116041
116127
  };
116128
+ await wakeStoppedAgentsForPendingTasks(filteredTasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
116042
116129
  await reviveNativeTasks(filteredTasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
116043
116130
  if (filteredTasks.length > 0) {
116044
116131
  const first = filteredTasks[0];
116045
- logNativeDeliveryFallback("signal-presence", first.agentConfig.role, first.chatroomId, first.taskId);
116132
+ logNativeDeliveryFallback(_pass, first.agentConfig.role, first.chatroomId, first.taskId);
116046
116133
  }
116047
116134
  getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
116048
116135
  tasks: filteredTasks,
@@ -116054,60 +116141,333 @@ async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, age
116054
116141
  });
116055
116142
  await nudgeStuckTasks(filteredTasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
116056
116143
  }
116057
- function listDeliverablePendingFromStore(agentMgr) {
116058
- if (!hasAssignedTaskSnapshot())
116059
- return [];
116060
- return listAssignedTaskSnapshots().filter((row) => {
116061
- if (row.status !== "pending")
116062
- return false;
116063
- const slot = agentMgr.getSlot(row.chatroomId, row.agentConfig.role);
116064
- return isAgentReadyForNativeDelivery(row, slot);
116144
+ var init_task_delivery_processor = __esm(() => {
116145
+ init_parse_session_augmentation();
116146
+ init_esm();
116147
+ init_native_task_delivery_coordinator();
116148
+ init_native_task_injector_logic();
116149
+ init_api3();
116150
+ init_convex_error();
116151
+ init_restart_orchestrator_in_flight();
116152
+ init_task_delivery_logic();
116153
+ });
116154
+
116155
+ // src/daemon/infrastructure/inbox/fetch-machine-assigned-task-snapshots.ts
116156
+ async function fetchMachineAssignedTaskSnapshots(sessionDeps, machineId) {
116157
+ const result = await sessionDeps.backend.query(api.machines.listMachineAssignedTaskSnapshots, {
116158
+ sessionId: sessionDeps.sessionId,
116159
+ machineId
116065
116160
  });
116161
+ return mapAssignedTaskSnapshotList(parseAssignedTaskSnapshotRows(result?.tasks ?? []));
116066
116162
  }
116067
- function runLocalStoreReconcilePass(params) {
116068
- const { stopped, monitorPassInFlight, agentMgr, runtime: runtime4, effectContext: effectContext2, sessionDeps, machineId } = params;
116069
- if (stopped || monitorPassInFlight)
116070
- return;
116071
- const deliverable = filterSnapshotsExcludingRestartInFlight(listDeliverablePendingFromStore(agentMgr));
116072
- if (deliverable.length === 0)
116163
+ var init_fetch_machine_assigned_task_snapshots = __esm(() => {
116164
+ init_assigned_task_snapshot_contract();
116165
+ init_api3();
116166
+ });
116167
+
116168
+ // src/daemon/infrastructure/inbox/store/schema.ts
116169
+ var SCHEMA_VERSION = 1, MIGRATIONS;
116170
+ var init_schema = __esm(() => {
116171
+ MIGRATIONS = [
116172
+ `CREATE TABLE IF NOT EXISTS schema_meta (
116173
+ key TEXT PRIMARY KEY,
116174
+ value TEXT NOT NULL
116175
+ )`,
116176
+ `CREATE TABLE IF NOT EXISTS inbox_state (
116177
+ inbox_type TEXT NOT NULL,
116178
+ scope_key TEXT NOT NULL,
116179
+ state_json TEXT NOT NULL,
116180
+ created_at INTEGER NOT NULL,
116181
+ updated_at INTEGER NOT NULL,
116182
+ PRIMARY KEY (inbox_type, scope_key)
116183
+ )`,
116184
+ `CREATE INDEX IF NOT EXISTS idx_inbox_state_type_updated
116185
+ ON inbox_state(inbox_type, updated_at DESC)`,
116186
+ `CREATE INDEX IF NOT EXISTS idx_inbox_state_updated
116187
+ ON inbox_state(updated_at DESC)`
116188
+ ];
116189
+ });
116190
+
116191
+ // src/daemon/infrastructure/inbox/store/open-database.ts
116192
+ import { mkdirSync as mkdirSync8 } from "node:fs";
116193
+ import { dirname as dirname15 } from "node:path";
116194
+ import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
116195
+ function openDatabase(dbPath) {
116196
+ mkdirSync8(dirname15(dbPath), { recursive: true });
116197
+ const db = new DatabaseSync3(dbPath);
116198
+ for (const sql of MIGRATIONS) {
116199
+ db.exec(sql);
116200
+ }
116201
+ db.prepare(`INSERT INTO schema_meta(key, value) VALUES('version', ?)
116202
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(SCHEMA_VERSION));
116203
+ return db;
116204
+ }
116205
+ var init_open_database = __esm(() => {
116206
+ init_schema();
116207
+ });
116208
+
116209
+ // src/daemon/infrastructure/inbox/store/state-store.ts
116210
+ function assertKeyPart(value, name) {
116211
+ if (value.trim().length === 0) {
116212
+ throw new Error(`${name} cannot be empty`);
116213
+ }
116214
+ }
116215
+ function encodeState(state) {
116216
+ const encoded = JSON.stringify(state);
116217
+ if (encoded === undefined) {
116218
+ throw new Error("Inbox state must be JSON serializable");
116219
+ }
116220
+ return encoded;
116221
+ }
116222
+ function decodeRow(row) {
116223
+ return {
116224
+ inboxType: row.inbox_type,
116225
+ scopeKey: row.scope_key,
116226
+ state: JSON.parse(row.state_json),
116227
+ createdAt: row.created_at,
116228
+ updatedAt: row.updated_at
116229
+ };
116230
+ }
116231
+ function buildQuery(options) {
116232
+ const clauses = [];
116233
+ const params = [];
116234
+ if (options.inboxType !== undefined) {
116235
+ clauses.push("inbox_type = ?");
116236
+ params.push(options.inboxType);
116237
+ }
116238
+ if (options.scopeKey !== undefined) {
116239
+ clauses.push("scope_key = ?");
116240
+ params.push(options.scopeKey);
116241
+ }
116242
+ if (options.scopePrefix !== undefined) {
116243
+ clauses.push("scope_key LIKE ?");
116244
+ params.push(`${options.scopePrefix}%`);
116245
+ }
116246
+ if (options.updatedAfter !== undefined) {
116247
+ clauses.push("updated_at > ?");
116248
+ params.push(options.updatedAfter);
116249
+ }
116250
+ const where = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
116251
+ const limit = Math.min(Math.max(options.limit ?? MAX_QUERY_LIMIT, 1), MAX_QUERY_LIMIT);
116252
+ return {
116253
+ sql: `SELECT inbox_type, scope_key, state_json, created_at, updated_at
116254
+ FROM inbox_state ${where}
116255
+ ORDER BY updated_at DESC, inbox_type ASC, scope_key ASC
116256
+ LIMIT ?`,
116257
+ params: [...params, limit]
116258
+ };
116259
+ }
116260
+ function getInboxState(db, key) {
116261
+ assertKeyPart(key.inboxType, "inboxType");
116262
+ assertKeyPart(key.scopeKey, "scopeKey");
116263
+ const row = db.prepare(`SELECT inbox_type, scope_key, state_json, created_at, updated_at
116264
+ FROM inbox_state
116265
+ WHERE inbox_type = ? AND scope_key = ?`).get(key.inboxType, key.scopeKey);
116266
+ return row ? decodeRow(row) : null;
116267
+ }
116268
+ function saveInboxState(db, key, state, updatedAt = Date.now()) {
116269
+ assertKeyPart(key.inboxType, "inboxType");
116270
+ assertKeyPart(key.scopeKey, "scopeKey");
116271
+ const stateJson = encodeState(state);
116272
+ db.prepare(`INSERT INTO inbox_state(inbox_type, scope_key, state_json, created_at, updated_at)
116273
+ VALUES(?, ?, ?, ?, ?)
116274
+ ON CONFLICT(inbox_type, scope_key) DO UPDATE SET
116275
+ state_json = excluded.state_json,
116276
+ updated_at = excluded.updated_at`).run(key.inboxType, key.scopeKey, stateJson, updatedAt, updatedAt);
116277
+ }
116278
+ function queryInboxState(db, options = {}) {
116279
+ const { sql, params } = buildQuery(options);
116280
+ return db.prepare(sql).all(...params).map((row) => decodeRow(row));
116281
+ }
116282
+ function deleteInboxState(db, key) {
116283
+ assertKeyPart(key.inboxType, "inboxType");
116284
+ assertKeyPart(key.scopeKey, "scopeKey");
116285
+ db.prepare("DELETE FROM inbox_state WHERE inbox_type = ? AND scope_key = ?").run(key.inboxType, key.scopeKey);
116286
+ }
116287
+ var MAX_QUERY_LIMIT = 1000;
116288
+
116289
+ // src/daemon/infrastructure/inbox/store/inbox-state-store.ts
116290
+ function createInboxStateStore(dbPath) {
116291
+ const db = openDatabase(dbPath);
116292
+ return {
116293
+ get: (key) => getInboxState(db, key),
116294
+ save: (key, state, updatedAt) => saveInboxState(db, key, state, updatedAt),
116295
+ query: (options) => queryInboxState(db, options),
116296
+ delete: (key) => deleteInboxState(db, key),
116297
+ close: () => db.close()
116298
+ };
116299
+ }
116300
+ var init_inbox_state_store = __esm(() => {
116301
+ init_open_database();
116302
+ });
116303
+
116304
+ // src/daemon/infrastructure/inbox/store/inbox-db-path.ts
116305
+ import { homedir as homedir10 } from "node:os";
116306
+ import { join as join26 } from "node:path";
116307
+ function resolveInboxDbPath(machineId) {
116308
+ return join26(homedir10(), ".chatroom", "daemon", machineId, "inboxes.sqlite");
116309
+ }
116310
+ var init_inbox_db_path = () => {};
116311
+
116312
+ // src/daemon/infrastructure/inbox/index.ts
116313
+ var init_inbox = __esm(() => {
116314
+ init_inbox_state_store();
116315
+ init_inbox_db_path();
116316
+ });
116317
+
116318
+ // src/daemon/infrastructure/inbox/task-inbox-delivery.ts
116319
+ async function handleTaskInboxUpdate(update6, deps) {
116320
+ const taskSnapshotState = deps.taskSnapshotState ?? getNativeDeliverySession()?.taskSnapshotState;
116321
+ taskSnapshotState?.applySignalPage(update6.signals, update6.snapshots);
116322
+ if (update6.snapshots.length === 0)
116073
116323
  return;
116074
- const first = deliverable[0];
116075
- logNativeDeliveryFallback("periodic-reconcile", first.agentConfig.role, first.chatroomId, first.taskId);
116076
- getNativeTaskDeliveryCoordinator().reconcileAssignedTasks({
116077
- tasks: deliverable,
116078
- runtime: runtime4,
116079
- effectContext: effectContext2,
116080
- agentMgr,
116081
- sessionDeps,
116082
- machineId
116083
- });
116324
+ await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "inbox-signal", { snapshots: update6.snapshots });
116325
+ }
116326
+ var init_task_inbox_delivery = __esm(() => {
116327
+ init_native_delivery_session_registry();
116328
+ init_task_delivery_processor();
116329
+ });
116330
+
116331
+ // src/daemon/infrastructure/inbox/task.ts
116332
+ function taskSignalCursorAt(timestamp) {
116333
+ return `${String(Math.max(0, Math.floor(timestamp))).padStart(16, "0")}:`;
116084
116334
  }
116085
- function subscribeAssignedTaskSnapshotStore(wsClient2, args2, isStopped) {
116086
- return wsClient2.onUpdate(api.machines.listMachineAssignedTaskSnapshots, args2, (result) => {
116087
- if (isStopped())
116335
+ function abortError() {
116336
+ const error51 = new Error("Task inbox stopped");
116337
+ error51.name = "AbortError";
116338
+ return error51;
116339
+ }
116340
+ function throwIfAborted(signal) {
116341
+ if (signal?.aborted)
116342
+ throw abortError();
116343
+ }
116344
+ function waitForTaskSignalPage(options, afterSignalKey) {
116345
+ return new Promise((resolve8, reject) => {
116346
+ let unsubscribe;
116347
+ let settled = false;
116348
+ const cleanup = () => {
116349
+ unsubscribe?.();
116350
+ unsubscribe = undefined;
116351
+ options.signal?.removeEventListener("abort", onAbort);
116352
+ };
116353
+ const settle2 = (fn2) => {
116354
+ if (settled)
116355
+ return;
116356
+ settled = true;
116357
+ cleanup();
116358
+ fn2();
116359
+ };
116360
+ const onAbort = () => {
116361
+ settle2(() => reject(abortError()));
116362
+ };
116363
+ options.signal?.addEventListener("abort", onAbort, { once: true });
116364
+ try {
116365
+ throwIfAborted(options.signal);
116366
+ } catch (error51) {
116367
+ settle2(() => reject(error51));
116088
116368
  return;
116089
- const tasks = mapAssignedTaskSnapshotList(parseAssignedTaskMonitorRows(result?.tasks ?? []));
116090
- replaceAssignedTaskSnapshots(tasks);
116091
- }, (err) => {
116092
- console.warn(`[${formatTimestamp()}] ⚠️ Assigned-task snapshot subscription error: ${getErrorMessage(err)}`);
116369
+ }
116370
+ unsubscribe = options.client.onUpdate(api.messageList.subscribeTaskStatusSignalsSince, {
116371
+ sessionId: options.sessionId,
116372
+ machineId: options.machineId,
116373
+ afterKey: afterSignalKey,
116374
+ limit: options.signalPageLimit ?? DEFAULT_SIGNAL_PAGE_LIMIT
116375
+ }, (result) => {
116376
+ if (!result || typeof result !== "object")
116377
+ return;
116378
+ const page = result;
116379
+ const items = page.items;
116380
+ const highKey = page.highKey;
116381
+ if (!items?.length || !highKey)
116382
+ return;
116383
+ settle2(() => resolve8({
116384
+ items,
116385
+ afterSignalKey,
116386
+ highSignalKey: highKey
116387
+ }));
116388
+ }, (error51) => {
116389
+ settle2(() => reject(error51));
116390
+ });
116093
116391
  });
116094
116392
  }
116095
- function handleInboundAssignedTaskEvent(event, runMonitorPass) {
116096
- const row = listAssignedTaskSnapshots().find((snapshot) => snapshot.taskId === event.taskId && snapshot.agentConfig.role === event.role);
116097
- if (!row)
116393
+ async function* createTaskSignalIterator(options) {
116394
+ let afterSignalKey = options.initialAfterSignalKey ?? taskSignalCursorAt(options.serviceStartedAt ?? Date.now());
116395
+ while (!options.signal?.aborted) {
116396
+ const page = await waitForTaskSignalPage(options, afterSignalKey);
116397
+ yield page;
116398
+ afterSignalKey = page.highSignalKey;
116399
+ }
116400
+ }
116401
+ async function fetchSnapshotsForSignalPage(options, page) {
116402
+ const snapshots = [];
116403
+ let afterSignalKey = page.afterSignalKey;
116404
+ while (true) {
116405
+ throwIfAborted(options.signal);
116406
+ const result = await options.client.query(api.tasks.listTasksForMachineSignalRange, {
116407
+ sessionId: options.sessionId,
116408
+ machineId: options.machineId,
116409
+ afterSignalKey,
116410
+ throughSignalKey: page.highSignalKey,
116411
+ limit: options.taskPageLimit ?? DEFAULT_TASK_PAGE_LIMIT
116412
+ });
116413
+ snapshots.push(...result.snapshots);
116414
+ if (!result.hasMore || !result.nextSignalKey)
116415
+ break;
116416
+ afterSignalKey = result.nextSignalKey;
116417
+ }
116418
+ return snapshots;
116419
+ }
116420
+ async function runTaskInbox(options, onUpdate) {
116421
+ for await (const page of createTaskSignalIterator(options)) {
116422
+ const snapshots = await fetchSnapshotsForSignalPage(options, page);
116423
+ await onUpdate({
116424
+ signals: page.items,
116425
+ snapshots,
116426
+ afterSignalKey: page.afterSignalKey,
116427
+ throughSignalKey: page.highSignalKey
116428
+ });
116429
+ }
116430
+ }
116431
+ var DEFAULT_SIGNAL_PAGE_LIMIT = 100, DEFAULT_TASK_PAGE_LIMIT = 500;
116432
+ var init_task = __esm(() => {
116433
+ init_api3();
116434
+ });
116435
+
116436
+ // src/daemon/entry/task-inbox-runtime.ts
116437
+ async function bootstrapMachineAssignedTaskSnapshots(deps) {
116438
+ await deps.sessionDeps.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
116439
+ sessionId: deps.sessionDeps.sessionId,
116440
+ machineId: deps.machineId
116441
+ });
116442
+ const tasks = await fetchMachineAssignedTaskSnapshots(deps.sessionDeps, deps.machineId);
116443
+ deps.taskSnapshotState?.replace(tasks);
116444
+ if (!tasks.length)
116098
116445
  return;
116099
- const pass = event.type === "assigned-task.signal" ? "signal" : "presence";
116100
- runMonitorPass([row], pass);
116446
+ await processTasksUpdate(deps.runtime, deps.effectContext, deps.cooldown, deps.agentMgr, deps.sessionDeps, deps.machineId, "bootstrap", { snapshots: tasks });
116101
116447
  }
116102
- var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
116448
+ function isAbortError(error51) {
116449
+ return error51 instanceof Error && error51.name === "AbortError";
116450
+ }
116451
+ async function runInboxLoopWithRestart(options, onUpdate, isStopped) {
116452
+ let backoffMs = INBOX_RESTART_INITIAL_MS;
116453
+ while (!isStopped()) {
116454
+ try {
116455
+ await runTaskInbox(options, onUpdate);
116456
+ return;
116457
+ } catch (error51) {
116458
+ if (isStopped() || isAbortError(error51))
116459
+ return;
116460
+ console.warn(`[TaskInbox] loop error, restarting in ${backoffMs}ms:`, error51);
116461
+ await new Promise((resolve8) => setTimeout(resolve8, backoffMs));
116462
+ backoffMs = Math.min(backoffMs * 2, INBOX_RESTART_MAX_MS);
116463
+ }
116464
+ }
116465
+ }
116466
+ var NATIVE_DELIVERY_RECONCILE_MS = 1e4, INBOX_RESTART_INITIAL_MS = 1000, INBOX_RESTART_MAX_MS = 30000, startTaskInboxEffect = (wsClient2) => exports_Effect.gen(function* () {
116103
116467
  const session2 = yield* DaemonSessionService;
116104
116468
  const agentMgr = yield* DaemonAgentProcessManagerService;
116105
116469
  const effectContext2 = yield* exports_Effect.context();
116106
116470
  const runtime4 = yield* exports_Effect.runtime();
116107
- console.log(`[${formatTimestamp()}] \uD83D\uDCCB Starting task-monitor (incremental subscribe)`);
116108
- const cooldown = new NudgeCooldown;
116109
- let stopped = false;
116110
- let monitorPassInFlight = false;
116111
116471
  const sessionDeps = {
116112
116472
  sessionId: session2.sessionId,
116113
116473
  convexUrl: session2.convexUrl,
@@ -116118,68 +116478,95 @@ var startTaskMonitorEffect = (wsClient2) => exports_Effect.gen(function* () {
116118
116478
  query: (fn2, args2) => session2.backend.query(fn2, args2)
116119
116479
  }
116120
116480
  };
116481
+ console.log(`[${formatTimestamp()}] \uD83D\uDCEC Starting task-inbox (machine-scoped signals)`);
116482
+ const inboxStore = createInboxStateStore(resolveInboxDbPath(session2.machineId));
116483
+ const persisted = inboxStore.get({
116484
+ inboxType: "task",
116485
+ scopeKey: session2.machineId
116486
+ });
116487
+ const abort = new AbortController;
116488
+ let stopped = false;
116489
+ const taskSnapshotState = new MachineTaskSnapshotState;
116121
116490
  registerNativeDeliverySession({
116122
116491
  runtime: runtime4,
116123
116492
  effectContext: effectContext2,
116124
116493
  agentMgr,
116125
116494
  sessionDeps,
116126
- machineId: session2.machineId
116495
+ machineId: session2.machineId,
116496
+ taskSnapshotState
116127
116497
  });
116128
- const unsubscribeSnapshotStore = subscribeAssignedTaskSnapshotStore(wsClient2, { sessionId: session2.sessionId, machineId: session2.machineId }, () => stopped);
116129
- const runMonitorPass = (tasks, pass) => {
116130
- if (stopped || monitorPassInFlight || tasks.length === 0)
116131
- return;
116132
- monitorPassInFlight = true;
116133
- processTasksUpdate(tasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, pass).finally(() => {
116134
- monitorPassInFlight = false;
116135
- });
116498
+ const cooldown = new RecoveryCooldown;
116499
+ let inboxUpdateInFlight = false;
116500
+ let reconcileInFlight = false;
116501
+ const inboxOptions = {
116502
+ client: wsClient2,
116503
+ sessionId: session2.sessionId,
116504
+ machineId: session2.machineId,
116505
+ serviceStartedAt: Date.now(),
116506
+ initialAfterSignalKey: persisted?.state.afterSignalKey,
116507
+ signal: abort.signal
116136
116508
  };
116137
- registerAssignedTaskMonitorHandler(async (event) => {
116138
- handleInboundAssignedTaskEvent(event, runMonitorPass);
116139
- });
116509
+ const inboxHandler = async (update6) => {
116510
+ inboxUpdateInFlight = true;
116511
+ try {
116512
+ await handleTaskInboxUpdate(update6, {
116513
+ runtime: runtime4,
116514
+ effectContext: effectContext2,
116515
+ cooldown,
116516
+ agentMgr,
116517
+ sessionDeps,
116518
+ machineId: session2.machineId,
116519
+ taskSnapshotState
116520
+ });
116521
+ inboxStore.save({ inboxType: "task", scopeKey: session2.machineId }, { afterSignalKey: update6.throughSignalKey });
116522
+ } finally {
116523
+ inboxUpdateInFlight = false;
116524
+ }
116525
+ };
116526
+ yield* exports_Effect.tryPromise(() => bootstrapMachineAssignedTaskSnapshots({
116527
+ sessionDeps,
116528
+ runtime: runtime4,
116529
+ effectContext: effectContext2,
116530
+ cooldown,
116531
+ agentMgr,
116532
+ machineId: session2.machineId,
116533
+ taskSnapshotState
116534
+ })).pipe(exports_Effect.catchAll((error51) => {
116535
+ console.warn("[TaskInbox] bootstrap failed:", error51);
116536
+ return exports_Effect.void;
116537
+ }));
116140
116538
  const reconcileTimer = setInterval(() => {
116141
- runLocalStoreReconcilePass({
116142
- stopped,
116143
- monitorPassInFlight,
116144
- agentMgr,
116145
- runtime: runtime4,
116146
- effectContext: effectContext2,
116147
- sessionDeps,
116148
- machineId: session2.machineId
116539
+ if (stopped || inboxUpdateInFlight || reconcileInFlight)
116540
+ return;
116541
+ reconcileInFlight = true;
116542
+ processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr, sessionDeps, session2.machineId, "periodic-reconcile", { snapshots: taskSnapshotState.listAll() }).catch((error51) => {
116543
+ console.warn("[TaskInbox] local delivery reconciliation failed:", error51);
116544
+ }).finally(() => {
116545
+ reconcileInFlight = false;
116149
116546
  });
116150
116547
  }, NATIVE_DELIVERY_RECONCILE_MS);
116151
- yield* exports_Effect.tryPromise(() => session2.backend.mutation(api.machines.syncMachineAssignedTaskSnapshotsMutation, {
116152
- sessionId: session2.sessionId,
116153
- machineId: session2.machineId
116154
- })).pipe(exports_Effect.catchAll(() => exports_Effect.void));
116548
+ runInboxLoopWithRestart(inboxOptions, inboxHandler, () => stopped);
116155
116549
  return {
116156
116550
  stop() {
116157
116551
  stopped = true;
116158
- unregisterAssignedTaskMonitorHandler();
116159
- unsubscribeSnapshotStore();
116160
- clearAssignedTaskSnapshots();
116161
- unregisterNativeDeliverySession();
116552
+ abort.abort();
116162
116553
  clearInterval(reconcileTimer);
116163
- console.log(`[${formatTimestamp()}] \uD83D\uDCCB Task-monitor stopped`);
116554
+ unregisterNativeDeliverySession();
116555
+ inboxStore.close();
116164
116556
  }
116165
116557
  };
116166
116558
  });
116167
- var init_task_monitor_runtime = __esm(() => {
116168
- init_reliability();
116169
- init_participant();
116170
- init_parse_session_augmentation();
116171
- init_assigned_task_monitor_contract();
116559
+ var init_task_inbox_runtime = __esm(() => {
116172
116560
  init_esm();
116173
116561
  init_daemon_services();
116174
- init_native_ready_invariant();
116175
- init_native_task_delivery_coordinator();
116176
- init_native_task_injector_logic();
116177
- init_restart_orchestrator_in_flight();
116178
- init_task_monitor_logic();
116179
116562
  init_api3();
116180
- init_assigned_task_snapshot_store();
116181
- init_convex_error();
116182
- init_execution_kind();
116563
+ init_native_delivery_session_registry();
116564
+ init_task_delivery_processor();
116565
+ init_task_delivery_logic();
116566
+ init_fetch_machine_assigned_task_snapshots();
116567
+ init_inbox();
116568
+ init_task_inbox_delivery();
116569
+ init_task();
116183
116570
  });
116184
116571
 
116185
116572
  // src/daemon/entry/workspace-git/git-subscription.ts
@@ -116529,16 +116916,16 @@ var init_workspace_list_subscription = __esm(() => {
116529
116916
 
116530
116917
  // src/daemon/entry/workspace-git-inbound-registry.ts
116531
116918
  function registerWorkspaceGitInboundHandler(h) {
116532
- handler7 = h;
116919
+ handler6 = h;
116533
116920
  }
116534
116921
  function unregisterWorkspaceGitInboundHandler() {
116535
- handler7 = undefined;
116922
+ handler6 = undefined;
116536
116923
  }
116537
116924
  async function dispatchWorkspaceGitInboundEvent(event) {
116538
- if (handler7)
116539
- await handler7(event);
116925
+ if (handler6)
116926
+ await handler6(event);
116540
116927
  }
116541
- var handler7;
116928
+ var handler6;
116542
116929
 
116543
116930
  // src/events/lifecycle/on-daemon-shutdown.ts
116544
116931
  var onDaemonShutdownEffect;
@@ -116579,7 +116966,7 @@ function createDaemonRuntime(deps) {
116579
116966
  let directHarnessWorkerHandle = null;
116580
116967
  let agenticQueryWorkerHandle = null;
116581
116968
  let enhancerWorkerHandle = null;
116582
- let taskMonitorHandle = null;
116969
+ let taskInboxHandle = null;
116583
116970
  const activeSessions = new Map;
116584
116971
  const harnesses = new Map;
116585
116972
  let signalCount = 0;
@@ -116614,7 +117001,7 @@ function createDaemonRuntime(deps) {
116614
117001
  gitSubscriptionHandle?.stop();
116615
117002
  fileTreeSubscriptionHandle?.stop();
116616
117003
  workspaceListSubscriptionHandle?.stop();
116617
- taskMonitorHandle?.stop();
117004
+ taskInboxHandle?.stop();
116618
117005
  logObserverSubscriptionHandle?.stop();
116619
117006
  directHarnessWorkerHandle?.stop();
116620
117007
  agenticQueryWorkerHandle?.stop();
@@ -116720,7 +117107,7 @@ function createDaemonRuntime(deps) {
116720
117107
  break;
116721
117108
  }
116722
117109
  });
116723
- taskMonitorHandle = yield* startTaskMonitorEffect(deps.wsClient);
117110
+ taskInboxHandle = yield* startTaskInboxEffect(deps.wsClient);
116724
117111
  logObserverSubscriptionHandle = startLogObserverSubscription({ sessionId: session2.sessionId, machineId: session2.machineId }, deps.wsClient);
116725
117112
  const commandRunRuntime = yield* exports_Effect.runtime();
116726
117113
  if (featureFlags.directHarnessWorkers) {
@@ -116780,7 +117167,7 @@ var init_daemon_runtime = __esm(() => {
116780
117167
  init_command_run_subscription();
116781
117168
  init_log_observer_sync();
116782
117169
  init_init_daemon();
116783
- init_task_monitor_runtime();
117170
+ init_task_inbox_runtime();
116784
117171
  init_git_heartbeat();
116785
117172
  init_git_subscription();
116786
117173
  init_api3();
@@ -116808,24 +117195,6 @@ var init_agentic_query_bridge = __esm(() => {
116808
117195
  init_process_agentic_query_prompt();
116809
117196
  });
116810
117197
 
116811
- // src/daemon/domain/usecase/deliver-assigned-task.ts
116812
- async function deliverAssignedTaskInbound(deps, event) {
116813
- await deps.dispatchInbound(event);
116814
- }
116815
-
116816
- // src/daemon/entry/bridge/assigned-task-bridge.ts
116817
- function createDeliverAssignedTaskDeps() {
116818
- return { dispatchInbound: dispatchAssignedTaskMonitorEvent };
116819
- }
116820
- function createAssignedTaskRouterDeps() {
116821
- return {
116822
- deliverInbound: async (event) => {
116823
- await deliverAssignedTaskInbound(createDeliverAssignedTaskDeps(), event);
116824
- }
116825
- };
116826
- }
116827
- var init_assigned_task_bridge = () => {};
116828
-
116829
117198
  // src/daemon/domain/usecase/handle-command-event.ts
116830
117199
  async function handleCommandEvent(deps, event) {
116831
117200
  await deps.dispatchInbound(event);
@@ -116943,7 +117312,6 @@ var init_workspace_git_bridge = () => {};
116943
117312
  // src/daemon/entry/default-router-deps.ts
116944
117313
  function createDefaultEventRouterDeps() {
116945
117314
  return {
116946
- assignedTask: createAssignedTaskRouterDeps(),
116947
117315
  directHarness: createDirectHarnessRouterDeps(),
116948
117316
  command: createCommandRouterDeps(),
116949
117317
  workspaceGit: createWorkspaceGitRouterDeps(),
@@ -116954,7 +117322,6 @@ function createDefaultEventRouterDeps() {
116954
117322
  }
116955
117323
  var init_default_router_deps = __esm(() => {
116956
117324
  init_agentic_query_bridge();
116957
- init_assigned_task_bridge();
116958
117325
  init_command_bridge();
116959
117326
  init_direct_harness_bridge();
116960
117327
  init_enhancer_bridge();
@@ -117335,10 +117702,10 @@ var init_deps = __esm(() => {
117335
117702
  });
117336
117703
 
117337
117704
  // src/daemon/entry/persistence-path.ts
117338
- import { homedir as homedir10 } from "node:os";
117339
- import { join as join26 } from "node:path";
117705
+ import { homedir as homedir11 } from "node:os";
117706
+ import { join as join27 } from "node:path";
117340
117707
  function resolvePersistenceDbPath(machineId) {
117341
- return join26(homedir10(), ".chatroom", "daemon", machineId, "events.sqlite");
117708
+ return join27(homedir11(), ".chatroom", "daemon", machineId, "events.sqlite");
117342
117709
  }
117343
117710
  var init_persistence_path = () => {};
117344
117711
 
@@ -117349,13 +117716,6 @@ async function handleAgenticQueryInbound(deps, event) {
117349
117716
  }
117350
117717
  }
117351
117718
 
117352
- // src/daemon/domain/usecase/handle-assigned-task-inbound.ts
117353
- async function handleAssignedTaskInbound(deps, event) {
117354
- if (deps.deliverInbound) {
117355
- await deps.deliverInbound(event);
117356
- }
117357
- }
117358
-
117359
117719
  // src/daemon/domain/usecase/handle-command-inbound.ts
117360
117720
  async function handleCommandInbound(deps, event) {
117361
117721
  if (deps.deliverInbound) {
@@ -117394,10 +117754,6 @@ async function handleWorkspaceGitInbound(deps, event) {
117394
117754
  // src/daemon/entry/event-router.ts
117395
117755
  async function routeInboundEvent(deps, event) {
117396
117756
  switch (event.type) {
117397
- case "assigned-task.signal":
117398
- case "assigned-task.presence":
117399
- await handleAssignedTaskInbound(deps.assignedTask, event);
117400
- break;
117401
117757
  case "direct-harness.session-opened":
117402
117758
  case "direct-harness.prompt":
117403
117759
  case "direct-harness.command":
@@ -117496,403 +117852,6 @@ var init_agentic_query_session = __esm(() => {
117496
117852
  init_api3();
117497
117853
  });
117498
117854
 
117499
- // src/infrastructure/incremental-sync/layers.ts
117500
- var IntervalClock, IntervalClockLive;
117501
- var init_layers = __esm(() => {
117502
- init_esm();
117503
- IntervalClock = class IntervalClock extends exports_Context.Tag("IntervalClock")() {
117504
- };
117505
- IntervalClockLive = exports_Layer.succeed(IntervalClock, {
117506
- sleep: (ms) => exports_Effect.promise(() => new Promise((resolve8) => setTimeout(resolve8, ms)))
117507
- });
117508
- });
117509
-
117510
- // src/infrastructure/incremental-sync/message-buffer.ts
117511
- class MessageBuffer {
117512
- keyOf;
117513
- queue = [];
117514
- inBuffer = new Set;
117515
- inFlight = new Map;
117516
- recentlyAcked = new Map;
117517
- dedupe;
117518
- dedupeTtlMs;
117519
- maxSize;
117520
- constructor(config4, keyOf) {
117521
- this.keyOf = keyOf;
117522
- this.dedupe = config4.dedupe ?? true;
117523
- this.dedupeTtlMs = config4.dedupeTtlMs ?? 0;
117524
- this.maxSize = config4.maxSize;
117525
- }
117526
- enqueue(items) {
117527
- this.pruneRecentlyAcked();
117528
- let enqueued = 0;
117529
- for (const item of items) {
117530
- const key = this.keyOf(item);
117531
- if (this.dedupe && this.shouldSkip(key)) {
117532
- continue;
117533
- }
117534
- this.queue.push({ key, item });
117535
- this.inBuffer.add(key);
117536
- enqueued++;
117537
- }
117538
- if (enqueued > 0) {
117539
- this.queue.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
117540
- }
117541
- this.enforceMaxSize();
117542
- return enqueued;
117543
- }
117544
- dequeue() {
117545
- this.pruneRecentlyAcked();
117546
- const next4 = this.queue.shift();
117547
- if (!next4)
117548
- return;
117549
- this.inBuffer.delete(next4.key);
117550
- this.inFlight.set(next4.key, next4.item);
117551
- return next4.item;
117552
- }
117553
- ack(key) {
117554
- this.inFlight.delete(key);
117555
- if (this.dedupe) {
117556
- this.recentlyAcked.set(key, Date.now());
117557
- }
117558
- }
117559
- nack(key, requeue = false) {
117560
- const item = this.inFlight.get(key);
117561
- this.inFlight.delete(key);
117562
- if (requeue && item !== undefined) {
117563
- this.enqueue([item]);
117564
- }
117565
- }
117566
- size() {
117567
- return this.queue.length;
117568
- }
117569
- highKeyOf(items) {
117570
- if (items.length === 0)
117571
- return null;
117572
- let high = null;
117573
- for (const item of items) {
117574
- const key = this.keyOf(item);
117575
- if (high === null || key > high) {
117576
- high = key;
117577
- }
117578
- }
117579
- return high;
117580
- }
117581
- shouldSkip(key) {
117582
- if (this.inBuffer.has(key) || this.inFlight.has(key)) {
117583
- return true;
117584
- }
117585
- if (this.dedupeTtlMs > 0) {
117586
- const ackedAt = this.recentlyAcked.get(key);
117587
- if (ackedAt !== undefined && Date.now() - ackedAt < this.dedupeTtlMs) {
117588
- return true;
117589
- }
117590
- } else if (this.recentlyAcked.has(key)) {
117591
- return true;
117592
- }
117593
- return false;
117594
- }
117595
- pruneRecentlyAcked() {
117596
- if (this.dedupeTtlMs <= 0)
117597
- return;
117598
- const now = Date.now();
117599
- for (const [key, ackedAt] of this.recentlyAcked) {
117600
- if (now - ackedAt >= this.dedupeTtlMs) {
117601
- this.recentlyAcked.delete(key);
117602
- }
117603
- }
117604
- }
117605
- enforceMaxSize() {
117606
- while (this.queue.length > this.maxSize) {
117607
- const dropped = this.queue.shift();
117608
- if (dropped) {
117609
- this.inBuffer.delete(dropped.key);
117610
- console.warn(`[incremental-sync] Buffer full — dropped oldest unacked item (key=${dropped.key})`);
117611
- }
117612
- }
117613
- }
117614
- }
117615
- // src/infrastructure/incremental-sync/resolve-high-key.ts
117616
- function resolveHighKey(def, buffer, page) {
117617
- if (page.highKey !== null)
117618
- return page.highKey;
117619
- const fromItems = buffer.highKeyOf(page.items);
117620
- if (fromItems !== null)
117621
- return fromItems;
117622
- if (def.itemToKey && page.items.length > 0) {
117623
- let high = null;
117624
- for (const item of page.items) {
117625
- const key = def.itemToKey(item);
117626
- if (high === null || key > high)
117627
- high = key;
117628
- }
117629
- return high;
117630
- }
117631
- return null;
117632
- }
117633
-
117634
- // src/infrastructure/incremental-sync/subscribe-loop.ts
117635
- function parseFeedItems(def, items, onError3) {
117636
- if (!def.parseItem) {
117637
- return items;
117638
- }
117639
- const parsed = [];
117640
- for (const raw of items) {
117641
- try {
117642
- parsed.push(def.parseItem(raw));
117643
- } catch (err) {
117644
- onError3?.(err);
117645
- }
117646
- }
117647
- return parsed;
117648
- }
117649
- function startSubscribeLoop(opts) {
117650
- let afterKey = opts.initialAfterKey ?? null;
117651
- let stopped = false;
117652
- let unsubscribe;
117653
- let drainInFlight = false;
117654
- const subscribe = () => {
117655
- if (stopped)
117656
- return;
117657
- unsubscribe?.();
117658
- unsubscribe = opts.wsClient.onUpdate(opts.target.query, opts.target.buildArgs(opts.args, afterKey, opts.config.limit), (result) => {
117659
- if (stopped)
117660
- return;
117661
- const page = opts.target.parsePage(result);
117662
- drainPages(page);
117663
- }, (err) => {
117664
- opts.onError?.(err);
117665
- });
117666
- };
117667
- const fetchPage = async (cursor) => {
117668
- const result = await opts.wsClient.query(opts.target.query, opts.target.buildArgs(opts.args, cursor, opts.config.limit));
117669
- return opts.target.parsePage(result);
117670
- };
117671
- const drainPages = async (initialPage) => {
117672
- if (stopped || drainInFlight)
117673
- return;
117674
- drainInFlight = true;
117675
- try {
117676
- const cursorAtStart = afterKey;
117677
- let page = initialPage;
117678
- while (!stopped && page.items.length > 0) {
117679
- const items = parseFeedItems(opts.def, page.items, opts.onError);
117680
- if (items.length > 0) {
117681
- opts.buffer.enqueue(items);
117682
- }
117683
- const nextKey = resolveHighKey(opts.def, opts.buffer, page);
117684
- if (nextKey === null) {
117685
- break;
117686
- }
117687
- afterKey = nextKey;
117688
- if (!page.hasMore) {
117689
- break;
117690
- }
117691
- page = await fetchPage(afterKey);
117692
- }
117693
- if (!stopped && afterKey !== cursorAtStart) {
117694
- subscribe();
117695
- }
117696
- } catch (err) {
117697
- opts.onError?.(err);
117698
- } finally {
117699
- drainInFlight = false;
117700
- }
117701
- };
117702
- subscribe();
117703
- return {
117704
- stop: () => {
117705
- stopped = true;
117706
- unsubscribe?.();
117707
- unsubscribe = undefined;
117708
- },
117709
- getAfterKey: () => afterKey
117710
- };
117711
- }
117712
- var init_subscribe_loop = () => {};
117713
-
117714
- // src/infrastructure/incremental-sync/feed-runtime.ts
117715
- function runWorkerLoop(feedName, buffer, keyOf, onItem) {
117716
- return exports_Effect.gen(function* () {
117717
- while (true) {
117718
- const item = buffer.dequeue();
117719
- if (item === undefined) {
117720
- yield* exports_Effect.sleep("10 millis");
117721
- continue;
117722
- }
117723
- const key = keyOf(item);
117724
- const ctx = {
117725
- item,
117726
- feedName,
117727
- ack: () => buffer.ack(key),
117728
- nack: (opts) => buffer.nack(key, opts?.requeue ?? false)
117729
- };
117730
- yield* onItem(ctx).pipe(exports_Effect.catchAll(() => exports_Effect.void));
117731
- }
117732
- });
117733
- }
117734
- var runIncrementalSubscribeLive = (opts) => exports_Effect.gen(function* () {
117735
- const buffer = new MessageBuffer(opts.buffer, opts.def.itemKey);
117736
- const subscribeHandle = startSubscribeLoop({
117737
- wsClient: opts.wsClient,
117738
- target: opts.target,
117739
- args: opts.args,
117740
- buffer,
117741
- def: opts.def,
117742
- config: opts.subscribe,
117743
- initialAfterKey: opts.initialAfterKey ?? null,
117744
- onError: opts.onError
117745
- });
117746
- const workerFiber = yield* exports_Effect.forkDaemon(runWorkerLoop(opts.def.name, buffer, opts.def.itemKey, opts.onItem));
117747
- return {
117748
- buffer,
117749
- stop: () => exports_Effect.gen(function* () {
117750
- subscribeHandle.stop();
117751
- yield* exports_Fiber.interrupt(workerFiber);
117752
- })
117753
- };
117754
- });
117755
- var init_feed_runtime = __esm(() => {
117756
- init_esm();
117757
- init_layers();
117758
- init_subscribe_loop();
117759
- });
117760
-
117761
- // src/infrastructure/incremental-sync/feeds/assigned-task-presence.ts
117762
- var assignedTaskPresenceFeedDef, assignedTaskPresenceSubscribeTarget, ASSIGNED_TASK_PRESENCE_FEED_LIMIT = 50, ASSIGNED_TASK_PRESENCE_FEED_BUFFER;
117763
- var init_assigned_task_presence = __esm(() => {
117764
- init_assigned_task_monitor_contract();
117765
- init_api3();
117766
- assignedTaskPresenceFeedDef = {
117767
- name: "assigned-task-presence",
117768
- itemKey: (item) => item.presenceKey,
117769
- parseItem: parseAssignedTaskPresenceSignal
117770
- };
117771
- assignedTaskPresenceSubscribeTarget = {
117772
- query: api.machines.subscribeAssignedTaskPresenceSince,
117773
- buildArgs: (args2, afterKey, limit) => ({
117774
- sessionId: args2.sessionId,
117775
- machineId: args2.machineId,
117776
- afterPresenceKey: afterKey ?? undefined,
117777
- limit
117778
- }),
117779
- parsePage: (result) => {
117780
- const page = result;
117781
- return {
117782
- items: page.items,
117783
- highKey: page.highPresenceKey,
117784
- hasMore: page.hasMore
117785
- };
117786
- }
117787
- };
117788
- ASSIGNED_TASK_PRESENCE_FEED_BUFFER = {
117789
- maxSize: 200,
117790
- dedupe: true
117791
- };
117792
- });
117793
-
117794
- // src/daemon/infrastructure/convex/subscribers/assigned-task-presence.ts
117795
- function startAssignedTaskPresenceSubscriber(deps, onEvent) {
117796
- let stopped = false;
117797
- const startPromise = exports_Effect.runPromise(runIncrementalSubscribeLive({
117798
- wsClient: deps.wsClient,
117799
- def: assignedTaskPresenceFeedDef,
117800
- target: assignedTaskPresenceSubscribeTarget,
117801
- args: { sessionId: deps.sessionId, machineId: deps.machineId },
117802
- buffer: ASSIGNED_TASK_PRESENCE_FEED_BUFFER,
117803
- subscribe: { limit: ASSIGNED_TASK_PRESENCE_FEED_LIMIT },
117804
- onItem: ({ item, ack }) => exports_Effect.sync(() => {
117805
- if (stopped)
117806
- return;
117807
- ack();
117808
- onEvent({ type: "assigned-task.presence", taskId: item.taskId, role: item.role });
117809
- }),
117810
- onError: (err) => {
117811
- console.warn(`[daemon] assigned-task-presence subscriber error: ${String(err)}`);
117812
- }
117813
- }));
117814
- let feedHandle;
117815
- startPromise.then((handle) => {
117816
- feedHandle = handle;
117817
- });
117818
- return {
117819
- async stop() {
117820
- stopped = true;
117821
- const handle = feedHandle ?? await startPromise;
117822
- await exports_Effect.runPromise(handle.stop());
117823
- }
117824
- };
117825
- }
117826
- var init_assigned_task_presence2 = __esm(() => {
117827
- init_esm();
117828
- init_feed_runtime();
117829
- init_assigned_task_presence();
117830
- });
117831
-
117832
- // src/infrastructure/incremental-sync/feeds/assigned-task-signals.ts
117833
- var assignedTaskSignalsFeedDef, assignedTaskSignalsSubscribeTarget, ASSIGNED_TASK_SIGNAL_FEED_LIMIT = 50, ASSIGNED_TASK_SIGNAL_FEED_BUFFER;
117834
- var init_assigned_task_signals = __esm(() => {
117835
- init_assigned_task_monitor_contract();
117836
- init_api3();
117837
- assignedTaskSignalsFeedDef = {
117838
- name: "assigned-task-signals",
117839
- itemKey: (item) => item.revisionKey,
117840
- parseItem: parseAssignedTaskSignal
117841
- };
117842
- assignedTaskSignalsSubscribeTarget = {
117843
- query: api.machines.subscribeAssignedTaskSignalsSince,
117844
- buildArgs: (args2, afterKey, limit) => ({
117845
- sessionId: args2.sessionId,
117846
- machineId: args2.machineId,
117847
- afterKey: afterKey ?? undefined,
117848
- limit
117849
- }),
117850
- parsePage: (result) => result
117851
- };
117852
- ASSIGNED_TASK_SIGNAL_FEED_BUFFER = {
117853
- maxSize: 200,
117854
- dedupe: true
117855
- };
117856
- });
117857
-
117858
- // src/daemon/infrastructure/convex/subscribers/assigned-task-signals.ts
117859
- function startAssignedTaskSignalsSubscriber(deps, onEvent) {
117860
- let stopped = false;
117861
- const startPromise = exports_Effect.runPromise(runIncrementalSubscribeLive({
117862
- wsClient: deps.wsClient,
117863
- def: assignedTaskSignalsFeedDef,
117864
- target: assignedTaskSignalsSubscribeTarget,
117865
- args: { sessionId: deps.sessionId, machineId: deps.machineId },
117866
- buffer: ASSIGNED_TASK_SIGNAL_FEED_BUFFER,
117867
- subscribe: { limit: ASSIGNED_TASK_SIGNAL_FEED_LIMIT },
117868
- onItem: ({ item, ack }) => exports_Effect.sync(() => {
117869
- if (stopped)
117870
- return;
117871
- ack();
117872
- onEvent({ type: "assigned-task.signal", taskId: item.taskId, role: item.role });
117873
- }),
117874
- onError: (err) => {
117875
- console.warn(`[daemon] assigned-task-signals subscriber error: ${String(err)}`);
117876
- }
117877
- }));
117878
- let feedHandle;
117879
- startPromise.then((handle) => {
117880
- feedHandle = handle;
117881
- });
117882
- return {
117883
- async stop() {
117884
- stopped = true;
117885
- const handle = feedHandle ?? await startPromise;
117886
- await exports_Effect.runPromise(handle.stop());
117887
- }
117888
- };
117889
- }
117890
- var init_assigned_task_signals2 = __esm(() => {
117891
- init_esm();
117892
- init_feed_runtime();
117893
- init_assigned_task_signals();
117894
- });
117895
-
117896
117855
  // src/daemon/infrastructure/convex/subscribers/command-events.ts
117897
117856
  function startCommandEventsSubscriber(deps, onEvent) {
117898
117857
  const seen = new Set;
@@ -118280,10 +118239,10 @@ function startWorkspaceListSubscriber(deps, onEvent) {
118280
118239
  const unsub = deps.wsClient.onUpdate(api.workspaces.listRecentlyObservedWorkspacesForMachine, queryArgs, (workspaces) => {
118281
118240
  if (workspaces == null)
118282
118241
  return;
118283
- const snapshotKey = JSON.stringify(workspaces);
118284
- if (snapshotKey === lastSnapshotKey)
118242
+ const snapshotKey2 = JSON.stringify(workspaces);
118243
+ if (snapshotKey2 === lastSnapshotKey)
118285
118244
  return;
118286
- lastSnapshotKey = snapshotKey;
118245
+ lastSnapshotKey = snapshotKey2;
118287
118246
  onEvent({ type: "workspace.list-changed", machineId: deps.machineId });
118288
118247
  }, (err) => {
118289
118248
  console.warn(`[daemon] workspace-list subscriber error: ${err instanceof Error ? err.message : String(err)}`);
@@ -118304,8 +118263,6 @@ function startAllSubscribers(deps) {
118304
118263
  const onEvent = (event) => {
118305
118264
  routeInboundEvent(deps.router, event);
118306
118265
  };
118307
- const signals = startAssignedTaskSignalsSubscriber(deps, onEvent);
118308
- const presence = startAssignedTaskPresenceSubscriber(deps, onEvent);
118309
118266
  const session2 = startDirectHarnessSessionSubscriber(deps, onEvent);
118310
118267
  const prompt = startDirectHarnessPromptSubscriber(deps, onEvent);
118311
118268
  const directHarnessCommand = startDirectHarnessCommandSubscriber(deps, onEvent);
@@ -118323,8 +118280,6 @@ function startAllSubscribers(deps) {
118323
118280
  return {
118324
118281
  async stopAll() {
118325
118282
  await Promise.all([
118326
- signals.stop(),
118327
- presence.stop(),
118328
118283
  session2.stop(),
118329
118284
  prompt.stop(),
118330
118285
  directHarnessCommand.stop(),
@@ -118347,8 +118302,6 @@ var init_subscriber_registry = __esm(() => {
118347
118302
  init_event_router();
118348
118303
  init_agentic_query_prompt();
118349
118304
  init_agentic_query_session();
118350
- init_assigned_task_presence2();
118351
- init_assigned_task_signals2();
118352
118305
  init_command_events();
118353
118306
  init_command_run();
118354
118307
  init_direct_harness_command();
@@ -118378,19 +118331,19 @@ function resolveEnvSlug(convexUrl) {
118378
118331
  }
118379
118332
 
118380
118333
  // src/infrastructure/log-server/resolve-logs-db-path.ts
118381
- import { homedir as homedir11 } from "node:os";
118382
- import { join as join27 } from "node:path";
118334
+ import { homedir as homedir12 } from "node:os";
118335
+ import { join as join28 } from "node:path";
118383
118336
  function resolveLogsDbPath(convexUrl) {
118384
- return join27(homedir11(), ".chatroom", resolveEnvSlug(convexUrl ?? getConvexUrl()), "logs.sqlite");
118337
+ return join28(homedir12(), ".chatroom", resolveEnvSlug(convexUrl ?? getConvexUrl()), "logs.sqlite");
118385
118338
  }
118386
118339
  var init_resolve_logs_db_path = __esm(() => {
118387
118340
  init_client2();
118388
118341
  });
118389
118342
 
118390
118343
  // src/infrastructure/log-server/log-schema.ts
118391
- var SCHEMA_VERSION = 2, MIGRATIONS;
118344
+ var SCHEMA_VERSION2 = 2, MIGRATIONS2;
118392
118345
  var init_log_schema = __esm(() => {
118393
- MIGRATIONS = [
118346
+ MIGRATIONS2 = [
118394
118347
  `CREATE TABLE IF NOT EXISTS schema_meta (key TEXT PRIMARY KEY, value TEXT NOT NULL)`,
118395
118348
  `CREATE TABLE IF NOT EXISTS log_entries (
118396
118349
  id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -118414,18 +118367,18 @@ var init_log_schema = __esm(() => {
118414
118367
  });
118415
118368
 
118416
118369
  // src/infrastructure/log-server/open-log-database.ts
118417
- import { mkdirSync as mkdirSync8 } from "node:fs";
118418
- import { dirname as dirname15 } from "node:path";
118419
- import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
118370
+ import { mkdirSync as mkdirSync9 } from "node:fs";
118371
+ import { dirname as dirname16 } from "node:path";
118372
+ import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
118420
118373
  function openLogDatabase(dbPath) {
118421
- mkdirSync8(dirname15(dbPath), { recursive: true });
118422
- const db = new DatabaseSync3(dbPath);
118374
+ mkdirSync9(dirname16(dbPath), { recursive: true });
118375
+ const db = new DatabaseSync4(dbPath);
118423
118376
  db.exec("PRAGMA journal_mode = WAL");
118424
118377
  db.exec("PRAGMA busy_timeout = 5000");
118425
118378
  db.exec("PRAGMA synchronous = NORMAL");
118426
- for (const migration of MIGRATIONS)
118379
+ for (const migration of MIGRATIONS2)
118427
118380
  db.exec(migration);
118428
- db.prepare(`INSERT INTO schema_meta(key,value) VALUES('version',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(String(SCHEMA_VERSION));
118381
+ db.prepare(`INSERT INTO schema_meta(key,value) VALUES('version',?) ON CONFLICT(key) DO UPDATE SET value=excluded.value`).run(String(SCHEMA_VERSION2));
118429
118382
  return db;
118430
118383
  }
118431
118384
  var init_open_log_database = __esm(() => {
@@ -118474,8 +118427,8 @@ function queryEventStream(db, input) {
118474
118427
  ...input.toTimestamp !== undefined ? [input.toTimestamp] : [],
118475
118428
  clamp4(input.limit)
118476
118429
  ];
118477
- const rows2 = db.prepare(`SELECT * FROM event_stream_entries WHERE 1=1 ${filters} ORDER BY id DESC LIMIT ?`).all(...values3);
118478
- return rows2.reverse().map((row) => ({
118430
+ const rows = db.prepare(`SELECT * FROM event_stream_entries WHERE 1=1 ${filters} ORDER BY id DESC LIMIT ?`).all(...values3);
118431
+ return rows.reverse().map((row) => ({
118479
118432
  id: Number(row.id),
118480
118433
  timestamp: Number(row.timestamp),
118481
118434
  type: row.type,
@@ -118501,8 +118454,8 @@ function queryAfterId(db, afterId = 0, limit = 100, source, chatroomId, role, ha
118501
118454
  ...toTimestamp !== undefined ? [toTimestamp] : [],
118502
118455
  clamp4(limit)
118503
118456
  ];
118504
- const rows2 = db.prepare(`SELECT * FROM log_entries WHERE id > ? ${filters} ORDER BY id ASC LIMIT ?`).all(...values3);
118505
- return rows2.map(map19);
118457
+ const rows = db.prepare(`SELECT * FROM log_entries WHERE id > ? ${filters} ORDER BY id ASC LIMIT ?`).all(...values3);
118458
+ return rows.map(map19);
118506
118459
  }
118507
118460
  function queryHistory(db, beforeId, limit = 100, source, chatroomId, role, harness, fromTimestamp, toTimestamp) {
118508
118461
  const filters = [
@@ -118524,8 +118477,8 @@ function queryHistory(db, beforeId, limit = 100, source, chatroomId, role, harne
118524
118477
  ...toTimestamp !== undefined ? [toTimestamp] : [],
118525
118478
  clamp4(limit)
118526
118479
  ];
118527
- const rows2 = db.prepare(`SELECT * FROM log_entries WHERE 1=1 ${filters} ORDER BY id DESC LIMIT ?`).all(...values3);
118528
- return rows2.map(map19).reverse();
118480
+ const rows = db.prepare(`SELECT * FROM log_entries WHERE 1=1 ${filters} ORDER BY id DESC LIMIT ?`).all(...values3);
118481
+ return rows.map(map19).reverse();
118529
118482
  }
118530
118483
  function listLogDimensions(db, chatroomId, limit = 100) {
118531
118484
  const clamped = clamp4(limit);
@@ -118614,9 +118567,9 @@ function appendOutboundEvent(db, event) {
118614
118567
  }
118615
118568
 
118616
118569
  // src/daemon/infrastructure/persistence/schema.ts
118617
- var SCHEMA_VERSION2 = 1, MIGRATIONS2;
118618
- var init_schema = __esm(() => {
118619
- MIGRATIONS2 = [
118570
+ var SCHEMA_VERSION3 = 1, MIGRATIONS3;
118571
+ var init_schema2 = __esm(() => {
118572
+ MIGRATIONS3 = [
118620
118573
  `CREATE TABLE IF NOT EXISTS schema_meta (
118621
118574
  key TEXT PRIMARY KEY,
118622
118575
  value TEXT NOT NULL
@@ -118645,21 +118598,21 @@ var init_schema = __esm(() => {
118645
118598
  });
118646
118599
 
118647
118600
  // src/daemon/infrastructure/persistence/open-database.ts
118648
- import { mkdirSync as mkdirSync9 } from "node:fs";
118649
- import { dirname as dirname16 } from "node:path";
118650
- import { DatabaseSync as DatabaseSync4 } from "node:sqlite";
118651
- function openDatabase(dbPath) {
118652
- mkdirSync9(dirname16(dbPath), { recursive: true });
118653
- const db = new DatabaseSync4(dbPath);
118654
- for (const sql of MIGRATIONS2) {
118601
+ import { mkdirSync as mkdirSync10 } from "node:fs";
118602
+ import { dirname as dirname17 } from "node:path";
118603
+ import { DatabaseSync as DatabaseSync5 } from "node:sqlite";
118604
+ function openDatabase2(dbPath) {
118605
+ mkdirSync10(dirname17(dbPath), { recursive: true });
118606
+ const db = new DatabaseSync5(dbPath);
118607
+ for (const sql of MIGRATIONS3) {
118655
118608
  db.exec(sql);
118656
118609
  }
118657
118610
  db.prepare(`INSERT INTO schema_meta(key, value) VALUES('version', ?)
118658
- ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(SCHEMA_VERSION2));
118611
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(String(SCHEMA_VERSION3));
118659
118612
  return db;
118660
118613
  }
118661
- var init_open_database = __esm(() => {
118662
- init_schema();
118614
+ var init_open_database2 = __esm(() => {
118615
+ init_schema2();
118663
118616
  });
118664
118617
 
118665
118618
  // src/daemon/infrastructure/persistence/outbox.ts
@@ -118677,10 +118630,10 @@ function listPendingOutbox(db, limit = 100) {
118677
118630
  // src/daemon/infrastructure/persistence/read-model.ts
118678
118631
  function listHarnessStreamLines(db, opts = {}) {
118679
118632
  const limit = opts.limit ?? 500;
118680
- const rows2 = db.prepare(`SELECT payload_json FROM outbound_events
118633
+ const rows = db.prepare(`SELECT payload_json FROM outbound_events
118681
118634
  WHERE event_type = 'harness.stream'
118682
118635
  ORDER BY id DESC LIMIT ?`).all(limit);
118683
- const parsed = rows2.map((row) => JSON.parse(row.payload_json)).filter((event) => event.type === "harness.stream");
118636
+ const parsed = rows.map((row) => JSON.parse(row.payload_json)).filter((event) => event.type === "harness.stream");
118684
118637
  if (!opts.harness)
118685
118638
  return parsed.reverse();
118686
118639
  return parsed.filter((e) => e.harness === opts.harness).reverse();
@@ -118688,7 +118641,7 @@ function listHarnessStreamLines(db, opts = {}) {
118688
118641
 
118689
118642
  // src/daemon/infrastructure/persistence/persistence-store.ts
118690
118643
  function createPersistenceStore(dbPath) {
118691
- const db = openDatabase(dbPath);
118644
+ const db = openDatabase2(dbPath);
118692
118645
  return {
118693
118646
  append(event) {
118694
118647
  const eventId = appendOutboundEvent(db, event);
@@ -118702,7 +118655,7 @@ function createPersistenceStore(dbPath) {
118702
118655
  };
118703
118656
  }
118704
118657
  var init_persistence_store = __esm(() => {
118705
- init_open_database();
118658
+ init_open_database2();
118706
118659
  });
118707
118660
 
118708
118661
  // src/daemon/infrastructure/persistence/index.ts
@@ -121435,9 +121388,9 @@ var require_event_target2 = __commonJS((exports, module) => {
121435
121388
  }
121436
121389
  Object.defineProperty(MessageEvent.prototype, "data", { enumerable: true });
121437
121390
  var EventTarget = {
121438
- addEventListener(type, handler8, options = {}) {
121391
+ addEventListener(type, handler7, options = {}) {
121439
121392
  for (const listener of this.listeners(type)) {
121440
- if (!options[kForOnEventAttribute] && listener[kListener] === handler8 && !listener[kForOnEventAttribute]) {
121393
+ if (!options[kForOnEventAttribute] && listener[kListener] === handler7 && !listener[kForOnEventAttribute]) {
121441
121394
  return;
121442
121395
  }
121443
121396
  }
@@ -121448,7 +121401,7 @@ var require_event_target2 = __commonJS((exports, module) => {
121448
121401
  data: isBinary ? data : data.toString()
121449
121402
  });
121450
121403
  event[kTarget] = this;
121451
- callListener(handler8, this, event);
121404
+ callListener(handler7, this, event);
121452
121405
  };
121453
121406
  } else if (type === "close") {
121454
121407
  wrapper = function onClose(code2, message) {
@@ -121458,7 +121411,7 @@ var require_event_target2 = __commonJS((exports, module) => {
121458
121411
  wasClean: this._closeFrameReceived && this._closeFrameSent
121459
121412
  });
121460
121413
  event[kTarget] = this;
121461
- callListener(handler8, this, event);
121414
+ callListener(handler7, this, event);
121462
121415
  };
121463
121416
  } else if (type === "error") {
121464
121417
  wrapper = function onError3(error51) {
@@ -121467,28 +121420,28 @@ var require_event_target2 = __commonJS((exports, module) => {
121467
121420
  message: error51.message
121468
121421
  });
121469
121422
  event[kTarget] = this;
121470
- callListener(handler8, this, event);
121423
+ callListener(handler7, this, event);
121471
121424
  };
121472
121425
  } else if (type === "open") {
121473
121426
  wrapper = function onOpen() {
121474
121427
  const event = new Event2("open");
121475
121428
  event[kTarget] = this;
121476
- callListener(handler8, this, event);
121429
+ callListener(handler7, this, event);
121477
121430
  };
121478
121431
  } else {
121479
121432
  return;
121480
121433
  }
121481
121434
  wrapper[kForOnEventAttribute] = !!options[kForOnEventAttribute];
121482
- wrapper[kListener] = handler8;
121435
+ wrapper[kListener] = handler7;
121483
121436
  if (options.once) {
121484
121437
  this.once(type, wrapper);
121485
121438
  } else {
121486
121439
  this.on(type, wrapper);
121487
121440
  }
121488
121441
  },
121489
- removeEventListener(type, handler8) {
121442
+ removeEventListener(type, handler7) {
121490
121443
  for (const listener of this.listeners(type)) {
121491
- if (listener[kListener] === handler8 && !listener[kForOnEventAttribute]) {
121444
+ if (listener[kListener] === handler7 && !listener[kForOnEventAttribute]) {
121492
121445
  this.removeListener(type, listener);
121493
121446
  break;
121494
121447
  }
@@ -122017,16 +121970,16 @@ var require_websocket2 = __commonJS((exports, module) => {
122017
121970
  }
122018
121971
  return null;
122019
121972
  },
122020
- set(handler8) {
121973
+ set(handler7) {
122021
121974
  for (const listener of this.listeners(method)) {
122022
121975
  if (listener[kForOnEventAttribute]) {
122023
121976
  this.removeListener(method, listener);
122024
121977
  break;
122025
121978
  }
122026
121979
  }
122027
- if (typeof handler8 !== "function")
121980
+ if (typeof handler7 !== "function")
122028
121981
  return;
122029
- this.addEventListener(method, handler8, {
121982
+ this.addEventListener(method, handler7, {
122030
121983
  [kForOnEventAttribute]: true
122031
121984
  });
122032
121985
  }
@@ -132360,19 +132313,19 @@ function routeRequest(req, res, deps) {
132360
132313
 
132361
132314
  // src/daemon/local-web/server/serve-static.ts
132362
132315
  import { existsSync as existsSync10, readFileSync as readFileSync11 } from "node:fs";
132363
- import { dirname as dirname17, join as join28 } from "node:path";
132316
+ import { dirname as dirname18, join as join29 } from "node:path";
132364
132317
  import { fileURLToPath as fileURLToPath7 } from "node:url";
132365
132318
  function clientDistCandidates(here) {
132366
132319
  return [
132367
- join28(here, "client/build"),
132368
- join28(here, "../client/build"),
132369
- join28(here, "../src/daemon/local-web/client/build")
132320
+ join29(here, "client/build"),
132321
+ join29(here, "../client/build"),
132322
+ join29(here, "../src/daemon/local-web/client/build")
132370
132323
  ];
132371
132324
  }
132372
- function resolveClientDistDir(here = dirname17(fileURLToPath7(import.meta.url))) {
132325
+ function resolveClientDistDir(here = dirname18(fileURLToPath7(import.meta.url))) {
132373
132326
  const candidates = clientDistCandidates(here);
132374
132327
  for (const dir of candidates) {
132375
- if (existsSync10(join28(dir, "index.html")))
132328
+ if (existsSync10(join29(dir, "index.html")))
132376
132329
  return dir;
132377
132330
  }
132378
132331
  return candidates[0];
@@ -132385,7 +132338,7 @@ function tryServeStatic(req, res, distDir) {
132385
132338
  return false;
132386
132339
  }
132387
132340
  const safePath = pathname === "/" ? "/index.html" : pathname;
132388
- const filePath = join28(distDir, safePath);
132341
+ const filePath = join29(distDir, safePath);
132389
132342
  if (!filePath.startsWith(distDir)) {
132390
132343
  res.writeHead(403);
132391
132344
  res.end();
@@ -132402,7 +132355,7 @@ function tryServeStatic(req, res, distDir) {
132402
132355
  }
132403
132356
  return true;
132404
132357
  }
132405
- const indexPath = join28(distDir, "index.html");
132358
+ const indexPath = join29(distDir, "index.html");
132406
132359
  if (existsSync10(indexPath)) {
132407
132360
  res.writeHead(200, { "Content-Type": "text/html" });
132408
132361
  if (req.method === "HEAD") {
@@ -132984,7 +132937,7 @@ async function harnessStatus() {
132984
132937
  };
132985
132938
  const program2 = exports_Effect.forEach(services, detectOne, { concurrency: "unbounded" });
132986
132939
  const results = await exports_Effect.runPromise(program2);
132987
- const rows2 = results.map(({ id: id3, displayName, result }) => {
132940
+ const rows = results.map(({ id: id3, displayName, result }) => {
132988
132941
  if (isInstalled(result)) {
132989
132942
  return { id: id3, displayName, status: "installed" };
132990
132943
  }
@@ -132996,13 +132949,13 @@ async function harnessStatus() {
132996
132949
  }
132997
132950
  return { id: id3, displayName, status: "not-installed" };
132998
132951
  });
132999
- const idWidth = Math.max(4, ...rows2.map((r) => r.id.length));
133000
- const nameWidth = Math.max(11, ...rows2.map((r) => r.displayName.length));
132952
+ const idWidth = Math.max(4, ...rows.map((r) => r.id.length));
132953
+ const nameWidth = Math.max(11, ...rows.map((r) => r.displayName.length));
133001
132954
  const header = `${"ID".padEnd(idWidth)} ${"DISPLAY NAME".padEnd(nameWidth)} STATUS`;
133002
132955
  const divider = `${"-".repeat(idWidth)} ${"-".repeat(nameWidth)} ------`;
133003
132956
  console.log(header);
133004
132957
  console.log(divider);
133005
- for (const row of rows2) {
132958
+ for (const row of rows) {
133006
132959
  const statusIcon = row.status === "installed" ? "✅ installed" : row.status === "error" ? "⚠️ error" : "❌ not installed";
133007
132960
  const line = `${row.id.padEnd(idWidth)} ${row.displayName.padEnd(nameWidth)} ${statusIcon}`;
133008
132961
  console.log(line);
@@ -133011,8 +132964,8 @@ async function harnessStatus() {
133011
132964
  }
133012
132965
  }
133013
132966
  console.log("");
133014
- const installedCount = rows2.filter((r) => r.status === "installed").length;
133015
- const totalCount = rows2.length;
132967
+ const installedCount = rows.filter((r) => r.status === "installed").length;
132968
+ const totalCount = rows.length;
133016
132969
  console.log(`${installedCount}/${totalCount} harnesses available on this machine.`);
133017
132970
  }
133018
132971
  var init_harness_status = __esm(() => {
@@ -134133,4 +134086,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
134133
134086
  });
134134
134087
  program2.parse();
134135
134088
 
134136
- //# debugId=D41963016C23E20F64756E2164756E21
134089
+ //# debugId=D3E73C85EB221DCE64756E2164756E21