forgecraft-mcp 1.4.0 → 1.6.1
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 +2 -2
- package/dist/analyzers/anchors/anchor-loader.d.ts +47 -0
- package/dist/analyzers/anchors/anchor-loader.d.ts.map +1 -0
- package/dist/analyzers/anchors/anchor-loader.js +113 -0
- package/dist/analyzers/anchors/anchor-loader.js.map +1 -0
- package/dist/analyzers/anti-pattern.d.ts.map +1 -1
- package/dist/analyzers/anti-pattern.js +38 -26
- package/dist/analyzers/anti-pattern.js.map +1 -1
- package/dist/analyzers/completeness-helpers.d.ts +5 -0
- package/dist/analyzers/completeness-helpers.d.ts.map +1 -1
- package/dist/analyzers/completeness-helpers.js +17 -0
- package/dist/analyzers/completeness-helpers.js.map +1 -1
- package/dist/analyzers/completeness.d.ts.map +1 -1
- package/dist/analyzers/completeness.js +4 -4
- package/dist/analyzers/completeness.js.map +1 -1
- package/dist/analyzers/gs-scorer.d.ts +3 -1
- package/dist/analyzers/gs-scorer.d.ts.map +1 -1
- package/dist/analyzers/gs-scorer.js +5 -2
- package/dist/analyzers/gs-scorer.js.map +1 -1
- package/dist/analyzers/scorers/composable-scorer.d.ts +4 -2
- package/dist/analyzers/scorers/composable-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/composable-scorer.js +50 -2
- package/dist/analyzers/scorers/composable-scorer.js.map +1 -1
- package/dist/analyzers/scorers/executable-scorer.d.ts +3 -2
- package/dist/analyzers/scorers/executable-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/executable-scorer.js +64 -4
- package/dist/analyzers/scorers/executable-scorer.js.map +1 -1
- package/dist/analyzers/scorers/scorer-utils.d.ts +5 -3
- package/dist/analyzers/scorers/scorer-utils.d.ts.map +1 -1
- package/dist/analyzers/scorers/scorer-utils.js +34 -9
- package/dist/analyzers/scorers/scorer-utils.js.map +1 -1
- package/dist/analyzers/scorers/self-describing-scorer.d.ts +7 -4
- package/dist/analyzers/scorers/self-describing-scorer.d.ts.map +1 -1
- package/dist/analyzers/scorers/self-describing-scorer.js +17 -18
- package/dist/analyzers/scorers/self-describing-scorer.js.map +1 -1
- package/dist/disciplines/catalog.d.ts +16 -0
- package/dist/disciplines/catalog.d.ts.map +1 -0
- package/dist/disciplines/catalog.js +196 -0
- package/dist/disciplines/catalog.js.map +1 -0
- package/dist/disciplines/runner.d.ts +13 -0
- package/dist/disciplines/runner.d.ts.map +1 -0
- package/dist/disciplines/runner.js +35 -0
- package/dist/disciplines/runner.js.map +1 -0
- package/dist/registry/remote-gates.js +1 -1
- package/dist/registry/remote-gates.js.map +1 -1
- package/dist/sentinel/detect.d.ts +41 -0
- package/dist/sentinel/detect.d.ts.map +1 -0
- package/dist/sentinel/detect.js +122 -0
- package/dist/sentinel/detect.js.map +1 -0
- package/dist/sentinel/write.d.ts +54 -0
- package/dist/sentinel/write.d.ts.map +1 -0
- package/dist/sentinel/write.js +75 -0
- package/dist/sentinel/write.js.map +1 -0
- package/dist/shared/cnt-health.d.ts.map +1 -1
- package/dist/shared/cnt-health.js +12 -4
- package/dist/shared/cnt-health.js.map +1 -1
- package/dist/shared/config.d.ts +8 -0
- package/dist/shared/config.d.ts.map +1 -1
- package/dist/shared/config.js +23 -0
- package/dist/shared/config.js.map +1 -1
- package/dist/shared/project-gates-helpers.d.ts +9 -0
- package/dist/shared/project-gates-helpers.d.ts.map +1 -1
- package/dist/shared/project-gates-helpers.js +35 -0
- package/dist/shared/project-gates-helpers.js.map +1 -1
- package/dist/shared/types/config.d.ts +7 -1
- package/dist/shared/types/config.d.ts.map +1 -1
- package/dist/shared/types/gates.d.ts +28 -0
- package/dist/shared/types/gates.d.ts.map +1 -1
- package/dist/shared/types/project.d.ts +66 -0
- package/dist/shared/types/project.d.ts.map +1 -1
- package/dist/shared/types/project.js.map +1 -1
- package/dist/shared/types/verify.d.ts +51 -1
- package/dist/shared/types/verify.d.ts.map +1 -1
- package/dist/shared/types/verify.js +37 -1
- package/dist/shared/types/verify.js.map +1 -1
- package/dist/tools/advise-session-advisor.d.ts +16 -0
- package/dist/tools/advise-session-advisor.d.ts.map +1 -0
- package/dist/tools/advise-session-advisor.js +89 -0
- package/dist/tools/advise-session-advisor.js.map +1 -0
- package/dist/tools/advise-session-signals.d.ts +21 -0
- package/dist/tools/advise-session-signals.d.ts.map +1 -0
- package/dist/tools/advise-session-signals.js +113 -0
- package/dist/tools/advise-session-signals.js.map +1 -0
- package/dist/tools/advise-session.d.ts +22 -0
- package/dist/tools/advise-session.d.ts.map +1 -0
- package/dist/tools/advise-session.js +31 -0
- package/dist/tools/advise-session.js.map +1 -0
- package/dist/tools/change-request.d.ts +53 -0
- package/dist/tools/change-request.d.ts.map +1 -0
- package/dist/tools/change-request.js +375 -0
- package/dist/tools/change-request.js.map +1 -0
- package/dist/tools/check-cascade-contracts.d.ts +13 -0
- package/dist/tools/check-cascade-contracts.d.ts.map +1 -1
- package/dist/tools/check-cascade-contracts.js +73 -2
- package/dist/tools/check-cascade-contracts.js.map +1 -1
- package/dist/tools/check-cascade.d.ts +4 -3
- package/dist/tools/check-cascade.d.ts.map +1 -1
- package/dist/tools/check-cascade.js +30 -12
- package/dist/tools/check-cascade.js.map +1 -1
- package/dist/tools/check-spec-consistency.d.ts +25 -0
- package/dist/tools/check-spec-consistency.d.ts.map +1 -0
- package/dist/tools/check-spec-consistency.js +339 -0
- package/dist/tools/check-spec-consistency.js.map +1 -0
- package/dist/tools/check-t4.d.ts +54 -0
- package/dist/tools/check-t4.d.ts.map +1 -0
- package/dist/tools/check-t4.js +305 -0
- package/dist/tools/check-t4.js.map +1 -0
- package/dist/tools/close-cycle.d.ts.map +1 -1
- package/dist/tools/close-cycle.js +341 -3
- package/dist/tools/close-cycle.js.map +1 -1
- package/dist/tools/consolidate-status.d.ts +31 -0
- package/dist/tools/consolidate-status.d.ts.map +1 -1
- package/dist/tools/consolidate-status.js +105 -0
- package/dist/tools/consolidate-status.js.map +1 -1
- package/dist/tools/executable-gates.d.ts +52 -0
- package/dist/tools/executable-gates.d.ts.map +1 -0
- package/dist/tools/executable-gates.js +332 -0
- package/dist/tools/executable-gates.js.map +1 -0
- package/dist/tools/forgecraft-dispatch-extended.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch-extended.js +75 -0
- package/dist/tools/forgecraft-dispatch-extended.js.map +1 -1
- package/dist/tools/forgecraft-dispatch.d.ts.map +1 -1
- package/dist/tools/forgecraft-dispatch.js +11 -0
- package/dist/tools/forgecraft-dispatch.js.map +1 -1
- package/dist/tools/forgecraft-schema-params.d.ts +59 -2
- package/dist/tools/forgecraft-schema-params.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema-params.js +95 -0
- package/dist/tools/forgecraft-schema-params.js.map +1 -1
- package/dist/tools/forgecraft-schema.d.ts +60 -3
- package/dist/tools/forgecraft-schema.d.ts.map +1 -1
- package/dist/tools/forgecraft-schema.js +21 -0
- package/dist/tools/forgecraft-schema.js.map +1 -1
- package/dist/tools/generate-adr.js +6 -6
- package/dist/tools/generate-adr.js.map +1 -1
- package/dist/tools/generate-env-probe.d.ts +49 -0
- package/dist/tools/generate-env-probe.d.ts.map +1 -0
- package/dist/tools/generate-env-probe.js +365 -0
- package/dist/tools/generate-env-probe.js.map +1 -0
- package/dist/tools/generate-harness.d.ts +52 -0
- package/dist/tools/generate-harness.d.ts.map +1 -0
- package/dist/tools/generate-harness.js +333 -0
- package/dist/tools/generate-harness.js.map +1 -0
- package/dist/tools/generate-roadmap.d.ts +1 -1
- package/dist/tools/generate-roadmap.d.ts.map +1 -1
- package/dist/tools/generate-roadmap.js +38 -4
- package/dist/tools/generate-roadmap.js.map +1 -1
- package/dist/tools/generate-session-prompt.d.ts +3 -3
- package/dist/tools/generate-session-prompt.d.ts.map +1 -1
- package/dist/tools/generate-session-prompt.js +9 -1
- package/dist/tools/generate-session-prompt.js.map +1 -1
- package/dist/tools/generate-slo-probe.d.ts +53 -0
- package/dist/tools/generate-slo-probe.d.ts.map +1 -0
- package/dist/tools/generate-slo-probe.js +366 -0
- package/dist/tools/generate-slo-probe.js.map +1 -0
- package/dist/tools/layer-status-gates.d.ts +24 -0
- package/dist/tools/layer-status-gates.d.ts.map +1 -0
- package/dist/tools/layer-status-gates.js +151 -0
- package/dist/tools/layer-status-gates.js.map +1 -0
- package/dist/tools/layer-status.d.ts +133 -0
- package/dist/tools/layer-status.d.ts.map +1 -0
- package/dist/tools/layer-status.js +593 -0
- package/dist/tools/layer-status.js.map +1 -0
- package/dist/tools/postcondition-coverage.d.ts +57 -0
- package/dist/tools/postcondition-coverage.d.ts.map +1 -0
- package/dist/tools/postcondition-coverage.js +256 -0
- package/dist/tools/postcondition-coverage.js.map +1 -0
- package/dist/tools/probe-runners.d.ts +21 -0
- package/dist/tools/probe-runners.d.ts.map +1 -0
- package/dist/tools/probe-runners.js +246 -0
- package/dist/tools/probe-runners.js.map +1 -0
- package/dist/tools/probe-templates.d.ts +27 -0
- package/dist/tools/probe-templates.d.ts.map +1 -0
- package/dist/tools/probe-templates.js +279 -0
- package/dist/tools/probe-templates.js.map +1 -0
- package/dist/tools/propose-session.d.ts +28 -0
- package/dist/tools/propose-session.d.ts.map +1 -0
- package/dist/tools/propose-session.js +333 -0
- package/dist/tools/propose-session.js.map +1 -0
- package/dist/tools/roadmap-builder.d.ts +34 -1
- package/dist/tools/roadmap-builder.d.ts.map +1 -1
- package/dist/tools/roadmap-builder.js +135 -3
- package/dist/tools/roadmap-builder.js.map +1 -1
- package/dist/tools/run-env-probe.d.ts +57 -0
- package/dist/tools/run-env-probe.d.ts.map +1 -0
- package/dist/tools/run-env-probe.js +270 -0
- package/dist/tools/run-env-probe.js.map +1 -0
- package/dist/tools/run-harness.d.ts +52 -0
- package/dist/tools/run-harness.d.ts.map +1 -0
- package/dist/tools/run-harness.js +279 -0
- package/dist/tools/run-harness.js.map +1 -0
- package/dist/tools/run-slo-probe.d.ts +50 -0
- package/dist/tools/run-slo-probe.d.ts.map +1 -0
- package/dist/tools/run-slo-probe.js +281 -0
- package/dist/tools/run-slo-probe.js.map +1 -0
- package/dist/tools/scaffold-writer.d.ts.map +1 -1
- package/dist/tools/scaffold-writer.js +4 -0
- package/dist/tools/scaffold-writer.js.map +1 -1
- package/dist/tools/session-prompt-builders.d.ts +20 -0
- package/dist/tools/session-prompt-builders.d.ts.map +1 -1
- package/dist/tools/session-prompt-builders.js +78 -5
- package/dist/tools/session-prompt-builders.js.map +1 -1
- package/dist/tools/session-prompt-sections.d.ts +4 -2
- package/dist/tools/session-prompt-sections.d.ts.map +1 -1
- package/dist/tools/session-prompt-sections.js +22 -10
- package/dist/tools/session-prompt-sections.js.map +1 -1
- package/dist/tools/setup-monitoring.d.ts +41 -0
- package/dist/tools/setup-monitoring.d.ts.map +1 -0
- package/dist/tools/setup-monitoring.js +364 -0
- package/dist/tools/setup-monitoring.js.map +1 -0
- package/dist/tools/verify-formatter.d.ts.map +1 -1
- package/dist/tools/verify-formatter.js +15 -1
- package/dist/tools/verify-formatter.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +3 -0
- package/dist/tools/verify.js.map +1 -1
- package/package.json +11 -2
- package/templates/api/harness/uc-template.hurl +20 -0
- package/templates/docs-manifest.yaml +224 -0
- package/templates/game/harness/uc-template.sim.ts +29 -0
- package/templates/universal/claude-md-blocks/layer-navigation.md +20 -0
- package/templates/universal/claude-md-blocks/nfr-contracts.md +22 -0
- package/templates/web-react/harness/uc-template.spec.ts +35 -0
package/README.md
CHANGED
|
@@ -110,7 +110,7 @@ Gates are organized by release phase so you're not running pre-release chaos tes
|
|
|
110
110
|
|
|
111
111
|
Gates tagged `requires_human_review: true` cannot be auto-passed — some checks require a human.
|
|
112
112
|
|
|
113
|
-
The full gate library, contribution guide, and schema are in the [quality gates repository →](https://github.com/jghiringhelli/
|
|
113
|
+
The full gate library, contribution guide, and schema are in the [quality gates repository →](https://github.com/jghiringhelli/quality-gates)
|
|
114
114
|
|
|
115
115
|
---
|
|
116
116
|
|
|
@@ -250,7 +250,7 @@ Every block is sourced from established engineering literature (Martin, Evans, W
|
|
|
250
250
|
|
|
251
251
|
Tags tell ForgeCraft what your project is. On first setup, the AI analyzes your spec and codebase and assigns them. You can review and override in `forgecraft.yaml`. Blocks merge without conflicts — add or remove tags as the project evolves.
|
|
252
252
|
|
|
253
|
-
The full tag list and contribution guide live in the [quality gates repository →](https://github.com/jghiringhelli/
|
|
253
|
+
The full tag list and contribution guide live in the [quality gates repository →](https://github.com/jghiringhelli/quality-gates)
|
|
254
254
|
|
|
255
255
|
| Tag | What it adds |
|
|
256
256
|
|-----|-------------|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calibration anchor loader.
|
|
3
|
+
*
|
|
4
|
+
* Anchors are markdown files that ground each GS property score level (0/1/2)
|
|
5
|
+
* in a concrete real-world example. Consumers (e.g. pragmaworks) ship their
|
|
6
|
+
* own anchor library; this repo also includes a default set under `anchors/`
|
|
7
|
+
* for self-calibration and tests.
|
|
8
|
+
*
|
|
9
|
+
* Layout:
|
|
10
|
+
* <anchorPath>/<property>/<level>.md
|
|
11
|
+
* e.g. anchors/bounded/2.md
|
|
12
|
+
*
|
|
13
|
+
* Anchor file format:
|
|
14
|
+
* # <title>
|
|
15
|
+
* - repo: <repo+commit-hash>
|
|
16
|
+
* - feature: <feature being anchored>
|
|
17
|
+
*
|
|
18
|
+
* ## Why this score
|
|
19
|
+
* <reason it sits at the level>
|
|
20
|
+
*
|
|
21
|
+
* ## What would move it up
|
|
22
|
+
* <delta to next level>
|
|
23
|
+
*/
|
|
24
|
+
import type { AnchorReference, GsProperty, GsPropertyScore } from "../../shared/types.js";
|
|
25
|
+
/** Options accepted by the scoring engine to control anchor lookup. */
|
|
26
|
+
export interface AnchorOptions {
|
|
27
|
+
/**
|
|
28
|
+
* Absolute path to a directory of anchor files. When unset, anchors are
|
|
29
|
+
* not consulted and scores remain non-provisional.
|
|
30
|
+
*/
|
|
31
|
+
readonly anchorPath?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Load a calibration anchor for a property + level.
|
|
35
|
+
*
|
|
36
|
+
* @returns The parsed anchor reference, or null when no file exists.
|
|
37
|
+
*/
|
|
38
|
+
export declare function loadAnchor(anchorPath: string, property: GsProperty, level: 0 | 1 | 2): AnchorReference | null;
|
|
39
|
+
/** Parse the markdown body of an anchor file into an AnchorReference. */
|
|
40
|
+
export declare function parseAnchorFile(raw: string, path: string, property: GsProperty, level: 0 | 1 | 2): AnchorReference;
|
|
41
|
+
/**
|
|
42
|
+
* Apply a calibration anchor to a score. When the anchor exists, append a
|
|
43
|
+
* reference line to evidence and attach the AnchorReference. When no anchor
|
|
44
|
+
* is available, mark the score `provisional: true` and add an explanatory note.
|
|
45
|
+
*/
|
|
46
|
+
export declare function applyAnchor(score: GsPropertyScore, options: AnchorOptions): GsPropertyScore;
|
|
47
|
+
//# sourceMappingURL=anchor-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor-loader.d.ts","sourceRoot":"","sources":["../../../src/analyzers/anchors/anchor-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,eAAe,EAChB,MAAM,uBAAuB,CAAC;AAE/B,uEAAuE;AACvE,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GACf,eAAe,GAAG,IAAI,CAYxB;AAED,yEAAyE;AACzE,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,UAAU,EACpB,KAAK,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GACf,eAAe,CAiBjB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,aAAa,GACrB,eAAe,CAuBjB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calibration anchor loader.
|
|
3
|
+
*
|
|
4
|
+
* Anchors are markdown files that ground each GS property score level (0/1/2)
|
|
5
|
+
* in a concrete real-world example. Consumers (e.g. pragmaworks) ship their
|
|
6
|
+
* own anchor library; this repo also includes a default set under `anchors/`
|
|
7
|
+
* for self-calibration and tests.
|
|
8
|
+
*
|
|
9
|
+
* Layout:
|
|
10
|
+
* <anchorPath>/<property>/<level>.md
|
|
11
|
+
* e.g. anchors/bounded/2.md
|
|
12
|
+
*
|
|
13
|
+
* Anchor file format:
|
|
14
|
+
* # <title>
|
|
15
|
+
* - repo: <repo+commit-hash>
|
|
16
|
+
* - feature: <feature being anchored>
|
|
17
|
+
*
|
|
18
|
+
* ## Why this score
|
|
19
|
+
* <reason it sits at the level>
|
|
20
|
+
*
|
|
21
|
+
* ## What would move it up
|
|
22
|
+
* <delta to next level>
|
|
23
|
+
*/
|
|
24
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
25
|
+
import { join } from "node:path";
|
|
26
|
+
/**
|
|
27
|
+
* Load a calibration anchor for a property + level.
|
|
28
|
+
*
|
|
29
|
+
* @returns The parsed anchor reference, or null when no file exists.
|
|
30
|
+
*/
|
|
31
|
+
export function loadAnchor(anchorPath, property, level) {
|
|
32
|
+
const filePath = join(anchorPath, property, `${level}.md`);
|
|
33
|
+
if (!existsSync(filePath)) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
let raw = "";
|
|
37
|
+
try {
|
|
38
|
+
raw = readFileSync(filePath, "utf-8");
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
return parseAnchorFile(raw, filePath, property, level);
|
|
44
|
+
}
|
|
45
|
+
/** Parse the markdown body of an anchor file into an AnchorReference. */
|
|
46
|
+
export function parseAnchorFile(raw, path, property, level) {
|
|
47
|
+
const titleMatch = raw.match(/^#\s+(.+)$/m);
|
|
48
|
+
const repoMatch = raw.match(/^[-*]\s*repo\s*:\s*(.+)$/im);
|
|
49
|
+
const featureMatch = raw.match(/^[-*]\s*feature\s*:\s*(.+)$/im);
|
|
50
|
+
const rationale = extractSection(raw, /Why this score/i);
|
|
51
|
+
const nextLevelDelta = extractSection(raw, /What would move it up/i);
|
|
52
|
+
return {
|
|
53
|
+
property,
|
|
54
|
+
level,
|
|
55
|
+
path,
|
|
56
|
+
title: titleMatch?.[1]?.trim(),
|
|
57
|
+
anchoredRepo: repoMatch?.[1]?.trim(),
|
|
58
|
+
feature: featureMatch?.[1]?.trim(),
|
|
59
|
+
rationale: rationale ?? undefined,
|
|
60
|
+
nextLevelDelta: nextLevelDelta ?? undefined,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Apply a calibration anchor to a score. When the anchor exists, append a
|
|
65
|
+
* reference line to evidence and attach the AnchorReference. When no anchor
|
|
66
|
+
* is available, mark the score `provisional: true` and add an explanatory note.
|
|
67
|
+
*/
|
|
68
|
+
export function applyAnchor(score, options) {
|
|
69
|
+
if (!options.anchorPath) {
|
|
70
|
+
return score;
|
|
71
|
+
}
|
|
72
|
+
const anchor = loadAnchor(options.anchorPath, score.property, score.score);
|
|
73
|
+
if (anchor) {
|
|
74
|
+
const ref = anchor.title
|
|
75
|
+
? `Anchor: ${anchor.title} (${anchor.path})`
|
|
76
|
+
: `Anchor: ${anchor.path}`;
|
|
77
|
+
return {
|
|
78
|
+
...score,
|
|
79
|
+
anchor,
|
|
80
|
+
evidence: [...score.evidence, ref],
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
...score,
|
|
85
|
+
provisional: true,
|
|
86
|
+
evidence: [
|
|
87
|
+
...score.evidence,
|
|
88
|
+
`Provisional: no anchor at ${join(options.anchorPath, score.property, `${score.score}.md`)} — score is unanchored.`,
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function extractSection(raw, header) {
|
|
93
|
+
const lines = raw.split("\n");
|
|
94
|
+
let inSection = false;
|
|
95
|
+
const collected = [];
|
|
96
|
+
for (const line of lines) {
|
|
97
|
+
if (/^#{1,6}\s+/.test(line)) {
|
|
98
|
+
if (inSection)
|
|
99
|
+
break;
|
|
100
|
+
const heading = line.replace(/^#+\s+/, "").trim();
|
|
101
|
+
if (header.test(heading)) {
|
|
102
|
+
inSection = true;
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
else if (inSection) {
|
|
107
|
+
collected.push(line);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const body = collected.join("\n").trim();
|
|
111
|
+
return body.length > 0 ? body : null;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=anchor-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor-loader.js","sourceRoot":"","sources":["../../../src/analyzers/anchors/anchor-loader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anti-pattern.d.ts","sourceRoot":"","sources":["../../src/analyzers/anti-pattern.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"anti-pattern.d.ts","sourceRoot":"","sources":["../../src/analyzers/anti-pattern.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAIrD,uCAAuC;AACvC,UAAU,UAAU;IAClB,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC;AAOD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,OAAO,CAAC,UAAU,CAAM,GAC/B;IAAE,UAAU,EAAE,UAAU,EAAE,CAAC;IAAC,QAAQ,EAAE,UAAU,EAAE,CAAA;CAAE,CA6HtD"}
|
|
@@ -8,6 +8,7 @@ import { readFileSync, existsSync } from "node:fs";
|
|
|
8
8
|
import { join, extname } from "node:path";
|
|
9
9
|
import { createLogger } from "../shared/logger/index.js";
|
|
10
10
|
import { listAllFiles } from "./folder-structure.js";
|
|
11
|
+
import { readExceptions, findMatchingException } from "../shared/exceptions.js";
|
|
11
12
|
const logger = createLogger("analyzers/anti-pattern");
|
|
12
13
|
const DEFAULT_CONFIG = {
|
|
13
14
|
maxFileLength: 300,
|
|
@@ -20,6 +21,7 @@ export function scanAntiPatterns(projectDir, config = {}) {
|
|
|
20
21
|
const cfg = { ...DEFAULT_CONFIG, ...config };
|
|
21
22
|
const violations = [];
|
|
22
23
|
const warnings = [];
|
|
24
|
+
const exceptions = readExceptions(projectDir);
|
|
23
25
|
const allFiles = listAllFiles(projectDir);
|
|
24
26
|
const sourceFiles = allFiles.filter((f) => isSourceFile(f) && !isTestFile(f));
|
|
25
27
|
logger.info("Scanning for anti-patterns", {
|
|
@@ -33,21 +35,26 @@ export function scanAntiPatterns(projectDir, config = {}) {
|
|
|
33
35
|
try {
|
|
34
36
|
const content = readFileSync(fullPath, "utf-8");
|
|
35
37
|
const lines = content.split("\n");
|
|
36
|
-
// Check file length
|
|
37
|
-
if (lines.length > cfg.maxFileLength
|
|
38
|
+
// Check file length (skip when exempted)
|
|
39
|
+
if (lines.length > cfg.maxFileLength &&
|
|
40
|
+
!findMatchingException(exceptions, "audit/file_length", relPath)) {
|
|
38
41
|
warnings.push({
|
|
39
42
|
check: "file_length",
|
|
40
43
|
message: `${relPath}: ${lines.length} lines (max ${cfg.maxFileLength}). Consider splitting.`,
|
|
41
44
|
severity: "warning",
|
|
42
45
|
});
|
|
43
46
|
}
|
|
44
|
-
// Check for hardcoded URLs (skip config files)
|
|
45
|
-
if (!isConfigFile(relPath)
|
|
47
|
+
// Check for hardcoded URLs (skip config files and exempted files)
|
|
48
|
+
if (!isConfigFile(relPath) &&
|
|
49
|
+
!findMatchingException(exceptions, "audit/hardcoded_url", relPath)) {
|
|
46
50
|
const urlMatches = findPattern(lines, /(localhost|127\.0\.0\.1|0\.0\.0\.0)/,
|
|
47
51
|
// Exclude: comments, test/spec/mock paths, regex literals,
|
|
48
52
|
// JS/TS env-var fallback defaults (process.env.X ?? 'localhost'),
|
|
49
|
-
//
|
|
50
|
-
|
|
53
|
+
// Python env-var fallback defaults (os.environ.get("X", "localhost")),
|
|
54
|
+
// Shell env-var fallback defaults (${VAR:-http://localhost:...}),
|
|
55
|
+
// Backtick markdown code-block lines, and lines inside string-array
|
|
56
|
+
// template literals (e.g. emitting example HTTP fixtures).
|
|
57
|
+
/^\s*(\/\/|\/\*|\*|#|`)|test|spec|mock|\/\(.*localhost|\?\?.*['"`]|os\.environ|os\.getenv|environ\.get|\$\{[^}]*:-|^\s*`[^`]*`\s*,\s*$/i);
|
|
51
58
|
if (urlMatches.length > 0) {
|
|
52
59
|
violations.push({
|
|
53
60
|
check: "hardcoded_url",
|
|
@@ -56,19 +63,22 @@ export function scanAntiPatterns(projectDir, config = {}) {
|
|
|
56
63
|
});
|
|
57
64
|
}
|
|
58
65
|
}
|
|
59
|
-
// Check for mock/stub data in production code
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
// Check for mock/stub data in production code (skip exempted)
|
|
67
|
+
if (!findMatchingException(exceptions, "audit/mock_in_source", relPath)) {
|
|
68
|
+
const mockMatches = findPattern(lines, /\b(mock_data|fake_data|dummy_data|stub_response|FIXME.*return|TODO.*hardcod)/i,
|
|
69
|
+
// Exclude: lines that are regex literal patterns or new RegExp constructs
|
|
70
|
+
/\/\\b\(|\/\(|new RegExp/i);
|
|
71
|
+
if (mockMatches.length > 0) {
|
|
72
|
+
violations.push({
|
|
73
|
+
check: "mock_in_source",
|
|
74
|
+
message: `${relPath}: mock/stub/fake data at line(s) ${mockMatches.join(", ")}. Remove from production code.`,
|
|
75
|
+
severity: "error",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
69
78
|
}
|
|
70
|
-
// Check for bare exception catches (TypeScript)
|
|
71
|
-
if (relPath.endsWith(".ts") || relPath.endsWith(".js"))
|
|
79
|
+
// Check for bare exception catches (TypeScript) — skip exempted
|
|
80
|
+
if ((relPath.endsWith(".ts") || relPath.endsWith(".js")) &&
|
|
81
|
+
!findMatchingException(exceptions, "audit/bare_exception", relPath)) {
|
|
72
82
|
const bareCatches = findPattern(lines, /catch\s*\(\s*\)\s*\{/);
|
|
73
83
|
if (bareCatches.length > 0) {
|
|
74
84
|
warnings.push({
|
|
@@ -78,14 +88,16 @@ export function scanAntiPatterns(projectDir, config = {}) {
|
|
|
78
88
|
});
|
|
79
89
|
}
|
|
80
90
|
}
|
|
81
|
-
// Check for hardcoded credentials
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
91
|
+
// Check for hardcoded credentials (skip exempted)
|
|
92
|
+
if (!findMatchingException(exceptions, "audit/hardcoded_credential", relPath)) {
|
|
93
|
+
const credMatches = findPattern(lines, /(password|secret|api_key|token)\s*[:=]\s*['"][^'"]{3,}/i, /env|config|example|template|schema|type|interface|\/\//i);
|
|
94
|
+
if (credMatches.length > 0) {
|
|
95
|
+
violations.push({
|
|
96
|
+
check: "hardcoded_credential",
|
|
97
|
+
message: `${relPath}: possible hardcoded credential at line(s) ${credMatches.join(", ")}.`,
|
|
98
|
+
severity: "error",
|
|
99
|
+
});
|
|
100
|
+
}
|
|
89
101
|
}
|
|
90
102
|
}
|
|
91
103
|
catch {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anti-pattern.js","sourceRoot":"","sources":["../../src/analyzers/anti-pattern.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"anti-pattern.js","sourceRoot":"","sources":["../../src/analyzers/anti-pattern.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,11 @@ export declare function checkInstructionFileExists(projectDir: string, passing:
|
|
|
24
24
|
* @param failing - Accumulator for failing checks
|
|
25
25
|
*/
|
|
26
26
|
export declare function checkFileExists(projectDir: string, relativePath: string, checkId: string, description: string, passing: AuditCheck[], failing: AuditCheck[]): void;
|
|
27
|
+
/**
|
|
28
|
+
* Pass if any of the candidate paths exists. Used for canonical+legacy fallbacks
|
|
29
|
+
* (e.g. docs/specs/PRD.md OR docs/PRD.md). The first existing path is reported.
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkAnyFileExists(projectDir: string, candidates: readonly string[], checkId: string, description: string, passing: AuditCheck[], failing: AuditCheck[]): void;
|
|
27
32
|
/**
|
|
28
33
|
* Check if Status.md was updated recently (within 7 days).
|
|
29
34
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completeness-helpers.d.ts","sourceRoot":"","sources":["../../src/analyzers/completeness-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAyB,MAAM,yBAAyB,CAAC;AAEhF,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB,UAOnC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAkBN;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAWN;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAwBN;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAqCN;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CA4BN;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,EACrB,UAAU,GAAE,UAAU,CAAC,OAAO,cAAc,CAAM,GACjD,IAAI,CA0DN"}
|
|
1
|
+
{"version":3,"file":"completeness-helpers.d.ts","sourceRoot":"","sources":["../../src/analyzers/completeness-helpers.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAyB,MAAM,yBAAyB,CAAC;AAEhF,0DAA0D;AAC1D,eAAO,MAAM,uBAAuB,UAOnC,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAkBN;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAWN;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAWN;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAwBN;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAqCN;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CA4BN;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,UAAU,EAAE,EACrB,OAAO,EAAE,UAAU,EAAE,EACrB,UAAU,GAAE,UAAU,CAAC,OAAO,cAAc,CAAM,GACjD,IAAI,CA0DN"}
|
|
@@ -59,6 +59,23 @@ export function checkFileExists(projectDir, relativePath, checkId, description,
|
|
|
59
59
|
});
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Pass if any of the candidate paths exists. Used for canonical+legacy fallbacks
|
|
64
|
+
* (e.g. docs/specs/PRD.md OR docs/PRD.md). The first existing path is reported.
|
|
65
|
+
*/
|
|
66
|
+
export function checkAnyFileExists(projectDir, candidates, checkId, description, passing, failing) {
|
|
67
|
+
const found = candidates.find((p) => existsSync(join(projectDir, p)));
|
|
68
|
+
if (found) {
|
|
69
|
+
passing.push({ check: checkId, message: `✅ ${found} exists` });
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
failing.push({
|
|
73
|
+
check: checkId,
|
|
74
|
+
message: `none of [${candidates.join(", ")}] found — ${description}`,
|
|
75
|
+
severity: "error",
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
62
79
|
/**
|
|
63
80
|
* Check if Status.md was updated recently (within 7 days).
|
|
64
81
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completeness-helpers.js","sourceRoot":"","sources":["../../src/analyzers/completeness-helpers.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"completeness-helpers.js","sourceRoot":"","sources":["../../src/analyzers/completeness-helpers.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completeness.d.ts","sourceRoot":"","sources":["../../src/analyzers/completeness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"completeness.d.ts","sourceRoot":"","sources":["../../src/analyzers/completeness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,oBAAoB,CAAC;AAc1D;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,GAAG,EAAE,GAChB;IAAE,OAAO,EAAE,UAAU,EAAE,CAAC;IAAC,OAAO,EAAE,UAAU,EAAE,CAAA;CAAE,CAiFlD"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { existsSync } from "node:fs";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { createLogger } from "../shared/logger/index.js";
|
|
10
|
-
import { checkInstructionFileExists, checkFileExists, checkStatusMdFreshness, checkHooksInstalled, checkSharedModules, checkPackageJson, } from "./completeness-helpers.js";
|
|
10
|
+
import { checkInstructionFileExists, checkFileExists, checkAnyFileExists, checkStatusMdFreshness, checkHooksInstalled, checkSharedModules, checkPackageJson, } from "./completeness-helpers.js";
|
|
11
11
|
import { readExceptions } from "../shared/exceptions.js";
|
|
12
12
|
const logger = createLogger("analyzers/completeness");
|
|
13
13
|
/**
|
|
@@ -27,9 +27,9 @@ export function checkCompleteness(projectDir, activeTags) {
|
|
|
27
27
|
checkFileExists(projectDir, ".env.example", "env_example_exists", ".env.example documents required env vars", passing, failing);
|
|
28
28
|
checkStatusMdFreshness(projectDir, passing, failing);
|
|
29
29
|
checkHooksInstalled(projectDir, passing, failing);
|
|
30
|
-
// Check docs
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
// Check docs (canonical paths first; legacy as fallback for non-migrated projects)
|
|
31
|
+
checkAnyFileExists(projectDir, ["docs/specs/PRD.md", "docs/PRD.md"], "prd_exists", "PRD documents requirements", passing, failing);
|
|
32
|
+
checkAnyFileExists(projectDir, ["docs/contracts/TechSpec.md", "docs/TechSpec.md"], "tech_spec_exists", "Tech Spec documents architecture", passing, failing);
|
|
33
33
|
checkSharedModules(projectDir, passing, failing);
|
|
34
34
|
// Tag-specific checks
|
|
35
35
|
if (activeTags.includes("API") || activeTags.includes("LIBRARY")) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"completeness.js","sourceRoot":"","sources":["../../src/analyzers/completeness.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,OAAO,EACL,0BAA0B,EAC1B,eAAe,EACf,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAEzD,MAAM,MAAM,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;AAEtD;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAC/B,UAAkB,EAClB,UAAiB;IAEjB,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,OAAO,GAAiB,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAE9C,gCAAgC;IAChC,0BAA0B,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACzD,eAAe,CACb,UAAU,EACV,WAAW,EACX,kBAAkB,EAClB,sCAAsC,EACtC,OAAO,EACP,OAAO,CACR,CAAC;IACF,eAAe,CACb,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,0CAA0C,EAC1C,OAAO,EACP,OAAO,CACR,CAAC;IAEF,sBAAsB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACrD,mBAAmB,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAElD,
|
|
1
|
+
{"version":3,"file":"completeness.js","sourceRoot":"","sources":["../../src/analyzers/completeness.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Each property scorer lives in scorers/ and is re-exported for backward compatibility.
|
|
6
6
|
*/
|
|
7
7
|
import type { GsPropertyScore, LayerViolation, MissingTestFile } from "../shared/types.js";
|
|
8
|
+
import { type AnchorOptions } from "./anchors/anchor-loader.js";
|
|
8
9
|
/**
|
|
9
10
|
* Score all seven GS properties for a project directory.
|
|
10
11
|
*
|
|
@@ -12,9 +13,10 @@ import type { GsPropertyScore, LayerViolation, MissingTestFile } from "../shared
|
|
|
12
13
|
* @param testsPassed - Whether the test suite passed (feeds Verifiable)
|
|
13
14
|
* @param layerViolations - Pre-computed layer violations (feeds Bounded)
|
|
14
15
|
* @param missingTestFiles - Pre-computed missing test files (feeds Verifiable)
|
|
16
|
+
* @param options - Optional scoring options (e.g. calibration anchorPath)
|
|
15
17
|
* @returns Array of scored GS properties in canonical §4.3 order (7 properties)
|
|
16
18
|
*/
|
|
17
|
-
export declare function scoreGsProperties(projectDir: string, testsPassed: boolean, layerViolations: LayerViolation[], missingTestFiles: MissingTestFile[]): GsPropertyScore[];
|
|
19
|
+
export declare function scoreGsProperties(projectDir: string, testsPassed: boolean, layerViolations: LayerViolation[], missingTestFiles: MissingTestFile[], options?: AnchorOptions): GsPropertyScore[];
|
|
18
20
|
/**
|
|
19
21
|
* Find all direct-DB / ORM calls inside route and controller source files.
|
|
20
22
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gs-scorer.d.ts","sourceRoot":"","sources":["../../src/analyzers/gs-scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EAChB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"gs-scorer.d.ts","sourceRoot":"","sources":["../../src/analyzers/gs-scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,eAAe,EAChB,MAAM,oBAAoB,CAAC;AAkB5B,OAAO,EAAe,KAAK,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAI7E;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,OAAO,EACpB,eAAe,EAAE,cAAc,EAAE,EACjC,gBAAgB,EAAE,eAAe,EAAE,EACnC,OAAO,GAAE,aAAkB,GAC1B,eAAe,EAAE,CAgBnB;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,MAAM,GACjB,cAAc,EAAE,CAwBlB;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,EAAE,CAqB1E"}
|
|
@@ -16,6 +16,7 @@ import { scoreDefended } from "./scorers/defended-scorer.js";
|
|
|
16
16
|
import { scoreAuditable } from "./scorers/auditable-scorer.js";
|
|
17
17
|
import { scoreComposable } from "./scorers/composable-scorer.js";
|
|
18
18
|
import { scoreExecutable } from "./scorers/executable-scorer.js";
|
|
19
|
+
import { applyAnchor } from "./anchors/anchor-loader.js";
|
|
19
20
|
const logger = createLogger("analyzers/gs-scorer");
|
|
20
21
|
/**
|
|
21
22
|
* Score all seven GS properties for a project directory.
|
|
@@ -24,12 +25,13 @@ const logger = createLogger("analyzers/gs-scorer");
|
|
|
24
25
|
* @param testsPassed - Whether the test suite passed (feeds Verifiable)
|
|
25
26
|
* @param layerViolations - Pre-computed layer violations (feeds Bounded)
|
|
26
27
|
* @param missingTestFiles - Pre-computed missing test files (feeds Verifiable)
|
|
28
|
+
* @param options - Optional scoring options (e.g. calibration anchorPath)
|
|
27
29
|
* @returns Array of scored GS properties in canonical §4.3 order (7 properties)
|
|
28
30
|
*/
|
|
29
|
-
export function scoreGsProperties(projectDir, testsPassed, layerViolations, missingTestFiles) {
|
|
31
|
+
export function scoreGsProperties(projectDir, testsPassed, layerViolations, missingTestFiles, options = {}) {
|
|
30
32
|
logger.info("Scoring GS properties", { projectDir });
|
|
31
33
|
const allFiles = listAllFiles(projectDir);
|
|
32
|
-
|
|
34
|
+
const scores = [
|
|
33
35
|
scoreSelfDescribing(projectDir),
|
|
34
36
|
scoreBounded(layerViolations),
|
|
35
37
|
scoreVerifiable(testsPassed, missingTestFiles, allFiles),
|
|
@@ -38,6 +40,7 @@ export function scoreGsProperties(projectDir, testsPassed, layerViolations, miss
|
|
|
38
40
|
scoreComposable(projectDir, allFiles),
|
|
39
41
|
scoreExecutable(projectDir, testsPassed),
|
|
40
42
|
];
|
|
43
|
+
return scores.map((s) => applyAnchor(s, options));
|
|
41
44
|
}
|
|
42
45
|
/**
|
|
43
46
|
* Find all direct-DB / ORM calls inside route and controller source files.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gs-scorer.js","sourceRoot":"","sources":["../../src/analyzers/gs-scorer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAMrD,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,EACrB,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,qBAAqB,EACrB,cAAc,GACf,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"gs-scorer.js","sourceRoot":"","sources":["../../src/analyzers/gs-scorer.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,10 @@ import type { GsPropertyScore } from "../../shared/types.js";
|
|
|
6
6
|
* Score the Composable GS property.
|
|
7
7
|
* 2 = services + repositories + interface files, 1 = services only, 0 = none.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
9
|
+
* Project-type aware:
|
|
10
|
+
* - GitHub Actions: composability measured via action.yml interface contract
|
|
11
|
+
* - Libraries/CLIs: composability measured via exported types and public API surface
|
|
12
|
+
* - Web services: conventional service/repository layer split
|
|
11
13
|
*/
|
|
12
14
|
export declare function scoreComposable(projectDir: string, allFiles: string[]): GsPropertyScore;
|
|
13
15
|
//# sourceMappingURL=composable-scorer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"composable-scorer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/scorers/composable-scorer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"composable-scorer.d.ts","sourceRoot":"","sources":["../../../src/analyzers/scorers/composable-scorer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAsC7D;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,eAAe,CAmEvF"}
|
|
@@ -4,14 +4,49 @@
|
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import { join } from "node:path";
|
|
6
6
|
import { gs, isSourceCodeFile } from "./scorer-utils.js";
|
|
7
|
+
/**
|
|
8
|
+
* Detect whether a project is a GitHub Action (has action.yml / action.yaml at root).
|
|
9
|
+
* GitHub Actions define their composability contract through action.yml inputs/outputs —
|
|
10
|
+
* a service/repository layer split is not applicable to this project type.
|
|
11
|
+
*/
|
|
12
|
+
function isGitHubAction(projectDir) {
|
|
13
|
+
return existsSync(join(projectDir, "action.yml")) || existsSync(join(projectDir, "action.yaml"));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Detect whether a project is a library, CLI, or standalone tool.
|
|
17
|
+
* These project types expose composability through exported types and interfaces
|
|
18
|
+
* rather than internal service/repository layers.
|
|
19
|
+
*/
|
|
20
|
+
function isLibraryOrCli(projectDir, allFiles) {
|
|
21
|
+
const hasSrc = existsSync(join(projectDir, "src"));
|
|
22
|
+
const root = hasSrc ? join(projectDir, "src") : projectDir;
|
|
23
|
+
// Has a shared/ or types/ directory with source files → library interface pattern
|
|
24
|
+
const hasSharedOrTypes = existsSync(join(root, "shared")) || existsSync(join(root, "types"));
|
|
25
|
+
// Has index.ts at the root of src/ → explicit public API surface (library pattern)
|
|
26
|
+
const hasIndexExport = existsSync(join(root, "index.ts")) || existsSync(join(root, "index.js"));
|
|
27
|
+
// Has a bin/ directory or bin field in package.json → CLI project
|
|
28
|
+
const hasBin = existsSync(join(projectDir, "bin"));
|
|
29
|
+
// No route/controller files anywhere → not a web service
|
|
30
|
+
const hasRouteFiles = allFiles.some((f) => /\/(routes?|controllers?|handlers?|endpoints?|api)\//i.test(f.replace(/\\/g, "/")));
|
|
31
|
+
return !hasRouteFiles && (hasSharedOrTypes || hasIndexExport || hasBin);
|
|
32
|
+
}
|
|
7
33
|
/**
|
|
8
34
|
* Score the Composable GS property.
|
|
9
35
|
* 2 = services + repositories + interface files, 1 = services only, 0 = none.
|
|
10
36
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
37
|
+
* Project-type aware:
|
|
38
|
+
* - GitHub Actions: composability measured via action.yml interface contract
|
|
39
|
+
* - Libraries/CLIs: composability measured via exported types and public API surface
|
|
40
|
+
* - Web services: conventional service/repository layer split
|
|
13
41
|
*/
|
|
14
42
|
export function scoreComposable(projectDir, allFiles) {
|
|
43
|
+
// GitHub Actions define their contract through action.yml — service layers don't apply
|
|
44
|
+
if (isGitHubAction(projectDir)) {
|
|
45
|
+
return gs("composable", 2, [
|
|
46
|
+
"GitHub Action detected — composability contract defined by action.yml inputs/outputs",
|
|
47
|
+
"Interface boundary enforced by the GitHub Actions runner (not an internal service layer)",
|
|
48
|
+
]);
|
|
49
|
+
}
|
|
15
50
|
const hasSrc = existsSync(join(projectDir, "src"));
|
|
16
51
|
const root = hasSrc ? "src" : "";
|
|
17
52
|
const serviceDir = [
|
|
@@ -43,6 +78,19 @@ export function scoreComposable(projectDir, allFiles) {
|
|
|
43
78
|
"No repository layer found — consider extracting DB access to repositories/",
|
|
44
79
|
]);
|
|
45
80
|
}
|
|
81
|
+
// Library/CLI projects: check for public API surface as composability evidence
|
|
82
|
+
if (isLibraryOrCli(projectDir, allFiles)) {
|
|
83
|
+
if (hasInterfaces) {
|
|
84
|
+
return gs("composable", 2, [
|
|
85
|
+
"Library/CLI project — composability measured via exported interface surface",
|
|
86
|
+
"Interface/type files detected — public API contract is explicit",
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
89
|
+
return gs("composable", 1, [
|
|
90
|
+
"Library/CLI project — composability measured via exported interface surface",
|
|
91
|
+
"No dedicated interface/type files found — consider adding types/ or shared/ for explicit contracts",
|
|
92
|
+
]);
|
|
93
|
+
}
|
|
46
94
|
return gs("composable", 0, [
|
|
47
95
|
"No service layer found — business logic likely lives in route handlers",
|
|
48
96
|
"No repository layer found",
|