@adhdev/daemon-core 0.9.82-rc.486 → 0.9.82-rc.487
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/git/git-status.d.ts +23 -0
- package/dist/index.js +98 -29
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +98 -29
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/mesh-refine-gates.d.ts +29 -0
- package/package.json +3 -3
- package/src/commands/router-refine.ts +27 -2
- package/src/git/git-status.ts +84 -29
- package/src/mesh/mesh-refine-gates.ts +113 -7
package/dist/index.mjs
CHANGED
|
@@ -409,10 +409,10 @@ function readInjected(value) {
|
|
|
409
409
|
}
|
|
410
410
|
function getDaemonBuildInfo() {
|
|
411
411
|
if (cached) return cached;
|
|
412
|
-
const commit = readInjected(true ? "
|
|
413
|
-
const commitShort = readInjected(true ? "
|
|
414
|
-
const version = readInjected(true ? "0.9.82-rc.
|
|
415
|
-
const builtAt = readInjected(true ? "2026-07-
|
|
412
|
+
const commit = readInjected(true ? "ef3ded0f5df148982ed222411ea08c6ab0fdb39b" : void 0) ?? "unknown";
|
|
413
|
+
const commitShort = readInjected(true ? "ef3ded0f" : void 0) ?? (commit !== "unknown" ? commit.slice(0, 7) : "unknown");
|
|
414
|
+
const version = readInjected(true ? "0.9.82-rc.487" : void 0) ?? readInjected(typeof process !== "undefined" ? process.env?.ADHDEV_PKG_VERSION : void 0) ?? "unknown";
|
|
415
|
+
const builtAt = readInjected(true ? "2026-07-10T01:53:17.254Z" : void 0);
|
|
416
416
|
cached = builtAt ? { commit, commitShort, version, builtAt } : { commit, commitShort, version };
|
|
417
417
|
return cached;
|
|
418
418
|
}
|
|
@@ -784,30 +784,41 @@ function isNonRuntimeRootFile(file, policy) {
|
|
|
784
784
|
}
|
|
785
785
|
return false;
|
|
786
786
|
}
|
|
787
|
+
function classifyChangedFileList(files, policy) {
|
|
788
|
+
if (files.length === 0) {
|
|
789
|
+
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
790
|
+
}
|
|
791
|
+
const pkgs = /* @__PURE__ */ new Set();
|
|
792
|
+
let sawRuntimeAmbiguousNonPackage = false;
|
|
793
|
+
for (const file of files) {
|
|
794
|
+
const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
|
|
795
|
+
if (!match) {
|
|
796
|
+
if (!isNonRuntimeRootFile(file, policy)) sawRuntimeAmbiguousNonPackage = true;
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
pkgs.add(match[1]);
|
|
800
|
+
}
|
|
801
|
+
const affectedPackages = [...pkgs].sort();
|
|
802
|
+
const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p));
|
|
803
|
+
return { isDaemonAffecting: !allBenign, affectedPackages };
|
|
804
|
+
}
|
|
787
805
|
async function classifyDaemonBuildChange(repoPath, buildCommit, options, policy) {
|
|
788
806
|
try {
|
|
789
807
|
const diff = await runGit(repoPath, ["diff", "--name-only", `${buildCommit}..HEAD`], options);
|
|
790
808
|
const files = diff.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
791
|
-
|
|
792
|
-
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
793
|
-
}
|
|
794
|
-
const pkgs = /* @__PURE__ */ new Set();
|
|
795
|
-
let sawRuntimeAmbiguousNonPackage = false;
|
|
796
|
-
for (const file of files) {
|
|
797
|
-
const match = file.match(/(?:^|\/)packages\/([^/]+)\//);
|
|
798
|
-
if (!match) {
|
|
799
|
-
if (!isNonRuntimeRootFile(file, policy)) sawRuntimeAmbiguousNonPackage = true;
|
|
800
|
-
continue;
|
|
801
|
-
}
|
|
802
|
-
pkgs.add(match[1]);
|
|
803
|
-
}
|
|
804
|
-
const affectedPackages = [...pkgs].sort();
|
|
805
|
-
const allBenign = !sawRuntimeAmbiguousNonPackage && affectedPackages.every((p) => policy.webOnlyPackages.has(p) && !policy.daemonRuntimePackages.has(p));
|
|
806
|
-
return { isDaemonAffecting: !allBenign, affectedPackages };
|
|
809
|
+
return classifyChangedFileList(files, policy);
|
|
807
810
|
} catch {
|
|
808
811
|
return { isDaemonAffecting: true, affectedPackages: [] };
|
|
809
812
|
}
|
|
810
813
|
}
|
|
814
|
+
async function classifyChangedPackages(repoPath, fromRef, toRef, options = {}) {
|
|
815
|
+
const repo = await resolveGitRepository(repoPath, options);
|
|
816
|
+
const { config } = resolveChangeImpactConfigForRepo(repo.repoRoot, options);
|
|
817
|
+
const policy = resolveChangeImpactPolicy(config);
|
|
818
|
+
const diff = await runGit(repoPath, ["diff", "--name-only", `${fromRef}..${toRef}`], options);
|
|
819
|
+
const files = diff.stdout.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
820
|
+
return classifyChangedFileList(files, policy);
|
|
821
|
+
}
|
|
811
822
|
function resolveChangeImpactConfigForRepo(repoRoot, options) {
|
|
812
823
|
if (options.changeImpactConfig === null) {
|
|
813
824
|
return { config: null, sourceKey: "forced-default" };
|
|
@@ -57804,6 +57815,7 @@ function orderMeshRefineBatchNodes(changeAreas) {
|
|
|
57804
57815
|
|
|
57805
57816
|
// src/commands/router-refine.ts
|
|
57806
57817
|
init_repo_mesh_types();
|
|
57818
|
+
init_git_status();
|
|
57807
57819
|
init_mesh_node_identity();
|
|
57808
57820
|
|
|
57809
57821
|
// src/mesh/mesh-refine-gates.ts
|
|
@@ -58744,6 +58756,41 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
58744
58756
|
if (fs31.existsSync(pathJoin2(cwd, "node_modules"))) return false;
|
|
58745
58757
|
return ["package-lock.json", "npm-shrinkwrap.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"].some((lock) => fs31.existsSync(pathJoin2(cwd, lock)));
|
|
58746
58758
|
};
|
|
58759
|
+
const needsNodeModules = (candidate, cwd) => isPackageManagerValidation(candidate) && dependenciesLikelyMissing(cwd);
|
|
58760
|
+
const isDaemonScopedCommand = (candidate) => {
|
|
58761
|
+
const haystack = [candidate.command, ...candidate.args || [], candidate.displayCommand || ""].join(" ").toLowerCase();
|
|
58762
|
+
if (candidate.category === "typecheck") return false;
|
|
58763
|
+
if (/\btypecheck\b/.test(haystack)) return false;
|
|
58764
|
+
if (/\bweb-core\b|\bweb-cloud\b|\bweb-standalone\b|\btest:web\b/.test(haystack)) return false;
|
|
58765
|
+
return /\bdaemon-core\b|\bdaemon-cloud\b|\btest:daemon\b|check-vendor-drift/.test(haystack);
|
|
58766
|
+
};
|
|
58767
|
+
const scopeUnaffectedDaemon = opts?.changeImpact?.isDaemonAffecting === false;
|
|
58768
|
+
const skippedDaemonCommands = [];
|
|
58769
|
+
const commandsToRun = [];
|
|
58770
|
+
for (const candidate of selection.commands) {
|
|
58771
|
+
if (scopeUnaffectedDaemon && isDaemonScopedCommand(candidate)) {
|
|
58772
|
+
skippedDaemonCommands.push(candidate.displayCommand);
|
|
58773
|
+
summary.commandsRun.push({
|
|
58774
|
+
command: candidate.command,
|
|
58775
|
+
args: candidate.args,
|
|
58776
|
+
displayCommand: candidate.displayCommand,
|
|
58777
|
+
category: candidate.category,
|
|
58778
|
+
source: candidate.source,
|
|
58779
|
+
passed: true,
|
|
58780
|
+
skipped: true,
|
|
58781
|
+
skipReason: "unaffected_daemon_scope"
|
|
58782
|
+
});
|
|
58783
|
+
continue;
|
|
58784
|
+
}
|
|
58785
|
+
commandsToRun.push(candidate);
|
|
58786
|
+
}
|
|
58787
|
+
if (opts?.changeImpact) {
|
|
58788
|
+
summary.changeImpact = {
|
|
58789
|
+
isDaemonAffecting: opts.changeImpact.isDaemonAffecting,
|
|
58790
|
+
affectedPackages: opts.changeImpact.affectedPackages,
|
|
58791
|
+
...skippedDaemonCommands.length ? { skippedDaemonCommands } : {}
|
|
58792
|
+
};
|
|
58793
|
+
}
|
|
58747
58794
|
if (runLegacyBootstrapCommands) {
|
|
58748
58795
|
summary.bootstrap = { stage: "legacy" };
|
|
58749
58796
|
for (const candidate of selection.bootstrapCommands) {
|
|
@@ -58778,23 +58825,22 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
58778
58825
|
}
|
|
58779
58826
|
}
|
|
58780
58827
|
}
|
|
58781
|
-
|
|
58828
|
+
let missingDepsBlocked = false;
|
|
58829
|
+
for (const candidate of commandsToRun) {
|
|
58782
58830
|
const startedAt = Date.now();
|
|
58783
58831
|
const cwd = candidate.cwd ? pathResolve2(workspace, candidate.cwd) : workspace;
|
|
58784
58832
|
const timeout = candidate.timeoutMs || REFINE_VALIDATION_TIMEOUT_MS;
|
|
58785
58833
|
const bootstrapProvidedDependencies = summary.bootstrap?.stage === "cached" || summary.bootstrap?.stage === "ran" || summary.bootstrap?.stage === "legacy";
|
|
58786
|
-
if (!bootstrapProvidedDependencies &&
|
|
58834
|
+
if (!bootstrapProvidedDependencies && needsNodeModules(candidate, cwd)) {
|
|
58787
58835
|
summary.commandsRun.push(commandRecord(candidate, cwd, startedAt, {
|
|
58788
|
-
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."
|
|
58836
|
+
stderr: "Dependencies appear to be missing: package.json and a lockfile are present, but node_modules is absent. Configure validation.bootstrapCommands (or .adhdev/worktree_bootstrap.json) in repo mesh/refine config if Refinery should install/bootstrap before validation."
|
|
58789
58837
|
}, false, {
|
|
58790
58838
|
exitCode: null,
|
|
58791
58839
|
skipped: true,
|
|
58792
58840
|
failureKind: "missing_dependencies"
|
|
58793
58841
|
}));
|
|
58794
|
-
|
|
58795
|
-
|
|
58796
|
-
summary.failureCode = "missing_dependencies";
|
|
58797
|
-
return summary;
|
|
58842
|
+
missingDepsBlocked = true;
|
|
58843
|
+
continue;
|
|
58798
58844
|
}
|
|
58799
58845
|
const resolvedCommand = resolveWin32Executable(candidate.command);
|
|
58800
58846
|
const spawn5 = buildWin32ExecFileSpawn(resolvedCommand, candidate.args);
|
|
@@ -58830,6 +58876,12 @@ async function runMeshRefineValidationGate(mesh, workspace, opts) {
|
|
|
58830
58876
|
return summary;
|
|
58831
58877
|
}
|
|
58832
58878
|
}
|
|
58879
|
+
if (missingDepsBlocked) {
|
|
58880
|
+
summary.status = "failed";
|
|
58881
|
+
summary.failureKind = "missing_dependencies";
|
|
58882
|
+
summary.failureCode = "missing_dependencies";
|
|
58883
|
+
return summary;
|
|
58884
|
+
}
|
|
58833
58885
|
summary.status = "passed";
|
|
58834
58886
|
return summary;
|
|
58835
58887
|
}
|
|
@@ -59037,7 +59089,20 @@ async function refineResolveRefsStage(self, meshId, nodeId, args, refineStages)
|
|
|
59037
59089
|
const { stdout: branchHeadStdout } = await execFileAsync4("git", ["rev-parse", branch], { cwd: node.workspace, encoding: "utf8" });
|
|
59038
59090
|
const baseHead = baseHeadRaw;
|
|
59039
59091
|
const branchHead = branchHeadStdout.trim();
|
|
59040
|
-
|
|
59092
|
+
let changeImpact;
|
|
59093
|
+
try {
|
|
59094
|
+
changeImpact = await classifyChangedPackages(node.workspace, baseHead, branchHead);
|
|
59095
|
+
} catch {
|
|
59096
|
+
changeImpact = void 0;
|
|
59097
|
+
}
|
|
59098
|
+
recordMeshRefineStage(refineStages, "resolve_refs", "passed", resolveStarted, {
|
|
59099
|
+
branch,
|
|
59100
|
+
baseBranch,
|
|
59101
|
+
baseHead,
|
|
59102
|
+
branchHead,
|
|
59103
|
+
...changeImpact ? { changeImpact } : {},
|
|
59104
|
+
...fetchWarning ? { fetchWarning } : {}
|
|
59105
|
+
});
|
|
59041
59106
|
return {
|
|
59042
59107
|
kind: "continue",
|
|
59043
59108
|
ctx: {
|
|
@@ -59054,6 +59119,7 @@ async function refineResolveRefsStage(self, meshId, nodeId, args, refineStages)
|
|
|
59054
59119
|
baseBranch,
|
|
59055
59120
|
baseHead,
|
|
59056
59121
|
branchHead,
|
|
59122
|
+
changeImpact,
|
|
59057
59123
|
validationSummary: void 0,
|
|
59058
59124
|
patchEquivalence: void 0,
|
|
59059
59125
|
submoduleReachability: void 0
|
|
@@ -59064,6 +59130,9 @@ async function refineValidationStage(self, ctx) {
|
|
|
59064
59130
|
const { mesh, node, branch, baseBranch, refineStages } = ctx;
|
|
59065
59131
|
const validationStarted = Date.now();
|
|
59066
59132
|
const validationSummary = await runMeshRefineValidationGate(mesh, node.workspace, {
|
|
59133
|
+
// (a) Scope the validation command set by coarse change-impact (resolved
|
|
59134
|
+
// in resolve_refs). Undefined → gate runs the full command set (fail-open).
|
|
59135
|
+
changeImpact: ctx.changeImpact,
|
|
59067
59136
|
// M2-2: consume the node's persisted bootstrap state; persist re-runs.
|
|
59068
59137
|
persistedBootstrapState: node.worktreeBootstrap,
|
|
59069
59138
|
onBootstrapStateChange: (state) => {
|
|
@@ -59083,7 +59152,7 @@ async function refineValidationStage(self, ctx) {
|
|
|
59083
59152
|
if (validationSummary.status === "failed") {
|
|
59084
59153
|
const firstFailedCmd = Array.isArray(validationSummary.commandsRun) ? validationSummary.commandsRun.find((c) => c.success === false) : void 0;
|
|
59085
59154
|
const buildValidationFailedError = () => {
|
|
59086
|
-
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing; merge/refine was not attempted.
|
|
59155
|
+
const base = validationSummary.failureCode === "missing_dependencies" ? "Refinery validation dependencies are missing for a change-affected package; merge/refine was not attempted. To make this self-service, either (1) configure .adhdev/worktree_bootstrap.json (or validation.bootstrapCommands in .adhdev/refine.json) so Refinery installs deps before validation, or (2) converge the branch via the documented manual fast-forward-only bypass (rebase onto the fetched base, verify strict ancestry, then push ff-only) instead of the refine gate." : validationSummary.failureCode === "dependency_bootstrap_failed" ? "Refinery dependency/bootstrap command failed; merge/refine was not attempted." : validationSummary.failureCode === "spawn_resolution_failed" ? validationSummary.spawnResolutionError || "Refinery validation command could not be spawned (executable not found); merge/refine was not attempted." : "Refinery validation gate failed; merge/refine was not attempted.";
|
|
59087
59156
|
if (!firstFailedCmd) return base;
|
|
59088
59157
|
const cmdName = typeof firstFailedCmd.displayCommand === "string" ? firstFailedCmd.displayCommand : typeof firstFailedCmd.command === "string" ? [firstFailedCmd.command, ...Array.isArray(firstFailedCmd.args) ? firstFailedCmd.args : []].join(" ").trim() : typeof firstFailedCmd.cmd === "string" ? firstFailedCmd.cmd : "";
|
|
59089
59158
|
const rawOutput = [firstFailedCmd.stdout, firstFailedCmd.stderr, firstFailedCmd.output].filter((s2) => typeof s2 === "string" && s2.length > 0).join("\n");
|