@adhdev/daemon-standalone 0.9.82-rc.212 → 0.9.82-rc.214

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
@@ -29749,6 +29749,7 @@ var require_dist3 = __commonJS({
29749
29749
  maxParallelTasks: 2,
29750
29750
  spawnedSessionVisibility: "visible",
29751
29751
  sessionCleanupOnNodeRemove: "preserve",
29752
+ autoFastForward: { enabled: true },
29752
29753
  maxTaskRetries: 1
29753
29754
  };
29754
29755
  }
@@ -31074,7 +31075,17 @@ ${error48.message || ""}`;
31074
31075
  return identity;
31075
31076
  }
31076
31077
  function mergeMeshPolicy(base, patch) {
31077
- const policy = { ...DEFAULT_MESH_POLICY, ...base || {}, ...patch || {} };
31078
+ const autoFastForward = normalizeAutoFastForwardPolicy({
31079
+ ...DEFAULT_MESH_POLICY.autoFastForward,
31080
+ ...base?.autoFastForward && typeof base.autoFastForward === "object" ? base.autoFastForward : {},
31081
+ ...patch?.autoFastForward && typeof patch.autoFastForward === "object" ? patch.autoFastForward : {}
31082
+ });
31083
+ const policy = {
31084
+ ...DEFAULT_MESH_POLICY,
31085
+ ...base || {},
31086
+ ...patch || {},
31087
+ autoFastForward
31088
+ };
31078
31089
  if (!["block", "warn", "checkpoint_then_continue"].includes(policy.dirtyWorkspaceBehavior)) {
31079
31090
  policy.dirtyWorkspaceBehavior = "warn";
31080
31091
  }
@@ -31089,6 +31100,15 @@ ${error48.message || ""}`;
31089
31100
  }
31090
31101
  return policy;
31091
31102
  }
31103
+ function normalizeAutoFastForwardPolicy(value) {
31104
+ const record2 = value && typeof value === "object" && !Array.isArray(value) ? value : {};
31105
+ const maxBehind = Number(record2.maxBehind);
31106
+ return {
31107
+ enabled: record2.enabled !== false,
31108
+ ...Number.isFinite(maxBehind) && maxBehind >= 0 ? { maxBehind: Math.floor(maxBehind) } : {},
31109
+ requireCleanSubmodules: record2.requireCleanSubmodules !== false
31110
+ };
31111
+ }
31092
31112
  function listMeshes() {
31093
31113
  return loadMeshConfig().meshes;
31094
31114
  }
@@ -36482,6 +36502,34 @@ Next step: ${nextStep}`;
36482
36502
  function isDirtyNode(node) {
36483
36503
  return node?.health === "dirty" || node?.git?.dirty === true;
36484
36504
  }
36505
+ function resolveAutoFastForwardPolicy(mesh) {
36506
+ const record2 = mesh?.policy?.autoFastForward && typeof mesh.policy.autoFastForward === "object" && !Array.isArray(mesh.policy.autoFastForward) ? mesh.policy.autoFastForward : {};
36507
+ const maxBehind = Number(record2.maxBehind);
36508
+ return {
36509
+ enabled: record2.enabled !== false,
36510
+ ...Number.isFinite(maxBehind) && maxBehind >= 0 ? { maxBehind: Math.floor(maxBehind) } : {},
36511
+ requireCleanSubmodules: record2.requireCleanSubmodules !== false
36512
+ };
36513
+ }
36514
+ function sessionStateLooksActive(state) {
36515
+ const status = readNonEmptyString2(state?.status).toLowerCase();
36516
+ const chatStatus = readNonEmptyString2(state?.activeChat?.status).toLowerCase();
36517
+ const active = /* @__PURE__ */ new Set(["generating", "streaming", "long_generating", "working", "starting", "waiting_approval"]);
36518
+ return active.has(status) || active.has(chatStatus);
36519
+ }
36520
+ function nodeHasActiveMeshWork(components, meshId, nodeId, currentSessionId) {
36521
+ if (nodeHasActiveAssignment(meshId, nodeId)) return true;
36522
+ return components.instanceManager.getByCategory("cli").some((inst) => {
36523
+ const state = inst.getState();
36524
+ const settings = state.settings || {};
36525
+ if (readNonEmptyString2(settings.meshNodeFor) !== meshId) return false;
36526
+ const instNodeId = readNonEmptyString2(settings.meshNodeId) || readNonEmptyString2(settings.nodeId);
36527
+ if (instNodeId !== nodeId) return false;
36528
+ const sessionId = readNonEmptyString2(state.instanceId);
36529
+ if (currentSessionId && sessionId === currentSessionId && isIdleSessionState(state)) return false;
36530
+ return sessionStateLooksActive(state);
36531
+ });
36532
+ }
36485
36533
  function isLaunchableNode(node) {
36486
36534
  if (!node || node.status === "disabled" || node.status === "removed") return false;
36487
36535
  const health = readNonEmptyString2(node.health).toLowerCase();
@@ -36810,6 +36858,9 @@ Next step: ${nextStep}`;
36810
36858
  const workspace = readNonEmptyString2(node?.workspace);
36811
36859
  if (!workspace) return;
36812
36860
  if (!(0, import_fs10.existsSync)(workspace)) return;
36861
+ const policy = resolveAutoFastForwardPolicy(mesh);
36862
+ if (!policy.enabled) return;
36863
+ if (nodeHasActiveMeshWork(components, args.meshId, args.nodeId, args.sessionId)) return;
36813
36864
  const throttleKey = `${args.meshId}:${args.nodeId}`;
36814
36865
  const now = Date.now();
36815
36866
  const lastAttempt = idleAutoFastForwardLastAttempt.get(throttleKey) || 0;
@@ -36828,6 +36879,12 @@ Next step: ${nextStep}`;
36828
36879
  trigger: "idle_auto"
36829
36880
  });
36830
36881
  if (!dryRun || dryRun.code !== "fast_forward_available" || dryRun.allowed !== true) return;
36882
+ const behind = Number(dryRun.current?.behind);
36883
+ if (policy.maxBehind !== void 0 && Number.isFinite(behind) && behind > policy.maxBehind) return;
36884
+ if (policy.requireCleanSubmodules) {
36885
+ const submodules = Array.isArray(dryRun.current?.submodules) ? dryRun.current.submodules : [];
36886
+ if (submodules.some((submodule) => submodule?.dirty || submodule?.outOfSync || submodule?.error)) return;
36887
+ }
36831
36888
  await fastForwardMeshNode({
36832
36889
  meshId: args.meshId,
36833
36890
  nodeId: args.nodeId,
@@ -40109,7 +40166,25 @@ ${cont}` : cont;
40109
40166
  "CLI",
40110
40167
  `[${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}`
40111
40168
  );
40112
- const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && !(parsedStatus === "idle" && !!lastParsedAssistant);
40169
+ const hasFinalCurrentTurnAssistant = (() => {
40170
+ if (parsedStatus !== "idle") return false;
40171
+ const msgs = Array.isArray(parsedMessages) ? parsedMessages : [];
40172
+ let lastUserIdx = -1;
40173
+ for (let i = msgs.length - 1; i >= 0; i--) {
40174
+ if (msgs[i]?.role === "user") {
40175
+ lastUserIdx = i;
40176
+ break;
40177
+ }
40178
+ }
40179
+ const searchSlice = lastUserIdx >= 0 ? msgs.slice(lastUserIdx + 1) : msgs;
40180
+ return searchSlice.some((m) => {
40181
+ if (!m || m.role !== "assistant") return false;
40182
+ if (typeof m.content !== "string" || !m.content.trim()) return false;
40183
+ const kind = typeof m.kind === "string" && m.kind.trim() ? m.kind.trim() : "standard";
40184
+ return kind === "standard" && m.meta?.streaming !== true;
40185
+ });
40186
+ })();
40187
+ const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && !hasFinalCurrentTurnAssistant;
40113
40188
  if (shouldHoldGenerating) {
40114
40189
  this.applyHoldGenerating(ctx);
40115
40190
  return;
@@ -65305,6 +65380,35 @@ Run 'adhdev doctor' for detailed diagnostics.`
65305
65380
  }
65306
65381
  return "";
65307
65382
  }
65383
+ function hasAssistantStandardMessageSinceLastUser(records, content) {
65384
+ const normalized = content.trim();
65385
+ if (!normalized) return false;
65386
+ for (let i = records.length - 1; i >= 0; i--) {
65387
+ const record2 = records[i];
65388
+ if (record2.kind === "session_start") continue;
65389
+ if (record2.role === "user") return false;
65390
+ if (record2.role === "assistant" && record2.kind === "standard" && record2.content.trim() === normalized) {
65391
+ return true;
65392
+ }
65393
+ }
65394
+ return false;
65395
+ }
65396
+ function pushAssistantStandardMessage(records, sessionId, receivedAt, content, workspace) {
65397
+ const text = content.trim();
65398
+ if (!text) return;
65399
+ if (hasAssistantStandardMessageSinceLastUser(records, text)) return;
65400
+ const msg = {
65401
+ ts: new Date(receivedAt).toISOString(),
65402
+ receivedAt,
65403
+ role: "assistant",
65404
+ content: text,
65405
+ kind: "standard",
65406
+ agent: "codex-cli",
65407
+ historySessionId: sessionId
65408
+ };
65409
+ if (workspace) msg.workspace = workspace;
65410
+ records.push(msg);
65411
+ }
65308
65412
  function readSessionMeta(filePath) {
65309
65413
  try {
65310
65414
  const firstLine = fs15.readFileSync(filePath, "utf-8").split("\n").find(Boolean);
@@ -65360,13 +65464,34 @@ Run 'adhdev doctor' for detailed diagnostics.`
65360
65464
  }
65361
65465
  continue;
65362
65466
  }
65363
- if (type !== "response_item") continue;
65364
65467
  const payloadType = String(payload.type ?? "").trim();
65468
+ if (type === "event_msg") {
65469
+ if (payloadType === "task_complete") {
65470
+ pushAssistantStandardMessage(
65471
+ records,
65472
+ sessionId,
65473
+ receivedAt,
65474
+ flattenCodexContent(payload.last_agent_message),
65475
+ detectedWorkspace
65476
+ );
65477
+ } else if (payloadType === "agent_message" && String(payload.phase ?? "").trim() === "final_answer") {
65478
+ pushAssistantStandardMessage(
65479
+ records,
65480
+ sessionId,
65481
+ receivedAt,
65482
+ flattenCodexContent(payload.message),
65483
+ detectedWorkspace
65484
+ );
65485
+ }
65486
+ continue;
65487
+ }
65488
+ if (type !== "response_item") continue;
65365
65489
  if (payloadType === "message") {
65366
65490
  const role = String(payload.role ?? "").trim();
65367
65491
  if (role !== "user" && role !== "assistant") continue;
65368
65492
  const content = flattenCodexContent(payload.content);
65369
65493
  if (!content) continue;
65494
+ if (role === "assistant" && hasAssistantStandardMessageSinceLastUser(records, content)) continue;
65370
65495
  const msg = {
65371
65496
  ts: new Date(receivedAt).toISOString(),
65372
65497
  receivedAt,
@@ -69271,6 +69396,7 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
69271
69396
  }
69272
69397
  }
69273
69398
  init_mesh_work_queue();
69399
+ init_repo_mesh_types();
69274
69400
  var import_os3 = require("os");
69275
69401
  var import_path10 = require("path");
69276
69402
  var fs222 = __toESM2(require("fs"));
@@ -69763,6 +69889,23 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
69763
69889
  }
69764
69890
  return { dirty, outOfSync };
69765
69891
  }
69892
+ function isInlineMeshAutoFastForwardEligible(git) {
69893
+ if (!git) return false;
69894
+ if (readBooleanValue(git.isGitRepo) !== true) return false;
69895
+ if (!readStringValue(git.branch)) return false;
69896
+ if (!readStringValue(git.upstream)) return false;
69897
+ const upstreamStatus = readStringValue(git.upstreamStatus, git.upstream_status);
69898
+ if (upstreamStatus !== "fresh") return false;
69899
+ if ((readNumberValue(git.ahead) ?? 0) !== 0) return false;
69900
+ if ((readNumberValue(git.behind) ?? 0) <= 0) return false;
69901
+ const hasConflicts = readBooleanValue(git.hasConflicts) ?? (Array.isArray(git.conflictFiles) && git.conflictFiles.length > 0);
69902
+ if (hasConflicts) return false;
69903
+ if ((readNumberValue(git.stashCount, git.stash_count) ?? 0) > 0) return false;
69904
+ const submoduleDrift = getGitSubmoduleDriftState(git);
69905
+ if (submoduleDrift.dirty || submoduleDrift.outOfSync) return false;
69906
+ const dirty = readBooleanValue(git.dirty) ?? countGitWorktreeChanges(git) > 0;
69907
+ return dirty !== true && countGitWorktreeChanges(git) === 0;
69908
+ }
69766
69909
  function deriveMeshNodeHealthFromGit(git) {
69767
69910
  if (!git || readBooleanValue(git.isGitRepo) === false) return "degraded";
69768
69911
  const branch = readStringValue(git.branch);
@@ -69892,6 +70035,12 @@ ${formatManifestValidationIssues2(validation2.issues)}`);
69892
70035
  status.isDirty = uncommittedChanges > 0;
69893
70036
  status.uncommittedChanges = uncommittedChanges;
69894
70037
  status.branchConvergence = buildInlineMeshBranchConvergence({ mesh, node, status });
70038
+ status.autoFastForwardEligible = isInlineMeshAutoFastForwardEligible(git);
70039
+ if (status.autoFastForwardEligible) {
70040
+ status.suggestedAction = "auto_fast_forward";
70041
+ } else {
70042
+ delete status.suggestedAction;
70043
+ }
69895
70044
  }
69896
70045
  function summarizeInlineMeshBranchConvergence(nodes) {
69897
70046
  const followUps = nodes.filter((node) => readObjectRecord(node.branchConvergence).needsConvergence === true).map((node) => {
@@ -71807,7 +71956,8 @@ ${e?.stderr || ""}`
71807
71956
  ...result ? {
71808
71957
  success: result.success === true,
71809
71958
  result,
71810
- finalBranchConvergenceState: result.finalBranchConvergenceState
71959
+ finalBranchConvergenceState: result.finalBranchConvergenceState,
71960
+ ...result.blockerContext ? { blockerContext: result.blockerContext } : {}
71811
71961
  } : {}
71812
71962
  }
71813
71963
  });
@@ -72337,6 +72487,27 @@ ${e?.stderr || ""}`
72337
72487
  finalBranchConvergenceState
72338
72488
  };
72339
72489
  }
72490
+ const requireApprovalForPush = mesh?.policy?.requireApprovalForPush ?? DEFAULT_MESH_POLICY.requireApprovalForPush;
72491
+ let pushResult;
72492
+ if (!requireApprovalForPush) {
72493
+ const pushStarted = Date.now();
72494
+ try {
72495
+ await execFileAsync3("git", ["push", "origin", baseBranch], { cwd: repoRoot, encoding: "utf8" });
72496
+ pushResult = { pushed: true, remote: "origin", branch: baseBranch, durationMs: Date.now() - pushStarted };
72497
+ recordMeshRefineStage(refineStages, "push", "passed", pushStarted, pushResult);
72498
+ finalBranchConvergenceState.status = "merged_pushed";
72499
+ } catch (e) {
72500
+ pushResult = {
72501
+ pushed: false,
72502
+ remote: "origin",
72503
+ branch: baseBranch,
72504
+ error: e?.message || String(e),
72505
+ stderr: e?.stderr,
72506
+ durationMs: Date.now() - pushStarted
72507
+ };
72508
+ recordMeshRefineStage(refineStages, "push", "failed", pushStarted, pushResult);
72509
+ }
72510
+ }
72340
72511
  return {
72341
72512
  success: true,
72342
72513
  merged: true,
@@ -72350,7 +72521,13 @@ ${e?.stderr || ""}`
72350
72521
  mergeResult,
72351
72522
  refineStages,
72352
72523
  ...ledgerError ? { ledgerError } : {},
72353
- finalBranchConvergenceState
72524
+ finalBranchConvergenceState,
72525
+ // Push outcome or readiness info for coordinator.
72526
+ ...pushResult ? { pushResult } : {
72527
+ pushReady: true,
72528
+ pushCommand: `git push origin ${baseBranch}`,
72529
+ pushNote: "requireApprovalForPush is enabled \u2014 run the push command or obtain user approval before pushing."
72530
+ }
72354
72531
  };
72355
72532
  } catch (e) {
72356
72533
  return { success: false, error: e.message, refineStages };
@@ -72368,9 +72545,46 @@ ${e?.stderr || ""}`
72368
72545
  const refineCode = typeof result.code === "string" ? result.code : "";
72369
72546
  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";
72370
72547
  const isTerminalSuccess = refineTerminalKind === "completed";
72548
+ const blockerContext = isTerminalSuccess ? void 0 : (() => {
72549
+ const code = typeof result.code === "string" ? result.code : refineTerminalKind;
72550
+ 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";
72551
+ const ctx = {
72552
+ stage,
72553
+ reason: code,
72554
+ terminalKind: refineTerminalKind
72555
+ };
72556
+ if (typeof result.error === "string") ctx.error = result.error;
72557
+ if (typeof result.blockedReason === "string") ctx.blockedReason = result.blockedReason;
72558
+ if (stage === "patch_equivalence" && result.patchEquivalence) {
72559
+ const pe = result.patchEquivalence;
72560
+ ctx.details = {
72561
+ expectedPatchId: pe.expectedPatchId,
72562
+ actualPatchId: pe.actualPatchId,
72563
+ status: pe.status,
72564
+ actionableHint: pe.actionableHint,
72565
+ error: pe.error
72566
+ };
72567
+ }
72568
+ if (stage === "submodule_reachability" && Array.isArray(result.unreachableSubmoduleCommits)) {
72569
+ ctx.details = {
72570
+ unreachableCount: result.unreachableSubmoduleCommits.length,
72571
+ paths: result.unreachableSubmoduleCommits.map((e) => e.path),
72572
+ autoPublishAllowed: result.unreachableSubmoduleCommits[0]?.autoPublishAllowed
72573
+ };
72574
+ }
72575
+ if (stage === "validation" && result.validationSummary) {
72576
+ const vs = result.validationSummary;
72577
+ ctx.details = {
72578
+ failureCode: vs.failureCode,
72579
+ commandsRun: Array.isArray(vs.commandsRun) ? vs.commandsRun.length : void 0
72580
+ };
72581
+ }
72582
+ return ctx;
72583
+ })();
72371
72584
  const normalizedResult = {
72372
72585
  ...result,
72373
72586
  terminalKind: refineTerminalKind,
72587
+ ...blockerContext ? { blockerContext } : {},
72374
72588
  ...result.nextStep === void 0 && !isTerminalSuccess ? {
72375
72589
  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."
72376
72590
  } : {}