@adhdev/daemon-core 0.9.82-rc.64 → 0.9.82-rc.66
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 +110 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +110 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/router.ts +142 -1
package/package.json
CHANGED
package/src/commands/router.ts
CHANGED
|
@@ -166,6 +166,7 @@ function summarizeRepoMeshStatusDebug(status: any): Record<string, unknown> {
|
|
|
166
166
|
meshId: readStringValue(status?.meshId, status?.mesh_id) ?? null,
|
|
167
167
|
refreshedAt: readStringValue(status?.refreshedAt, status?.refreshed_at) ?? null,
|
|
168
168
|
sourceOfTruth: status?.sourceOfTruth ?? null,
|
|
169
|
+
branchConvergenceSummary: status?.branchConvergenceSummary ?? status?.branch_convergence_summary ?? null,
|
|
169
170
|
nodeCount: nodes.length,
|
|
170
171
|
nodes: nodes.map((node: any) => ({
|
|
171
172
|
nodeId: readStringValue(node?.nodeId, node?.id) ?? null,
|
|
@@ -182,6 +183,7 @@ function summarizeRepoMeshStatusDebug(status: any): Record<string, unknown> {
|
|
|
182
183
|
gitProbePending: node?.gitProbePending === true,
|
|
183
184
|
launchReady: node?.launchReady === true,
|
|
184
185
|
git: summarizeRepoMeshDebugGit(node?.git),
|
|
186
|
+
branchConvergence: node?.branchConvergence ?? node?.branch_convergence ?? null,
|
|
185
187
|
})),
|
|
186
188
|
};
|
|
187
189
|
}
|
|
@@ -793,7 +795,7 @@ async function probeRemoteMeshGitStatus(args: {
|
|
|
793
795
|
}): Promise<Record<string, unknown> | null> {
|
|
794
796
|
if (!args.dispatchMeshCommand) return null;
|
|
795
797
|
const remoteResult = await Promise.race([
|
|
796
|
-
args.dispatchMeshCommand(args.daemonId, 'git_status', { workspace: args.workspace }),
|
|
798
|
+
args.dispatchMeshCommand(args.daemonId, 'git_status', { workspace: args.workspace, refreshUpstream: true }),
|
|
797
799
|
new Promise<never>((_, reject) => setTimeout(() => reject(new Error('timeout')), args.timeoutMs)),
|
|
798
800
|
]) as any;
|
|
799
801
|
const remoteGit = remoteResult?.status ?? remoteResult?.git ?? remoteResult;
|
|
@@ -1082,6 +1084,24 @@ type MeshRefinePatchEquivalenceSummary = {
|
|
|
1082
1084
|
stderr?: string;
|
|
1083
1085
|
};
|
|
1084
1086
|
|
|
1087
|
+
type MeshRefineSubmoduleReachabilityEntry = {
|
|
1088
|
+
path: string;
|
|
1089
|
+
commit: string;
|
|
1090
|
+
reachable: boolean;
|
|
1091
|
+
checkedLocal?: boolean;
|
|
1092
|
+
fetchedFromOrigin?: boolean;
|
|
1093
|
+
error?: string;
|
|
1094
|
+
};
|
|
1095
|
+
|
|
1096
|
+
type MeshRefineSubmoduleReachabilitySummary = {
|
|
1097
|
+
status: MeshRefineStageStatus;
|
|
1098
|
+
checked: number;
|
|
1099
|
+
unreachable: MeshRefineSubmoduleReachabilityEntry[];
|
|
1100
|
+
entries: MeshRefineSubmoduleReachabilityEntry[];
|
|
1101
|
+
durationMs: number;
|
|
1102
|
+
error?: string;
|
|
1103
|
+
};
|
|
1104
|
+
|
|
1085
1105
|
type MeshRefineAsyncJobStatus = 'accepted' | 'completed' | 'failed';
|
|
1086
1106
|
|
|
1087
1107
|
type MeshRefineJobHandle = {
|
|
@@ -1214,6 +1234,95 @@ async function runMeshRefinePatchEquivalenceGate(
|
|
|
1214
1234
|
}
|
|
1215
1235
|
}
|
|
1216
1236
|
|
|
1237
|
+
async function runMeshRefineSubmoduleReachabilityGate(
|
|
1238
|
+
repoRoot: string,
|
|
1239
|
+
mergedTree: string,
|
|
1240
|
+
): Promise<MeshRefineSubmoduleReachabilitySummary> {
|
|
1241
|
+
const startedAt = Date.now();
|
|
1242
|
+
const entries: MeshRefineSubmoduleReachabilityEntry[] = [];
|
|
1243
|
+
try {
|
|
1244
|
+
const { execFile } = await import('node:child_process');
|
|
1245
|
+
const { promisify } = await import('node:util');
|
|
1246
|
+
const execFileAsync = promisify(execFile);
|
|
1247
|
+
const runGit = async (cwd: string, args: string[]): Promise<string> => {
|
|
1248
|
+
const { stdout } = await execFileAsync('git', args, {
|
|
1249
|
+
cwd,
|
|
1250
|
+
encoding: 'utf8',
|
|
1251
|
+
timeout: 30_000,
|
|
1252
|
+
maxBuffer: REFINE_PATCH_EQUIVALENCE_OUTPUT_LIMIT_BYTES,
|
|
1253
|
+
windowsHide: true,
|
|
1254
|
+
});
|
|
1255
|
+
return String(stdout || '');
|
|
1256
|
+
};
|
|
1257
|
+
|
|
1258
|
+
const treeOutput = await runGit(repoRoot, ['ls-tree', '-r', '-z', mergedTree]);
|
|
1259
|
+
const gitlinks = treeOutput
|
|
1260
|
+
.split('\0')
|
|
1261
|
+
.filter(Boolean)
|
|
1262
|
+
.map(record => {
|
|
1263
|
+
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
1264
|
+
return match ? { commit: match[1], path: match[2] } : null;
|
|
1265
|
+
})
|
|
1266
|
+
.filter((entry): entry is { commit: string; path: string } => !!entry);
|
|
1267
|
+
|
|
1268
|
+
for (const gitlink of gitlinks) {
|
|
1269
|
+
const submodulePath = pathResolve(repoRoot, gitlink.path);
|
|
1270
|
+
const entry: MeshRefineSubmoduleReachabilityEntry = {
|
|
1271
|
+
path: gitlink.path,
|
|
1272
|
+
commit: gitlink.commit,
|
|
1273
|
+
reachable: false,
|
|
1274
|
+
};
|
|
1275
|
+
try {
|
|
1276
|
+
if (!fs.existsSync(submodulePath)) {
|
|
1277
|
+
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
1278
|
+
entries.push(entry);
|
|
1279
|
+
continue;
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
entry.checkedLocal = true;
|
|
1283
|
+
try {
|
|
1284
|
+
await runGit(submodulePath, ['cat-file', '-e', `${gitlink.commit}^{commit}`]);
|
|
1285
|
+
entry.reachable = true;
|
|
1286
|
+
entries.push(entry);
|
|
1287
|
+
continue;
|
|
1288
|
+
} catch {
|
|
1289
|
+
// Probe the submodule remote before allowing cleanup/completion.
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
try {
|
|
1293
|
+
await runGit(submodulePath, ['fetch', 'origin', gitlink.commit]);
|
|
1294
|
+
entry.fetchedFromOrigin = true;
|
|
1295
|
+
await runGit(submodulePath, ['cat-file', '-e', `${gitlink.commit}^{commit}`]);
|
|
1296
|
+
entry.reachable = true;
|
|
1297
|
+
} catch (e: any) {
|
|
1298
|
+
entry.error = truncateValidationOutput(e?.stderr || e?.message || String(e));
|
|
1299
|
+
}
|
|
1300
|
+
} catch (e: any) {
|
|
1301
|
+
entry.error = truncateValidationOutput(e?.message || String(e));
|
|
1302
|
+
}
|
|
1303
|
+
entries.push(entry);
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
const unreachable = entries.filter(entry => !entry.reachable);
|
|
1307
|
+
return {
|
|
1308
|
+
status: unreachable.length ? 'failed' : 'passed',
|
|
1309
|
+
checked: entries.length,
|
|
1310
|
+
unreachable,
|
|
1311
|
+
entries,
|
|
1312
|
+
durationMs: Date.now() - startedAt,
|
|
1313
|
+
};
|
|
1314
|
+
} catch (e: any) {
|
|
1315
|
+
return {
|
|
1316
|
+
status: 'failed',
|
|
1317
|
+
checked: entries.length,
|
|
1318
|
+
unreachable: entries.filter(entry => !entry.reachable),
|
|
1319
|
+
entries,
|
|
1320
|
+
durationMs: Date.now() - startedAt,
|
|
1321
|
+
error: truncateValidationOutput(e?.message || String(e)),
|
|
1322
|
+
};
|
|
1323
|
+
}
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1217
1326
|
function buildMeshRefineValidationPlan(mesh: any, workspace: string): Record<string, unknown> {
|
|
1218
1327
|
const plan = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
1219
1328
|
return {
|
|
@@ -2564,6 +2673,38 @@ export class DaemonCommandRouter {
|
|
|
2564
2673
|
};
|
|
2565
2674
|
}
|
|
2566
2675
|
|
|
2676
|
+
const submoduleReachabilityStarted = Date.now();
|
|
2677
|
+
const submoduleReachability = await runMeshRefineSubmoduleReachabilityGate(repoRoot, patchEquivalence.mergedTree || branchHead);
|
|
2678
|
+
recordMeshRefineStage(refineStages, 'submodule_reachability', submoduleReachability.status, submoduleReachabilityStarted, {
|
|
2679
|
+
checked: submoduleReachability.checked,
|
|
2680
|
+
unreachable: submoduleReachability.unreachable.map(entry => ({ path: entry.path, commit: entry.commit, error: entry.error })),
|
|
2681
|
+
error: submoduleReachability.error,
|
|
2682
|
+
});
|
|
2683
|
+
if (submoduleReachability.status === 'failed') {
|
|
2684
|
+
return {
|
|
2685
|
+
success: false,
|
|
2686
|
+
code: 'submodule_reachability_failed',
|
|
2687
|
+
convergenceStatus: 'blocked_review',
|
|
2688
|
+
error: 'Refinery submodule reachability preflight failed; merge/refine cleanup was not attempted.',
|
|
2689
|
+
branch,
|
|
2690
|
+
into: baseBranch,
|
|
2691
|
+
validationSummary,
|
|
2692
|
+
patchEquivalence,
|
|
2693
|
+
submoduleReachability,
|
|
2694
|
+
refineStages,
|
|
2695
|
+
finalBranchConvergenceState: {
|
|
2696
|
+
branch,
|
|
2697
|
+
baseBranch,
|
|
2698
|
+
merged: false,
|
|
2699
|
+
removed: false,
|
|
2700
|
+
validation: 'passed',
|
|
2701
|
+
patchEquivalence: 'passed',
|
|
2702
|
+
submoduleReachability: 'failed',
|
|
2703
|
+
status: 'blocked_review',
|
|
2704
|
+
},
|
|
2705
|
+
};
|
|
2706
|
+
}
|
|
2707
|
+
|
|
2567
2708
|
let mergeResult: Record<string, unknown> | undefined;
|
|
2568
2709
|
const mergeStarted = Date.now();
|
|
2569
2710
|
try {
|