@adhdev/daemon-core 0.9.82-rc.260 → 0.9.82-rc.262

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.
@@ -15,6 +15,87 @@ import type { ProviderLoader } from '../providers/provider-loader.js';
15
15
  import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
16
16
  import { SessionRegistry } from '../sessions/registry.js';
17
17
  export declare function readCachedInlineMeshActiveSessionDetails(node: any): Array<Record<string, unknown>>;
18
+ type MeshRefineStageStatus = 'passed' | 'failed' | 'skipped';
19
+ type MeshRefineEffectiveDiffSummary = {
20
+ status: MeshRefineStageStatus;
21
+ /** True when there is at least one root-tree change between base and branch (incl. gitlink bumps). */
22
+ hasEffectiveDiff: boolean;
23
+ baseHead: string;
24
+ branchHead: string;
25
+ /** Root-level paths that differ between base and branch (capped). */
26
+ changedPaths?: string[];
27
+ /** Submodule paths with uncommitted/divergent commits but NO committed gitlink bump in the root tree. */
28
+ submoduleHints?: Array<{
29
+ path: string;
30
+ reason: string;
31
+ }>;
32
+ durationMs: number;
33
+ error?: string;
34
+ stdout?: string;
35
+ stderr?: string;
36
+ };
37
+ /**
38
+ * No-op guard: detect a "silent no-op" merge before the Refinery merge runs.
39
+ *
40
+ * A silent no-op occurs when the refine target branch's ROOT tree is byte-identical
41
+ * to the merge base (origin/main). This is the trap where a submodule (e.g. oss) has
42
+ * real commits but the root branch never committed the gitlink (oss-pointer) bump, so
43
+ * the root diff Refinery would merge is empty. Merging that produces a merge commit with
44
+ * no content change — reported as "success" while the actual work never reaches main.
45
+ *
46
+ * A committed gitlink bump (the legitimate oss-pointer bump) DOES show up in the root
47
+ * tree diff (as a 160000-mode entry), so this guard does NOT block legitimate refines —
48
+ * it only fires when the root tree diff vs base is COMPLETELY empty.
49
+ *
50
+ * Runs after the patch-equivalence gate; the "already merged via other path" case
51
+ * (branch has real changes already present in base) is handled upstream and never
52
+ * reaches here, so an empty root diff at this point is genuinely a no-op.
53
+ */
54
+ export declare function runMeshRefineEffectiveDiffGate(repoRoot: string, baseHead: string, branchHead: string): Promise<MeshRefineEffectiveDiffSummary>;
55
+ /**
56
+ * Result of evaluating whether a `git merge-tree --write-tree` submodule
57
+ * conflict is in fact a trivial gitlink fast-forward that should pass the
58
+ * patch-equivalence gate.
59
+ *
60
+ * `git merge-tree` (and `git merge` with the default recursive strategy)
61
+ * refuses to 3-way merge gitlinks unless the case is "trivial" — and it
62
+ * treats *any* gitlink that differs across merge-base/base/branch as
63
+ * non-trivial, even when the branch-side commit is a strict descendant of the
64
+ * base-side commit (i.e. a real fast-forward). Refinery only ever wants to
65
+ * accept the branch's recorded gitlink, so a fast-forwardable bump is safe to
66
+ * resolve to the branch side without any conflict.
67
+ */
68
+ type GitlinkTrivialFastForwardEvaluation = {
69
+ /** True only when the merge-tree conflict is *fully* explained by trivial-ff gitlinks. */
70
+ trivial: boolean;
71
+ /** Why the evaluation declined to treat the conflict as trivial (set when trivial=false). */
72
+ reason?: string;
73
+ /** Per-path detail for the changed gitlinks that were inspected. */
74
+ gitlinks: Array<{
75
+ path: string;
76
+ baseCommit?: string;
77
+ branchCommit?: string;
78
+ fastForward: boolean;
79
+ }>;
80
+ };
81
+ /**
82
+ * Decide whether a merge-tree submodule conflict between base and branch is a
83
+ * trivial gitlink fast-forward (and nothing else).
84
+ *
85
+ * The conflict is treated as trivial ONLY when:
86
+ * 1. at least one changed gitlink exists,
87
+ * 2. every changed gitlink fast-forwards (base-commit is an ancestor of the
88
+ * branch-commit inside that submodule's repo), and
89
+ * 3. the *only* paths that changed on both sides of the merge (i.e. the paths
90
+ * that could possibly produce a 3-way conflict — the intersection of
91
+ * mergeBase→base and mergeBase→branch changes) are gitlinks. Any
92
+ * overlapping non-gitlink path means a genuine content conflict could be
93
+ * hiding behind the submodule failure, so we keep the block.
94
+ *
95
+ * If any of these fail, the conflict is left as a genuine block. This never
96
+ * passes a regular-file conflict or a diverged (non-ff) gitlink.
97
+ */
98
+ export declare function evaluateGitlinkTrivialFastForward(repoRoot: string, baseHead: string, branchHead: string): GitlinkTrivialFastForwardEvaluation;
18
99
  export interface SessionHostControlPlane {
19
100
  getDiagnostics(payload?: {
20
101
  includeSessions?: boolean;
@@ -96,6 +177,10 @@ export declare class DaemonCommandRouter {
96
177
  private runningRefineJobs;
97
178
  /** Terminal async Refinery jobs preserve a clear answer after the worktree node has been removed. */
98
179
  private terminalRefineJobs;
180
+ /** In-memory async batch Refinery jobs keyed by meshId (one batch convergence per mesh at a time). */
181
+ private runningRefineBatchJobs;
182
+ /** Terminal async batch Refinery jobs preserve the last batch outcome for late readers. */
183
+ private terminalRefineBatchJobs;
99
184
  constructor(deps: CommandRouterDeps);
100
185
  private cloneJsonValue;
101
186
  private hydrateCachedAggregateMeshStatusFromInline;
@@ -154,6 +239,36 @@ export declare class DaemonCommandRouter {
154
239
  * isolated as blocked_review while the rest of the batch proceeds.
155
240
  */
156
241
  private batchRefineMeshNodes;
242
+ /**
243
+ * Convergence core shared by the synchronous batch entry and the async batch job.
244
+ * Refines each node in order: the per-node refine pipeline fetches origin/<base>
245
+ * fresh, so each merged sibling advances the base before the next node's auto-rebase
246
+ * + patch-equivalence re-check. A blocked/failed node is isolated; the batch
247
+ * continues with the remaining nodes. Does NOT touch the per-node merge logic — it
248
+ * only sequences calls to executeMeshRefineNodeSynchronously and aggregates outcomes.
249
+ */
250
+ private runMeshRefineBatchConvergence;
251
+ private buildRefineBatchJobKey;
252
+ private buildRefineBatchJobHandle;
253
+ /**
254
+ * Emit a batch Refinery terminal/accepted event through the SAME pending-event +
255
+ * forward mechanism single-node refine uses (queueRefineJobEvent), so the
256
+ * coordinator's existing refine:accepted/completed/failed handling and message
257
+ * renderer apply unchanged. The aggregate per-node results ride along in `result`.
258
+ */
259
+ private queueRefineBatchJobEvent;
260
+ private appendRefineBatchJobLedger;
261
+ private finishMeshRefineBatchJob;
262
+ /**
263
+ * Async entry for the batch Refinery execute path. Mirrors startMeshRefineJob:
264
+ * resolves the plan synchronously (so target/ordering errors and the dry-run shape
265
+ * stay synchronous), then for execute=true registers an in-flight batch job, returns
266
+ * {async:true, status:'accepted', batch:true, ...plan} immediately, and runs the
267
+ * convergence loop in the background — emitting the same terminal refine event.
268
+ * Idempotent: a batch already in flight for this mesh returns the running handle
269
+ * with duplicate:true rather than spawning a second background job.
270
+ */
271
+ private startMeshRefineBatchJob;
157
272
  private finishMeshRefineJob;
158
273
  private startMeshRefineJob;
159
274
  /**
@@ -166,3 +281,4 @@ export declare class DaemonCommandRouter {
166
281
  */
167
282
  private stopIde;
168
283
  }
284
+ export {};