@opensip-cli/yagni 0.1.11 → 0.1.13
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/README.md +3 -3
- package/dist/__tests__/apply-advisory-exit.test.js +2 -1
- package/dist/__tests__/apply-advisory-exit.test.js.map +1 -1
- package/dist/__tests__/architecture-invariants.test.d.ts +6 -0
- package/dist/__tests__/architecture-invariants.test.d.ts.map +1 -0
- package/dist/__tests__/architecture-invariants.test.js +37 -0
- package/dist/__tests__/architecture-invariants.test.js.map +1 -0
- package/dist/__tests__/detector-progress.test.d.ts +2 -0
- package/dist/__tests__/detector-progress.test.d.ts.map +1 -0
- package/dist/__tests__/detector-progress.test.js +77 -0
- package/dist/__tests__/detector-progress.test.js.map +1 -0
- package/dist/__tests__/duplicate-parity.test.d.ts +15 -0
- package/dist/__tests__/duplicate-parity.test.d.ts.map +1 -0
- package/dist/__tests__/duplicate-parity.test.js +304 -0
- package/dist/__tests__/duplicate-parity.test.js.map +1 -0
- package/dist/__tests__/hardening.test.d.ts +2 -0
- package/dist/__tests__/hardening.test.d.ts.map +1 -0
- package/dist/__tests__/hardening.test.js +102 -0
- package/dist/__tests__/hardening.test.js.map +1 -0
- package/dist/__tests__/session-payload.test.d.ts +2 -0
- package/dist/__tests__/session-payload.test.d.ts.map +1 -0
- package/dist/__tests__/session-payload.test.js +61 -0
- package/dist/__tests__/session-payload.test.js.map +1 -0
- package/dist/__tests__/walk-typescript-files.test.js +15 -1
- package/dist/__tests__/walk-typescript-files.test.js.map +1 -1
- package/dist/__tests__/yagni-coverage.test.js +49 -202
- package/dist/__tests__/yagni-coverage.test.js.map +1 -1
- package/dist/__tests__/yagni-golden.test.js +8 -24
- package/dist/__tests__/yagni-golden.test.js.map +1 -1
- package/dist/__tests__/yagni-presentation.test.js +5 -5
- package/dist/__tests__/yagni-presentation.test.js.map +1 -1
- package/dist/baseline-strategy.d.ts +1 -2
- package/dist/baseline-strategy.d.ts.map +1 -1
- package/dist/baseline-strategy.js +21 -16
- package/dist/baseline-strategy.js.map +1 -1
- package/dist/cli/__tests__/yagni-runner.test.js +10 -7
- package/dist/cli/__tests__/yagni-runner.test.js.map +1 -1
- package/dist/cli/execute-yagni.d.ts +15 -4
- package/dist/cli/execute-yagni.d.ts.map +1 -1
- package/dist/cli/execute-yagni.js +68 -30
- package/dist/cli/execute-yagni.js.map +1 -1
- package/dist/cli/report-data.d.ts +0 -2
- package/dist/cli/report-data.d.ts.map +1 -1
- package/dist/cli/report-data.js +0 -2
- package/dist/cli/report-data.js.map +1 -1
- package/dist/cli/yagni-command-spec.d.ts.map +1 -1
- package/dist/cli/yagni-command-spec.js +4 -19
- package/dist/cli/yagni-command-spec.js.map +1 -1
- package/dist/cli/yagni-config-schema.d.ts +1 -7
- package/dist/cli/yagni-config-schema.d.ts.map +1 -1
- package/dist/cli/yagni-config-schema.js +4 -6
- package/dist/cli/yagni-config-schema.js.map +1 -1
- package/dist/cli/yagni-config.d.ts.map +1 -1
- package/dist/cli/yagni-config.js +3 -7
- package/dist/cli/yagni-config.js.map +1 -1
- package/dist/cli/yagni-presentation.d.ts +1 -2
- package/dist/cli/yagni-presentation.d.ts.map +1 -1
- package/dist/cli/yagni-presentation.js +4 -4
- package/dist/cli/yagni-presentation.js.map +1 -1
- package/dist/cli/yagni-runner.d.ts +0 -2
- package/dist/cli/yagni-runner.d.ts.map +1 -1
- package/dist/cli/yagni-runner.js +40 -8
- package/dist/cli/yagni-runner.js.map +1 -1
- package/dist/detectors/duplicate-body-candidate.d.ts +9 -2
- package/dist/detectors/duplicate-body-candidate.d.ts.map +1 -1
- package/dist/detectors/duplicate-body-candidate.js +123 -120
- package/dist/detectors/duplicate-body-candidate.js.map +1 -1
- package/dist/detectors/registry.d.ts +9 -1
- package/dist/detectors/registry.d.ts.map +1 -1
- package/dist/detectors/registry.js +9 -1
- package/dist/detectors/registry.js.map +1 -1
- package/dist/detectors/types.d.ts +1 -2
- package/dist/detectors/types.d.ts.map +1 -1
- package/dist/detectors/unused-config-surface.d.ts.map +1 -1
- package/dist/detectors/unused-config-surface.js +0 -2
- package/dist/detectors/unused-config-surface.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/build-ts-inventory.d.ts +33 -0
- package/dist/lib/build-ts-inventory.d.ts.map +1 -0
- package/dist/lib/build-ts-inventory.js +252 -0
- package/dist/lib/build-ts-inventory.js.map +1 -0
- package/dist/persistence/session-payload.d.ts +7 -10
- package/dist/persistence/session-payload.d.ts.map +1 -1
- package/dist/persistence/session-payload.js +64 -6
- package/dist/persistence/session-payload.js.map +1 -1
- package/dist/scoring/__tests__/confidence.test.js +3 -4
- package/dist/scoring/__tests__/confidence.test.js.map +1 -1
- package/dist/scoring/confidence.d.ts +1 -1
- package/dist/scoring/confidence.d.ts.map +1 -1
- package/dist/scoring/confidence.js +1 -2
- package/dist/scoring/confidence.js.map +1 -1
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js +3 -1
- package/dist/tool.js.map +1 -1
- package/dist/types/yagni-config.d.ts +1 -4
- package/dist/types/yagni-config.d.ts.map +1 -1
- package/dist/types/yagni-config.js +0 -1
- package/dist/types/yagni-config.js.map +1 -1
- package/dist/types/yagni-metadata.d.ts +0 -1
- package/dist/types/yagni-metadata.d.ts.map +1 -1
- package/package.json +10 -10
- package/dist/__tests__/graph-evidence.test.d.ts +0 -2
- package/dist/__tests__/graph-evidence.test.d.ts.map +0 -1
- package/dist/__tests__/graph-evidence.test.js +0 -159
- package/dist/__tests__/graph-evidence.test.js.map +0 -1
- package/dist/evidence/graph-evidence.d.ts +0 -15
- package/dist/evidence/graph-evidence.d.ts.map +0 -1
- package/dist/evidence/graph-evidence.js +0 -89
- package/dist/evidence/graph-evidence.js.map +0 -1
- package/dist/evidence/load-graph-adapters.d.ts +0 -13
- package/dist/evidence/load-graph-adapters.d.ts.map +0 -1
- package/dist/evidence/load-graph-adapters.js +0 -67
- package/dist/evidence/load-graph-adapters.js.map +0 -1
- package/dist/lib/isolate-exit-code.d.ts +0 -8
- package/dist/lib/isolate-exit-code.d.ts.map +0 -1
- package/dist/lib/isolate-exit-code.js +0 -27
- package/dist/lib/isolate-exit-code.js.map +0 -1
|
@@ -1,137 +1,140 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* duplicate-body-candidate —
|
|
3
|
-
*
|
|
2
|
+
* duplicate-body-candidate — flags function bodies that are byte-identical (after comment
|
|
3
|
+
* strip + whitespace normalization) across two or more sites, so they can be consolidated.
|
|
4
|
+
*
|
|
5
|
+
* yagni owns NO detection math (ADR-0064): it builds its own TypeScript inventory
|
|
6
|
+
* (`buildTsInventory`, no `@opensip-cli/graph` dependency) and calls the shared
|
|
7
|
+
* `findDuplicateBodies` from `@opensip-cli/clone-detection` — the SAME implementation +
|
|
8
|
+
* curation policy graph's `graph:duplicated-function-body` rule uses, so the two tools
|
|
9
|
+
* cannot diverge (the cross-tool parity test is the standing guard). yagni adds only the
|
|
10
|
+
* reduction framing + confidence/metadata.
|
|
4
11
|
*/
|
|
5
|
-
import {
|
|
12
|
+
import { findDuplicateBodies } from '@opensip-cli/clone-detection';
|
|
13
|
+
import { currentScope, withSpan } from '@opensip-cli/core';
|
|
14
|
+
import { buildTsInventory } from '../lib/build-ts-inventory.js';
|
|
6
15
|
import { severityForConfidence } from '../scoring/confidence.js';
|
|
7
16
|
import { createYagniSignal } from './create-yagni-signal.js';
|
|
8
17
|
const DETECTOR_ID = 'duplicate-body-candidate';
|
|
9
18
|
const SLUG = 'yagni:duplicate-body-candidate';
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const buckets = new Map();
|
|
14
|
-
for (const occurrences of Object.values(catalog.functions)) {
|
|
15
|
-
for (const occ of occurrences) {
|
|
16
|
-
const bucket = buckets.get(occ.bodyHash);
|
|
17
|
-
if (bucket)
|
|
18
|
-
bucket.push(occ);
|
|
19
|
-
else
|
|
20
|
-
buckets.set(occ.bodyHash, [occ]);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return buckets;
|
|
19
|
+
const CONFIDENCE = 'medium';
|
|
20
|
+
function span(occ) {
|
|
21
|
+
return occ.bodyLines ?? occ.endLine - occ.line + 1;
|
|
24
22
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
function
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
23
|
+
/**
|
|
24
|
+
* Build a reduction signal for a duplicate group.
|
|
25
|
+
*
|
|
26
|
+
* @throws {Error} If the clone-detection substrate returns a structurally invalid
|
|
27
|
+
* empty group.
|
|
28
|
+
*/
|
|
29
|
+
function groupSignal(group) {
|
|
30
|
+
const primary = group.members[0];
|
|
31
|
+
/* v8 ignore next */
|
|
32
|
+
if (!primary)
|
|
33
|
+
throw new Error('duplicate group with no members');
|
|
34
|
+
const count = group.members.length;
|
|
35
|
+
const netEstimate = span(primary) * (count - 1);
|
|
36
|
+
const peers = group.members
|
|
37
|
+
.slice(1)
|
|
38
|
+
.map((m) => `${m.filePath}:${String(m.line)}`)
|
|
39
|
+
.join(', ');
|
|
40
|
+
return createYagniSignal({
|
|
41
|
+
source: SLUG,
|
|
42
|
+
ruleId: SLUG,
|
|
43
|
+
severity: severityForConfidence(CONFIDENCE),
|
|
44
|
+
category: 'quality',
|
|
45
|
+
message: `${primary.simpleName} has a body duplicated across ${String(count)} sites — consolidate.`,
|
|
46
|
+
suggestion: `Extract the shared body into one function and have all ${String(count)} sites call it.`,
|
|
47
|
+
code: { file: primary.filePath, line: primary.line, column: primary.column },
|
|
48
|
+
yagni: {
|
|
49
|
+
detector: DETECTOR_ID,
|
|
50
|
+
reductionCategory: 'dedupe',
|
|
51
|
+
confidence: CONFIDENCE,
|
|
52
|
+
locDelta: { remove: netEstimate, add: 0, netEstimate, estimateKind: 'lower-bound' },
|
|
53
|
+
preservationArgument: `The body is byte-identical (normalized) across ${String(count)} sites, so consolidating to one function preserves behavior.`,
|
|
54
|
+
suggestedAction: `Consolidate ${String(count)} identical copies of ${primary.simpleName} (peers: ${peers}).`,
|
|
55
|
+
validationRequired: [
|
|
56
|
+
'Confirm the copies are behaviorally identical, not just textually (closures, captured scope).',
|
|
57
|
+
'Run the affected packages’ test suites after consolidation.',
|
|
58
|
+
],
|
|
59
|
+
riskTags: [],
|
|
60
|
+
evidence: [
|
|
61
|
+
{
|
|
62
|
+
id: `dup-body:${primary.bodyHash}`,
|
|
63
|
+
kind: 'duplicate-body',
|
|
64
|
+
summary: `${String(count)} sites share body hash ${primary.bodyHash.slice(0, 12)}.`,
|
|
65
|
+
data: {
|
|
66
|
+
bodyHash: primary.bodyHash,
|
|
67
|
+
occurrenceCount: count,
|
|
68
|
+
sites: group.members.map((m) => `${m.filePath}:${String(m.line)}`),
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
});
|
|
46
74
|
}
|
|
47
|
-
function
|
|
48
|
-
|
|
75
|
+
function aggregateSignal(agg) {
|
|
76
|
+
const netEstimate = span(agg.anchor) * (agg.occurrenceCount - 1);
|
|
77
|
+
return createYagniSignal({
|
|
78
|
+
source: SLUG,
|
|
79
|
+
ruleId: SLUG,
|
|
80
|
+
severity: severityForConfidence(CONFIDENCE),
|
|
81
|
+
category: 'quality',
|
|
82
|
+
message: `A body is duplicated across ${String(agg.packages.length)} packages (${agg.packages.join(', ')}) in ${String(agg.occurrenceCount)} sites — hoist it into a shared package.`,
|
|
83
|
+
suggestion: 'Hoist the shared body into one shared package and have every copy import it.',
|
|
84
|
+
code: { file: agg.anchor.filePath, line: agg.anchor.line, column: agg.anchor.column },
|
|
85
|
+
yagni: {
|
|
86
|
+
detector: DETECTOR_ID,
|
|
87
|
+
reductionCategory: 'dedupe',
|
|
88
|
+
confidence: CONFIDENCE,
|
|
89
|
+
locDelta: { remove: netEstimate, add: 0, netEstimate, estimateKind: 'lower-bound' },
|
|
90
|
+
preservationArgument: `The same normalized body appears in ${String(agg.occurrenceCount)} sites across ${String(agg.packages.length)} packages; hoisting to a shared package preserves behavior.`,
|
|
91
|
+
suggestedAction: `Hoist the body shared across ${agg.packages.join(', ')} into one shared package.`,
|
|
92
|
+
validationRequired: [
|
|
93
|
+
'Confirm the cross-package copies are behaviorally identical.',
|
|
94
|
+
'Add the new shared package as a dependency of each consumer and run their tests.',
|
|
95
|
+
],
|
|
96
|
+
riskTags: ['cross-package'],
|
|
97
|
+
evidence: [
|
|
98
|
+
{
|
|
99
|
+
id: `dup-body-xpkg:${agg.bodyHash}`,
|
|
100
|
+
kind: 'cross-package-duplicate-body',
|
|
101
|
+
summary: `${String(agg.occurrenceCount)} sites across ${agg.packages.join(', ')} share body hash ${agg.bodyHash.slice(0, 12)}.`,
|
|
102
|
+
data: {
|
|
103
|
+
bodyHash: agg.bodyHash,
|
|
104
|
+
occurrenceCount: agg.occurrenceCount,
|
|
105
|
+
packages: agg.packages,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
});
|
|
49
111
|
}
|
|
50
112
|
function runDuplicateBodyCandidate(ctx) {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const anchorRel = relPath(ctx.cwd, anchor.filePath);
|
|
72
|
-
const peer = occs.find((o) => o.qualifiedName !== anchor.qualifiedName) ?? anchor;
|
|
73
|
-
const peerDisplay = displayOccurrence(ctx.cwd, peer);
|
|
74
|
-
signals.push(createYagniSignal({
|
|
75
|
-
source: SLUG,
|
|
76
|
-
ruleId: SLUG,
|
|
77
|
-
severity: severityForConfidence(confidence),
|
|
78
|
-
category: 'architecture',
|
|
79
|
-
message: `Duplicate body candidate (${String(occs.length)} occurrences) — consolidate shared logic (${confidence} confidence)`,
|
|
80
|
-
suggestion: 'Extract the shared body into one module and import it from each copy site.',
|
|
81
|
-
code: {
|
|
82
|
-
file: anchor.filePath,
|
|
83
|
-
line: anchor.line,
|
|
84
|
-
column: anchor.column,
|
|
85
|
-
},
|
|
86
|
-
yagni: {
|
|
87
|
-
detector: DETECTOR_ID,
|
|
88
|
-
reductionCategory: 'dedupe',
|
|
89
|
-
confidence,
|
|
90
|
-
locDelta: {
|
|
91
|
-
remove: netEstimate,
|
|
92
|
-
add: Math.max(1, Math.floor(bodyLines / 2)),
|
|
93
|
-
netEstimate,
|
|
94
|
-
estimateKind: 'heuristic',
|
|
95
|
-
},
|
|
96
|
-
preservationArgument: 'Occurrences share an identical bodyHash from the graph catalog; behavior should match after hoisting.',
|
|
97
|
-
suggestedAction: `Consolidate with ${peerDisplay}.`,
|
|
98
|
-
validationRequired: [
|
|
99
|
-
'Confirm neither occurrence is published public API.',
|
|
100
|
-
'Run tests covering each duplicate site after extraction.',
|
|
101
|
-
],
|
|
102
|
-
riskTags: ['cross-package', 'behavior-preservation'],
|
|
103
|
-
evidence: [
|
|
104
|
-
{
|
|
105
|
-
id: `body-hash:${bodyHash}`,
|
|
106
|
-
kind: 'body-hash-group',
|
|
107
|
-
summary: `${String(occs.length)} functions share bodyHash ${bodyHash.slice(0, 8)}.`,
|
|
108
|
-
data: {
|
|
109
|
-
bodyHash,
|
|
110
|
-
occurrenceCount: occs.length,
|
|
111
|
-
packages,
|
|
112
|
-
anchor: {
|
|
113
|
-
qualifiedName: anchor.qualifiedName,
|
|
114
|
-
filePath: anchorRel,
|
|
115
|
-
line: anchor.line,
|
|
116
|
-
},
|
|
117
|
-
peer: {
|
|
118
|
-
qualifiedName: peer.qualifiedName,
|
|
119
|
-
filePath: relPath(ctx.cwd, peer.filePath),
|
|
120
|
-
line: peer.line,
|
|
121
|
-
},
|
|
122
|
-
},
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
},
|
|
126
|
-
}));
|
|
127
|
-
}
|
|
128
|
-
return Promise.resolve({ signals, durationMs: Date.now() - started });
|
|
113
|
+
const result = withSpan('opensip-cli-yagni', 'yagni.duplicate_body_candidate', () => {
|
|
114
|
+
const started = Date.now();
|
|
115
|
+
const candidates = buildTsInventory(ctx.cwd, ctx.pathRoots);
|
|
116
|
+
const { aggregates, groups } = findDuplicateBodies(candidates);
|
|
117
|
+
const signals = [
|
|
118
|
+
...aggregates.map((a) => aggregateSignal(a)),
|
|
119
|
+
...groups.map((g) => groupSignal(g)),
|
|
120
|
+
];
|
|
121
|
+
const durationMs = Date.now() - started;
|
|
122
|
+
// O2 — one structured scan-complete event (counts + duration only; never body text).
|
|
123
|
+
currentScope()?.logger?.info({
|
|
124
|
+
evt: 'yagni.duplicate-detector.scan.complete',
|
|
125
|
+
module: 'yagni:duplicate-body-candidate',
|
|
126
|
+
durationMs,
|
|
127
|
+
candidateCount: candidates.length,
|
|
128
|
+
groupCount: aggregates.length + groups.length,
|
|
129
|
+
});
|
|
130
|
+
return { signals, durationMs };
|
|
131
|
+
}, { 'yagni.detector': DETECTOR_ID });
|
|
132
|
+
return Promise.resolve(result);
|
|
129
133
|
}
|
|
130
134
|
export const duplicateBodyCandidateDetector = {
|
|
131
135
|
id: DETECTOR_ID,
|
|
132
136
|
slug: SLUG,
|
|
133
|
-
description: '
|
|
134
|
-
requiresGraph: true,
|
|
137
|
+
description: 'Function bodies duplicated across two or more sites (consolidation candidates)',
|
|
135
138
|
run: runDuplicateBodyCandidate,
|
|
136
139
|
};
|
|
137
140
|
//# sourceMappingURL=duplicate-body-candidate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"duplicate-body-candidate.js","sourceRoot":"","sources":["../../src/detectors/duplicate-body-candidate.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"duplicate-body-candidate.js","sourceRoot":"","sources":["../../src/detectors/duplicate-body-candidate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { YagniDetector } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Built-in detector registry in stable registration order.
|
|
4
|
+
*
|
|
5
|
+
* Duplicate-body detection is back (ADR-0064) but now owns NO detection math: it builds
|
|
6
|
+
* yagni's own TypeScript inventory and calls `findDuplicateBodies` from the shared
|
|
7
|
+
* `@opensip-cli/clone-detection` substrate — the same implementation + policy graph uses,
|
|
8
|
+
* so the 430-vs-0 divergence cannot recur (cross-tool parity test guards it). yagni keeps
|
|
9
|
+
* NO dependency on `@opensip-cli/graph`.
|
|
10
|
+
*/
|
|
3
11
|
export declare const YAGNI_DETECTORS: readonly YagniDetector[];
|
|
4
12
|
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/detectors/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/detectors/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,aAAa,EAGnD,CAAC"}
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import { duplicateBodyCandidateDetector } from './duplicate-body-candidate.js';
|
|
2
2
|
import { unusedConfigSurfaceDetector } from './unused-config-surface.js';
|
|
3
|
-
/**
|
|
3
|
+
/**
|
|
4
|
+
* Built-in detector registry in stable registration order.
|
|
5
|
+
*
|
|
6
|
+
* Duplicate-body detection is back (ADR-0064) but now owns NO detection math: it builds
|
|
7
|
+
* yagni's own TypeScript inventory and calls `findDuplicateBodies` from the shared
|
|
8
|
+
* `@opensip-cli/clone-detection` substrate — the same implementation + policy graph uses,
|
|
9
|
+
* so the 430-vs-0 divergence cannot recur (cross-tool parity test guards it). yagni keeps
|
|
10
|
+
* NO dependency on `@opensip-cli/graph`.
|
|
11
|
+
*/
|
|
4
12
|
export const YAGNI_DETECTORS = [
|
|
5
13
|
unusedConfigSurfaceDetector,
|
|
6
14
|
duplicateBodyCandidateDetector,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/detectors/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAIzE
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/detectors/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AAIzE;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,2BAA2B;IAC3B,8BAA8B;CAC/B,CAAC"}
|
|
@@ -16,13 +16,12 @@ export interface YagniDetector {
|
|
|
16
16
|
readonly id: string;
|
|
17
17
|
readonly slug: string;
|
|
18
18
|
readonly description: string;
|
|
19
|
-
readonly requiresGraph: boolean;
|
|
20
19
|
run(ctx: YagniDetectorContext): Promise<YagniDetectorResult>;
|
|
21
20
|
}
|
|
22
21
|
export interface SkippedDetector {
|
|
23
22
|
readonly id: string;
|
|
24
23
|
readonly slug: string;
|
|
25
|
-
readonly reason: 'disabled'
|
|
24
|
+
readonly reason: 'disabled';
|
|
26
25
|
readonly detail?: string;
|
|
27
26
|
}
|
|
28
27
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/detectors/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/detectors/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,GAAG,CAAC,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;CAC9D;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unused-config-surface.d.ts","sourceRoot":"","sources":["../../src/detectors/unused-config-surface.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"unused-config-surface.d.ts","sourceRoot":"","sources":["../../src/detectors/unused-config-surface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,OAAO,KAAK,EAAE,aAAa,EAA6C,MAAM,YAAY,CAAC;AA2M3F,eAAO,MAAM,2BAA2B,EAAE,aAKzC,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @fitness-ignore-file batch-operation-limits -- walks a bounded, already-discovered source file list synchronously; no DB, network, async fanout, or unbounded external batch.
|
|
2
1
|
/**
|
|
3
2
|
* unused-config-surface — flags required config properties on the public API
|
|
4
3
|
* surface that are never read anywhere in the project.
|
|
@@ -193,7 +192,6 @@ export const unusedConfigSurfaceDetector = {
|
|
|
193
192
|
id: DETECTOR_ID,
|
|
194
193
|
slug: SLUG,
|
|
195
194
|
description: 'Unused required config properties on the public API surface',
|
|
196
|
-
requiresGraph: false,
|
|
197
195
|
run: runUnusedConfigSurface,
|
|
198
196
|
};
|
|
199
197
|
//# sourceMappingURL=unused-config-surface.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unused-config-surface.js","sourceRoot":"","sources":["../../src/detectors/unused-config-surface.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"unused-config-surface.js","sourceRoot":"","sources":["../../src/detectors/unused-config-surface.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export { yagniTool, yagniTool as tool, YAGNI_CONTRACT_VERSION, YAGNI_STABLE_ID } from './tool.js';
|
|
5
5
|
export { executeYagni } from './cli/execute-yagni.js';
|
|
6
|
-
export type { YagniConfig
|
|
6
|
+
export type { YagniConfig } from './types/yagni-config.js';
|
|
7
7
|
export type { YagniFindingMetadata } from './types/yagni-metadata.js';
|
|
8
8
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,SAAS,EAAE,SAAS,IAAI,IAAI,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* build-ts-inventory — yagni's OWN TypeScript function-body inventory, the input to its
|
|
3
|
+
* duplicate detector. yagni builds this in-process (no `@opensip-cli/graph` dependency,
|
|
4
|
+
* ADR-0064) by walking the TS AST exactly as graph-typescript's inventory does, so the
|
|
5
|
+
* two tools produce byte-identical `CloneCandidate`s and cannot diverge (the cross-tool
|
|
6
|
+
* parity test is the standing guard).
|
|
7
|
+
*
|
|
8
|
+
* Byte-identity contract (must match `graph-typescript/inventory-helpers/hash-body.ts`
|
|
9
|
+
* + the inventory visitors):
|
|
10
|
+
* - bodyHash/bodySize = `digestCanonicalBody(normalizeWhitespace(stripComments(
|
|
11
|
+
* sourceFile.text.slice(node.getStart(sf), node.getEnd()))))` — same span, same
|
|
12
|
+
* `stripComments` (lang-typescript), same digest (clone-detection).
|
|
13
|
+
* - line = getStart line + 1 (1-based); column = getStart character (0-based);
|
|
14
|
+
* endLine = getEnd line + 1. bodyLines fallback (`endLine − line + 1`) equals graph's
|
|
15
|
+
* feature column (features.ts:132).
|
|
16
|
+
* - inTestFile via the shared `isTestFilePath` (Phase 1 Task 1.3a) — the single predicate.
|
|
17
|
+
* - kind ∈ the eligible set only (function-declaration/method/constructor/getter/setter,
|
|
18
|
+
* with class static blocks emitted as graph's synthetic '<static-init>' function).
|
|
19
|
+
* Arrows / function-expressions / module-init are excluded by policy on both tools, so
|
|
20
|
+
* emitting only the eligible kinds yields the same post-filter groups as graph.
|
|
21
|
+
*
|
|
22
|
+
* Body source text NEVER leaves this parse — only the hash/size/location enter a
|
|
23
|
+
* `CloneCandidate` (H4).
|
|
24
|
+
*/
|
|
25
|
+
import { type CloneCandidate } from '@opensip-cli/clone-detection';
|
|
26
|
+
/**
|
|
27
|
+
* Build the function-body inventory for `cwd` (optionally scoped to `pathRoots`).
|
|
28
|
+
* Walks ALL TS files (including test files) so `inTestFile` stamping is complete and
|
|
29
|
+
* cross-file duplicates are seen; the policy (`findDuplicateBodies`) excludes test-file
|
|
30
|
+
* candidates, exactly as graph does.
|
|
31
|
+
*/
|
|
32
|
+
export declare function buildTsInventory(cwd: string, pathRoots?: readonly string[]): CloneCandidate[];
|
|
33
|
+
//# sourceMappingURL=build-ts-inventory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-ts-inventory.d.ts","sourceRoot":"","sources":["../../src/lib/build-ts-inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,8BAA8B,CAAC;AAYtC;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,cAAc,EAAE,CAyB7F"}
|