@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.js CHANGED
@@ -10401,7 +10401,25 @@ var init_cli_state_engine = __esm({
10401
10401
  "CLI",
10402
10402
  `[${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}`
10403
10403
  );
10404
- const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && !(parsedStatus === "idle" && !!lastParsedAssistant);
10404
+ const hasFinalCurrentTurnAssistant = (() => {
10405
+ if (parsedStatus !== "idle") return false;
10406
+ const msgs = Array.isArray(parsedMessages) ? parsedMessages : [];
10407
+ let lastUserIdx = -1;
10408
+ for (let i = msgs.length - 1; i >= 0; i--) {
10409
+ if (msgs[i]?.role === "user") {
10410
+ lastUserIdx = i;
10411
+ break;
10412
+ }
10413
+ }
10414
+ const searchSlice = lastUserIdx >= 0 ? msgs.slice(lastUserIdx + 1) : msgs;
10415
+ return searchSlice.some((m) => {
10416
+ if (!m || m.role !== "assistant") return false;
10417
+ if (typeof m.content !== "string" || !m.content.trim()) return false;
10418
+ const kind = typeof m.kind === "string" && m.kind.trim() ? m.kind.trim() : "standard";
10419
+ return kind === "standard" && m.meta?.streaming !== true;
10420
+ });
10421
+ })();
10422
+ const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && !hasFinalCurrentTurnAssistant;
10405
10423
  if (shouldHoldGenerating) {
10406
10424
  this.applyHoldGenerating(ctx);
10407
10425
  return;
@@ -29225,6 +29243,12 @@ var SpecDriver = class {
29225
29243
  completionIdleKey = "";
29226
29244
  /** Previous screen lines — passed to evaluate() for `changed` condition detection. */
29227
29245
  prevScreenLines = [];
29246
+ /** Timestamp when idle was last committed (either direct or via idle_hold_ms).
29247
+ * Used to suppress immediate idle → busy re-entry from transient `changed`
29248
+ * condition blips (e.g. completion-marker counter "Completed for Xs" updating
29249
+ * every second, which triggers cursor_above:changed and bounces back to busy
29250
+ * right after an idle commit). */
29251
+ lastIdleCommittedAt = 0;
29228
29252
  /** Timestamp of the last PTY frame that changed the screen content.
29229
29253
  * Used by screen_active_hold_ms to suppress idle downshifts while
29230
29254
  * the terminal is still actively updating. */
@@ -29279,6 +29303,7 @@ var SpecDriver = class {
29279
29303
  this.adapter.resize(cmd.cols, cmd.rows);
29280
29304
  return;
29281
29305
  case "cancel":
29306
+ this.lastIdleCommittedAt = 0;
29282
29307
  this.adapter.send_keys("");
29283
29308
  return;
29284
29309
  case "shutdown":
@@ -29503,6 +29528,12 @@ var SpecDriver = class {
29503
29528
  if (screenIsActive && this.currentStateId === "busy" && evState.id === (this.spec.default_state ?? "idle")) {
29504
29529
  evState = this.lastBusyState ?? evState;
29505
29530
  }
29531
+ const idleReentryHoldMs = Math.max(screenActiveMs, 1500);
29532
+ if (evState.id === "busy" && this.currentStateId === (this.spec.default_state ?? "idle") && this.lastIdleCommittedAt > 0 && now - this.lastIdleCommittedAt < idleReentryHoldMs) {
29533
+ LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idle\u2192busy suppressed (idle_reentry_hold ageMs=${now - this.lastIdleCommittedAt} holdMs=${idleReentryHoldMs})`);
29534
+ this.scheduleBusyExpiry(idleReentryHoldMs - (now - this.lastIdleCommittedAt) + 50);
29535
+ return;
29536
+ }
29506
29537
  if (evState.id === "busy") {
29507
29538
  this.lastBusyAt = Date.now();
29508
29539
  this.lastBusyState = evState;
@@ -29538,6 +29569,7 @@ var SpecDriver = class {
29538
29569
  this.pendingIdleState = null;
29539
29570
  if (!committed) return;
29540
29571
  LOG.debug("SpecDriver", `[${this.opts.specPath.split("/").slice(-3).join("/")}] idleHold committed after ${idleHoldMs}ms`);
29572
+ this.lastIdleCommittedAt = Date.now();
29541
29573
  this.currentStateId = committed.id;
29542
29574
  this.currentEval = capturedEv;
29543
29575
  this.pushHistory(committed.id, committed.label, {
@@ -29580,6 +29612,9 @@ var SpecDriver = class {
29580
29612
  }
29581
29613
  }
29582
29614
  if (changed) {
29615
+ if (evState.id === (this.spec.default_state ?? "idle")) {
29616
+ this.lastIdleCommittedAt = Date.now();
29617
+ }
29583
29618
  this.currentStateId = evState.id;
29584
29619
  const matchedRules = extractMatchedRules(ev);
29585
29620
  let transitionReason;
@@ -29647,6 +29682,7 @@ var SpecDriver = class {
29647
29682
  this.pendingSends.push(text);
29648
29683
  return;
29649
29684
  }
29685
+ this.lastIdleCommittedAt = 0;
29650
29686
  this.actuallySendMessage(text);
29651
29687
  }
29652
29688
  actuallySendMessage(text) {
@@ -35792,6 +35828,35 @@ function extractToolOutputContent(payload) {
35792
35828
  }
35793
35829
  return "";
35794
35830
  }
35831
+ function hasAssistantStandardMessageSinceLastUser(records, content) {
35832
+ const normalized = content.trim();
35833
+ if (!normalized) return false;
35834
+ for (let i = records.length - 1; i >= 0; i--) {
35835
+ const record = records[i];
35836
+ if (record.kind === "session_start") continue;
35837
+ if (record.role === "user") return false;
35838
+ if (record.role === "assistant" && record.kind === "standard" && record.content.trim() === normalized) {
35839
+ return true;
35840
+ }
35841
+ }
35842
+ return false;
35843
+ }
35844
+ function pushAssistantStandardMessage(records, sessionId, receivedAt, content, workspace) {
35845
+ const text = content.trim();
35846
+ if (!text) return;
35847
+ if (hasAssistantStandardMessageSinceLastUser(records, text)) return;
35848
+ const msg = {
35849
+ ts: new Date(receivedAt).toISOString(),
35850
+ receivedAt,
35851
+ role: "assistant",
35852
+ content: text,
35853
+ kind: "standard",
35854
+ agent: "codex-cli",
35855
+ historySessionId: sessionId
35856
+ };
35857
+ if (workspace) msg.workspace = workspace;
35858
+ records.push(msg);
35859
+ }
35795
35860
  function readSessionMeta(filePath) {
35796
35861
  try {
35797
35862
  const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
@@ -35847,13 +35912,34 @@ function parseSessionFile(filePath, sessionId, workspaceFallback) {
35847
35912
  }
35848
35913
  continue;
35849
35914
  }
35850
- if (type !== "response_item") continue;
35851
35915
  const payloadType = String(payload.type ?? "").trim();
35916
+ if (type === "event_msg") {
35917
+ if (payloadType === "task_complete") {
35918
+ pushAssistantStandardMessage(
35919
+ records,
35920
+ sessionId,
35921
+ receivedAt,
35922
+ flattenCodexContent(payload.last_agent_message),
35923
+ detectedWorkspace
35924
+ );
35925
+ } else if (payloadType === "agent_message" && String(payload.phase ?? "").trim() === "final_answer") {
35926
+ pushAssistantStandardMessage(
35927
+ records,
35928
+ sessionId,
35929
+ receivedAt,
35930
+ flattenCodexContent(payload.message),
35931
+ detectedWorkspace
35932
+ );
35933
+ }
35934
+ continue;
35935
+ }
35936
+ if (type !== "response_item") continue;
35852
35937
  if (payloadType === "message") {
35853
35938
  const role = String(payload.role ?? "").trim();
35854
35939
  if (role !== "user" && role !== "assistant") continue;
35855
35940
  const content = flattenCodexContent(payload.content);
35856
35941
  if (!content) continue;
35942
+ if (role === "assistant" && hasAssistantStandardMessageSinceLastUser(records, content)) continue;
35857
35943
  const msg = {
35858
35944
  ts: new Date(receivedAt).toISOString(),
35859
35945
  receivedAt,
@@ -39786,6 +39872,7 @@ async function maybeRunDaemonUpgradeHelperFromEnv() {
39786
39872
 
39787
39873
  // src/commands/router.ts
39788
39874
  init_mesh_work_queue();
39875
+ init_repo_mesh_types();
39789
39876
  var import_os3 = require("os");
39790
39877
  var import_path10 = require("path");
39791
39878
  var fs22 = __toESM(require("fs"));
@@ -42345,7 +42432,8 @@ var DaemonCommandRouter = class {
42345
42432
  ...result ? {
42346
42433
  success: result.success === true,
42347
42434
  result,
42348
- finalBranchConvergenceState: result.finalBranchConvergenceState
42435
+ finalBranchConvergenceState: result.finalBranchConvergenceState,
42436
+ ...result.blockerContext ? { blockerContext: result.blockerContext } : {}
42349
42437
  } : {}
42350
42438
  }
42351
42439
  });
@@ -42875,6 +42963,27 @@ var DaemonCommandRouter = class {
42875
42963
  finalBranchConvergenceState
42876
42964
  };
42877
42965
  }
42966
+ const requireApprovalForPush = mesh?.policy?.requireApprovalForPush ?? DEFAULT_MESH_POLICY.requireApprovalForPush;
42967
+ let pushResult;
42968
+ if (!requireApprovalForPush) {
42969
+ const pushStarted = Date.now();
42970
+ try {
42971
+ await execFileAsync3("git", ["push", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8" });
42972
+ pushResult = { pushed: true, remote: "origin", branch: baseBranch, durationMs: Date.now() - pushStarted };
42973
+ recordMeshRefineStage(refineStages, "push", "passed", pushStarted, pushResult);
42974
+ finalBranchConvergenceState.status = "merged_pushed";
42975
+ } catch (e) {
42976
+ pushResult = {
42977
+ pushed: false,
42978
+ remote: "origin",
42979
+ branch: baseBranch,
42980
+ error: e?.message || String(e),
42981
+ stderr: e?.stderr,
42982
+ durationMs: Date.now() - pushStarted
42983
+ };
42984
+ recordMeshRefineStage(refineStages, "push", "failed", pushStarted, pushResult);
42985
+ }
42986
+ }
42878
42987
  return {
42879
42988
  success: true,
42880
42989
  merged: true,
@@ -42888,7 +42997,13 @@ var DaemonCommandRouter = class {
42888
42997
  mergeResult,
42889
42998
  refineStages,
42890
42999
  ...ledgerError ? { ledgerError } : {},
42891
- finalBranchConvergenceState
43000
+ finalBranchConvergenceState,
43001
+ // Push outcome or readiness info for coordinator.
43002
+ ...pushResult ? { pushResult } : {
43003
+ pushReady: true,
43004
+ pushCommand: `git push origin ${baseBranch}`,
43005
+ pushNote: "requireApprovalForPush is enabled \u2014 run the push command or obtain user approval before pushing."
43006
+ }
42892
43007
  };
42893
43008
  } catch (e) {
42894
43009
  return { success: false, error: e.message, refineStages };
@@ -42906,9 +43021,46 @@ var DaemonCommandRouter = class {
42906
43021
  const refineCode = typeof result.code === "string" ? result.code : "";
42907
43022
  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";
42908
43023
  const isTerminalSuccess = refineTerminalKind === "completed";
43024
+ const blockerContext = isTerminalSuccess ? void 0 : (() => {
43025
+ const code = typeof result.code === "string" ? result.code : refineTerminalKind;
43026
+ 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";
43027
+ const ctx = {
43028
+ stage,
43029
+ reason: code,
43030
+ terminalKind: refineTerminalKind
43031
+ };
43032
+ if (typeof result.error === "string") ctx.error = result.error;
43033
+ if (typeof result.blockedReason === "string") ctx.blockedReason = result.blockedReason;
43034
+ if (stage === "patch_equivalence" && result.patchEquivalence) {
43035
+ const pe = result.patchEquivalence;
43036
+ ctx.details = {
43037
+ expectedPatchId: pe.expectedPatchId,
43038
+ actualPatchId: pe.actualPatchId,
43039
+ status: pe.status,
43040
+ actionableHint: pe.actionableHint,
43041
+ error: pe.error
43042
+ };
43043
+ }
43044
+ if (stage === "submodule_reachability" && Array.isArray(result.unreachableSubmoduleCommits)) {
43045
+ ctx.details = {
43046
+ unreachableCount: result.unreachableSubmoduleCommits.length,
43047
+ paths: result.unreachableSubmoduleCommits.map((e) => e.path),
43048
+ autoPublishAllowed: result.unreachableSubmoduleCommits[0]?.autoPublishAllowed
43049
+ };
43050
+ }
43051
+ if (stage === "validation" && result.validationSummary) {
43052
+ const vs = result.validationSummary;
43053
+ ctx.details = {
43054
+ failureCode: vs.failureCode,
43055
+ commandsRun: Array.isArray(vs.commandsRun) ? vs.commandsRun.length : void 0
43056
+ };
43057
+ }
43058
+ return ctx;
43059
+ })();
42909
43060
  const normalizedResult = {
42910
43061
  ...result,
42911
43062
  terminalKind: refineTerminalKind,
43063
+ ...blockerContext ? { blockerContext } : {},
42912
43064
  ...result.nextStep === void 0 && !isTerminalSuccess ? {
42913
43065
  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."
42914
43066
  } : {}