@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.js
CHANGED
|
@@ -8713,6 +8713,23 @@ var MESH_REFINE_CONFIG_SCHEMA = {
|
|
|
8713
8713
|
env: { type: "object", additionalProperties: { type: "string" } }
|
|
8714
8714
|
}
|
|
8715
8715
|
}
|
|
8716
|
+
},
|
|
8717
|
+
bootstrapCommands: {
|
|
8718
|
+
type: "array",
|
|
8719
|
+
maxItems: 4,
|
|
8720
|
+
items: {
|
|
8721
|
+
type: "object",
|
|
8722
|
+
additionalProperties: false,
|
|
8723
|
+
required: ["command"],
|
|
8724
|
+
properties: {
|
|
8725
|
+
command: { type: "string", minLength: 1 },
|
|
8726
|
+
args: { type: "array", items: { type: "string" } },
|
|
8727
|
+
category: { enum: [...MESH_REFINE_VALIDATION_CATEGORIES, "custom"] },
|
|
8728
|
+
cwd: { type: "string" },
|
|
8729
|
+
timeoutMs: { type: "number", minimum: 1e3, maximum: 6e5 },
|
|
8730
|
+
env: { type: "object", additionalProperties: { type: "string" } }
|
|
8731
|
+
}
|
|
8732
|
+
}
|
|
8716
8733
|
}
|
|
8717
8734
|
}
|
|
8718
8735
|
}
|
|
@@ -8779,9 +8796,10 @@ function normalizeCommandConfig(entry, source) {
|
|
|
8779
8796
|
}
|
|
8780
8797
|
function validateMeshRefineConfig(config, source = "inline") {
|
|
8781
8798
|
const errors = [];
|
|
8799
|
+
const bootstrapCommands = [];
|
|
8782
8800
|
const commands = [];
|
|
8783
8801
|
const rejectedCommands = [];
|
|
8784
|
-
if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], commands, rejectedCommands };
|
|
8802
|
+
if (!isRecord(config)) return { valid: false, errors: ["config must be an object"], bootstrapCommands, commands, rejectedCommands };
|
|
8785
8803
|
if (config.version !== 1) errors.push("version must be 1");
|
|
8786
8804
|
if (config.allowAutoPublishSubmoduleMainCommits !== void 0 && typeof config.allowAutoPublishSubmoduleMainCommits !== "boolean") {
|
|
8787
8805
|
errors.push("allowAutoPublishSubmoduleMainCommits must be a boolean when provided");
|
|
@@ -8789,7 +8807,16 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
8789
8807
|
const validation = config.validation;
|
|
8790
8808
|
if (validation !== void 0 && !isRecord(validation)) errors.push("validation must be an object");
|
|
8791
8809
|
const rawCommands = isRecord(validation) ? validation.commands : void 0;
|
|
8810
|
+
const rawBootstrapCommands = isRecord(validation) ? validation.bootstrapCommands : void 0;
|
|
8792
8811
|
if (rawCommands !== void 0 && !Array.isArray(rawCommands)) errors.push("validation.commands must be an array");
|
|
8812
|
+
if (rawBootstrapCommands !== void 0 && !Array.isArray(rawBootstrapCommands)) errors.push("validation.bootstrapCommands must be an array");
|
|
8813
|
+
if (Array.isArray(rawBootstrapCommands)) {
|
|
8814
|
+
rawBootstrapCommands.forEach((entry, index) => {
|
|
8815
|
+
const normalized = normalizeCommandConfig(entry, `${source}:validation.bootstrapCommands[${index}]`);
|
|
8816
|
+
if (normalized.command) bootstrapCommands.push(normalized.command);
|
|
8817
|
+
if (normalized.rejected) rejectedCommands.push(normalized.rejected);
|
|
8818
|
+
});
|
|
8819
|
+
}
|
|
8793
8820
|
if (Array.isArray(rawCommands)) {
|
|
8794
8821
|
rawCommands.forEach((entry, index) => {
|
|
8795
8822
|
const normalized = normalizeCommandConfig(entry, `${source}:validation.commands[${index}]`);
|
|
@@ -8798,7 +8825,7 @@ function validateMeshRefineConfig(config, source = "inline") {
|
|
|
8798
8825
|
});
|
|
8799
8826
|
}
|
|
8800
8827
|
if (rejectedCommands.length) errors.push("one or more validation commands are invalid");
|
|
8801
|
-
return { valid: errors.length === 0, errors, commands, rejectedCommands };
|
|
8828
|
+
return { valid: errors.length === 0, errors, bootstrapCommands, commands, rejectedCommands };
|
|
8802
8829
|
}
|
|
8803
8830
|
function parseConfigText(path28, text) {
|
|
8804
8831
|
if (/\.json$/i.test(path28)) return JSON.parse(text);
|
|
@@ -8883,6 +8910,7 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
8883
8910
|
return {
|
|
8884
8911
|
source: loaded.source,
|
|
8885
8912
|
sourceType: loaded.sourceType,
|
|
8913
|
+
bootstrapCommands: [],
|
|
8886
8914
|
commands: [],
|
|
8887
8915
|
rejectedCommands: loaded.error ? [{ source: loaded.source, reason: loaded.error }] : [],
|
|
8888
8916
|
suggestions: suggestion.suggestions,
|
|
@@ -8894,6 +8922,7 @@ function resolveMeshRefineValidationPlan(mesh, workspace) {
|
|
|
8894
8922
|
return {
|
|
8895
8923
|
source: loaded.path || loaded.source,
|
|
8896
8924
|
sourceType: loaded.sourceType,
|
|
8925
|
+
bootstrapCommands: validation.bootstrapCommands,
|
|
8897
8926
|
commands: validation.commands,
|
|
8898
8927
|
rejectedCommands: validation.rejectedCommands,
|
|
8899
8928
|
suggestions: suggestion.suggestions,
|
|
@@ -27041,6 +27070,17 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27041
27070
|
});
|
|
27042
27071
|
return { stdout: String(stdout || ""), stderr: String(stderr || ""), refspec };
|
|
27043
27072
|
};
|
|
27073
|
+
const importCommitFromWorktreeSubmodule = async (submodulePath, worktreeSubmodulePath, commit) => {
|
|
27074
|
+
if (!fs11.existsSync(worktreeSubmodulePath)) return false;
|
|
27075
|
+
try {
|
|
27076
|
+
await runGit2(worktreeSubmodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
27077
|
+
} catch {
|
|
27078
|
+
return false;
|
|
27079
|
+
}
|
|
27080
|
+
await runGit2(submodulePath, ["-c", "protocol.file.allow=always", "fetch", worktreeSubmodulePath, commit]);
|
|
27081
|
+
await runGit2(submodulePath, ["cat-file", "-e", `${commit}^{commit}`]);
|
|
27082
|
+
return true;
|
|
27083
|
+
};
|
|
27044
27084
|
const treeOutput = await runGit2(repoRoot, ["ls-tree", "-r", "-z", mergedTree]);
|
|
27045
27085
|
const gitlinks = treeOutput.split("\0").filter(Boolean).map((record) => {
|
|
27046
27086
|
const match = /^160000\s+commit\s+([0-9a-f]{40})\t(.+)$/.exec(record);
|
|
@@ -27057,6 +27097,11 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27057
27097
|
if (!fs11.existsSync(submodulePath)) {
|
|
27058
27098
|
entry.error = `Submodule checkout missing at ${gitlink.path}`;
|
|
27059
27099
|
entry.publishRequired = true;
|
|
27100
|
+
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
27101
|
+
entry.autoPublishAllowed = true;
|
|
27102
|
+
entry.autoPublishAttempted = false;
|
|
27103
|
+
entry.autoPublishSkippedReason = `submodule checkout missing at ${gitlink.path}; cannot perform non-force push to origin/main`;
|
|
27104
|
+
}
|
|
27060
27105
|
entries.push(entry);
|
|
27061
27106
|
continue;
|
|
27062
27107
|
}
|
|
@@ -27066,6 +27111,21 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27066
27111
|
entry.localReachable = true;
|
|
27067
27112
|
} catch {
|
|
27068
27113
|
entry.localReachable = false;
|
|
27114
|
+
if (options.allowAutoPublishSubmoduleMainCommits === true && options.worktreeRoot) {
|
|
27115
|
+
try {
|
|
27116
|
+
const imported = await importCommitFromWorktreeSubmodule(
|
|
27117
|
+
submodulePath,
|
|
27118
|
+
(0, import_path8.resolve)(options.worktreeRoot, gitlink.path),
|
|
27119
|
+
gitlink.commit
|
|
27120
|
+
);
|
|
27121
|
+
if (imported) {
|
|
27122
|
+
entry.localReachable = true;
|
|
27123
|
+
entry.importedFromWorktree = true;
|
|
27124
|
+
}
|
|
27125
|
+
} catch (importError) {
|
|
27126
|
+
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))}`;
|
|
27127
|
+
}
|
|
27128
|
+
}
|
|
27069
27129
|
}
|
|
27070
27130
|
try {
|
|
27071
27131
|
entry.remote = "origin";
|
|
@@ -27077,6 +27137,11 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27077
27137
|
} catch {
|
|
27078
27138
|
entry.error = "Submodule remote reachability check failed: no configured origin remote";
|
|
27079
27139
|
entry.publishRequired = true;
|
|
27140
|
+
if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
27141
|
+
entry.autoPublishAllowed = true;
|
|
27142
|
+
entry.autoPublishAttempted = false;
|
|
27143
|
+
entry.autoPublishSkippedReason = "submodule origin remote is not configured; cannot perform non-force push to origin/main";
|
|
27144
|
+
}
|
|
27080
27145
|
entries.push(entry);
|
|
27081
27146
|
continue;
|
|
27082
27147
|
}
|
|
@@ -27116,6 +27181,10 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27116
27181
|
const publishDetails = truncateValidationOutput(publishError?.stderr || publishError?.message || String(publishError));
|
|
27117
27182
|
entry.error = `Submodule auto-publish to origin/main failed or could not be verified: ${publishDetails}`;
|
|
27118
27183
|
}
|
|
27184
|
+
} else if (options.allowAutoPublishSubmoduleMainCommits === true) {
|
|
27185
|
+
entry.autoPublishAllowed = true;
|
|
27186
|
+
entry.autoPublishAttempted = false;
|
|
27187
|
+
entry.autoPublishSkippedReason = entry.autoPublishSkippedReason || "candidate commit is not reachable in the source checkout or worktree submodule, so Refinery cannot push it to origin/main";
|
|
27119
27188
|
}
|
|
27120
27189
|
}
|
|
27121
27190
|
} catch (e) {
|
|
@@ -27157,16 +27226,18 @@ async function runMeshRefineSubmoduleReachabilityGate(repoRoot, mergedTree, opti
|
|
|
27157
27226
|
}
|
|
27158
27227
|
function buildMeshRefineValidationPlan(mesh, workspace) {
|
|
27159
27228
|
const plan = resolveMeshRefineValidationPlan(mesh, workspace);
|
|
27229
|
+
const mapCommand = (command) => ({
|
|
27230
|
+
displayCommand: command.displayCommand,
|
|
27231
|
+
category: command.category,
|
|
27232
|
+
source: command.source,
|
|
27233
|
+
cwd: command.cwd,
|
|
27234
|
+
timeoutMs: command.timeoutMs
|
|
27235
|
+
});
|
|
27160
27236
|
return {
|
|
27161
27237
|
source: plan.source,
|
|
27162
27238
|
sourceType: plan.sourceType,
|
|
27163
|
-
|
|
27164
|
-
|
|
27165
|
-
category: command.category,
|
|
27166
|
-
source: command.source,
|
|
27167
|
-
cwd: command.cwd,
|
|
27168
|
-
timeoutMs: command.timeoutMs
|
|
27169
|
-
})),
|
|
27239
|
+
bootstrapCommands: plan.bootstrapCommands.map(mapCommand),
|
|
27240
|
+
commands: plan.commands.map(mapCommand),
|
|
27170
27241
|
unavailableReason: plan.unavailableReason,
|
|
27171
27242
|
rejectedCommands: plan.rejectedCommands,
|
|
27172
27243
|
suggestions: plan.suggestions,
|
|
@@ -27183,6 +27254,7 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27183
27254
|
status: "skipped",
|
|
27184
27255
|
required: true,
|
|
27185
27256
|
commandsRun: [],
|
|
27257
|
+
bootstrapCommandsRun: [],
|
|
27186
27258
|
rejectedCommands: selection.rejectedCommands,
|
|
27187
27259
|
skippedReason: void 0,
|
|
27188
27260
|
timeoutMs: REFINE_VALIDATION_TIMEOUT_MS,
|
|
@@ -27196,7 +27268,29 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27196
27268
|
summary.skippedReason = selection.unavailableReason || "validation_unavailable: repo mesh/refine config did not provide executable validation.commands";
|
|
27197
27269
|
return summary;
|
|
27198
27270
|
}
|
|
27199
|
-
|
|
27271
|
+
const commandRecord = (candidate, cwd, startedAt, result, passed, extras = {}) => ({
|
|
27272
|
+
command: candidate.command,
|
|
27273
|
+
args: candidate.args,
|
|
27274
|
+
displayCommand: candidate.displayCommand,
|
|
27275
|
+
category: candidate.category,
|
|
27276
|
+
source: candidate.source,
|
|
27277
|
+
cwd,
|
|
27278
|
+
passed,
|
|
27279
|
+
durationMs: Date.now() - startedAt,
|
|
27280
|
+
stdout: truncateValidationOutput(result?.stdout),
|
|
27281
|
+
stderr: truncateValidationOutput(result?.stderr || result?.message),
|
|
27282
|
+
...extras
|
|
27283
|
+
});
|
|
27284
|
+
const isPackageManagerValidation = (candidate) => {
|
|
27285
|
+
const command = (0, import_path8.basename)(candidate.command).replace(/\.(?:cmd|exe)$/i, "");
|
|
27286
|
+
return ["npm", "pnpm", "yarn", "bun"].includes(command) && candidate.args.some((arg) => arg === "run" || arg === "test" || arg === "exec");
|
|
27287
|
+
};
|
|
27288
|
+
const dependenciesLikelyMissing = (cwd) => {
|
|
27289
|
+
if (!fs11.existsSync((0, import_path8.join)(cwd, "package.json"))) return false;
|
|
27290
|
+
if (fs11.existsSync((0, import_path8.join)(cwd, "node_modules"))) return false;
|
|
27291
|
+
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs11.existsSync((0, import_path8.join)(cwd, lock)));
|
|
27292
|
+
};
|
|
27293
|
+
for (const candidate of selection.bootstrapCommands) {
|
|
27200
27294
|
const startedAt = Date.now();
|
|
27201
27295
|
const cwd = candidate.cwd ? (0, import_path8.resolve)(workspace, candidate.cwd) : workspace;
|
|
27202
27296
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
@@ -27208,36 +27302,60 @@ async function runMeshRefineValidationGate(mesh, workspace) {
|
|
|
27208
27302
|
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27209
27303
|
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
27210
27304
|
});
|
|
27211
|
-
summary.
|
|
27212
|
-
|
|
27213
|
-
|
|
27214
|
-
|
|
27215
|
-
|
|
27216
|
-
|
|
27305
|
+
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
27306
|
+
} catch (error) {
|
|
27307
|
+
summary.bootstrapCommandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
27308
|
+
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
27309
|
+
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
27310
|
+
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
27311
|
+
failureKind: "dependency_bootstrap_failed"
|
|
27312
|
+
}));
|
|
27313
|
+
summary.status = "failed";
|
|
27314
|
+
summary.failureKind = "dependency_bootstrap_failed";
|
|
27315
|
+
summary.failureCode = "dependency_bootstrap_failed";
|
|
27316
|
+
return summary;
|
|
27317
|
+
}
|
|
27318
|
+
}
|
|
27319
|
+
for (const candidate of selection.commands) {
|
|
27320
|
+
const startedAt = Date.now();
|
|
27321
|
+
const cwd = candidate.cwd ? (0, import_path8.resolve)(workspace, candidate.cwd) : workspace;
|
|
27322
|
+
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
27323
|
+
if (selection.bootstrapCommands.length === 0 && isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd)) {
|
|
27324
|
+
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, {
|
|
27325
|
+
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."
|
|
27326
|
+
}, false, {
|
|
27327
|
+
exitCode: null,
|
|
27328
|
+
skipped: true,
|
|
27329
|
+
failureKind: "missing_dependencies"
|
|
27330
|
+
}));
|
|
27331
|
+
summary.status = "failed";
|
|
27332
|
+
summary.failureKind = "missing_dependencies";
|
|
27333
|
+
summary.failureCode = "missing_dependencies";
|
|
27334
|
+
return summary;
|
|
27335
|
+
}
|
|
27336
|
+
try {
|
|
27337
|
+
const result = await execFileAsync3(candidate.command, candidate.args, {
|
|
27217
27338
|
cwd,
|
|
27218
|
-
|
|
27219
|
-
|
|
27220
|
-
|
|
27221
|
-
|
|
27222
|
-
stderr: truncateValidationOutput(result.stderr)
|
|
27339
|
+
encoding: "utf8",
|
|
27340
|
+
timeout,
|
|
27341
|
+
maxBuffer: REFINE_VALIDATION_OUTPUT_LIMIT_BYTES,
|
|
27342
|
+
env: { ...process.env, CI: process.env.CI || "1", ...candidate.env || {} }
|
|
27223
27343
|
});
|
|
27344
|
+
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, result, true, { exitCode: 0 }));
|
|
27224
27345
|
} catch (error) {
|
|
27225
|
-
|
|
27226
|
-
|
|
27227
|
-
|
|
27228
|
-
displayCommand: candidate.displayCommand,
|
|
27229
|
-
category: candidate.category,
|
|
27230
|
-
source: candidate.source,
|
|
27231
|
-
cwd,
|
|
27232
|
-
passed: false,
|
|
27346
|
+
const stderr = truncateValidationOutput(error?.stderr || error?.message);
|
|
27347
|
+
const missingDependencyFailure = /Cannot find module|MODULE_NOT_FOUND|node_modules|command not found|not found/i.test(stderr);
|
|
27348
|
+
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, error, false, {
|
|
27233
27349
|
exitCode: typeof error?.code === "number" ? error.code : null,
|
|
27234
27350
|
signal: typeof error?.signal === "string" ? error.signal : null,
|
|
27235
27351
|
timedOut: error?.killed === true || /timed out/i.test(String(error?.message || "")),
|
|
27236
|
-
|
|
27237
|
-
|
|
27238
|
-
stderr: truncateValidationOutput(error?.stderr || error?.message)
|
|
27239
|
-
});
|
|
27352
|
+
...missingDependencyFailure ? { failureKind: "missing_dependencies" } : {}
|
|
27353
|
+
}));
|
|
27240
27354
|
summary.status = "failed";
|
|
27355
|
+
if (missingDependencyFailure) {
|
|
27356
|
+
summary.failureKind = "missing_dependencies";
|
|
27357
|
+
summary.failureCode = "missing_dependencies";
|
|
27358
|
+
}
|
|
27241
27359
|
return summary;
|
|
27242
27360
|
}
|
|
27243
27361
|
}
|
|
@@ -28221,9 +28339,9 @@ var DaemonCommandRouter = class {
|
|
|
28221
28339
|
if (validationSummary.status === "failed") {
|
|
28222
28340
|
return {
|
|
28223
28341
|
success: false,
|
|
28224
|
-
code: "validation_failed",
|
|
28342
|
+
code: validationSummary.failureCode || "validation_failed",
|
|
28225
28343
|
convergenceStatus: "blocked_review",
|
|
28226
|
-
error: "Refinery validation gate failed; merge/refine was not attempted.",
|
|
28344
|
+
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.",
|
|
28227
28345
|
branch,
|
|
28228
28346
|
into: baseBranch,
|
|
28229
28347
|
validationSummary,
|
|
@@ -28292,7 +28410,8 @@ var DaemonCommandRouter = class {
|
|
|
28292
28410
|
const autoPublishSubmoduleMainCommits = resolveRefineryAutoPublishSubmoduleMainCommits(mesh, node.workspace);
|
|
28293
28411
|
const submoduleReachability = await runMeshRefineSubmoduleReachabilityGate(repoRoot, patchEquivalence.mergedTree || branchHead, {
|
|
28294
28412
|
allowAutoPublishSubmoduleMainCommits: autoPublishSubmoduleMainCommits.enabled,
|
|
28295
|
-
autoPublishPolicySource: autoPublishSubmoduleMainCommits.source
|
|
28413
|
+
autoPublishPolicySource: autoPublishSubmoduleMainCommits.source,
|
|
28414
|
+
worktreeRoot: node.workspace
|
|
28296
28415
|
});
|
|
28297
28416
|
recordMeshRefineStage(refineStages, "submodule_reachability", submoduleReachability.status, submoduleReachabilityStarted, {
|
|
28298
28417
|
checked: submoduleReachability.checked,
|
|
@@ -28310,6 +28429,14 @@ var DaemonCommandRouter = class {
|
|
|
28310
28429
|
remoteMainReachable: entry.remoteMainReachable,
|
|
28311
28430
|
error: entry.error
|
|
28312
28431
|
})),
|
|
28432
|
+
autoPublishSkipped: submoduleReachability.entries.filter((entry) => entry.autoPublishAllowed === true && entry.autoPublishAttempted !== true).map((entry) => ({
|
|
28433
|
+
path: entry.path,
|
|
28434
|
+
commit: entry.commit,
|
|
28435
|
+
remote: entry.remote,
|
|
28436
|
+
remoteUrl: entry.remoteUrl,
|
|
28437
|
+
remoteMainBranch: entry.remoteMainBranch,
|
|
28438
|
+
reason: entry.autoPublishSkippedReason || entry.error || "auto-publish was allowed but no publish attempt was possible"
|
|
28439
|
+
})),
|
|
28313
28440
|
unreachable: submoduleReachability.unreachable.map((entry) => ({
|
|
28314
28441
|
path: entry.path,
|
|
28315
28442
|
commit: entry.commit,
|
|
@@ -28319,6 +28446,7 @@ var DaemonCommandRouter = class {
|
|
|
28319
28446
|
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
28320
28447
|
autoPublishVerified: entry.autoPublishVerified,
|
|
28321
28448
|
autoPublishRefspec: entry.autoPublishRefspec,
|
|
28449
|
+
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
28322
28450
|
remote: entry.remote,
|
|
28323
28451
|
remoteUrl: entry.remoteUrl,
|
|
28324
28452
|
remoteReachable: entry.remoteReachable,
|
|
@@ -28357,6 +28485,7 @@ var DaemonCommandRouter = class {
|
|
|
28357
28485
|
autoPublishSucceeded: entry.autoPublishSucceeded,
|
|
28358
28486
|
autoPublishVerified: entry.autoPublishVerified,
|
|
28359
28487
|
autoPublishRefspec: entry.autoPublishRefspec,
|
|
28488
|
+
autoPublishSkippedReason: entry.autoPublishSkippedReason,
|
|
28360
28489
|
error: entry.error
|
|
28361
28490
|
})),
|
|
28362
28491
|
branch,
|
|
@@ -30144,8 +30273,9 @@ ${block2}`);
|
|
|
30144
30273
|
if (!mesh) return { success: false, error: "Mesh not found" };
|
|
30145
30274
|
const meshHost = resolveMeshHostStatus(mesh);
|
|
30146
30275
|
const refreshRequested = args?.refresh === true || args?.forceRefresh === true;
|
|
30276
|
+
const pendingCoordinatorEventCount = getPendingMeshCoordinatorEvents(meshId).length;
|
|
30147
30277
|
const hadAggregateCache = this.aggregateMeshStatusCache.has(meshId);
|
|
30148
|
-
if (!refreshRequested) {
|
|
30278
|
+
if (!refreshRequested && pendingCoordinatorEventCount === 0) {
|
|
30149
30279
|
const cachedStatus = this.getCachedAggregateMeshStatus(meshId, mesh, { requireDirectPeerTruth: args?.requireDirectPeerTruth === true });
|
|
30150
30280
|
if (cachedStatus) {
|
|
30151
30281
|
logRepoMeshStatusDebug("return_cached", {
|
|
@@ -30157,7 +30287,7 @@ ${block2}`);
|
|
|
30157
30287
|
return cachedStatus;
|
|
30158
30288
|
}
|
|
30159
30289
|
}
|
|
30160
|
-
const refreshReason = refreshRequested ? "explicit_refresh" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
30290
|
+
const refreshReason = refreshRequested ? "explicit_refresh" : pendingCoordinatorEventCount > 0 ? "pending_coordinator_events" : hadAggregateCache ? "stale_pending_cache_refresh" : "cold_cache_miss";
|
|
30161
30291
|
const { getMeshQueueStats: getMeshQueueStats2, getQueue: getQueue2 } = await Promise.resolve().then(() => (init_mesh_work_queue(), mesh_work_queue_exports));
|
|
30162
30292
|
const queue = getQueue2(meshId);
|
|
30163
30293
|
const queueSummary = getMeshQueueStats2(meshId);
|
|
@@ -30183,7 +30313,9 @@ ${block2}`);
|
|
|
30183
30313
|
};
|
|
30184
30314
|
const passivePeerTruthNotAttempted = requireDirectPeerTruth && !refreshRequested && directTruth.directEvidenceCount > 0 && directTruth.peerAttemptedCount === 0;
|
|
30185
30315
|
const effectiveDirectTruth = passivePeerTruthNotAttempted ? { ...directTruth, unavailableNodeIds: [] } : directTruth;
|
|
30186
|
-
const
|
|
30316
|
+
const unavailableDirectTruthNodeIds = new Set(effectiveDirectTruth.unavailableNodeIds);
|
|
30317
|
+
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);
|
|
30318
|
+
const directTruthSatisfied = !requireDirectPeerTruth || effectiveDirectTruth.directEvidenceCount > 0 && (effectiveDirectTruth.unavailableNodeIds.length === 0 || unavailableNodesAreOnlyRemovedWorktrees);
|
|
30187
30319
|
if (requireDirectPeerTruth && !directTruthSatisfied) {
|
|
30188
30320
|
const failureResult = {
|
|
30189
30321
|
success: false,
|
|
@@ -30414,6 +30546,7 @@ ${block2}`);
|
|
|
30414
30546
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
30415
30547
|
nodeStatuses.push(status);
|
|
30416
30548
|
}
|
|
30549
|
+
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId);
|
|
30417
30550
|
const statusResult = {
|
|
30418
30551
|
success: true,
|
|
30419
30552
|
meshId: mesh.id,
|
|
@@ -30450,9 +30583,12 @@ ${block2}`);
|
|
|
30450
30583
|
branchConvergenceSummary: summarizeInlineMeshBranchConvergence(nodeStatuses),
|
|
30451
30584
|
nodes: nodeStatuses,
|
|
30452
30585
|
queue: { tasks: queue, summary: queueSummary },
|
|
30453
|
-
ledger: { entries: ledgerEntries, summary: ledgerSummary }
|
|
30586
|
+
ledger: { entries: ledgerEntries, summary: ledgerSummary },
|
|
30587
|
+
...pendingCoordinatorEvents.length > 0 ? { pendingCoordinatorEvents } : {}
|
|
30454
30588
|
};
|
|
30455
|
-
const
|
|
30589
|
+
const { pendingCoordinatorEvents: _pendingCoordinatorEvents, ...cacheableStatusResult } = statusResult;
|
|
30590
|
+
const rememberedStatus = this.rememberAggregateMeshStatus(meshId, cacheableStatusResult, refreshReason);
|
|
30591
|
+
const returnedStatus = pendingCoordinatorEvents.length > 0 ? { ...rememberedStatus, pendingCoordinatorEvents } : rememberedStatus;
|
|
30456
30592
|
logRepoMeshStatusDebug("return_live", {
|
|
30457
30593
|
meshId,
|
|
30458
30594
|
command: "mesh_status",
|
|
@@ -30460,9 +30596,9 @@ ${block2}`);
|
|
|
30460
30596
|
refreshReason,
|
|
30461
30597
|
meshSource: meshRecord.source,
|
|
30462
30598
|
directTruth,
|
|
30463
|
-
summary: summarizeRepoMeshStatusDebug(
|
|
30599
|
+
summary: summarizeRepoMeshStatusDebug(returnedStatus)
|
|
30464
30600
|
});
|
|
30465
|
-
return
|
|
30601
|
+
return returnedStatus;
|
|
30466
30602
|
} catch (e) {
|
|
30467
30603
|
return { success: false, error: e.message };
|
|
30468
30604
|
}
|