mandrel 2.24.0 → 2.26.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/agents/acceptance-critic.md +19 -21
- package/.agents/agents/auditor.md +16 -19
- package/.agents/agents/story-worker.md +41 -54
- package/.agents/audit-checklists/architecture.md +5 -1
- package/.agents/audit-checklists/baselines.md +21 -0
- package/.agents/audit-checklists/quality.md +3 -0
- package/.agents/docs/agentrc-reference.json +2 -1
- package/.agents/docs/configuration.md +2 -1
- package/.agents/docs/quality-gates.md +80 -18
- package/.agents/docs/workflows.md +4 -2
- package/.agents/instructions.md +1 -1
- package/.agents/rules/ci-remediation.md +68 -3
- package/.agents/schemas/agentrc.schema.json +6 -1
- package/.agents/schemas/audit-rules.json +15 -0
- package/.agents/schemas/baselines/audit-baselines-envelope.schema.json +242 -0
- package/.agents/schemas/baselines/baseline-envelope.schema.json +8 -0
- package/.agents/schemas/baselines/crap.schema.json +13 -1
- package/.agents/schemas/crap-report.schema.json +37 -0
- package/.agents/schemas/model-attribution.schema.json +4 -0
- package/.agents/scripts/acceptance-eval.js +124 -15
- package/.agents/scripts/audit-baselines.js +136 -0
- package/.agents/scripts/audit-labels-bootstrap.js +16 -95
- package/.agents/scripts/audit-to-stories.js +33 -3
- package/.agents/scripts/check-arch-cycles.js +12 -93
- package/.agents/scripts/check-baseline-drift.js +16 -3
- package/.agents/scripts/check-baselines.js +19 -3
- package/.agents/scripts/check-context-budget.js +95 -14
- package/.agents/scripts/check-cyclomatic.js +214 -0
- package/.agents/scripts/check-schema-references.js +392 -0
- package/.agents/scripts/check-test-temp-hygiene.js +121 -1
- package/.agents/scripts/check-workflow-timeouts.js +291 -0
- package/.agents/scripts/cleanup-repo-test-temp.js +7 -5
- package/.agents/scripts/deliver-light.js +3 -4
- package/.agents/scripts/deliver-recover.js +13 -0
- package/.agents/scripts/diagnose-friction.js +85 -19
- package/.agents/scripts/lib/audit-baselines/engine.js +177 -0
- package/.agents/scripts/lib/audit-baselines/gate-surface.js +63 -0
- package/.agents/scripts/lib/audit-baselines/headroom.js +72 -0
- package/.agents/scripts/lib/audit-baselines/hotspots.js +69 -0
- package/.agents/scripts/lib/audit-baselines/kinds.js +313 -0
- package/.agents/scripts/lib/audit-baselines/outliers.js +100 -0
- package/.agents/scripts/lib/audit-baselines/read.js +87 -0
- package/.agents/scripts/lib/audit-baselines/staleness.js +123 -0
- package/.agents/scripts/lib/audit-baselines/surface-entry.js +106 -0
- package/.agents/scripts/lib/audit-baselines/trend.js +125 -0
- package/.agents/scripts/lib/audit-baselines/weights.js +193 -0
- package/.agents/scripts/lib/audit-suite/index.js +0 -5
- package/.agents/scripts/lib/audit-suite/selector.js +9 -62
- package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +177 -0
- package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +1 -0
- package/.agents/scripts/lib/audit-to-stories/build-story-body.js +35 -3
- package/.agents/scripts/lib/audit-to-stories/group-findings.js +20 -11
- package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +23 -9
- package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +9 -2
- package/.agents/scripts/lib/baseline-loader.js +0 -0
- package/.agents/scripts/lib/baseline-schema-registry.js +13 -1
- package/.agents/scripts/lib/baselines/diff-scope-cli.js +22 -160
- package/.agents/scripts/lib/baselines/duplication-scanner.js +27 -0
- package/.agents/scripts/lib/baselines/git-base.js +0 -0
- package/.agents/scripts/lib/baselines/kinds/crap.js +499 -57
- package/.agents/scripts/lib/baselines/preview-gates.js +58 -15
- package/.agents/scripts/lib/baselines/reader.js +10 -0
- package/.agents/scripts/lib/baselines/refresh-service.js +69 -11
- package/.agents/scripts/lib/baselines/scope.js +39 -90
- package/.agents/scripts/lib/baselines/writer.js +16 -7
- package/.agents/scripts/lib/changed-files.js +8 -1
- package/.agents/scripts/lib/cli-args.js +115 -1
- package/.agents/scripts/lib/close-validation/runner.js +70 -25
- package/.agents/scripts/lib/config-settings-schema-delivery.js +5 -0
- package/.agents/scripts/lib/crap-engine.js +124 -27
- package/.agents/scripts/lib/crap-method-identity.js +153 -0
- package/.agents/scripts/lib/crap-utils.js +86 -13
- package/.agents/scripts/lib/cyclomatic-ceiling.js +265 -0
- package/.agents/scripts/lib/env-loader.js +46 -16
- package/.agents/scripts/lib/feedback-loop/audit-results-graduator.js +0 -2
- package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +0 -2
- package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +0 -2
- package/.agents/scripts/lib/findings/route-finding.js +123 -17
- package/.agents/scripts/lib/findings/severity.js +80 -2
- package/.agents/scripts/lib/git/cached-fetch.js +0 -0
- package/.agents/scripts/lib/git-utils.js +136 -80
- package/.agents/scripts/lib/import-graph.js +156 -0
- package/.agents/scripts/lib/label-constants.js +17 -0
- package/.agents/scripts/lib/observability/runtime-friction.js +17 -2
- package/.agents/scripts/lib/observability/source-classifier.js +175 -2
- package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +110 -17
- package/.agents/scripts/lib/orchestration/ceremony-routing.js +17 -12
- package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +36 -6
- package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +5 -0
- package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +12 -1
- package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +8 -1
- package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +548 -0
- package/.agents/scripts/lib/orchestration/deliver-recover.js +2 -2
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +10 -5
- package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +39 -3
- package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +71 -20
- package/.agents/scripts/lib/orchestration/light-backstop.js +20 -3
- package/.agents/scripts/lib/orchestration/light-escalation.js +82 -3
- package/.agents/scripts/lib/orchestration/light-suitability.js +103 -5
- package/.agents/scripts/lib/orchestration/plan-context.js +119 -66
- package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +31 -5
- package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +216 -109
- package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +61 -13
- package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +79 -22
- package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +51 -20
- package/.agents/scripts/lib/orchestration/planning/authoring-context.js +70 -74
- package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +231 -0
- package/.agents/scripts/lib/orchestration/resolve-stories.js +18 -17
- package/.agents/scripts/lib/orchestration/retro-proposals.js +0 -0
- package/.agents/scripts/lib/orchestration/run-epilogue.js +12 -0
- package/.agents/scripts/lib/orchestration/run-scoped-config.js +276 -0
- package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +41 -10
- package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +125 -37
- package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +6 -6
- package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +42 -38
- package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +129 -21
- package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -1
- package/.agents/scripts/lib/orchestration/single-story-close/runner.js +267 -125
- package/.agents/scripts/lib/orchestration/spec-budget.js +16 -5
- package/.agents/scripts/lib/orchestration/story-follow-ups.js +182 -95
- package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +22 -0
- package/.agents/scripts/lib/orchestration/ticket-validator.js +5 -11
- package/.agents/scripts/lib/orchestration/ticketing/reads.js +4 -4
- package/.agents/scripts/lib/reserved-test-ids.js +77 -0
- package/.agents/scripts/lib/story-adjacency.js +3 -3
- package/.agents/scripts/lib/story-plan.js +137 -42
- package/.agents/scripts/lib/templates/decomposer-prompts.js +4 -4
- package/.agents/scripts/lib/test-runner-contract.js +134 -0
- package/.agents/scripts/lib/test-tiers.js +11 -2
- package/.agents/scripts/lib/ticket-body-sections.js +1 -1
- package/.agents/scripts/lib/util/concurrent-map.js +17 -0
- package/.agents/scripts/lib/util/parse-id-list.js +103 -0
- package/.agents/scripts/lib/util/poll-loop.js +18 -2
- package/.agents/scripts/lib/wave-runner/live-probe.js +29 -13
- package/.agents/scripts/lib/wave-runner/ready-set.js +254 -43
- package/.agents/scripts/lib/workers/combined-mi-crap-worker.js +10 -13
- package/.agents/scripts/lib/workers/crap-worker.js +8 -13
- package/.agents/scripts/lib/workers/maintainability-report-worker.js +4 -10
- package/.agents/scripts/lib/workers/maintainability-worker.js +4 -10
- package/.agents/scripts/lib/workers/serve-worker-messages.js +35 -0
- package/.agents/scripts/lib/worktree/git-hooks.js +206 -0
- package/.agents/scripts/lib/worktree/lifecycle/creation.js +6 -0
- package/.agents/scripts/lib/worktree-manager.js +14 -0
- package/.agents/scripts/plan-run-epilogue.js +17 -5
- package/.agents/scripts/pr-watch-with-update.js +568 -213
- package/.agents/scripts/providers/github/tickets.js +33 -10
- package/.agents/scripts/provision-git-hooks.js +85 -0
- package/.agents/scripts/quality-preview.js +137 -28
- package/.agents/scripts/resolve-stories.js +4 -1
- package/.agents/scripts/run-coverage.js +86 -35
- package/.agents/scripts/run-lint.js +20 -0
- package/.agents/scripts/run-tests.js +36 -36
- package/.agents/scripts/single-story-close.js +34 -2
- package/.agents/scripts/single-story-confirm-merge.js +22 -6
- package/.agents/scripts/single-story-init.js +7 -0
- package/.agents/scripts/stories-wave-tick.js +308 -47
- package/.agents/scripts/story-plan.js +65 -9
- package/.agents/scripts/update-coverage-baseline.js +34 -4
- package/.agents/scripts/update-crap-baseline.js +42 -4
- package/.agents/scripts/update-duplication-baseline.js +209 -83
- package/.agents/scripts/update-maintainability-baseline.js +31 -4
- package/.agents/scripts/validate-docs-freshness.js +1 -0
- package/.agents/skills/core/diagnose-friction/SKILL.md +4 -1
- package/.agents/skills/core/gates-and-baselines/SKILL.md +17 -11
- package/.agents/skills/skills.index.json +2 -2
- package/.agents/templates/single-story-body.md +16 -8
- package/.agents/workflows/audit-architecture.md +69 -13
- package/.agents/workflows/audit-baselines.md +289 -0
- package/.agents/workflows/audit-navigability.md +5 -4
- package/.agents/workflows/audit-quality.md +26 -0
- package/.agents/workflows/audit-to-stories.md +30 -4
- package/.agents/workflows/deliver.md +92 -97
- package/.agents/workflows/helpers/acceptance-self-eval.md +47 -10
- package/.agents/workflows/helpers/audit-lens-core.md +25 -4
- package/.agents/workflows/helpers/code-quality-guardrails.md +9 -2
- package/.agents/workflows/helpers/deliver-digest.md +41 -21
- package/.agents/workflows/helpers/deliver-reference.md +95 -4
- package/.agents/workflows/helpers/deliver-story-reference.md +174 -52
- package/.agents/workflows/helpers/deliver-story.md +104 -119
- package/.agents/workflows/helpers/plan-reference.md +49 -5
- package/.agents/workflows/memory-consolidate.md +116 -0
- package/.agents/workflows/plan.md +62 -75
- package/README.md +13 -6
- package/docs/CHANGELOG.md +93 -0
- package/lib/cli/update.js +14 -11
- package/lib/cli/version-check.js +9 -1
- package/package.json +9 -4
- package/.agents/schemas/friction-event.schema.json +0 -56
- package/.agents/scripts/lib/feedback-loop/memory-freshness.js +0 -707
|
@@ -45,10 +45,22 @@ export const BASELINE_KIND_SCHEMA_FILES = Object.freeze([
|
|
|
45
45
|
'duplication.schema.json',
|
|
46
46
|
]);
|
|
47
47
|
|
|
48
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Report schemas that live under `.agents/schemas/baselines/` but describe
|
|
50
|
+
* an *engine's output about* the baselines rather than a committed baseline
|
|
51
|
+
* (Story #4902). They are registered here for two reasons: the AJV instance
|
|
52
|
+
* below is the one place a caller can compile a baselines-directory schema
|
|
53
|
+
* without re-registering the envelope, and the mirror-drift test compares
|
|
54
|
+
* this registry against the on-disk listing — an unregistered file there is
|
|
55
|
+
* drift regardless of which category it belongs to.
|
|
56
|
+
*/
|
|
57
|
+
const BASELINE_REPORT_SCHEMA_FILES = ['audit-baselines-envelope.schema.json'];
|
|
58
|
+
|
|
59
|
+
/** Every baseline schema filename (envelope + per-kind + report) in registration order. */
|
|
49
60
|
export const BASELINE_SCHEMA_FILES = Object.freeze([
|
|
50
61
|
BASELINE_ENVELOPE_FILE,
|
|
51
62
|
...BASELINE_KIND_SCHEMA_FILES,
|
|
63
|
+
...BASELINE_REPORT_SCHEMA_FILES,
|
|
52
64
|
]);
|
|
53
65
|
|
|
54
66
|
/**
|
|
@@ -3,26 +3,32 @@
|
|
|
3
3
|
* the manual baseline-update CLIs (Story #1974 / Task #1986, Epic #1943).
|
|
4
4
|
*
|
|
5
5
|
* `update-coverage-baseline.js`, `update-crap-baseline.js`,
|
|
6
|
-
* `update-maintainability-baseline.js`, and
|
|
7
|
-
* all accept an opt-in `--diff-scope <ref>`
|
|
8
|
-
* baseline write narrows to files changed since
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* `update-maintainability-baseline.js`, and
|
|
7
|
+
* `update-duplication-baseline.js` all accept an opt-in `--diff-scope <ref>`
|
|
8
|
+
* flag. When supplied, the baseline write narrows to files changed since
|
|
9
|
+
* `<ref>`; out-of-scope rows are preserved verbatim from the prior on-disk
|
|
10
|
+
* baseline.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* intentionally rewrite the whole baseline.
|
|
12
|
+
* The helper is shared to keep the flag's contract identical across the four
|
|
13
|
+
* scripts: one argv parser, one spelling, one error message.
|
|
15
14
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* **Scope of this module, post-Story #4944.** It parses the flag and nothing
|
|
16
|
+
* else. Everything downstream of the parse — resolving the changed-file set,
|
|
17
|
+
* reading the prior envelope, and assembling the writer call — used to live
|
|
18
|
+
* here too, in `buildWriterScopeArgs` and its helpers. Those were the
|
|
19
|
+
* pre-service path; `lib/baselines/refresh-service.js` owns all of it now
|
|
20
|
+
* (`resolveScope`, `readPriorEnvelope`, and the `writer.write()` handoff),
|
|
21
|
+
* and `refreshBaseline()` derives its own diff via `execFile` rather than
|
|
22
|
+
* `spawnSync`. `update-duplication-baseline.js` was the last caller of the
|
|
23
|
+
* legacy path; when it migrated, the whole write-side half of this module
|
|
24
|
+
* became unreachable and was removed rather than left shipped-but-uncalled.
|
|
25
|
+
*
|
|
26
|
+
* Note for anyone tracing the per-kind prior-row reader that used to live
|
|
27
|
+
* here: it is gone, not relocated. The service reads the prior envelope
|
|
28
|
+
* kind-agnostically (any `{ rows: [], rollup: {} }` document), so the
|
|
29
|
+
* per-kind row-shape filter it needed no longer has a job to do.
|
|
20
30
|
*/
|
|
21
31
|
|
|
22
|
-
import { spawnSync } from 'node:child_process';
|
|
23
|
-
import fs from 'node:fs';
|
|
24
|
-
import { parseNameOnlyStdout } from '../changed-files.js';
|
|
25
|
-
|
|
26
32
|
/**
|
|
27
33
|
* Parse `--diff-scope <ref>` (and the legacy `--diff-scope=<ref>` form)
|
|
28
34
|
* from an argv slice. Returns `null` when the flag is absent. Throws a
|
|
@@ -57,147 +63,3 @@ export function parseDiffScopeFlag(argv = []) {
|
|
|
57
63
|
}
|
|
58
64
|
return null;
|
|
59
65
|
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Resolve the file footprint of `git diff --name-only <ref>...HEAD`.
|
|
63
|
-
* Returns a `Set<string>` of repo-relative paths with forward-slash
|
|
64
|
-
* normalisation. Returns an empty Set when the diff is empty or git
|
|
65
|
-
* exits non-zero (best-effort; a missing-ref or corrupt repo is the
|
|
66
|
-
* operator's signal to inspect the working tree).
|
|
67
|
-
*
|
|
68
|
-
* The `spawnImpl` seam exists for unit tests — production callers omit it.
|
|
69
|
-
*
|
|
70
|
-
* @param {{ ref: string, cwd?: string, spawnImpl?: typeof spawnSync }} args
|
|
71
|
-
* @returns {Set<string>}
|
|
72
|
-
*/
|
|
73
|
-
export function resolveDiffScopeFiles({
|
|
74
|
-
ref,
|
|
75
|
-
cwd = process.cwd(),
|
|
76
|
-
spawnImpl = spawnSync,
|
|
77
|
-
} = {}) {
|
|
78
|
-
if (typeof ref !== 'string' || ref.length === 0) return new Set();
|
|
79
|
-
const res = spawnImpl('git', ['diff', '--name-only', `${ref}...HEAD`], {
|
|
80
|
-
cwd,
|
|
81
|
-
encoding: 'utf8',
|
|
82
|
-
});
|
|
83
|
-
if (!res || res.status !== 0) return new Set();
|
|
84
|
-
return new Set(parseNameOnlyStdout(res.stdout));
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Convenience: parse `--diff-scope` and resolve files in one call.
|
|
89
|
-
* Returns `null` when the flag is absent (so the caller can branch on
|
|
90
|
-
* "scope was opted in?"); otherwise returns
|
|
91
|
-
* `{ ref, files: Set<string>, scope: { mode: 'diff', files } }` ready to
|
|
92
|
-
* pass into `writer.write({ scope })`.
|
|
93
|
-
*
|
|
94
|
-
* @param {{ argv: string[], cwd?: string, spawnImpl?: typeof spawnSync }} args
|
|
95
|
-
* @returns {{ ref: string, files: Set<string>, scope: {mode: 'diff', files: Set<string>} } | null}
|
|
96
|
-
*/
|
|
97
|
-
export function resolveDiffScope({ argv, cwd, spawnImpl } = {}) {
|
|
98
|
-
const ref = parseDiffScopeFlag(argv);
|
|
99
|
-
if (ref === null) return null;
|
|
100
|
-
const files = resolveDiffScopeFiles({ ref, cwd, spawnImpl });
|
|
101
|
-
return { ref, files, scope: { mode: 'diff', files } };
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Read + parse the prior baseline at `absBaselinePath` and return the
|
|
106
|
-
* canonical `rows[]` array (per-kind row shape with `path:` keys, as
|
|
107
|
-
* expected by the per-kind `mergeRows` / `applyEpsilon` helpers from
|
|
108
|
-
* Story #1974). Returns `null` when the file is absent, malformed, or
|
|
109
|
-
* missing a `rows[]` envelope; the caller treats `null` as "skip the
|
|
110
|
-
* merge" (regression-fail-safe — equivalent to a fresh write).
|
|
111
|
-
*
|
|
112
|
-
* Pure-by-design (file I/O through the injected `fsImpl` seam).
|
|
113
|
-
*
|
|
114
|
-
* @param {{ kind: 'maintainability' | 'crap', absBaselinePath: string, fsImpl?: typeof fs }} args
|
|
115
|
-
* @returns {Array<object> | null}
|
|
116
|
-
*/
|
|
117
|
-
// Read + JSON-parse a baseline file. Returns `null` on any I/O or parse
|
|
118
|
-
// failure (the caller treats "no prior" the same as "unreadable prior").
|
|
119
|
-
function readBaselineJson(absBaselinePath, fsImpl) {
|
|
120
|
-
let raw;
|
|
121
|
-
try {
|
|
122
|
-
raw = fsImpl.readFileSync(absBaselinePath, 'utf8');
|
|
123
|
-
} catch {
|
|
124
|
-
return null;
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
const parsed = JSON.parse(raw);
|
|
128
|
-
return parsed && typeof parsed === 'object' ? parsed : null;
|
|
129
|
-
} catch {
|
|
130
|
-
return null;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// CRAP path: envelope `rows[]` only; rows already carry canonical `path:`.
|
|
135
|
-
function readCrapPriorRows(parsed) {
|
|
136
|
-
if (!Array.isArray(parsed.rows)) return null;
|
|
137
|
-
return parsed.rows;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Maintainability path: envelope `rows[]` only; rows already carry
|
|
141
|
-
// canonical `path:` + `mi:`.
|
|
142
|
-
function readMaintainabilityPriorRows(parsed) {
|
|
143
|
-
if (!Array.isArray(parsed.rows)) return null;
|
|
144
|
-
return parsed.rows.filter(
|
|
145
|
-
(r) => r && typeof r.path === 'string' && typeof r.mi === 'number',
|
|
146
|
-
);
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export function readPriorBaselineRows({ kind, absBaselinePath, fsImpl = fs }) {
|
|
150
|
-
const parsed = readBaselineJson(absBaselinePath, fsImpl);
|
|
151
|
-
if (!parsed) return null;
|
|
152
|
-
if (kind === 'crap') return readCrapPriorRows(parsed);
|
|
153
|
-
return readMaintainabilityPriorRows(parsed);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/**
|
|
157
|
-
* Compose the full Story #1974 write-side payload for a manual baseline
|
|
158
|
-
* CLI: read prior rows, resolve `--diff-scope`, log the scope decision,
|
|
159
|
-
* and return the four params (`prior`, `epsilon`, `scope`, plus the
|
|
160
|
-
* resolved `diffScope` for caller-side logging) that the CLI feeds into
|
|
161
|
-
* `writer.write({ ..., prior, epsilon, scope })`.
|
|
162
|
-
*
|
|
163
|
-
* Returns a flat record so each CLI can spread it into the writer call.
|
|
164
|
-
*
|
|
165
|
-
* @param {{
|
|
166
|
-
* kind: 'maintainability' | 'crap',
|
|
167
|
-
* absBaselinePath: string,
|
|
168
|
-
* epsilon: number,
|
|
169
|
-
* argv?: string[],
|
|
170
|
-
* cwd?: string,
|
|
171
|
-
* logger?: { info?: (msg: string) => void },
|
|
172
|
-
* logTag: string,
|
|
173
|
-
* }} args
|
|
174
|
-
* @returns {{
|
|
175
|
-
* prior: Array<object> | undefined,
|
|
176
|
-
* epsilon: number | undefined,
|
|
177
|
-
* scope: {mode: 'diff', files: Set<string>} | undefined,
|
|
178
|
-
* diffScope: {ref: string, files: Set<string>, scope: object} | null,
|
|
179
|
-
* }}
|
|
180
|
-
*/
|
|
181
|
-
export function buildWriterScopeArgs({
|
|
182
|
-
kind,
|
|
183
|
-
absBaselinePath,
|
|
184
|
-
epsilon,
|
|
185
|
-
argv = process.argv.slice(2),
|
|
186
|
-
cwd,
|
|
187
|
-
logger,
|
|
188
|
-
logTag,
|
|
189
|
-
}) {
|
|
190
|
-
const prior = readPriorBaselineRows({ kind, absBaselinePath });
|
|
191
|
-
const diffScope = resolveDiffScope({ argv, cwd });
|
|
192
|
-
if (diffScope && logger?.info) {
|
|
193
|
-
logger.info(
|
|
194
|
-
`${logTag} --diff-scope ${diffScope.ref}: ${diffScope.files.size} file(s) in scope; out-of-scope rows preserved verbatim.`,
|
|
195
|
-
);
|
|
196
|
-
}
|
|
197
|
-
return {
|
|
198
|
-
prior: prior ?? undefined,
|
|
199
|
-
epsilon: prior ? epsilon : undefined,
|
|
200
|
-
scope: diffScope?.scope,
|
|
201
|
-
diffScope,
|
|
202
|
-
};
|
|
203
|
-
}
|
|
@@ -26,11 +26,38 @@
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
import { readFileSync } from 'node:fs';
|
|
29
|
+
import { createRequire } from 'node:module';
|
|
29
30
|
import path from 'node:path';
|
|
30
31
|
|
|
31
32
|
const DEFAULT_MIN_TOKENS = 50;
|
|
32
33
|
const DEFAULT_FORMATS = Object.freeze(['javascript']);
|
|
33
34
|
|
|
35
|
+
const require = createRequire(import.meta.url);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Resolve jscpd's `detectClones` lazily. The jscpd ESM entrypoint has a
|
|
39
|
+
* broken transitive `colors/safe` specifier under Node's strict ESM
|
|
40
|
+
* resolver, so we load the CJS build via `createRequire`. Isolated behind a
|
|
41
|
+
* function so the rest of the module stays import-pure and testable — no
|
|
42
|
+
* importer of this file pays the jscpd load unless it actually scans.
|
|
43
|
+
*
|
|
44
|
+
* Lives here rather than in `update-duplication-baseline.js` since Story
|
|
45
|
+
* #4944: the refresh service's default duplication scorer needs the same
|
|
46
|
+
* seam, and a second copy in the CLI would be the classic "two
|
|
47
|
+
* implementations of one probe" divergence.
|
|
48
|
+
*
|
|
49
|
+
* @returns {(opts: object) => Promise<Array<object>>}
|
|
50
|
+
*/
|
|
51
|
+
export function resolveDetectClones() {
|
|
52
|
+
const jscpd = require('jscpd');
|
|
53
|
+
if (typeof jscpd.detectClones !== 'function') {
|
|
54
|
+
throw new Error(
|
|
55
|
+
"[Duplication] jscpd.detectClones is not available — run 'npm install'",
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return jscpd.detectClones;
|
|
59
|
+
}
|
|
60
|
+
|
|
34
61
|
/**
|
|
35
62
|
* Normalise a jscpd `sourceId` (or any path) to a canonical POSIX
|
|
36
63
|
* repo-relative path. jscpd already emits cwd-relative paths, but a future
|
|
Binary file
|