mandrel 2.35.0 → 2.37.0
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/.agents/docs/agentrc-reference.json +3 -1
- package/.agents/docs/configuration.md +27 -0
- package/.agents/rules/testing-standards.md +56 -0
- package/.agents/schemas/agentrc.schema.json +11 -0
- package/.agents/schemas/lifecycle/merge.unlanded.schema.json +2 -1
- package/.agents/schemas/story-deliver-terminal.schema.json +1 -0
- package/.agents/scripts/boot-sweep.js +7 -1
- package/.agents/scripts/check-context-budget.js +195 -103
- package/.agents/scripts/check-cyclomatic.js +112 -42
- package/.agents/scripts/check-doc-links.js +23 -2
- package/.agents/scripts/check-generated-validator.js +202 -0
- package/.agents/scripts/check-lifecycle-lint.js +2 -68
- package/.agents/scripts/check-schema-references.js +2 -28
- package/.agents/scripts/drain-pending-cleanup.js +18 -1
- package/.agents/scripts/git-cleanup.js +2 -0
- package/.agents/scripts/lib/baselines/components.js +32 -2
- package/.agents/scripts/lib/baselines/env-overrides.js +1 -1
- package/.agents/scripts/lib/bootstrap/branch-protection.js +1 -1
- package/.agents/scripts/lib/bootstrap/install-ledger.js +1 -1
- package/.agents/scripts/lib/bootstrap/prompt.js +1 -1
- package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +2 -2
- package/.agents/scripts/lib/checks/loop-health.js +1 -1
- package/.agents/scripts/lib/cli-args.js +0 -2
- package/.agents/scripts/lib/close-validation/gates.js +1 -1
- package/.agents/scripts/lib/close-validation/process.js +1 -1
- package/.agents/scripts/lib/config/ci.js +18 -0
- package/.agents/scripts/lib/config/sync-agentrc.js +1 -1
- package/.agents/scripts/lib/config-settings-schema-delivery.js +13 -0
- package/.agents/scripts/lib/config-settings-schema.js +46 -6
- package/.agents/scripts/lib/coverage-baseline.js +2 -2
- package/.agents/scripts/lib/cpu-pool.js +90 -10
- package/.agents/scripts/lib/crap-utils.js +6 -2
- package/.agents/scripts/lib/cyclomatic-ceiling.js +28 -6
- package/.agents/scripts/lib/cyclomatic-scope.js +144 -0
- package/.agents/scripts/lib/dependency-version.js +86 -0
- package/.agents/scripts/lib/duplicate-search.js +1 -1
- package/.agents/scripts/lib/errors/index.js +1 -1
- package/.agents/scripts/lib/feedback-loop/graduator-core.js +2 -2
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +1 -1
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
- package/.agents/scripts/lib/generated/agentrc-validator.js +16 -0
- package/.agents/scripts/lib/install-cmd-parser.js +1 -1
- package/.agents/scripts/lib/knip-entry-sync.js +1 -57
- package/.agents/scripts/lib/maintainability-utils.js +108 -10
- package/.agents/scripts/lib/observability/source-classifier.js +1 -1
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +22 -7
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +22 -14
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +132 -0
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +56 -11
- package/.agents/scripts/lib/orchestration/merge-block-class.js +10 -1
- package/.agents/scripts/lib/orchestration/merge-poll.js +164 -0
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +70 -9
- package/.agents/scripts/lib/orchestration/pr-watch.js +1 -30
- package/.agents/scripts/lib/orchestration/reassert-status-column.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/codex.js +3 -3
- package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +1 -1
- package/.agents/scripts/lib/orchestration/review-providers/native.js +9 -2
- package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +2 -2
- package/.agents/scripts/lib/orchestration/review-providers/security-review.js +3 -3
- package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +145 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +96 -5
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +52 -1
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +9 -1
- package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +2 -5
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +1 -1
- package/.agents/scripts/lib/orchestration/ticket-lease.js +34 -9
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +3 -1
- package/.agents/scripts/lib/preflight-runner.js +3 -3
- package/.agents/scripts/lib/qa/qa-session.js +1 -1
- package/.agents/scripts/lib/runtime-deps/manifest.js +1 -7
- package/.agents/scripts/lib/runtime-deps/scan-imports.js +3 -58
- package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +284 -25
- package/.agents/scripts/lib/skills/walk-skill-files.js +1 -1
- package/.agents/scripts/lib/source-text/strip-js-comments.js +115 -0
- package/.agents/scripts/lib/test-isolate/runner.js +3 -3
- package/.agents/scripts/lib/test-runner-contract.js +14 -6
- package/.agents/scripts/lib/test-tiers.js +135 -18
- package/.agents/scripts/lib/transpile.js +16 -3
- package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +169 -31
- package/.agents/scripts/lib/worktree/node-modules-strategy.js +2 -5
- package/.agents/scripts/notify.js +4 -10
- package/.agents/scripts/pr-watch-with-update.js +305 -137
- package/.agents/scripts/providers/github/tickets.js +109 -16
- package/.agents/scripts/quality-preview.js +162 -70
- package/.agents/scripts/run-test-profile.js +8 -5
- package/.agents/scripts/run-tests.js +79 -14
- package/.agents/scripts/single-story-close.js +0 -2
- package/.agents/scripts/single-story-init.js +5 -1
- package/.agents/workflows/audit-documentation.md +5 -6
- package/docs/CHANGELOG.md +50 -0
- package/lib/cli/migrate.js +100 -94
- package/lib/migrations/helpers/retire-agentrc-key.js +200 -0
- package/lib/migrations/index.js +32 -33
- package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +21 -80
- package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +15 -87
- package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +13 -71
- package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +13 -101
- package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +13 -100
- package/package.json +9 -5
- package/.agents/scripts/generate-lifecycle-docs.js +0 -237
- package/.agents/scripts/lib/audit-suite/frontmatter-lint.js +0 -32
- package/.agents/scripts/lib/baselines/maintainability-baseline-save.js +0 -37
- package/.agents/scripts/lib/cli/parse-numeric.js +0 -60
- package/.agents/scripts/lib/close-validation/telemetry.js +0 -79
- package/.agents/scripts/lib/orchestration/label-transitions.js +0 -44
- package/.agents/scripts/lib/orchestration/parked-follow-ons.js +0 -147
- package/.agents/scripts/lib/orchestration/phase-runner.js +0 -88
- package/.agents/scripts/lib/orchestration/recut.js +0 -56
|
@@ -1,18 +1,11 @@
|
|
|
1
1
|
// lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js
|
|
2
2
|
/**
|
|
3
|
-
* Story #
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* than bounding anything; that CLI is deleted in the same Story. Setting the
|
|
10
|
-
* knob to any value only ever changed a number printed in a report.
|
|
11
|
-
*
|
|
12
|
-
* `delivery.deliverRunner` declares `additionalProperties: false`, so a
|
|
13
|
-
* consumer whose config still carries the key hits a hard AJV validation
|
|
14
|
-
* failure on upgrade — every script that resolves config, not just the one
|
|
15
|
-
* that read it. This step strips it before that check runs.
|
|
3
|
+
* Story #4531 — `delivery.deliverRunner.verifyConcurrencyCap` was retired
|
|
4
|
+
* when verification stopped being separately capped, but it stayed
|
|
5
|
+
* schema-validated in consumers' configs under a block carrying
|
|
6
|
+
* `additionalProperties: false`, so a config still setting it fails AJV
|
|
7
|
+
* validation on upgrade rather than warning. This step strips it before
|
|
8
|
+
* that check runs.
|
|
16
9
|
*
|
|
17
10
|
* Unlike the 2.1.0 mi-drop step, this one also sweeps `.agentrc.local.json`:
|
|
18
11
|
* the resolver deep-merges the local override over `.agentrc.json` and
|
|
@@ -20,82 +13,17 @@
|
|
|
20
13
|
* same way a key in the committed file does.
|
|
21
14
|
*/
|
|
22
15
|
|
|
23
|
-
import
|
|
24
|
-
import path from 'node:path';
|
|
25
|
-
|
|
26
|
-
const AGENTRC_FILENAMES = ['.agentrc.json', '.agentrc.local.json'];
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* @param {unknown} ctx
|
|
30
|
-
* @param {string} filename
|
|
31
|
-
* @returns {string}
|
|
32
|
-
*/
|
|
33
|
-
function resolveAgentrcPath(ctx, filename) {
|
|
34
|
-
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
35
|
-
return path.join(projectRoot, filename);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* @param {unknown} ctx
|
|
40
|
-
* @param {string} filename
|
|
41
|
-
* @param {typeof nodeFs} fsImpl
|
|
42
|
-
* @returns {object | null}
|
|
43
|
-
*/
|
|
44
|
-
function readAgentrcConfig(ctx, filename, fsImpl) {
|
|
45
|
-
try {
|
|
46
|
-
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
|
|
47
|
-
return JSON.parse(raw);
|
|
48
|
-
} catch {
|
|
49
|
-
return null;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
16
|
+
import { createRetireAgentrcKeyStep } from '../helpers/retire-agentrc-key.js';
|
|
52
17
|
|
|
53
|
-
|
|
54
|
-
* @param {object | null} config
|
|
55
|
-
* @returns {boolean}
|
|
56
|
-
*/
|
|
57
|
-
function hasRetiredKey(config) {
|
|
58
|
-
const deliverRunner = config?.delivery?.deliverRunner;
|
|
59
|
-
return (
|
|
60
|
-
Boolean(deliverRunner) &&
|
|
61
|
-
Object.hasOwn(deliverRunner, 'verifyConcurrencyCap')
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export const retireVerifyConcurrencyCap = {
|
|
18
|
+
export const retireVerifyConcurrencyCap = createRetireAgentrcKeyStep({
|
|
66
19
|
version: '2.1.0',
|
|
67
20
|
description:
|
|
68
21
|
'strip retired delivery.deliverRunner.verifyConcurrencyCap from ' +
|
|
69
22
|
'.agentrc.json and .agentrc.local.json',
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
hasRetiredKey(readAgentrcConfig(ctx, filename, fsImpl)),
|
|
78
|
-
);
|
|
79
|
-
},
|
|
80
|
-
/**
|
|
81
|
-
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
82
|
-
* @returns {void}
|
|
83
|
-
*/
|
|
84
|
-
apply(ctx) {
|
|
85
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
86
|
-
for (const filename of AGENTRC_FILENAMES) {
|
|
87
|
-
const config = readAgentrcConfig(ctx, filename, fsImpl);
|
|
88
|
-
if (!hasRetiredKey(config)) continue;
|
|
89
|
-
|
|
90
|
-
delete config.delivery.deliverRunner.verifyConcurrencyCap;
|
|
91
|
-
if (Object.keys(config.delivery.deliverRunner).length === 0) {
|
|
92
|
-
delete config.delivery.deliverRunner;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
fsImpl.writeFileSync(
|
|
96
|
-
resolveAgentrcPath(ctx, filename),
|
|
97
|
-
`${JSON.stringify(config, null, 2)}\n`,
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
};
|
|
23
|
+
keys: [
|
|
24
|
+
{
|
|
25
|
+
path: ['delivery', 'deliverRunner', 'verifyConcurrencyCap'],
|
|
26
|
+
pruneDepth: 1,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
});
|
|
@@ -12,81 +12,23 @@
|
|
|
12
12
|
* `maxSeedWords` hits a hard validation failure on upgrade, not a
|
|
13
13
|
* warning. This step strips the key before that check runs — the same
|
|
14
14
|
* contract-cutover pattern as `2.1.0-retire-mi-drop-knobs.js`.
|
|
15
|
+
*
|
|
16
|
+
* `planning` is an optional block, so an emptied `complexityGate` and an
|
|
17
|
+
* emptied `planning` are both pruned rather than left as orphan objects.
|
|
15
18
|
*/
|
|
16
19
|
|
|
17
|
-
import
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @param {unknown} ctx
|
|
24
|
-
* @returns {string}
|
|
25
|
-
*/
|
|
26
|
-
function resolveAgentrcPath(ctx) {
|
|
27
|
-
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
28
|
-
return path.join(projectRoot, AGENTRC_FILENAME);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* @param {unknown} ctx
|
|
33
|
-
* @param {typeof nodeFs} fsImpl
|
|
34
|
-
* @returns {object | null}
|
|
35
|
-
*/
|
|
36
|
-
function readAgentrcConfig(ctx, fsImpl) {
|
|
37
|
-
try {
|
|
38
|
-
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx), 'utf8');
|
|
39
|
-
return JSON.parse(raw);
|
|
40
|
-
} catch {
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* @param {object | null} config
|
|
47
|
-
* @returns {boolean}
|
|
48
|
-
*/
|
|
49
|
-
function hasRetiredKey(config) {
|
|
50
|
-
const gate = config?.planning?.complexityGate;
|
|
51
|
-
return Boolean(gate) && Object.hasOwn(gate, 'maxSeedWords');
|
|
52
|
-
}
|
|
20
|
+
import {
|
|
21
|
+
AGENTRC_BASE_FILENAME,
|
|
22
|
+
createRetireAgentrcKeyStep,
|
|
23
|
+
} from '../helpers/retire-agentrc-key.js';
|
|
53
24
|
|
|
54
|
-
export const retireMaxSeedWords = {
|
|
25
|
+
export const retireMaxSeedWords = createRetireAgentrcKeyStep({
|
|
55
26
|
version: '2.11.0',
|
|
56
27
|
description:
|
|
57
28
|
'strip retired planning.complexityGate.maxSeedWords from .agentrc.json ' +
|
|
58
29
|
'(complexity routes on Story shape, never seed word count — Story #4722)',
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
65
|
-
return hasRetiredKey(readAgentrcConfig(ctx, fsImpl));
|
|
66
|
-
},
|
|
67
|
-
/**
|
|
68
|
-
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
69
|
-
* @returns {void}
|
|
70
|
-
*/
|
|
71
|
-
apply(ctx) {
|
|
72
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
73
|
-
const config = readAgentrcConfig(ctx, fsImpl);
|
|
74
|
-
if (!config) return;
|
|
75
|
-
|
|
76
|
-
const gate = config.planning?.complexityGate;
|
|
77
|
-
if (gate && Object.hasOwn(gate, 'maxSeedWords')) {
|
|
78
|
-
delete gate.maxSeedWords;
|
|
79
|
-
if (Object.keys(gate).length === 0) {
|
|
80
|
-
delete config.planning.complexityGate;
|
|
81
|
-
if (Object.keys(config.planning).length === 0) {
|
|
82
|
-
delete config.planning;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
fsImpl.writeFileSync(
|
|
88
|
-
resolveAgentrcPath(ctx),
|
|
89
|
-
`${JSON.stringify(config, null, 2)}\n`,
|
|
90
|
-
);
|
|
91
|
-
},
|
|
92
|
-
};
|
|
30
|
+
filenames: [AGENTRC_BASE_FILENAME],
|
|
31
|
+
keys: [
|
|
32
|
+
{ path: ['planning', 'complexityGate', 'maxSeedWords'], pruneDepth: 2 },
|
|
33
|
+
],
|
|
34
|
+
});
|
|
@@ -1,113 +1,25 @@
|
|
|
1
1
|
// lib/migrations/steps/2.20.0-retire-codebase-snapshot.js
|
|
2
2
|
/**
|
|
3
3
|
* Story #4811 — strip the retired `planning.codebaseSnapshot` block from a
|
|
4
|
-
* consumer's `.agentrc.json`
|
|
5
|
-
*
|
|
6
|
-
* #4811 hard-cutover-removed the `/plan` codebase snapshot: the pre-computed
|
|
7
|
-
* structural view grounded nothing it promised (its default include globs
|
|
8
|
-
* missed the standard monorepo layout, and its knobs only re-filtered the same
|
|
9
|
-
* matched set), and spec authoring is grounded instead by the author's own
|
|
10
|
-
* targeted repo retrieval plus the Phase 8 `validateStoryFileAssumptions`
|
|
11
|
-
* gate. The whole block was dropped from the runtime AJV schema and the
|
|
12
|
-
* published mirror. `planning` carries `additionalProperties: false`, so a
|
|
13
|
-
* consumer whose config still sets `codebaseSnapshot` hits a hard validation
|
|
14
|
-
* failure on upgrade, not a warning. This step strips the key before that
|
|
15
|
-
* check runs — the same contract-cutover pattern as
|
|
16
|
-
* `2.11.0-retire-max-seed-words.js`, widened to the local override file
|
|
17
|
-
* because a snapshot narrowed for one checkout is exactly the kind of knob an
|
|
4
|
+
* consumer's `.agentrc.json` and from the `.agentrc.local.json` overlay an
|
|
18
5
|
* operator pins in `.agentrc.local.json`.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
import nodeFs from 'node:fs';
|
|
22
|
-
import path from 'node:path';
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Both config files the resolver deep-merges. A key surviving in either one
|
|
26
|
-
* fails validation, so both are stripped.
|
|
27
|
-
*/
|
|
28
|
-
const AGENTRC_FILENAMES = ['.agentrc.json', '.agentrc.local.json'];
|
|
29
|
-
|
|
30
|
-
const RETIRED_KEY = 'codebaseSnapshot';
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* @param {unknown} ctx
|
|
34
|
-
* @param {string} filename
|
|
35
|
-
* @returns {string}
|
|
36
|
-
*/
|
|
37
|
-
function resolveAgentrcPath(ctx, filename) {
|
|
38
|
-
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
39
|
-
return path.join(projectRoot, filename);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @param {unknown} ctx
|
|
44
|
-
* @param {string} filename
|
|
45
|
-
* @param {typeof nodeFs} fsImpl
|
|
46
|
-
* @returns {object | null}
|
|
47
|
-
*/
|
|
48
|
-
function readAgentrcConfig(ctx, filename, fsImpl) {
|
|
49
|
-
try {
|
|
50
|
-
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
|
|
51
|
-
return JSON.parse(raw);
|
|
52
|
-
} catch {
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* @param {object | null} config
|
|
59
|
-
* @returns {boolean}
|
|
60
|
-
*/
|
|
61
|
-
function hasRetiredKey(config) {
|
|
62
|
-
const planning = config?.planning;
|
|
63
|
-
return Boolean(planning) && Object.hasOwn(planning, RETIRED_KEY);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Strip the key and prune the containers it emptied, so a config that carried
|
|
68
|
-
* nothing but the snapshot does not keep an orphan `planning: {}`.
|
|
69
6
|
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
7
|
+
* Spec authoring is grounded by targeted retrieval plus the Phase 8
|
|
8
|
+
* file-assumption gate, so the snapshot block has no consumer; the block
|
|
9
|
+
* carries `additionalProperties: false`, so a config still setting it fails
|
|
10
|
+
* validation on upgrade rather than warning.
|
|
11
|
+
*
|
|
12
|
+
* `planning` is optional, so a config that carried nothing but the snapshot
|
|
13
|
+
* does not keep an orphan `planning: {}`.
|
|
72
14
|
*/
|
|
73
|
-
function stripRetiredKey(config) {
|
|
74
|
-
delete config.planning[RETIRED_KEY];
|
|
75
|
-
if (Object.keys(config.planning).length === 0) {
|
|
76
|
-
delete config.planning;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
15
|
|
|
80
|
-
|
|
16
|
+
import { createRetireAgentrcKeyStep } from '../helpers/retire-agentrc-key.js';
|
|
17
|
+
|
|
18
|
+
export const retireCodebaseSnapshot = createRetireAgentrcKeyStep({
|
|
81
19
|
version: '2.20.0',
|
|
82
20
|
description:
|
|
83
21
|
'strip retired planning.codebaseSnapshot from .agentrc.json / ' +
|
|
84
22
|
'.agentrc.local.json (spec authoring is grounded by targeted retrieval ' +
|
|
85
23
|
'plus the Phase 8 file-assumption gate — Story #4811)',
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
* @returns {boolean}
|
|
89
|
-
*/
|
|
90
|
-
detect(ctx) {
|
|
91
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
92
|
-
return AGENTRC_FILENAMES.some((filename) =>
|
|
93
|
-
hasRetiredKey(readAgentrcConfig(ctx, filename, fsImpl)),
|
|
94
|
-
);
|
|
95
|
-
},
|
|
96
|
-
/**
|
|
97
|
-
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
98
|
-
* @returns {void}
|
|
99
|
-
*/
|
|
100
|
-
apply(ctx) {
|
|
101
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
102
|
-
for (const filename of AGENTRC_FILENAMES) {
|
|
103
|
-
const config = readAgentrcConfig(ctx, filename, fsImpl);
|
|
104
|
-
if (!hasRetiredKey(config)) continue;
|
|
105
|
-
|
|
106
|
-
stripRetiredKey(config);
|
|
107
|
-
fsImpl.writeFileSync(
|
|
108
|
-
resolveAgentrcPath(ctx, filename),
|
|
109
|
-
`${JSON.stringify(config, null, 2)}\n`,
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
},
|
|
113
|
-
};
|
|
24
|
+
keys: [{ path: ['planning', 'codebaseSnapshot'], pruneDepth: 1 }],
|
|
25
|
+
});
|
|
@@ -1,19 +1,9 @@
|
|
|
1
1
|
// lib/migrations/steps/2.32.0-retire-lint-baseline-command.js
|
|
2
2
|
/**
|
|
3
|
-
* Story #5004
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `lib/orchestration/lint-baseline-service.js`: the CLI spawned the configured
|
|
8
|
-
* command and parsed ESLint-shaped JSON, a shape this repo's own `npm run
|
|
9
|
-
* lint` (Biome + markdownlint fan-out) never produced, and nothing invoked the
|
|
10
|
-
* service. The key left the runtime AJV schema, the published mirror,
|
|
11
|
-
* `.agentrc.json` and `agentrc-reference.json` in the same change.
|
|
12
|
-
*
|
|
13
|
-
* `project.commands` carries `additionalProperties: false`, so a consumer
|
|
14
|
-
* whose config still sets `lintBaseline` hits a hard validation failure on
|
|
15
|
-
* upgrade, not a warning. This step strips the key before that check runs —
|
|
16
|
-
* the same contract-cutover pattern as `2.11.0-retire-max-seed-words.js`.
|
|
3
|
+
* Story #5004 — strip the retired `project.commands.lintBaseline` from a
|
|
4
|
+
* consumer's config. The framework-owned lint-baseline capture CLI is gone,
|
|
5
|
+
* and the `commands` block carries `additionalProperties: false`, so a
|
|
6
|
+
* config still naming the command fails validation on upgrade.
|
|
17
7
|
*
|
|
18
8
|
* It sweeps **both** config surfaces. `config-resolver.js` deep-merges
|
|
19
9
|
* `.agentrc.local.json` over `.agentrc.json` and validates the result, so a
|
|
@@ -27,6 +17,11 @@
|
|
|
27
17
|
* `baselines/lint.json`; only the framework-owned capture shell is gone, so
|
|
28
18
|
* nothing here touches the baseline file or the gate config.
|
|
29
19
|
*
|
|
20
|
+
* An emptied `commands` block is deliberately left in place (`pruneDepth: 0`):
|
|
21
|
+
* unlike `planning.complexityGate`, `project` is a required block and an empty
|
|
22
|
+
* `commands` object is valid against the schema, so pruning it would be a
|
|
23
|
+
* cosmetic edit to a config the consumer owns.
|
|
24
|
+
*
|
|
30
25
|
* This step is also the carrier for the release note #5004 never emitted: its
|
|
31
26
|
* commit ships the `BREAKING CHANGE:` footer that the squash subject on `main`
|
|
32
27
|
* (`227e1af4`) lacks, and which release-please therefore could not surface.
|
|
@@ -34,94 +29,12 @@
|
|
|
34
29
|
* fix that stops the next one being lost.
|
|
35
30
|
*/
|
|
36
31
|
|
|
37
|
-
import
|
|
38
|
-
import path from 'node:path';
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Both config surfaces the resolver reads. `.agentrc.local.json` is deep-merged
|
|
42
|
-
* over the base *before* the AJV gate runs
|
|
43
|
-
* (`.agents/scripts/lib/config-resolver.js`), so a `lintBaseline` surviving in
|
|
44
|
-
* the overlay fails validation exactly as one in the base would — and a step
|
|
45
|
-
* that swept only the base would leave that consumer hard-broken with no
|
|
46
|
-
* self-service remedy, since re-running `mandrel update` would keep reporting
|
|
47
|
-
* clean. The overlay is operator-owned and gitignored, which is why it is easy
|
|
48
|
-
* to forget and why the sweep has to name it explicitly.
|
|
49
|
-
*/
|
|
50
|
-
const AGENTRC_FILENAMES = Object.freeze([
|
|
51
|
-
'.agentrc.json',
|
|
52
|
-
'.agentrc.local.json',
|
|
53
|
-
]);
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* @param {unknown} ctx
|
|
57
|
-
* @param {string} filename
|
|
58
|
-
* @returns {string}
|
|
59
|
-
*/
|
|
60
|
-
function resolveAgentrcPath(ctx, filename) {
|
|
61
|
-
const projectRoot = ctx?.projectRoot ?? process.cwd();
|
|
62
|
-
return path.join(projectRoot, filename);
|
|
63
|
-
}
|
|
32
|
+
import { createRetireAgentrcKeyStep } from '../helpers/retire-agentrc-key.js';
|
|
64
33
|
|
|
65
|
-
|
|
66
|
-
* @param {unknown} ctx
|
|
67
|
-
* @param {typeof nodeFs} fsImpl
|
|
68
|
-
* @param {string} filename
|
|
69
|
-
* @returns {object | null}
|
|
70
|
-
*/
|
|
71
|
-
function readAgentrcConfig(ctx, fsImpl, filename) {
|
|
72
|
-
try {
|
|
73
|
-
const raw = fsImpl.readFileSync(resolveAgentrcPath(ctx, filename), 'utf8');
|
|
74
|
-
return JSON.parse(raw);
|
|
75
|
-
} catch {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* @param {object | null} config
|
|
82
|
-
* @returns {boolean}
|
|
83
|
-
*/
|
|
84
|
-
function hasRetiredKey(config) {
|
|
85
|
-
const commands = config?.project?.commands;
|
|
86
|
-
return Boolean(commands) && Object.hasOwn(commands, 'lintBaseline');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export const retireLintBaselineCommand = {
|
|
34
|
+
export const retireLintBaselineCommand = createRetireAgentrcKeyStep({
|
|
90
35
|
version: '2.32.0',
|
|
91
36
|
description:
|
|
92
37
|
'strip retired project.commands.lintBaseline from .agentrc.json ' +
|
|
93
38
|
'(the framework lint-baseline capture CLI is gone — Story #5004)',
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
* @returns {boolean}
|
|
97
|
-
*/
|
|
98
|
-
detect(ctx) {
|
|
99
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
100
|
-
return AGENTRC_FILENAMES.some((filename) =>
|
|
101
|
-
hasRetiredKey(readAgentrcConfig(ctx, fsImpl, filename)),
|
|
102
|
-
);
|
|
103
|
-
},
|
|
104
|
-
/**
|
|
105
|
-
* @param {{ projectRoot?: string, fs?: typeof nodeFs }} [ctx]
|
|
106
|
-
* @returns {void}
|
|
107
|
-
*/
|
|
108
|
-
apply(ctx) {
|
|
109
|
-
const fsImpl = ctx?.fs ?? nodeFs;
|
|
110
|
-
for (const filename of AGENTRC_FILENAMES) {
|
|
111
|
-
const config = readAgentrcConfig(ctx, fsImpl, filename);
|
|
112
|
-
// An absent overlay is the common case, not an error.
|
|
113
|
-
if (!config || !hasRetiredKey(config)) continue;
|
|
114
|
-
|
|
115
|
-
delete config.project.commands.lintBaseline;
|
|
116
|
-
// An emptied `commands` block is left in place: unlike
|
|
117
|
-
// `planning.complexityGate`, `project` is a required block and an empty
|
|
118
|
-
// `commands` object is valid against the schema, so pruning it would be
|
|
119
|
-
// a cosmetic edit to a config the consumer owns.
|
|
120
|
-
|
|
121
|
-
fsImpl.writeFileSync(
|
|
122
|
-
resolveAgentrcPath(ctx, filename),
|
|
123
|
-
`${JSON.stringify(config, null, 2)}\n`,
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
},
|
|
127
|
-
};
|
|
39
|
+
keys: [{ path: ['project', 'commands', 'lintBaseline'], pruneDepth: 0 }],
|
|
40
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mandrel",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.37.0",
|
|
4
4
|
"description": "Claude Code-first opinionated workflow framework: instructions, skills, rules, and SDLC workflows that govern AI coding assistants.",
|
|
5
5
|
"files": [
|
|
6
6
|
".agents/",
|
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
"test": "node .agents/scripts/run-tests.js",
|
|
20
20
|
"test:quick": "node .agents/scripts/run-tests.js --tier quick",
|
|
21
21
|
"test:integration": "node .agents/scripts/run-tests.js --tier integration",
|
|
22
|
+
"test:e2e": "node .agents/scripts/run-tests.js --tier e2e",
|
|
22
23
|
"test:profile": "node .agents/scripts/run-test-profile.js",
|
|
24
|
+
"test:census": "SPAWN_CENSUS_OUT=\"${SPAWN_CENSUS_OUT:-temp/census.json}\" NODE_OPTIONS=\"--require $PWD/tests/fixtures/spawn-census.cjs\" node .agents/scripts/run-tests.js",
|
|
23
25
|
"test:isolate": "node .agents/scripts/test-isolate.js",
|
|
24
26
|
"verify": "node .agents/scripts/run-verify.js",
|
|
25
27
|
"typecheck": "node -e \"process.exit(0)\"",
|
|
@@ -31,9 +33,9 @@
|
|
|
31
33
|
"baselines:scope": "node .agents/scripts/check-baseline-scope.js",
|
|
32
34
|
"baselines:prune": "node .agents/scripts/prune-baseline-orphans.js",
|
|
33
35
|
"lint:md": "markdownlint-cli2 \".agents/**/*.md\" \"*.md\" \"!node_modules/**\" \"!.worktrees/**\"",
|
|
34
|
-
"lint": "node .agents/scripts/run-lint.js && npm run docs:check",
|
|
35
|
-
"docs:gen": "node .agents/scripts/generate-config-docs.js && node .agents/scripts/generate-
|
|
36
|
-
"docs:check": "node .agents/scripts/generate-config-docs.js --check && node .agents/scripts/generate-
|
|
36
|
+
"lint": "node .agents/scripts/run-lint.js && node .agents/scripts/check-generated-validator.js --check && npm run docs:check",
|
|
37
|
+
"docs:gen": "node .agents/scripts/generate-config-docs.js && node .agents/scripts/generate-workflows-doc.js && node .agents/scripts/generate-lens-checklists.js",
|
|
38
|
+
"docs:check": "node .agents/scripts/generate-config-docs.js --check && node .agents/scripts/generate-workflows-doc.js --check && node .agents/scripts/generate-lens-checklists.js --check && node .agents/scripts/check-doc-links.js && npm run skills:check",
|
|
37
39
|
"skills:index": "node .agents/scripts/generate-skills-index.js",
|
|
38
40
|
"skills:check": "node .agents/scripts/generate-skills-index.js --check",
|
|
39
41
|
"format": "biome format --write .",
|
|
@@ -47,6 +49,8 @@
|
|
|
47
49
|
"cyclomatic:update": "node .agents/scripts/check-cyclomatic.js --update",
|
|
48
50
|
"dead-exports:update": "node .agents/scripts/update-dead-exports-baseline.js && node .agents/scripts/update-dead-exports-baseline.js --production",
|
|
49
51
|
"check:knip-entries": "node .agents/scripts/check-knip-entries.js",
|
|
52
|
+
"validator:gen": "node .agents/scripts/check-generated-validator.js",
|
|
53
|
+
"validator:check": "node .agents/scripts/check-generated-validator.js --check",
|
|
50
54
|
"check:schema-refs": "node .agents/scripts/check-schema-references.js",
|
|
51
55
|
"check:workflow-citations": "node .agents/scripts/check-workflow-citations.js",
|
|
52
56
|
"crap:check": "node .agents/scripts/check-baselines.js --gate crap",
|
|
@@ -101,7 +105,7 @@
|
|
|
101
105
|
"markdownlint-cli2": "^0.22.1",
|
|
102
106
|
"memfs": "^4.57.7",
|
|
103
107
|
"node-pty": "^1.0.0",
|
|
104
|
-
"typescript": "
|
|
108
|
+
"typescript": "^6.0.3"
|
|
105
109
|
},
|
|
106
110
|
"dependencies": {
|
|
107
111
|
"ajv": "^8.20.0",
|