@adhdev/daemon-standalone 1.0.18-rc.12 → 1.0.18-rc.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -30265,10 +30265,10 @@ var require_dist3 = __commonJS({
30265
30265
  }
30266
30266
  function getDaemonBuildInfo() {
30267
30267
  if (cached2) return cached2;
30268
- const commit = readInjected(true ? "8cce29137e6b62781be7645411736bd8d1a9e7a8" : void 0) ?? "unknown";
30269
- const commitShort = readInjected(true ? "8cce2913" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30270
- const version2 = readInjected(true ? "1.0.18-rc.12" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30271
- const builtAt = readInjected(true ? "2026-07-22T12:26:05.397Z" : void 0);
30268
+ const commit = readInjected(true ? "a44f4a2814c4db171a9ebb0f6fcfb0798203aebb" : void 0) ?? "unknown";
30269
+ const commitShort = readInjected(true ? "a44f4a28" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
30270
+ const version2 = readInjected(true ? "1.0.18-rc.14" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
30271
+ const builtAt = readInjected(true ? "2026-07-22T17:38:24.589Z" : void 0);
30272
30272
  cached2 = builtAt ? { commit, commitShort, version: version2, builtAt } : { commit, commitShort, version: version2 };
30273
30273
  return cached2;
30274
30274
  }
@@ -52218,34 +52218,37 @@ ${cleanBody}`;
52218
52218
  if (!dispatchMeshCommand) return;
52219
52219
  const meshId = mesh.id;
52220
52220
  const pulls = candidateDaemonIds.length > 0 ? candidateDaemonIds.map((id) => ({ meshId, coordinatorDaemonId: id })) : [{ meshId }];
52221
- await Promise.allSettled(mesh.nodes.map(async (node) => {
52222
- const nodeDaemonId = readNonEmptyString(node.daemonId);
52223
- if (!nodeDaemonId) return;
52224
- if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) return;
52225
- if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) return;
52226
- const getPeerStatus = components.getMeshPeerConnectionStatus;
52227
- if (getPeerStatus) {
52228
- const peerSnapshot = getPeerStatus(nodeDaemonId);
52229
- if (!peerSnapshot || String(peerSnapshot.state) !== "connected") return;
52230
- }
52231
- for (const pendingEventArgs of pulls) {
52232
- let events;
52221
+ await Promise.allSettled(mesh.nodes.map((node) => pullPendingEventsFromNode(components, meshId, node, localDaemonId, candidateDaemonIds, pulls)));
52222
+ }
52223
+ async function pullPendingEventsFromNode(components, meshId, node, localDaemonId, candidateDaemonIds, pulls) {
52224
+ const dispatchMeshCommand = components.dispatchMeshCommand;
52225
+ if (!dispatchMeshCommand) return;
52226
+ const nodeDaemonId = readNonEmptyString(node.daemonId);
52227
+ if (!nodeDaemonId) return;
52228
+ if (daemonIdsEquivalent(nodeDaemonId, localDaemonId)) return;
52229
+ if (daemonIdListIncludes(candidateDaemonIds, nodeDaemonId)) return;
52230
+ const getPeerStatus = components.getMeshPeerConnectionStatus;
52231
+ if (getPeerStatus) {
52232
+ const peerSnapshot = getPeerStatus(nodeDaemonId);
52233
+ if (!peerSnapshot || String(peerSnapshot.state) !== "connected") return;
52234
+ }
52235
+ for (const pendingEventArgs of pulls) {
52236
+ let events;
52237
+ try {
52238
+ events = await dispatchMeshCommand(nodeDaemonId, "get_pending_mesh_events", pendingEventArgs);
52239
+ } catch {
52240
+ break;
52241
+ }
52242
+ const list = extractPendingEvents(events).filter((e) => readNonEmptyString(e?.meshId) === meshId);
52243
+ for (const event of list) {
52244
+ const payload = buildForwardPayloadFromPending(event);
52245
+ if (!payload.event || !payload.meshId) continue;
52233
52246
  try {
52234
- events = await dispatchMeshCommand(nodeDaemonId, "get_pending_mesh_events", pendingEventArgs);
52247
+ handleMeshForwardEvent(components, payload);
52235
52248
  } catch {
52236
- break;
52237
- }
52238
- const list = extractPendingEvents(events).filter((e) => readNonEmptyString(e?.meshId) === meshId);
52239
- for (const event of list) {
52240
- const payload = buildForwardPayloadFromPending(event);
52241
- if (!payload.event || !payload.meshId) continue;
52242
- try {
52243
- handleMeshForwardEvent(components, payload);
52244
- } catch {
52245
- }
52246
52249
  }
52247
52250
  }
52248
- }));
52251
+ }
52249
52252
  }
52250
52253
  function unwrapReadChatPayload(raw) {
52251
52254
  let cursor = raw;
@@ -53145,7 +53148,7 @@ ${cleanBody}`;
53145
53148
  return false;
53146
53149
  }
53147
53150
  }
53148
- async function recoverStrandedAssignedDispatches(components, mesh, store) {
53151
+ async function recoverStrandedAssignedDispatches(components, mesh, store, localDaemonId, selfIds = []) {
53149
53152
  const meshId = mesh.id;
53150
53153
  const assigned = getQueue(meshId, { status: ["assigned"] });
53151
53154
  if (!assigned.length) return;
@@ -53169,6 +53172,24 @@ ${cleanBody}`;
53169
53172
  updateTaskStatus(meshId, row.id, status);
53170
53173
  continue;
53171
53174
  }
53175
+ const assignedNode = row.assignedNodeId ? mesh.nodes?.find((n) => meshNodeIdMatches(n, row.assignedNodeId)) : void 0;
53176
+ if (assignedNode?.daemonId) {
53177
+ try {
53178
+ await pullPendingEventsFromNode(
53179
+ components,
53180
+ meshId,
53181
+ assignedNode,
53182
+ localDaemonId,
53183
+ selfIds,
53184
+ selfIds.length > 0 ? selfIds.map((id) => ({ meshId, coordinatorDaemonId: id })) : [{ meshId }]
53185
+ );
53186
+ } catch {
53187
+ }
53188
+ if (store.taskDeliveryConsumed(meshId, row.id)) {
53189
+ deliveredUnconsumedUnknownStreak.delete(`${meshId}::${row.id}`);
53190
+ continue;
53191
+ }
53192
+ }
53172
53193
  const shortStreakKey = `${meshId}::${row.id}`;
53173
53194
  const verdict = row.assignedSessionId ? resolveSessionBusyVerdict(components, row.assignedSessionId) : "IDLE_CONFIRMED";
53174
53195
  if (verdict === "GENERATING") {
@@ -53427,7 +53448,7 @@ ${cleanBody}`;
53427
53448
  const selfIds = resolveCoordinatorSelfIds(mesh, drainDaemonIds);
53428
53449
  if (!daemonHostsMesh(mesh, selfIds)) continue;
53429
53450
  try {
53430
- await recoverStrandedAssignedDispatches(components, mesh, store);
53451
+ await recoverStrandedAssignedDispatches(components, mesh, store, localDaemonId, selfIds);
53431
53452
  } catch (e) {
53432
53453
  LOG2.warn("MeshReconcile", `Assigned-stranded watchdog failed for mesh ${mesh.id}: ${e?.message || e}`);
53433
53454
  }
@@ -79326,6 +79347,18 @@ ${body}
79326
79347
  // MESH_WORKER_STALL_REFIRE_COOLDOWN_MS between successive emissions across
79327
79348
  // anchor re-arms (the per-anchor guard only covers a single continuous stall).
79328
79349
  meshStallLastFiredAt = -1;
79350
+ // KIMI-MESH-COMPLETION-EMIT (axis 1): the native-source transcript progress
79351
+ // fingerprint (record count + source mtime) observed the LAST time the stall
79352
+ // watchdog checked a native-source provider (transcriptAuthority=provider — e.g.
79353
+ // kimi wire.jsonl). A pure-PTY native-source worker running a long, screen-quiet
79354
+ // tool (no viewport bytes for minutes) looks stalled by the lastOutputAt clock
79355
+ // even though its transcript file is still growing. Before firing the stall, we
79356
+ // compare the current transcript fingerprint against this snapshot; if the
79357
+ // transcript advanced, the "stall" is a false positive of PTY-render stasis, so
79358
+ // we re-arm the anchor instead of paging the coordinator (whose no_progress
79359
+ // handling can lead to the worker being stopped mid-work → completion never
79360
+ // emitted). null = not yet sampled for this session/anchor.
79361
+ meshStallNativeTranscriptSample = null;
79329
79362
  // FALSE-IDLE continuity epoch: monotonically bumped on EVERY entry into a busy
79330
79363
  // phase (→generating or →waiting_approval). The completedDebouncePending snapshots
79331
79364
  // this value at arm time (busyEpochAtArm); the flush guard requires it UNCHANGED
@@ -80135,6 +80168,14 @@ ${body}
80135
80168
  * once at completion). Reset on the next turn's start.
80136
80169
  */
80137
80170
  lastCompletionSummary = null;
80171
+ // KIMI-MESH-COMPLETION-EMIT (axis 2, double-emit guard): the (taskId, wall-clock)
80172
+ // of the most recent agent:generating_completed this instance emitted, stamped by
80173
+ // emitGeneratingCompleted. The pre-cleanup completion flush
80174
+ // (flushMeshCompletionBeforeCleanup, driven by cli-manager's exit monitor) reads
80175
+ // this to refuse a SECOND completion for a turn whose completion already fired —
80176
+ // so a worker that finished cleanly and is simply being auto-cleaned never emits a
80177
+ // duplicate. taskId '' covers an ad-hoc (no-task) turn. null = none emitted yet.
80178
+ lastEmittedCompletion = null;
80138
80179
  async enforceFreshSessionLaunchIfNeeded() {
80139
80180
  const scriptName = getForcedNewSessionScriptName(this.provider, this.launchMode);
80140
80181
  if (!scriptName) return;
@@ -80760,6 +80801,24 @@ ${body}
80760
80801
  const threshold = turnActive ? _CliProviderInstance.MESH_WORKER_STALL_TURN_THRESHOLD_MS : _CliProviderInstance.MESH_WORKER_STALL_IDLE_THRESHOLD_MS;
80761
80802
  const stalledMs = now - this.meshStallAnchorAt;
80762
80803
  if (stalledMs < threshold) return;
80804
+ const nativeSample = this.sampleNativeTranscriptProgress();
80805
+ if (nativeSample) {
80806
+ const prev = this.meshStallNativeTranscriptSample;
80807
+ const advanced = !prev || nativeSample.msgCount > prev.msgCount || nativeSample.sourceMtimeMs > prev.sourceMtimeMs;
80808
+ this.meshStallNativeTranscriptSample = nativeSample;
80809
+ if (advanced) {
80810
+ if (this.isMeshWorkerSession()) {
80811
+ traceMeshEventDrop(
80812
+ "mesh_worker_stall_transcript_advancing",
80813
+ this.meshTraceCtx("monitor:no_progress"),
80814
+ `msgCount=${nativeSample.msgCount} sourceMtime=${nativeSample.sourceMtimeMs} (PTY quiet ${Math.round(stalledMs / 1e3)}s but transcript advancing)`
80815
+ );
80816
+ }
80817
+ this.meshStallAnchorAt = now;
80818
+ this.meshStallEmittedForAnchor = false;
80819
+ return;
80820
+ }
80821
+ }
80763
80822
  this.meshStallEmittedForAnchor = true;
80764
80823
  if (this.meshStallLastFiredAt >= 0 && now - this.meshStallLastFiredAt < _CliProviderInstance.MESH_WORKER_STALL_REFIRE_COOLDOWN_MS) {
80765
80824
  return;
@@ -80796,6 +80855,99 @@ ${body}
80796
80855
  this.meshStallEmittedForAnchor = false;
80797
80856
  this.meshStallTurnActiveLast = void 0;
80798
80857
  this.meshStallLastFiredAt = -1;
80858
+ this.meshStallNativeTranscriptSample = null;
80859
+ }
80860
+ /**
80861
+ * KIMI-MESH-COMPLETION-EMIT (axis 1). For a native-source provider
80862
+ * (transcriptAuthority=provider — its authoritative history is an on-disk
80863
+ * transcript file, e.g. kimi's wire.jsonl), sample the transcript's current
80864
+ * progress fingerprint (record count + source-file mtime) WITHOUT parsing the
80865
+ * PTY. Used by the stall watchdog to distinguish "PTY render is quiet but the
80866
+ * worker is still doing long tool work (transcript growing)" from a genuine
80867
+ * wedge. Returns null for a pure-PTY provider (no native source) or when the
80868
+ * source cannot be resolved this tick — the caller then falls back to the
80869
+ * unchanged lastOutputAt-only judgment.
80870
+ *
80871
+ * Generalized on the provider's native-source flag, NOT a hardcoded provider
80872
+ * type, so every current and future pure-PTY long-tool native-source provider
80873
+ * benefits. Cheap enough for the stall path: it runs only at the stall threshold
80874
+ * (≥180s of PTY stasis), never on the routine 5s tick.
80875
+ */
80876
+ sampleNativeTranscriptProgress() {
80877
+ if (!isNativeSourceCanonicalHistory(this.provider?.nativeHistory)) return null;
80878
+ let messages = null;
80879
+ try {
80880
+ messages = this.readExternalCompletionMessages();
80881
+ } catch {
80882
+ return null;
80883
+ }
80884
+ const probe = this.lastExternalCompletionProbe;
80885
+ if (!probe) return null;
80886
+ return {
80887
+ msgCount: typeof probe.msgCount === "number" ? probe.msgCount : Array.isArray(messages) ? messages.length : 0,
80888
+ sourceMtimeMs: typeof probe.sourceMtimeMs === "number" ? probe.sourceMtimeMs : 0
80889
+ };
80890
+ }
80891
+ /**
80892
+ * KIMI-MESH-COMPLETION-EMIT (axis 2). Last-chance completion emit for a mesh
80893
+ * DELEGATED worker whose PTY has already exited (e.g. killed by a false stall)
80894
+ * and is about to be auto-cleaned (cli-manager.startCliExitMonitor →
80895
+ * removeInstance closes the event-emit window forever). If the worker actually
80896
+ * FINISHED its assigned turn — its authoritative native transcript holds a final
80897
+ * assistant message for the injected task — but the completion event never fired
80898
+ * (the stall-kill happened before the FSM's idle transition), emit it now so the
80899
+ * coordinator learns the task completed instead of waiting ~180s for the reconcile
80900
+ * transcript-poll to reclaim it.
80901
+ *
80902
+ * Scope & guards (must all hold to emit):
80903
+ * • mesh worker session only — a normal standalone session's ordinary exit is
80904
+ * never synthesized (isMeshWorkerSession()).
80905
+ * • DOUBLE-EMIT guard — refuse if this turn's completion already fired
80906
+ * (lastEmittedCompletion matches the current taskId). A worker that completed
80907
+ * cleanly and is merely being cleaned up never double-emits.
80908
+ * • evidence gate — reuse the same final-assistant/turn-scoped summary machinery
80909
+ * as the normal completion path (completionFinalSummary over the native
80910
+ * transcript). No in-turn assistant summary ⇒ no proof of completion ⇒ leave
80911
+ * the reclaim path to handle a genuinely-unfinished worker.
80912
+ *
80913
+ * Returns true when a synthetic completion was emitted, false otherwise. Safe to
80914
+ * call unconditionally from the cleanup path.
80915
+ */
80916
+ flushMeshCompletionBeforeCleanup() {
80917
+ if (!this.isMeshWorkerSession()) return false;
80918
+ const taskId = this.completingTurnTaskId();
80919
+ if (this.lastEmittedCompletion && this.lastEmittedCompletion.taskId === (taskId ?? "")) {
80920
+ return false;
80921
+ }
80922
+ if (!this.injectedTaskHasStartedGenerating()) return false;
80923
+ const turnStartedAt = typeof this.adapter?.currentTurnStartedAt === "number" ? this.adapter.currentTurnStartedAt : this.meshTaskInjectedAt || void 0;
80924
+ let parsedMessages;
80925
+ try {
80926
+ parsedMessages = this.adapter?.getScriptParsedStatus?.()?.messages;
80927
+ } catch {
80928
+ parsedMessages = void 0;
80929
+ }
80930
+ let finalSummary;
80931
+ try {
80932
+ finalSummary = this.completionFinalSummary(parsedMessages, turnStartedAt);
80933
+ } catch {
80934
+ finalSummary = void 0;
80935
+ }
80936
+ if (!finalSummary) return false;
80937
+ LOG2.warn("CLI", `[${this.type}] emitting pre-cleanup mesh completion for session ${this.instanceId} task=${taskId ?? "(none)"} \u2014 PTY exited before the completion event fired but the native transcript shows a finished turn; synthesizing completion so the coordinator is not left waiting for reclaim.`);
80938
+ if (this.isMeshWorkerSession()) {
80939
+ traceMeshEventStage("fired", this.meshTraceCtx(), "pre_cleanup_transcript_completion");
80940
+ }
80941
+ this.emitGeneratingCompleted({
80942
+ chatTitle: "",
80943
+ duration: void 0,
80944
+ timestamp: Date.now(),
80945
+ taskId,
80946
+ finalSummary,
80947
+ evidenceLevel: "transcript",
80948
+ completionDiagnostic: { source: "pre_cleanup_transcript_completion" }
80949
+ });
80950
+ return true;
80799
80951
  }
80800
80952
  /**
80801
80953
  * AUTOAPPROVE-FLAP-RECUR (Fix A+B): how long a busy blip / modal scroll-out may
@@ -81197,6 +81349,7 @@ ${body}
81197
81349
  if (summary) {
81198
81350
  this.lastCompletionSummary = { content: summary, receivedAt: opts.timestamp };
81199
81351
  }
81352
+ this.lastEmittedCompletion = { taskId: typeof opts.taskId === "string" ? opts.taskId : "", at: Date.now() };
81200
81353
  this.pushEvent({
81201
81354
  event: "agent:generating_completed",
81202
81355
  chatTitle: opts.chatTitle,
@@ -83980,6 +84133,15 @@ ${rawInput}` : rawInput;
83980
84133
  clearInterval(checkStopped);
83981
84134
  setTimeout(() => {
83982
84135
  if (this.adapters.has(key2)) {
84136
+ try {
84137
+ const inst = instanceManager?.getInstance(key2);
84138
+ if (typeof inst?.flushMeshCompletionBeforeCleanup === "function") {
84139
+ const emitted = inst.flushMeshCompletionBeforeCleanup();
84140
+ if (emitted) LOG2.info("CLI", `Emitted pre-cleanup mesh completion for ${cliType} session ${key2} before auto-clean`);
84141
+ }
84142
+ } catch (e) {
84143
+ LOG2.warn("CLI", `pre-cleanup mesh completion flush failed for ${key2}: ${e?.message || e}`);
84144
+ }
83983
84145
  this.adapters.delete(key2);
83984
84146
  this.deps.removeAgentTracking(key2);
83985
84147
  sessionRegistry?.unregisterByInstanceKey(key2);