@adhdev/daemon-core 0.9.82-rc.213 → 0.9.82-rc.215

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.mjs CHANGED
@@ -10397,7 +10397,25 @@ var init_cli_state_engine = __esm({
10397
10397
  "CLI",
10398
10398
  `[${this.provider.type}] settled diagnostics prompt=${JSON.stringify(this.currentTurnScope?.prompt || "").slice(0, 140)} status=${String(status || "")} parsedStatus=${String(parsedStatus || "")} parsedMsgCount=${parsedMessages.length} lastParsedAssistant=${JSON.stringify((lastParsedAssistant?.content || "").slice(0, 120)).slice(0, 160)} responseBuffer=${JSON.stringify((snap.responseBuffer || "").slice(0, 160)).slice(0, 220)} recentActivity=${recentInteractiveActivity}`
10399
10399
  );
10400
- const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && !(parsedStatus === "idle" && !!lastParsedAssistant);
10400
+ const hasFinalCurrentTurnAssistant = (() => {
10401
+ if (parsedStatus !== "idle") return false;
10402
+ const msgs = Array.isArray(parsedMessages) ? parsedMessages : [];
10403
+ let lastUserIdx = -1;
10404
+ for (let i = msgs.length - 1; i >= 0; i--) {
10405
+ if (msgs[i]?.role === "user") {
10406
+ lastUserIdx = i;
10407
+ break;
10408
+ }
10409
+ }
10410
+ const searchSlice = lastUserIdx >= 0 ? msgs.slice(lastUserIdx + 1) : msgs;
10411
+ return searchSlice.some((m) => {
10412
+ if (!m || m.role !== "assistant") return false;
10413
+ if (typeof m.content !== "string" || !m.content.trim()) return false;
10414
+ const kind = typeof m.kind === "string" && m.kind.trim() ? m.kind.trim() : "standard";
10415
+ return kind === "standard" && m.meta?.streaming !== true;
10416
+ });
10417
+ })();
10418
+ const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && !hasFinalCurrentTurnAssistant;
10401
10419
  if (shouldHoldGenerating) {
10402
10420
  this.applyHoldGenerating(ctx);
10403
10421
  return;
@@ -28892,6 +28910,12 @@ var SpecDriver = class {
28892
28910
  completionIdleKey = "";
28893
28911
  /** Previous screen lines — passed to evaluate() for `changed` condition detection. */
28894
28912
  prevScreenLines = [];
28913
+ /** Timestamp when idle was last committed (either direct or via idle_hold_ms).
28914
+ * Used to suppress immediate idle → busy re-entry from transient `changed`
28915
+ * condition blips (e.g. completion-marker counter "Completed for Xs" updating
28916
+ * every second, which triggers cursor_above:changed and bounces back to busy
28917
+ * right after an idle commit). */
28918
+ lastIdleCommittedAt = 0;
28895
28919
  /** Timestamp of the last PTY frame that changed the screen content.
28896
28920
  * Used by screen_active_hold_ms to suppress idle downshifts while
28897
28921
  * the terminal is still actively updating. */
@@ -28946,6 +28970,7 @@ var SpecDriver = class {
28946
28970
  this.adapter.resize(cmd.cols, cmd.rows);
28947
28971
  return;
28948
28972
  case "cancel":
28973
+ this.lastIdleCommittedAt = 0;
28949
28974
  this.adapter.send_keys("");
28950
28975
  return;
28951
28976
  case "shutdown":
@@ -29170,6 +29195,12 @@ var SpecDriver = class {
29170
29195
  if (screenIsActive && this.currentStateId === "busy" && evState.id === (this.spec.default_state ?? "idle")) {
29171
29196
  evState = this.lastBusyState ?? evState;
29172
29197
  }
29198
+ const idleReentryHoldMs = Math.max(screenActiveMs, 1500);
29199
+ if (evState.id === "busy" && this.currentStateId === (this.spec.default_state ?? "idle") && this.lastIdleCommittedAt > 0 && now - this.lastIdleCommittedAt < idleReentryHoldMs) {
29200
+ LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idle\u2192busy suppressed (idle_reentry_hold ageMs=${now - this.lastIdleCommittedAt} holdMs=${idleReentryHoldMs})`);
29201
+ this.scheduleBusyExpiry(idleReentryHoldMs - (now - this.lastIdleCommittedAt) + 50);
29202
+ return;
29203
+ }
29173
29204
  if (evState.id === "busy") {
29174
29205
  this.lastBusyAt = Date.now();
29175
29206
  this.lastBusyState = evState;
@@ -29205,6 +29236,7 @@ var SpecDriver = class {
29205
29236
  this.pendingIdleState = null;
29206
29237
  if (!committed) return;
29207
29238
  LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idleHold committed after ${idleHoldMs}ms`);
29239
+ this.lastIdleCommittedAt = Date.now();
29208
29240
  this.currentStateId = committed.id;
29209
29241
  this.currentEval = capturedEv;
29210
29242
  this.pushHistory(committed.id, committed.label, {
@@ -29247,6 +29279,9 @@ var SpecDriver = class {
29247
29279
  }
29248
29280
  }
29249
29281
  if (changed) {
29282
+ if (evState.id === (this.spec.default_state ?? "idle")) {
29283
+ this.lastIdleCommittedAt = Date.now();
29284
+ }
29250
29285
  this.currentStateId = evState.id;
29251
29286
  const matchedRules = extractMatchedRules(ev);
29252
29287
  let transitionReason;
@@ -29314,6 +29349,7 @@ var SpecDriver = class {
29314
29349
  this.pendingSends.push(text);
29315
29350
  return;
29316
29351
  }
29352
+ this.lastIdleCommittedAt = 0;
29317
29353
  this.actuallySendMessage(text);
29318
29354
  }
29319
29355
  actuallySendMessage(text) {
@@ -35464,6 +35500,35 @@ function extractToolOutputContent(payload) {
35464
35500
  }
35465
35501
  return "";
35466
35502
  }
35503
+ function hasAssistantStandardMessageSinceLastUser(records, content) {
35504
+ const normalized = content.trim();
35505
+ if (!normalized) return false;
35506
+ for (let i = records.length - 1; i >= 0; i--) {
35507
+ const record = records[i];
35508
+ if (record.kind === "session_start") continue;
35509
+ if (record.role === "user") return false;
35510
+ if (record.role === "assistant" && record.kind === "standard" && record.content.trim() === normalized) {
35511
+ return true;
35512
+ }
35513
+ }
35514
+ return false;
35515
+ }
35516
+ function pushAssistantStandardMessage(records, sessionId, receivedAt, content, workspace) {
35517
+ const text = content.trim();
35518
+ if (!text) return;
35519
+ if (hasAssistantStandardMessageSinceLastUser(records, text)) return;
35520
+ const msg = {
35521
+ ts: new Date(receivedAt).toISOString(),
35522
+ receivedAt,
35523
+ role: "assistant",
35524
+ content: text,
35525
+ kind: "standard",
35526
+ agent: "codex-cli",
35527
+ historySessionId: sessionId
35528
+ };
35529
+ if (workspace) msg.workspace = workspace;
35530
+ records.push(msg);
35531
+ }
35467
35532
  function readSessionMeta(filePath) {
35468
35533
  try {
35469
35534
  const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
@@ -35519,13 +35584,34 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
35519
35584
  }
35520
35585
  continue;
35521
35586
  }
35522
- if (type !== "response_item") continue;
35523
35587
  const payloadType = String(payload.type ?? "").trim();
35588
+ if (type === "event_msg") {
35589
+ if (payloadType === "task_complete") {
35590
+ pushAssistantStandardMessage(
35591
+ records,
35592
+ sessionId,
35593
+ receivedAt,
35594
+ flattenCodexContent(payload.last_agent_message),
35595
+ detectedWorkspace
35596
+ );
35597
+ } else if (payloadType === "agent_message" && String(payload.phase ?? "").trim() === "final_answer") {
35598
+ pushAssistantStandardMessage(
35599
+ records,
35600
+ sessionId,
35601
+ receivedAt,
35602
+ flattenCodexContent(payload.message),
35603
+ detectedWorkspace
35604
+ );
35605
+ }
35606
+ continue;
35607
+ }
35608
+ if (type !== "response_item") continue;
35524
35609
  if (payloadType === "message") {
35525
35610
  const role = String(payload.role ?? "").trim();
35526
35611
  if (role !== "user" && role !== "assistant") continue;
35527
35612
  const content = flattenCodexContent(payload.content);
35528
35613
  if (!content) continue;
35614
+ if (role === "assistant" && hasAssistantStandardMessageSinceLastUser(records, content)) continue;
35529
35615
  const msg = {
35530
35616
  ts: new Date(receivedAt).toISOString(),
35531
35617
  receivedAt,
@@ -39458,6 +39544,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
39458
39544
 
39459
39545
  // src/commands/router.ts
39460
39546
  init_mesh_work_queue();
39547
+ init_repo_mesh_types();
39461
39548
  import { homedir as homedir25, hostname as osHostname } from "os";
39462
39549
  import { basename as pathBasename, join as pathJoin, resolve as pathResolve2 } from "path";
39463
39550
  import * as fs22 from "fs";
@@ -42017,7 +42104,8 @@ var DaemonCommandRouter = class {
42017
42104
  ...result ? {
42018
42105
  success: result.success === true,
42019
42106
  result,
42020
- finalBranchConvergenceState: result.finalBranchConvergenceState
42107
+ finalBranchConvergenceState: result.finalBranchConvergenceState,
42108
+ ...result.blockerContext ? { blockerContext: result.blockerContext } : {}
42021
42109
  } : {}
42022
42110
  }
42023
42111
  });
@@ -42547,6 +42635,27 @@ var DaemonCommandRouter = class {
42547
42635
  finalBranchConvergenceState
42548
42636
  };
42549
42637
  }
42638
+ const requireApprovalForPush = mesh?.policy?.requireApprovalForPush ?? DEFAULT_MESH_POLICY.requireApprovalForPush;
42639
+ let pushResult;
42640
+ if (!requireApprovalForPush) {
42641
+ const pushStarted = Date.now();
42642
+ try {
42643
+ await execFileAsync3("git", ["push", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8" });
42644
+ pushResult = { pushed: true, remote: "origin", branch: baseBranch, durationMs: Date.now() - pushStarted };
42645
+ recordMeshRefineStage(refineStages, "push", "passed", pushStarted, pushResult);
42646
+ finalBranchConvergenceState.status = "merged_pushed";
42647
+ } catch (e) {
42648
+ pushResult = {
42649
+ pushed: false,
42650
+ remote: "origin",
42651
+ branch: baseBranch,
42652
+ error: e?.message || String(e),
42653
+ stderr: e?.stderr,
42654
+ durationMs: Date.now() - pushStarted
42655
+ };
42656
+ recordMeshRefineStage(refineStages, "push", "failed", pushStarted, pushResult);
42657
+ }
42658
+ }
42550
42659
  return {
42551
42660
  success: true,
42552
42661
  merged: true,
@@ -42560,7 +42669,13 @@ var DaemonCommandRouter = class {
42560
42669
  mergeResult,
42561
42670
  refineStages,
42562
42671
  ...ledgerError ? { ledgerError } : {},
42563
- finalBranchConvergenceState
42672
+ finalBranchConvergenceState,
42673
+ // Push outcome or readiness info for coordinator.
42674
+ ...pushResult ? { pushResult } : {
42675
+ pushReady: true,
42676
+ pushCommand: `git push origin ${baseBranch}`,
42677
+ pushNote: "requireApprovalForPush is enabled \u2014 run the push command or obtain user approval before pushing."
42678
+ }
42564
42679
  };
42565
42680
  } catch (e) {
42566
42681
  return { success: false, error: e.message, refineStages };
@@ -42578,9 +42693,46 @@ var DaemonCommandRouter = class {
42578
42693
  const refineCode = typeof result.code === "string" ? result.code : "";
42579
42694
  const refineTerminalKind = result.success === true ? "completed" : refineCode === "blocked_review" ? "blocked_review" : refineCode === "validation_failed" || refineCode === "validation_dependencies_missing" ? "validation_failed" : refineCode === "submodule_reachability_failed" ? "submodule_reachability_failed" : refineCode === "merge_failed" || refineCode === "patch_equivalence_failed" || refineCode === "needs_rebase" || refineCode === "needs_rebase_with_conflicts" ? "merge_failed" : refineCode === "cleanup_failed" ? "cleanup_failed" : "merge_failed";
42580
42695
  const isTerminalSuccess = refineTerminalKind === "completed";
42696
+ const blockerContext = isTerminalSuccess ? void 0 : (() => {
42697
+ const code = typeof result.code === "string" ? result.code : refineTerminalKind;
42698
+ const stage = refineTerminalKind === "validation_failed" ? "validation" : refineTerminalKind === "submodule_reachability_failed" ? "submodule_reachability" : refineCode === "patch_equivalence_failed" ? "patch_equivalence" : refineCode === "needs_rebase" || refineCode === "needs_rebase_with_conflicts" ? "patch_equivalence" : refineTerminalKind === "merge_failed" ? "merge" : refineTerminalKind === "cleanup_failed" ? "cleanup" : "unknown";
42699
+ const ctx = {
42700
+ stage,
42701
+ reason: code,
42702
+ terminalKind: refineTerminalKind
42703
+ };
42704
+ if (typeof result.error === "string") ctx.error = result.error;
42705
+ if (typeof result.blockedReason === "string") ctx.blockedReason = result.blockedReason;
42706
+ if (stage === "patch_equivalence" && result.patchEquivalence) {
42707
+ const pe = result.patchEquivalence;
42708
+ ctx.details = {
42709
+ expectedPatchId: pe.expectedPatchId,
42710
+ actualPatchId: pe.actualPatchId,
42711
+ status: pe.status,
42712
+ actionableHint: pe.actionableHint,
42713
+ error: pe.error
42714
+ };
42715
+ }
42716
+ if (stage === "submodule_reachability" && Array.isArray(result.unreachableSubmoduleCommits)) {
42717
+ ctx.details = {
42718
+ unreachableCount: result.unreachableSubmoduleCommits.length,
42719
+ paths: result.unreachableSubmoduleCommits.map((e) => e.path),
42720
+ autoPublishAllowed: result.unreachableSubmoduleCommits[0]?.autoPublishAllowed
42721
+ };
42722
+ }
42723
+ if (stage === "validation" && result.validationSummary) {
42724
+ const vs = result.validationSummary;
42725
+ ctx.details = {
42726
+ failureCode: vs.failureCode,
42727
+ commandsRun: Array.isArray(vs.commandsRun) ? vs.commandsRun.length : void 0
42728
+ };
42729
+ }
42730
+ return ctx;
42731
+ })();
42581
42732
  const normalizedResult = {
42582
42733
  ...result,
42583
42734
  terminalKind: refineTerminalKind,
42735
+ ...blockerContext ? { blockerContext } : {},
42584
42736
  ...result.nextStep === void 0 && !isTerminalSuccess ? {
42585
42737
  nextStep: refineTerminalKind === "blocked_review" ? "Request user review/approval before attempting to merge again." : refineTerminalKind === "validation_failed" ? "Fix failing tests or configure validation.bootstrapCommands and retry mesh_refine_node." : refineTerminalKind === "submodule_reachability_failed" ? "Push unreachable submodule commits to origin/main, then retry mesh_refine_node." : refineTerminalKind === "merge_failed" ? "Resolve merge conflicts or patch equivalence issues, then retry mesh_refine_node." : refineTerminalKind === "cleanup_failed" ? "Manually remove the worktree and retry or use mesh_remove_node." : "Inspect refineStages for the failing stage and retry."
42586
42738
  } : {}