@adhdev/daemon-core 0.9.82-rc.60 → 0.9.82-rc.62

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
@@ -2342,12 +2342,34 @@ function sweepExpiredRemoteIdleSessions() {
2342
2342
  if (session.expiresAt <= now) remoteIdleSessions.delete(key);
2343
2343
  }
2344
2344
  }
2345
+ function readRefineJobId(event) {
2346
+ const metadata = readRecord(event.metadataEvent) || event;
2347
+ const result = readRecord(metadata.result);
2348
+ const refineJob = readRecord(result?.refineJob);
2349
+ return readNonEmptyString2(metadata.jobId) || readNonEmptyString2(refineJob?.jobId);
2350
+ }
2351
+ function buildRefineTerminalEventFingerprint(meshId, eventName, metadataEvent) {
2352
+ const jobId = readRefineJobId({ metadataEvent });
2353
+ return jobId && REFINE_TERMINAL_EVENTS.has(eventName) ? `${meshId}::${eventName}::${jobId}` : "";
2354
+ }
2355
+ function hasPendingRefineTerminalEventDuplicate(event) {
2356
+ if (!REFINE_TERMINAL_EVENTS.has(event.event)) return false;
2357
+ const jobId = readRefineJobId(event);
2358
+ if (!jobId) return false;
2359
+ return getPendingMeshCoordinatorEvents(event.meshId).some(
2360
+ (pending) => pending.event === event.event && readRefineJobId(pending) === jobId
2361
+ );
2362
+ }
2345
2363
  function getPendingEventsPath(meshId) {
2346
2364
  const safe = meshId.replace(/[^a-zA-Z0-9_-]/g, "_");
2347
2365
  return (0, import_path6.join)(getLedgerDir(), `${safe}.pending-events.jsonl`);
2348
2366
  }
2349
2367
  function queuePendingMeshCoordinatorEvent(event) {
2350
2368
  try {
2369
+ if (hasPendingRefineTerminalEventDuplicate(event)) {
2370
+ LOG.info("MeshEvents", `Suppressed duplicate pending ${event.event} for refine job ${readRefineJobId(event)}`);
2371
+ return true;
2372
+ }
2351
2373
  (0, import_fs7.appendFileSync)(getPendingEventsPath(event.meshId), JSON.stringify(event) + "\n", "utf-8");
2352
2374
  return true;
2353
2375
  } catch (e) {
@@ -2485,6 +2507,17 @@ function isDuplicateMeshCompletionEvent(args) {
2485
2507
  recentCompletionFingerprints.set(fingerprint, now);
2486
2508
  return false;
2487
2509
  }
2510
+ function isDuplicateRefineTerminalEvent(meshId, eventName, metadataEvent) {
2511
+ const fingerprint = buildRefineTerminalEventFingerprint(meshId, eventName, metadataEvent);
2512
+ if (!fingerprint) return false;
2513
+ const now = Date.now();
2514
+ for (const [key, seenAt] of recentCompletionFingerprints.entries()) {
2515
+ if (now - seenAt > RECENT_COMPLETION_FINGERPRINT_TTL_MS) recentCompletionFingerprints.delete(key);
2516
+ }
2517
+ if (recentCompletionFingerprints.has(fingerprint)) return true;
2518
+ recentCompletionFingerprints.set(fingerprint, now);
2519
+ return false;
2520
+ }
2488
2521
  function tryAssignQueueTask(components, meshId, nodeId, sessionId, providerType) {
2489
2522
  const task = claimNextTask(meshId, nodeId, sessionId);
2490
2523
  if (!task) {
@@ -2827,6 +2860,32 @@ Do NOT retry on this node. Consider reassigning to a different node or asking th
2827
2860
  if (args.event === "monitor:long_generating") {
2828
2861
  return `[System] ${args.nodeLabel} has been generating for a long time${metadata}. Use mesh_read_chat once for a status check, but do not poll repeatedly.`;
2829
2862
  }
2863
+ if (args.event === "refine:accepted") {
2864
+ const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
2865
+ return `[System] Refinery accepted async job${jobId ? ` ${jobId}` : ""} for ${args.nodeLabel}. Completion/failure will be delivered as a terminal refine event; do not poll repeatedly.`;
2866
+ }
2867
+ if (args.event === "refine:completed") {
2868
+ const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
2869
+ const result = readRecord(args.metadataEvent.result);
2870
+ const validationSummary = readRecord(result?.validationSummary);
2871
+ const validationStatus = readNonEmptyString2(validationSummary?.status);
2872
+ const into = readNonEmptyString2(result?.into);
2873
+ const branch = readNonEmptyString2(result?.branch);
2874
+ const details = [
2875
+ jobId ? `job_id=${jobId}` : "",
2876
+ branch && into ? `${branch}\u2192${into}` : "",
2877
+ validationStatus ? `validation=${validationStatus}` : ""
2878
+ ].filter(Boolean).join("; ");
2879
+ return `[System] Refinery async job for ${args.nodeLabel} completed successfully${details ? ` (${details})` : ""}. The worktree was merged and cleanup completed; continue from the updated mesh state.`;
2880
+ }
2881
+ if (args.event === "refine:failed") {
2882
+ const jobId = readRefineJobId({ metadataEvent: args.metadataEvent });
2883
+ const result = readRecord(args.metadataEvent.result);
2884
+ const code = readNonEmptyString2(result?.code);
2885
+ const error = readNonEmptyString2(result?.error);
2886
+ const details = [jobId ? `job_id=${jobId}` : "", code ? `code=${code}` : ""].filter(Boolean).join("; ");
2887
+ return `[System] Refinery async job for ${args.nodeLabel} failed${details ? ` (${details})` : ""}${error ? `: ${error}` : "."} Review the terminal refine event/ledger before retrying.`;
2888
+ }
2830
2889
  return "";
2831
2890
  }
2832
2891
  function injectMeshSystemMessage(components, args) {
@@ -2846,6 +2905,10 @@ function injectMeshSystemMessage(components, args) {
2846
2905
  LOG.info("MeshEvents", `Suppressed ${args.event} for intentionally cleanup-stopped session ${eventSessionId || "(unknown session)"}`);
2847
2906
  return { success: true, forwarded: 0, suppressed: true, intentionalCleanupStop: true };
2848
2907
  }
2908
+ if (isDuplicateRefineTerminalEvent(args.meshId, args.event, args.metadataEvent)) {
2909
+ LOG.info("MeshEvents", `Suppressed duplicate ${args.event} for refine job ${readRefineJobId({ metadataEvent: args.metadataEvent })}`);
2910
+ return { success: true, forwarded: 0, suppressed: true, duplicateRefineTerminalEvent: true };
2911
+ }
2849
2912
  const eventTimestamp = readEventTimestamp(args.metadataEvent.timestamp);
2850
2913
  if (args.event === "agent:generating_completed" && eventSessionId) {
2851
2914
  const duplicateCompletion = isDuplicateMeshCompletionEvent({
@@ -3095,6 +3158,14 @@ function handleMeshForwardEvent(components, payload) {
3095
3158
  providerType: readNonEmptyString2(payload.providerType),
3096
3159
  providerSessionId: readNonEmptyString2(payload.providerSessionId),
3097
3160
  finalSummary: readNonEmptyString2(payload.finalSummary) || readNonEmptyString2(payload.summary),
3161
+ jobId: readNonEmptyString2(payload.jobId),
3162
+ interactionId: readNonEmptyString2(payload.interactionId),
3163
+ status: readNonEmptyString2(payload.status),
3164
+ targetDaemonId: readNonEmptyString2(payload.targetDaemonId),
3165
+ startedAt: readNonEmptyString2(payload.startedAt),
3166
+ completedAt: readNonEmptyString2(payload.completedAt),
3167
+ retryOfJobId: readNonEmptyString2(payload.retryOfJobId),
3168
+ ...payload.result && typeof payload.result === "object" && !Array.isArray(payload.result) ? { result: payload.result } : {},
3098
3169
  ...payload.timestamp !== void 0 ? { timestamp: payload.timestamp } : {},
3099
3170
  intentional: payload.intentional === true,
3100
3171
  intentionalStop: payload.intentionalStop === true,
@@ -3138,7 +3209,7 @@ function setupMeshEventForwarding(components) {
3138
3209
  });
3139
3210
  });
3140
3211
  }
3141
- var import_fs7, import_path6, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
3212
+ var import_fs7, import_path6, REMOTE_IDLE_SESSION_TTL_MS, remoteIdleSessions, REFINE_TERMINAL_EVENTS, MESH_COORDINATOR_EVENTS, EVENT_TO_LEDGER_KIND, INTENTIONAL_CLEANUP_STOP_SUPPRESSION_MS, RECENT_COMPLETION_FINGERPRINT_TTL_MS, recentCompletionFingerprints, autoLaunchInProgress, autoLaunchCooldownUntil, AUTO_LAUNCH_COOLDOWN_MS;
3142
3213
  var init_mesh_events = __esm({
3143
3214
  "src/mesh/mesh-events.ts"() {
3144
3215
  "use strict";
@@ -3152,13 +3223,17 @@ var init_mesh_events = __esm({
3152
3223
  init_mesh_work_queue();
3153
3224
  REMOTE_IDLE_SESSION_TTL_MS = 5 * 60 * 1e3;
3154
3225
  remoteIdleSessions = /* @__PURE__ */ new Map();
3226
+ REFINE_TERMINAL_EVENTS = /* @__PURE__ */ new Set(["refine:completed", "refine:failed"]);
3155
3227
  MESH_COORDINATOR_EVENTS = /* @__PURE__ */ new Set([
3156
3228
  "agent:generating_started",
3157
3229
  "agent:generating_completed",
3158
3230
  "agent:waiting_approval",
3159
3231
  "agent:stopped",
3160
3232
  "agent:ready",
3161
- "monitor:long_generating"
3233
+ "monitor:long_generating",
3234
+ "refine:accepted",
3235
+ "refine:completed",
3236
+ "refine:failed"
3162
3237
  ]);
3163
3238
  EVENT_TO_LEDGER_KIND = {
3164
3239
  "agent:generating_completed": "task_completed",
@@ -26904,6 +26979,7 @@ var DaemonCommandRouter = class {
26904
26979
  workspace: readStringValue(args.node?.workspace),
26905
26980
  startedAt: args.startedAt || (/* @__PURE__ */ new Date()).toISOString(),
26906
26981
  ...args.completedAt ? { completedAt: args.completedAt } : {},
26982
+ ...args.retryOfJobId ? { retryOfJobId: args.retryOfJobId } : {},
26907
26983
  eventDelivery: { pendingEvents: true, ledger: true },
26908
26984
  evidence: {
26909
26985
  pendingEventsCommand: "get_pending_mesh_events",
@@ -26930,6 +27006,7 @@ var DaemonCommandRouter = class {
26930
27006
  status: handle.status,
26931
27007
  startedAt: handle.startedAt,
26932
27008
  completedAt: handle.completedAt,
27009
+ retryOfJobId: handle.retryOfJobId,
26933
27010
  ...result ? { result } : {}
26934
27011
  },
26935
27012
  queuedAt: Date.now()
@@ -26952,9 +27029,11 @@ var DaemonCommandRouter = class {
26952
27029
  targetDaemonId: handle.targetDaemonId,
26953
27030
  workspace: handle.workspace,
26954
27031
  startedAt: handle.startedAt,
26955
- completedAt: handle.completedAt
27032
+ completedAt: handle.completedAt,
27033
+ retryOfJobId: handle.retryOfJobId
26956
27034
  },
26957
27035
  async: true,
27036
+ retryOfJobId: handle.retryOfJobId,
26958
27037
  ...result ? {
26959
27038
  success: result.success === true,
26960
27039
  result,
@@ -27192,6 +27271,7 @@ var DaemonCommandRouter = class {
27192
27271
  completedAt,
27193
27272
  jobId: handle.jobId,
27194
27273
  interactionId: handle.interactionId,
27274
+ retryOfJobId: handle.retryOfJobId,
27195
27275
  node: { daemonId: handle.targetDaemonId, workspace: handle.workspace }
27196
27276
  });
27197
27277
  const terminal = { ...terminalHandle, result };
@@ -27206,13 +27286,12 @@ var DaemonCommandRouter = class {
27206
27286
  const running = this.runningRefineJobs.get(key);
27207
27287
  if (running) return { ...running, duplicate: true };
27208
27288
  const terminal = this.terminalRefineJobs.get(key);
27209
- if (terminal) return { ...terminal, duplicate: true };
27210
27289
  const meshRecord = await this.getMeshForCommand(meshId, args?.inlineMesh);
27211
27290
  const mesh = meshRecord?.mesh;
27212
27291
  const node = mesh?.nodes?.find((n) => n.id === nodeId || n.nodeId === nodeId);
27213
27292
  if (!node) return { success: false, error: `Node '${nodeId}' not found in mesh` };
27214
27293
  if (!node.isLocalWorktree || !node.workspace) return { success: false, error: `Refinery requires a local worktree node` };
27215
- const handle = this.buildRefineJobHandle({ meshId, nodeId, node });
27294
+ const handle = this.buildRefineJobHandle({ meshId, nodeId, node, retryOfJobId: terminal?.jobId });
27216
27295
  this.runningRefineJobs.set(key, handle);
27217
27296
  await this.appendRefineJobLedger("task_dispatched", handle);
27218
27297
  this.queueRefineJobEvent("refine:accepted", handle);