@adhdev/daemon-core 0.9.82-rc.89 → 0.9.82-rc.90
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 +179 -43
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +179 -43
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/refine-config.d.ts +45 -0
- package/package.json +1 -1
- package/src/commands/router.ts +174 -43
- package/src/mesh/refine-config.ts +38 -3
package/dist/index.mjs
CHANGED
|
@@ -8454,6 +8454,23 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
8454
8454
|
env: { type: "object", additionalProperties: { type: "string" } }
|
|
8455
8455
|
}
|
|
8456
8456
|
}
|
|
8457
|
+
},
|
|
8458
|
+
bootstrapCommands: {
|
|
8459
|
+
type: "array",
|
|
8460
|
+
maxItems: 4,
|
|
8461
|
+
items: {
|
|
8462
|
+
type: "object",
|
|
8463
|
+
additionalProperties: false,
|
|
8464
|
+
required: ["command"],
|
|
8465
|
+
properties: {
|
|
8466
|
+
command: { type: "string", minLength: 1 },
|
|
8467
|
+
args: { type: "array", items: { type: "string" } },
|
|
8468
|
+
category: { enum: [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"] },
|
|
8469
|
+
cwd: { type: "string" },
|
|
8470
|
+
timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
|
|
8471
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
8472
|
+
}
|
|
8473
|
+
}
|
|
8457
8474
|
}
|
|
8458
8475
|
}
|
|
8459
8476
|
}
|
|
@@ -8520,9 +8537,10 @@ function normalizeCommandConfig(entry, source) {
|
|
|
8520
8537
|
}
|
|
8521
8538
|
function validateMeshRefineConfig(config, source = "inline") {
|
|
8522
8539
|
const errors = [];
|
|
8540
|
+
const bootstrapCommands = [];
|
|
8523
8541
|
const commands = [];
|
|
8524
8542
|
const rejectedCommands = [];
|
|
8525
|
-
if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], commands, rejectedCommands };
|
|
8543
|
+
if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands };
|
|
8526
8544
|
if (config.version !== 1) errors.push("version must be 1");
|
|
8527
8545
|
if (config.allowAutoPublishSubmoduleMainCommits !== void 0 && typeof config.allowAutoPublishSubmoduleMainCommits !== "boolean") {
|
|
8528
8546
|
errors.push("allowAutoPublishSubmoduleMainCommits must be a boolean when provided");
|
|
@@ -8530,7 +8548,16 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
8530
8548
|
const validation = config.validation;
|
|
8531
8549
|
if (validation !== void 0 && !isRecord(validation)) errors.push("validation must be an object");
|
|
8532
8550
|
const rawCommands = isRecord(validation) ? validation.commands : void 0;
|
|
8551
|
+
const rawBootstrapCommands = isRecord(validation) ? validation.bootstrapCommands : void 0;
|
|
8533
8552
|
if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
|
|
8553
|
+
if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
|
|
8554
|
+
if (Array.isArray(rawBootstrapCommands)) {
|
|
8555
|
+
rawBootstrapCommands.forEach((entry, index) => {
|
|
8556
|
+
const normalized = normalizeCommandConfig(entry, `${source}:validation.bootstrapCommands[${index}]`);
|
|
8557
|
+
if (normalized.command) bootstrapCommands.push(normalized.command);
|
|
8558
|
+
if (normalized.rejected) rejectedCommands.push(normalized.rejected);
|
|
8559
|
+
});
|
|
8560
|
+
}
|
|
8534
8561
|
if (Array.isArray(rawCommands)) {
|
|
8535
8562
|
rawCommands.forEach((entry, index) => {
|
|
8536
8563
|
const normalized = normalizeCommandConfig(entry, `${source}:validation.commands[${index}]`);
|
|
@@ -8539,7 +8566,7 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
8539
8566
|
});
|
|
8540
8567
|
}
|
|
8541
8568
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
8542
|
-
return { valid: errors.length === 0, errors, commands, rejectedCommands };
|
|
8569
|
+
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
8543
8570
|
}
|
|
8544
8571
|
function parseConfigText(path28, text) {
|
|
8545
8572
|
if (/\.json$/i.test(path28)) return JSON.parse(text);
|
|
@@ -8624,6 +8651,7 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
8624
8651
|
return {
|
|
8625
8652
|
source: loaded.source,
|
|
8626
8653
|
sourceType: loaded.sourceType,
|
|
8654
|
+
bootstrapCommands: [],
|
|
8627
8655
|
commands: [],
|
|
8628
8656
|
rejectedCommands: loaded.error ? [{ source: loaded.source, reason: loaded.error }] : [],
|
|
8629
8657
|
suggestions: suggestion.suggestions,
|
|
@@ -8635,6 +8663,7 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
8635
8663
|
return {
|
|
8636
8664
|
source: loaded.path || loaded.source,
|
|
8637
8665
|
sourceType: loaded.sourceType,
|
|
8666
|
+
bootstrapCommands: validation.bootstrapCommands,
|
|
8638
8667
|
commands: validation.commands,
|
|
8639
8668
|
rejectedCommands: validation.rejectedCommands,
|
|
8640
8669
|
suggestions: suggestion.suggestions,
|
|
@@ -26787,6 +26816,17 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
26787
26816
|
});
|
|
26788
26817
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
26789
26818
|
};
|
|
26819
|
+
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
26820
|
+
if (!fs11.existsSync(worktreeSubmodulePath)) return false;
|
|
26821
|
+
try {
|
|
26822
|
+
await runGit2(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
26823
|
+
} catch {
|
|
26824
|
+
return false;
|
|
26825
|
+
}
|
|
26826
|
+
await runGit2(submodulePath, ["-c", "protocol.file.allow=always", "fetch", worktreeSubmodulePath, commit]);
|
|
26827
|
+
await runGit2(submodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
26828
|
+
return true;
|
|
26829
|
+
};
|
|
26790
26830
|
const treeOutput = await runGit2(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
26791
26831
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record) => {
|
|
26792
26832
|
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
@@ -26803,6 +26843,11 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
26803
26843
|
if (!fs11.existsSync(submodulePath)) {
|
|
26804
26844
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
26805
26845
|
entry.publishRequired = true;
|
|
26846
|
+
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
26847
|
+
entry.autoPublishAllowed = true;
|
|
26848
|
+
entry.autoPublishAttempted = false;
|
|
26849
|
+
entry.autoPublishSkippedReason = `submodule checkout missing at ${gitlink.path}; cannot perform non-force push to origin/main`;
|
|
26850
|
+
}
|
|
26806
26851
|
entries.push(entry);
|
|
26807
26852
|
continue;
|
|
26808
26853
|
}
|
|
@@ -26812,6 +26857,21 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
26812
26857
|
entry.localReachable = true;
|
|
26813
26858
|
} catch {
|
|
26814
26859
|
entry.localReachable = false;
|
|
26860
|
+
if (options.allowAutoPublishSubmoduleMainCommits === true && options.worktreeRoot) {
|
|
26861
|
+
try {
|
|
26862
|
+
const imported = await importCommitFromWorktreeSubmodule(
|
|
26863
|
+
submodulePath,
|
|
26864
|
+
pathResolve(options.worktreeRoot, gitlink.path),
|
|
26865
|
+
gitlink.commit
|
|
26866
|
+
);
|
|
26867
|
+
if (imported) {
|
|
26868
|
+
entry.localReachable = true;
|
|
26869
|
+
entry.importedFromWorktree = true;
|
|
26870
|
+
}
|
|
26871
|
+
} catch (importError) {
|
|
26872
|
+
entry.autoPublishSkippedReason = `candidate commit was not present in the source checkout and could not be imported from worktree submodule: ${truncateValidationOutput(importError?.stderr || importError?.message || String(importError))}`;
|
|
26873
|
+
}
|
|
26874
|
+
}
|
|
26815
26875
|
}
|
|
26816
26876
|
try {
|
|
26817
26877
|
entry.remote = "origin";
|
|
@@ -26823,6 +26883,11 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
26823
26883
|
} catch {
|
|
26824
26884
|
entry.error = "Submodule remote reachability check failed: no configured origin remote";
|
|
26825
26885
|
entry.publishRequired = true;
|
|
26886
|
+
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
26887
|
+
entry.autoPublishAllowed = true;
|
|
26888
|
+
entry.autoPublishAttempted = false;
|
|
26889
|
+
entry.autoPublishSkippedReason = "submodule origin remote is not configured; cannot perform non-force push to origin/main";
|
|
26890
|
+
}
|
|
26826
26891
|
entries.push(entry);
|
|
26827
26892
|
continue;
|
|
26828
26893
|
}
|
|
@@ -26862,6 +26927,10 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
26862
26927
|
const publishDetails = truncateValidationOutput(publishError?.stderr || publishError?.message || String(publishError));
|
|
26863
26928
|
entry.error = `Submodule auto-publish to origin/main failed or could not be verified: ${publishDetails}`;
|
|
26864
26929
|
}
|
|
26930
|
+
} else if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
26931
|
+
entry.autoPublishAllowed = true;
|
|
26932
|
+
entry.autoPublishAttempted = false;
|
|
26933
|
+
entry.autoPublishSkippedReason = entry.autoPublishSkippedReason || "candidate commit is not reachable in the source checkout or worktree submodule, so Refinery cannot push it to origin/main";
|
|
26865
26934
|
}
|
|
26866
26935
|
}
|
|
26867
26936
|
} catch (e) {
|
|
@@ -26903,16 +26972,18 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
26903
26972
|
}
|
|
26904
26973
|
function buildMeshRefineValidationPlan(mesh, workspace) {
|
|
26905
26974
|
const plan = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
26975
|
+
const mapCommand = (command) => ({
|
|
26976
|
+
displayCommand: command.displayCommand,
|
|
26977
|
+
category: command.category,
|
|
26978
|
+
source: command.source,
|
|
26979
|
+
cwd: command.cwd,
|
|
26980
|
+
timeoutMs: command.timeoutMs
|
|
26981
|
+
});
|
|
26906
26982
|
return {
|
|
26907
26983
|
source: plan.source,
|
|
26908
26984
|
sourceType: plan.sourceType,
|
|
26909
|
-
|
|
26910
|
-
|
|
26911
|
-
category: command.category,
|
|
26912
|
-
source: command.source,
|
|
26913
|
-
cwd: command.cwd,
|
|
26914
|
-
timeoutMs: command.timeoutMs
|
|
26915
|
-
})),
|
|
26985
|
+
bootstrapCommands: plan.bootstrapCommands.map(mapCommand),
|
|
26986
|
+
commands: plan.commands.map(mapCommand),
|
|
26916
26987
|
unavailableReason: plan.unavailableReason,
|
|
26917
26988
|
rejectedCommands: plan.rejectedCommands,
|
|
26918
26989
|
suggestions: plan.suggestions,
|
|
@@ -26929,6 +27000,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
26929
27000
|
status: "skipped",
|
|
26930
27001
|
required: true,
|
|
26931
27002
|
commandsRun: [],
|
|
27003
|
+
bootstrapCommandsRun: [],
|
|
26932
27004
|
rejectedCommands: selection.rejectedCommands,
|
|
26933
27005
|
skippedReason: void 0,
|
|
26934
27006
|
timeoutMs: REFINE_VALIDATION_TIMEOUT_MS,
|
|
@@ -26942,7 +27014,29 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
26942
27014
|
summary.skippedReason = selection.unavailableReason || "validation_unavailable: repo mesh/refine config did not provide executable validation.commands";
|
|
26943
27015
|
return summary;
|
|
26944
27016
|
}
|
|
26945
|
-
|
|
27017
|
+
const commandRecord = (candidate, cwd, startedAt, result, passed, extras = {}) => ({
|
|
27018
|
+
command: candidate.command,
|
|
27019
|
+
args: candidate.args,
|
|
27020
|
+
displayCommand: candidate.displayCommand,
|
|
27021
|
+
category: candidate.category,
|
|
27022
|
+
source: candidate.source,
|
|
27023
|
+
cwd,
|
|
27024
|
+
passed,
|
|
27025
|
+
durationMs: Date.now() - startedAt,
|
|
27026
|
+
stdout: truncateValidationOutput(result?.stdout),
|
|
27027
|
+
stderr: truncateValidationOutput(result?.stderr || result?.message),
|
|
27028
|
+
...extras
|
|
27029
|
+
});
|
|
27030
|
+
const isPackageManagerValidation = (candidate) => {
|
|
27031
|
+
const command = pathBasename(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
|
|
27032
|
+
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
27033
|
+
};
|
|
27034
|
+
const dependenciesLikelyMissing = (cwd) => {
|
|
27035
|
+
if (!fs11.existsSync(pathJoin(cwd, "package.json"))) return false;
|
|
27036
|
+
if (fs11.existsSync(pathJoin(cwd, "node_modules"))) return false;
|
|
27037
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs11.existsSync(pathJoin(cwd, lock)));
|
|
27038
|
+
};
|
|
27039
|
+
for (const candidate of selection.bootstrapCommands) {
|
|
26946
27040
|
const startedAt = Date.now();
|
|
26947
27041
|
const cwd = candidate.cwd ? pathResolve(workspace, candidate.cwd) : workspace;
|
|
26948
27042
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
@@ -26954,36 +27048,60 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
26954
27048
|
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
26955
27049
|
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
26956
27050
|
});
|
|
26957
|
-
summary.
|
|
26958
|
-
|
|
26959
|
-
|
|
26960
|
-
|
|
26961
|
-
|
|
26962
|
-
|
|
27051
|
+
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
27052
|
+
} catch (error) {
|
|
27053
|
+
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
27054
|
+
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
27055
|
+
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
27056
|
+
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
27057
|
+
failureKind: "dependency_bootstrap_failed"
|
|
27058
|
+
}));
|
|
27059
|
+
summary.status = "failed";
|
|
27060
|
+
summary.failureKind = "dependency_bootstrap_failed";
|
|
27061
|
+
summary.failureCode = "dependency_bootstrap_failed";
|
|
27062
|
+
return summary;
|
|
27063
|
+
}
|
|
27064
|
+
}
|
|
27065
|
+
for (const candidate of selection.commands) {
|
|
27066
|
+
const startedAt = Date.now();
|
|
27067
|
+
const cwd = candidate.cwd ? pathResolve(workspace, candidate.cwd) : workspace;
|
|
27068
|
+
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
27069
|
+
if (selection.bootstrapCommands.length === 0 && isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd)) {
|
|
27070
|
+
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, {
|
|
27071
|
+
stderr: "Dependencies appear to be missing: package.json and a lockfile are present, but node_modules is absent. Configure validation.bootstrapCommands in repo mesh/refine config if Refinery should install/bootstrap before validation."
|
|
27072
|
+
}, false, {
|
|
27073
|
+
exitCode: null,
|
|
27074
|
+
skipped: true,
|
|
27075
|
+
failureKind: "missing_dependencies"
|
|
27076
|
+
}));
|
|
27077
|
+
summary.status = "failed";
|
|
27078
|
+
summary.failureKind = "missing_dependencies";
|
|
27079
|
+
summary.failureCode = "missing_dependencies";
|
|
27080
|
+
return summary;
|
|
27081
|
+
}
|
|
27082
|
+
try {
|
|
27083
|
+
const result = await execFileAsync3(candidate.command, candidate.args, {
|
|
26963
27084
|
cwd,
|
|
26964
|
-
|
|
26965
|
-
|
|
26966
|
-
|
|
26967
|
-
|
|
26968
|
-
stderr: truncateValidationOutput(result.stderr)
|
|
27085
|
+
encoding: "utf8",
|
|
27086
|
+
timeout,
|
|
27087
|
+
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27088
|
+
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
26969
27089
|
});
|
|
27090
|
+
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
26970
27091
|
} catch (error) {
|
|
26971
|
-
|
|
26972
|
-
|
|
26973
|
-
|
|
26974
|
-
displayCommand: candidate.displayCommand,
|
|
26975
|
-
category: candidate.category,
|
|
26976
|
-
source: candidate.source,
|
|
26977
|
-
cwd,
|
|
26978
|
-
passed: false,
|
|
27092
|
+
const stderr = truncateValidationOutput(error?.stderr || error?.message);
|
|
27093
|
+
const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
27094
|
+
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
26979
27095
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
26980
27096
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
26981
27097
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
26982
|
-
|
|
26983
|
-
|
|
26984
|
-
stderr: truncateValidationOutput(error?.stderr || error?.message)
|
|
26985
|
-
});
|
|
27098
|
+
...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
27099
|
+
}));
|
|
26986
27100
|
summary.status = "failed";
|
|
27101
|
+
if (missingDependencyFailure) {
|
|
27102
|
+
summary.failureKind = "missing_dependencies";
|
|
27103
|
+
summary.failureCode = "missing_dependencies";
|
|
27104
|
+
}
|
|
26987
27105
|
return summary;
|
|
26988
27106
|
}
|
|
26989
27107
|
}
|
|
@@ -27967,9 +28085,9 @@ var DaemonCommandRouter = class {
|
|
|
27967
28085
|
if (validationSummary.status === "failed") {
|
|
27968
28086
|
return {
|
|
27969
28087
|
success: false,
|
|
27970
|
-
code: "validation_failed",
|
|
28088
|
+
code: validationSummary.failureCode || "validation_failed",
|
|
27971
28089
|
convergenceStatus: "blocked_review",
|
|
27972
|
-
error: "Refinery validation gate failed; merge/refine was not attempted.",
|
|
28090
|
+
error: validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted. Configure validation.bootstrapCommands if Refinery should bootstrap dependencies before validation." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.",
|
|
27973
28091
|
branch,
|
|
27974
28092
|
into: baseBranch,
|
|
27975
28093
|
validationSummary,
|
|
@@ -28038,7 +28156,8 @@ var DaemonCommandRouter = class {
|
|
|
28038
28156
|
const autoPublishSubmoduleMainCommits = resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace);
|
|
28039
28157
|
const submoduleReachability = await runMeshRefineSubmoduleReachabilityGate(repoRoot, patchEquivalence.mergedTree || branchHead, {
|
|
28040
28158
|
allowAutoPublishSubmoduleMainCommits: autoPublishSubmoduleMainCommits.enabled,
|
|
28041
|
-
autoPublishPolicySource: autoPublishSubmoduleMainCommits.source
|
|
28159
|
+
autoPublishPolicySource: autoPublishSubmoduleMainCommits.source,
|
|
28160
|
+
worktreeRoot: node.workspace
|
|
28042
28161
|
});
|
|
28043
28162
|
recordMeshRefineStage(refineStages, "submodule_reachability", submoduleReachability.status, submoduleReachabilityStarted, {
|
|
28044
28163
|
checked: submoduleReachability.checked,
|
|
@@ -28056,6 +28175,14 @@ var DaemonCommandRouter = class {
|
|
|
28056
28175
|
remoteMainReachable: entry.remoteMainReachable,
|
|
28057
28176
|
error: entry.error
|
|
28058
28177
|
})),
|
|
28178
|
+
autoPublishSkipped: submoduleReachability.entries.filter((entry) => entry.autoPublishAllowed === true && entry.autoPublishAttempted !== true).map((entry) => ({
|
|
28179
|
+
path: entry.path,
|
|
28180
|
+
commit: entry.commit,
|
|
28181
|
+
remote: entry.remote,
|
|
28182
|
+
remoteUrl: entry.remoteUrl,
|
|
28183
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
28184
|
+
reason: entry.autoPublishSkippedReason || entry.error || "auto-publish was allowed but no publish attempt was possible"
|
|
28185
|
+
})),
|
|
28059
28186
|
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
28060
28187
|
path: entry.path,
|
|
28061
28188
|
commit: entry.commit,
|
|
@@ -28065,6 +28192,7 @@ var DaemonCommandRouter = class {
|
|
|
28065
28192
|
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
28066
28193
|
autoPublishVerified: entry.autoPublishVerified,
|
|
28067
28194
|
autoPublishRefspec: entry.autoPublishRefspec,
|
|
28195
|
+
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
28068
28196
|
remote: entry.remote,
|
|
28069
28197
|
remoteUrl: entry.remoteUrl,
|
|
28070
28198
|
remoteReachable: entry.remoteReachable,
|
|
@@ -28103,6 +28231,7 @@ var DaemonCommandRouter = class {
|
|
|
28103
28231
|
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
28104
28232
|
autoPublishVerified: entry.autoPublishVerified,
|
|
28105
28233
|
autoPublishRefspec: entry.autoPublishRefspec,
|
|
28234
|
+
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
28106
28235
|
error: entry.error
|
|
28107
28236
|
})),
|
|
28108
28237
|
branch,
|
|
@@ -29890,8 +30019,9 @@ ${block2}`);
|
|
|
29890
30019
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
29891
30020
|
const meshHost = resolveMeshHostStatus(mesh);
|
|
29892
30021
|
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
30022
|
+
const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId).length;
|
|
29893
30023
|
const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
|
|
29894
|
-
if (!refreshRequested) {
|
|
30024
|
+
if (!refreshRequested && pendingCoordinatorEventCount === 0) {
|
|
29895
30025
|
const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
|
|
29896
30026
|
if (cachedStatus) {
|
|
29897
30027
|
logRepoMeshStatusDebug("return_cached", {
|
|
@@ -29903,7 +30033,7 @@ ${block2}`);
|
|
|
29903
30033
|
return cachedStatus;
|
|
29904
30034
|
}
|
|
29905
30035
|
}
|
|
29906
|
-
const refreshReason = refreshRequested ? "explicit_refresh" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
30036
|
+
const refreshReason = refreshRequested ? "explicit_refresh" : pendingCoordinatorEventCount > 0 ? "pending_coordinator_events" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
29907
30037
|
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
29908
30038
|
const queue = getQueue2(meshId);
|
|
29909
30039
|
const queueSummary = getMeshQueueStats2(meshId);
|
|
@@ -29929,7 +30059,9 @@ ${block2}`);
|
|
|
29929
30059
|
};
|
|
29930
30060
|
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
29931
30061
|
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
29932
|
-
const
|
|
30062
|
+
const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
30063
|
+
const unavailableNodesAreOnlyRemovedWorktrees = unavailableDirectTruthNodeIds.size > 0 && Array.isArray(mesh.nodes) && mesh.nodes.filter((node) => unavailableDirectTruthNodeIds.has(String(node.id || node.nodeId || ""))).every((node) => node?.isLocalWorktree === true);
|
|
30064
|
+
const directTruthSatisfied = !requireDirectPeerTruth || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
|
|
29933
30065
|
if (requireDirectPeerTruth && !directTruthSatisfied) {
|
|
29934
30066
|
const failureResult = {
|
|
29935
30067
|
success: false,
|
|
@@ -30160,6 +30292,7 @@ ${block2}`);
|
|
|
30160
30292
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
30161
30293
|
nodeStatuses.push(status);
|
|
30162
30294
|
}
|
|
30295
|
+
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId);
|
|
30163
30296
|
const statusResult = {
|
|
30164
30297
|
success: true,
|
|
30165
30298
|
meshId: mesh.id,
|
|
@@ -30196,9 +30329,12 @@ ${block2}`);
|
|
|
30196
30329
|
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
30197
30330
|
nodes: nodeStatuses,
|
|
30198
30331
|
queue: { tasks: queue, summary: queueSummary },
|
|
30199
|
-
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
30332
|
+
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
30333
|
+
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {}
|
|
30200
30334
|
};
|
|
30201
|
-
const
|
|
30335
|
+
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, ...cacheableStatusResult } = statusResult;
|
|
30336
|
+
const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
30337
|
+
const returnedStatus = pendingCoordinatorEvents.length > 0 ? { ...rememberedStatus, pendingCoordinatorEvents } : rememberedStatus;
|
|
30202
30338
|
logRepoMeshStatusDebug("return_live", {
|
|
30203
30339
|
meshId,
|
|
30204
30340
|
command: "mesh_status",
|
|
@@ -30206,9 +30342,9 @@ ${block2}`);
|
|
|
30206
30342
|
refreshReason,
|
|
30207
30343
|
meshSource: meshRecord.source,
|
|
30208
30344
|
directTruth,
|
|
30209
|
-
summary: summarizeRepoMeshStatusDebug(
|
|
30345
|
+
summary: summarizeRepoMeshStatusDebug(returnedStatus)
|
|
30210
30346
|
});
|
|
30211
|
-
return
|
|
30347
|
+
return returnedStatus;
|
|
30212
30348
|
} catch (e) {
|
|
30213
30349
|
return { success: false, error: e.message };
|
|
30214
30350
|
}
|