@promptci/core 0.0.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/LICENSE +201 -0
- package/README.md +30 -0
- package/dist/agent-practices.d.ts +22 -0
- package/dist/agent-practices.d.ts.map +1 -0
- package/dist/agent-practices.js +582 -0
- package/dist/agent-practices.js.map +1 -0
- package/dist/baseline.d.ts +40 -0
- package/dist/baseline.d.ts.map +1 -0
- package/dist/baseline.js +172 -0
- package/dist/baseline.js.map +1 -0
- package/dist/canonical-owner.d.ts +3 -0
- package/dist/canonical-owner.d.ts.map +1 -0
- package/dist/canonical-owner.js +131 -0
- package/dist/canonical-owner.js.map +1 -0
- package/dist/cheap-model-routing.d.ts +4 -0
- package/dist/cheap-model-routing.d.ts.map +1 -0
- package/dist/cheap-model-routing.js +43 -0
- package/dist/cheap-model-routing.js.map +1 -0
- package/dist/ci-alignment.d.ts +10 -0
- package/dist/ci-alignment.d.ts.map +1 -0
- package/dist/ci-alignment.js +343 -0
- package/dist/ci-alignment.js.map +1 -0
- package/dist/cli-output-filter.d.ts +16 -0
- package/dist/cli-output-filter.d.ts.map +1 -0
- package/dist/cli-output-filter.js +88 -0
- package/dist/cli-output-filter.js.map +1 -0
- package/dist/command-validity.d.ts +12 -0
- package/dist/command-validity.d.ts.map +1 -0
- package/dist/command-validity.js +543 -0
- package/dist/command-validity.js.map +1 -0
- package/dist/conflicts.d.ts +49 -0
- package/dist/conflicts.d.ts.map +1 -0
- package/dist/conflicts.js +1065 -0
- package/dist/conflicts.js.map +1 -0
- package/dist/context-analysis.d.ts +15 -0
- package/dist/context-analysis.d.ts.map +1 -0
- package/dist/context-analysis.js +24 -0
- package/dist/context-analysis.js.map +1 -0
- package/dist/context-bloat.d.ts +17 -0
- package/dist/context-bloat.d.ts.map +1 -0
- package/dist/context-bloat.js +148 -0
- package/dist/context-bloat.js.map +1 -0
- package/dist/context-cost.d.ts +4 -0
- package/dist/context-cost.d.ts.map +1 -0
- package/dist/context-cost.js +70 -0
- package/dist/context-cost.js.map +1 -0
- package/dist/context-optimizer.d.ts +14 -0
- package/dist/context-optimizer.d.ts.map +1 -0
- package/dist/context-optimizer.js +219 -0
- package/dist/context-optimizer.js.map +1 -0
- package/dist/context-recommender.d.ts +3 -0
- package/dist/context-recommender.d.ts.map +1 -0
- package/dist/context-recommender.js +329 -0
- package/dist/context-recommender.js.map +1 -0
- package/dist/dead-references.d.ts +33 -0
- package/dist/dead-references.d.ts.map +1 -0
- package/dist/dead-references.js +607 -0
- package/dist/dead-references.js.map +1 -0
- package/dist/detectors.d.ts +11 -0
- package/dist/detectors.d.ts.map +1 -0
- package/dist/detectors.js +160 -0
- package/dist/detectors.js.map +1 -0
- package/dist/duplicates.d.ts +36 -0
- package/dist/duplicates.d.ts.map +1 -0
- package/dist/duplicates.js +436 -0
- package/dist/duplicates.js.map +1 -0
- package/dist/fix-engine.d.ts +16 -0
- package/dist/fix-engine.d.ts.map +1 -0
- package/dist/fix-engine.js +179 -0
- package/dist/fix-engine.js.map +1 -0
- package/dist/framework-packs.d.ts +8 -0
- package/dist/framework-packs.d.ts.map +1 -0
- package/dist/framework-packs.js +22 -0
- package/dist/framework-packs.js.map +1 -0
- package/dist/frameworks/dotnet.d.ts +4 -0
- package/dist/frameworks/dotnet.d.ts.map +1 -0
- package/dist/frameworks/dotnet.js +77 -0
- package/dist/frameworks/dotnet.js.map +1 -0
- package/dist/frameworks/go.d.ts +4 -0
- package/dist/frameworks/go.d.ts.map +1 -0
- package/dist/frameworks/go.js +39 -0
- package/dist/frameworks/go.js.map +1 -0
- package/dist/frameworks/nextjs.d.ts +4 -0
- package/dist/frameworks/nextjs.d.ts.map +1 -0
- package/dist/frameworks/nextjs.js +66 -0
- package/dist/frameworks/nextjs.js.map +1 -0
- package/dist/frameworks/python.d.ts +4 -0
- package/dist/frameworks/python.d.ts.map +1 -0
- package/dist/frameworks/python.js +66 -0
- package/dist/frameworks/python.js.map +1 -0
- package/dist/frameworks/rust.d.ts +4 -0
- package/dist/frameworks/rust.d.ts.map +1 -0
- package/dist/frameworks/rust.js +72 -0
- package/dist/frameworks/rust.js.map +1 -0
- package/dist/frameworks/unity.d.ts +4 -0
- package/dist/frameworks/unity.d.ts.map +1 -0
- package/dist/frameworks/unity.js +74 -0
- package/dist/frameworks/unity.js.map +1 -0
- package/dist/health-score.d.ts +37 -0
- package/dist/health-score.d.ts.map +1 -0
- package/dist/health-score.js +164 -0
- package/dist/health-score.js.map +1 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/llm.d.ts +6 -0
- package/dist/llm.d.ts.map +1 -0
- package/dist/llm.js +67 -0
- package/dist/llm.js.map +1 -0
- package/dist/manifest-consistency.d.ts +37 -0
- package/dist/manifest-consistency.d.ts.map +1 -0
- package/dist/manifest-consistency.js +659 -0
- package/dist/manifest-consistency.js.map +1 -0
- package/dist/mcp-detector.d.ts +4 -0
- package/dist/mcp-detector.d.ts.map +1 -0
- package/dist/mcp-detector.js +131 -0
- package/dist/mcp-detector.js.map +1 -0
- package/dist/missing-context.d.ts +15 -0
- package/dist/missing-context.d.ts.map +1 -0
- package/dist/missing-context.js +517 -0
- package/dist/missing-context.js.map +1 -0
- package/dist/native-tool-preference.d.ts +20 -0
- package/dist/native-tool-preference.d.ts.map +1 -0
- package/dist/native-tool-preference.js +94 -0
- package/dist/native-tool-preference.js.map +1 -0
- package/dist/output-verbosity.d.ts +3 -0
- package/dist/output-verbosity.d.ts.map +1 -0
- package/dist/output-verbosity.js +83 -0
- package/dist/output-verbosity.js.map +1 -0
- package/dist/product-boundary.d.ts +11 -0
- package/dist/product-boundary.d.ts.map +1 -0
- package/dist/product-boundary.js +301 -0
- package/dist/product-boundary.js.map +1 -0
- package/dist/project-type.d.ts +15 -0
- package/dist/project-type.d.ts.map +1 -0
- package/dist/project-type.js +116 -0
- package/dist/project-type.js.map +1 -0
- package/dist/prompt-cache.d.ts +3 -0
- package/dist/prompt-cache.d.ts.map +1 -0
- package/dist/prompt-cache.js +151 -0
- package/dist/prompt-cache.js.map +1 -0
- package/dist/repo-context.d.ts +37 -0
- package/dist/repo-context.d.ts.map +1 -0
- package/dist/repo-context.js +221 -0
- package/dist/repo-context.js.map +1 -0
- package/dist/report.d.ts +87 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +558 -0
- package/dist/report.js.map +1 -0
- package/dist/scan.d.ts +7 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +43 -0
- package/dist/scan.js.map +1 -0
- package/dist/scanner.d.ts +3 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +216 -0
- package/dist/scanner.js.map +1 -0
- package/dist/security-pack.d.ts +4 -0
- package/dist/security-pack.d.ts.map +1 -0
- package/dist/security-pack.js +403 -0
- package/dist/security-pack.js.map +1 -0
- package/dist/stale-instructions.d.ts +20 -0
- package/dist/stale-instructions.d.ts.map +1 -0
- package/dist/stale-instructions.js +269 -0
- package/dist/stale-instructions.js.map +1 -0
- package/dist/suppression.d.ts +64 -0
- package/dist/suppression.d.ts.map +1 -0
- package/dist/suppression.js +338 -0
- package/dist/suppression.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/vague-guidance.d.ts +12 -0
- package/dist/vague-guidance.d.ts.map +1 -0
- package/dist/vague-guidance.js +235 -0
- package/dist/vague-guidance.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale-instruction detector for PromptCI.
|
|
3
|
+
*
|
|
4
|
+
* Flags sections that likely reference outdated content:
|
|
5
|
+
* - Years 2019–2023 that appear outside code blocks
|
|
6
|
+
* - Cleanup keywords: "TODO remove", "remove later", "temporary fix", "workaround"
|
|
7
|
+
* - "deprecated" near a version number or tool name
|
|
8
|
+
* - Known old framework versions (React 16, Next.js 9, Unity 2019, etc.)
|
|
9
|
+
*
|
|
10
|
+
* Findings are heuristic — wording is intentionally cautious.
|
|
11
|
+
*/
|
|
12
|
+
import type { InstructionFile, PromptCiIssue } from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Detect sections that may contain stale or outdated instructions.
|
|
15
|
+
*
|
|
16
|
+
* Returns one issue per offending section (multiple patterns in the same
|
|
17
|
+
* section are merged into a single issue).
|
|
18
|
+
*/
|
|
19
|
+
export declare function detectStaleInstructions(files: InstructionFile[]): PromptCiIssue[];
|
|
20
|
+
//# sourceMappingURL=stale-instructions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-instructions.d.ts","sourceRoot":"","sources":["../src/stale-instructions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAqMrF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,CAwFjF"}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stale-instruction detector for PromptCI.
|
|
3
|
+
*
|
|
4
|
+
* Flags sections that likely reference outdated content:
|
|
5
|
+
* - Years 2019–2023 that appear outside code blocks
|
|
6
|
+
* - Cleanup keywords: "TODO remove", "remove later", "temporary fix", "workaround"
|
|
7
|
+
* - "deprecated" near a version number or tool name
|
|
8
|
+
* - Known old framework versions (React 16, Next.js 9, Unity 2019, etc.)
|
|
9
|
+
*
|
|
10
|
+
* Findings are heuristic — wording is intentionally cautious.
|
|
11
|
+
*/
|
|
12
|
+
import * as crypto from 'node:crypto';
|
|
13
|
+
// ─── Pattern definitions ──────────────────────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* Years likely stale in an AI instruction context.
|
|
16
|
+
* 2023 is now included since the current year is 2026.
|
|
17
|
+
* Must not be immediately preceded by "/" or "-" (avoids ISO dates like 2022-01-01
|
|
18
|
+
* or paths like /2022/report) — those are not year references.
|
|
19
|
+
*/
|
|
20
|
+
const STALE_YEAR_RE = /(?<![/-])\b(2019|2020|2021|2022|2023|2024|2025)\b(?![/-])/g;
|
|
21
|
+
/**
|
|
22
|
+
* BUG-A1: Section headings that indicate historical records rather than active
|
|
23
|
+
* instructions. Old year references in changelogs and release notes are expected
|
|
24
|
+
* and must not be flagged as stale instructions.
|
|
25
|
+
*/
|
|
26
|
+
const HISTORY_SECTION_RE = /\b(?:history|changelog|change\s*log|release\s+notes?|releases?|versions?|what.?s\s+new|for\s+reference)\b/i;
|
|
27
|
+
/** Explicit cleanup markers. */
|
|
28
|
+
const CLEANUP_KEYWORD_RE = /\b(TODO\s*:?\s*remove|remove\s+later|temporary\s+fix|workaround)\b/gi;
|
|
29
|
+
/**
|
|
30
|
+
* BUG-004: Dated TODO/FIXME/WORKAROUND markers inside HTML comments.
|
|
31
|
+
* The main STALE_YEAR_RE intentionally excludes ISO-formatted dates like 2022-03-10
|
|
32
|
+
* (using a negative lookahead on "/"). This separate pattern catches years that appear
|
|
33
|
+
* inside parenthesised dates in HTML comments, e.g.:
|
|
34
|
+
* <!-- TODO (2022-03-10): migrate NextAuth v3 callbacks -->
|
|
35
|
+
* <!-- WORKAROUND (2021-08-14): ... -->
|
|
36
|
+
* Groups: [1]=keyword, [2]=year
|
|
37
|
+
*
|
|
38
|
+
* ST1: Both `(?:(?!-->)[\s\S])*?` spans use a "tempered dot" — match anything
|
|
39
|
+
* (including newlines) as long as it's not the start of the comment's closing
|
|
40
|
+
* `-->`. This allows the keyword and its date to be split across lines
|
|
41
|
+
* (`<!-- TODO\n(2022-03-10): ... -->`) and allows ordinary `>` characters
|
|
42
|
+
* before the keyword (`<!-- if retries > 3 TODO (2022-01-01): remove -->`),
|
|
43
|
+
* neither of which the old `[^>]*?` / `[^(>\n]*` classes permitted, while
|
|
44
|
+
* still stopping at the actual end of the same comment.
|
|
45
|
+
*/
|
|
46
|
+
const HTML_COMMENT_DATED_TODO_RE = /<!--(?:(?!-->)[\s\S])*?\b(TODO|FIXME|WORKAROUND|HACK|NOTE)\b(?:(?!-->)[\s\S])*?\(\s*(\d{4})[-–\d]/gi;
|
|
47
|
+
/**
|
|
48
|
+
* "deprecated" within ~10 words of a version number or recognisable tool name.
|
|
49
|
+
*/
|
|
50
|
+
const DEPRECATED_NEAR_VERSION_RE = /deprecated[\w\s,.()\\\-:`]{0,60}(v?\d+[\w.]+|react|next\.?js|angular|vue|webpack|babel|unity|jest|mocha)/gi;
|
|
51
|
+
/**
|
|
52
|
+
* Known old framework/library versions that signal stale instructions.
|
|
53
|
+
*
|
|
54
|
+
* ST2: Every numeric version is prefixed with an optional `v?` so aliases
|
|
55
|
+
* like "React v16", "Node v12", "Angular v8" are caught too — the old
|
|
56
|
+
* patterns only matched the bare-number form, which was inconsistent with
|
|
57
|
+
* manifest-consistency.ts's checkNodeVersionMismatch (which already accepts
|
|
58
|
+
* `v?`).
|
|
59
|
+
*/
|
|
60
|
+
const OLD_VERSION_PATTERNS = [
|
|
61
|
+
{ re: /\breact\s+v?1[0-6]\b/gi, label: 'React 16 or earlier' },
|
|
62
|
+
{ re: /\bnext\.?js\s+v?[1-9]\b/gi, label: 'Next.js 9 or earlier' },
|
|
63
|
+
{ re: /\bunity\s+v?201[0-9]\b/gi, label: 'Unity 2019 or earlier' },
|
|
64
|
+
{ re: /\bangular\s+v?[1-9]\b/gi, label: 'Angular 9 or earlier' },
|
|
65
|
+
{ re: /\bvue\s+v?[12]\b/gi, label: 'Vue 2 or earlier' },
|
|
66
|
+
{ re: /\bwebpack\s+v?[1-3]\b/gi, label: 'Webpack 3 or earlier' },
|
|
67
|
+
{ re: /\bbabel\s+v?[1-6]\b/gi, label: 'Babel 6 or earlier' },
|
|
68
|
+
// BUG-005: Fixed — original pattern required "node.js" (with .js); bare "Node 12" was missed.
|
|
69
|
+
// Extended range to 16 since Node 14 & 16 are also EOL.
|
|
70
|
+
{ re: /\bnode(?:\.js?)?\s+v?(1[0-6]|[1-9])\b/gi, label: 'Node.js 16 or earlier' },
|
|
71
|
+
{ re: /\btypescript\s+v?[1-3]\b/gi, label: 'TypeScript 3 or earlier' },
|
|
72
|
+
// BUG-005: Added Go — Go 1.17 and earlier pre-date generics (1.18) and are commonly stale.
|
|
73
|
+
{ re: /\bgo\s+v?1\.(1[0-7]|[0-9])\b/gi, label: 'Go 1.17 or earlier' },
|
|
74
|
+
// BUG-005: Added Python 2 — Python 2 reached EOL in 2020.
|
|
75
|
+
{ re: /\bpython\s+v?2\./gi, label: 'Python 2' },
|
|
76
|
+
// BUG-G2: Python 3.9 and earlier are EOL (3.9 EOL Oct 2025, 3.8 Oct 2024, earlier all prior).
|
|
77
|
+
// Catches "Python 3.6", "Python 3.8", etc. without a 4-digit year.
|
|
78
|
+
{ re: /\bpython\s+v?3\.[0-9]\b/gi, label: 'Python 3.9 or earlier' },
|
|
79
|
+
// BUG-005: Added .NET 5 and earlier (non-LTS / EOL versions).
|
|
80
|
+
{ re: /\.NET\s+v?[1-5]\b/gi, label: '.NET 5 or earlier' },
|
|
81
|
+
];
|
|
82
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
83
|
+
function issueId(section, tag) {
|
|
84
|
+
const key = `${section.filePath}:${section.startLine}:${tag}`;
|
|
85
|
+
const hash = crypto.createHash('sha1').update(key).digest('hex').slice(0, 12);
|
|
86
|
+
return `stale-${hash}`;
|
|
87
|
+
}
|
|
88
|
+
function snippet(text, maxLen = 120) {
|
|
89
|
+
const clean = text.replace(/\s+/g, ' ').trim();
|
|
90
|
+
return clean.length <= maxLen ? clean : `${clean.slice(0, maxLen)}…`;
|
|
91
|
+
}
|
|
92
|
+
function collectMatches(text, re) {
|
|
93
|
+
const matches = [];
|
|
94
|
+
let m;
|
|
95
|
+
const cloned = new RegExp(re.source, re.flags);
|
|
96
|
+
while ((m = cloned.exec(text)) !== null) {
|
|
97
|
+
matches.push(m[0]);
|
|
98
|
+
}
|
|
99
|
+
return matches;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* BUG-013: Returns {match, index} pairs so we can check whether each match
|
|
103
|
+
* occurs in a negation / avoidance context before flagging it as stale.
|
|
104
|
+
*/
|
|
105
|
+
function collectMatchesWithIndex(text, re) {
|
|
106
|
+
const results = [];
|
|
107
|
+
let m;
|
|
108
|
+
const cloned = new RegExp(re.source, re.flags);
|
|
109
|
+
while ((m = cloned.exec(text)) !== null) {
|
|
110
|
+
results.push({ match: m[0], index: m.index });
|
|
111
|
+
}
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
function collectOldHtmlTodoMatches(text) {
|
|
115
|
+
const matches = [];
|
|
116
|
+
let m;
|
|
117
|
+
const cloned = new RegExp(HTML_COMMENT_DATED_TODO_RE.source, HTML_COMMENT_DATED_TODO_RE.flags);
|
|
118
|
+
while ((m = cloned.exec(text)) !== null) {
|
|
119
|
+
const year = Number(m[2]);
|
|
120
|
+
if (year <= 2025) {
|
|
121
|
+
matches.push(m[0]);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return matches;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* BUG-013: Detect whether an old-version reference is in a negation / avoidance
|
|
128
|
+
* context (e.g. "do not add Vue 2 compat", "avoid Vue 2", "dropped Vue 2 support").
|
|
129
|
+
*
|
|
130
|
+
* If so, the mention is a CURRENT rule ("don't use the old version") rather than
|
|
131
|
+
* a stale instruction, and should not be flagged.
|
|
132
|
+
*
|
|
133
|
+
* Looks at up to 80 chars before the match index for negation keywords.
|
|
134
|
+
*
|
|
135
|
+
* ST4: the trailing window only excludes sentence-ending punctuation
|
|
136
|
+
* (`.`/`!`/`?`), not newlines — a single hard-wrap ("Do not\nadd Vue 2...")
|
|
137
|
+
* no longer hides the negation keyword from the match. A BLANK line (a real
|
|
138
|
+
* paragraph break) still ends the window, via the `(?!\n[ \t]*\n)` tempered
|
|
139
|
+
* repetition, so negation from an unrelated earlier paragraph can't leak in.
|
|
140
|
+
*/
|
|
141
|
+
function isVersionInNegationContext(text, index) {
|
|
142
|
+
const preceding = text.slice(Math.max(0, index - 80), index).toLowerCase();
|
|
143
|
+
return /\b(?:do\s+not|don['']?t|avoid|never|no\s+longer|drop(?:ped|ping)?|remov(?:ed?|ing)|deprecat(?:ed?|ing)|stop(?:ped|ping)?\s+(?:using|support(?:ing)?))\b(?:(?!\n[ \t]*\n)[^.!?])*$/.test(preceding);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Strip fenced code blocks from text before scanning for stale years.
|
|
147
|
+
* Code blocks often contain version pins or changelog entries that are
|
|
148
|
+
* expected to reference specific years and should not trigger the detector.
|
|
149
|
+
*
|
|
150
|
+
* ST3: tracks fence character + length (matching scanner.ts's S1 fix and
|
|
151
|
+
* vague-guidance.ts's V4 fix) instead of a `` ```...``` `` regex, so ~~~
|
|
152
|
+
* fences are also stripped and an unclosed fence correctly swallows the
|
|
153
|
+
* remainder of the text (rather than leaving it unstripped, as
|
|
154
|
+
* `/```[\s\S]*?```/` did when no closing fence existed).
|
|
155
|
+
*/
|
|
156
|
+
function stripCodeBlocks(text, stripInlineCode = true) {
|
|
157
|
+
const lines = text.split('\n');
|
|
158
|
+
const kept = [];
|
|
159
|
+
let inBlock = false;
|
|
160
|
+
let fenceChar = null;
|
|
161
|
+
let fenceLen = 0;
|
|
162
|
+
for (const line of lines) {
|
|
163
|
+
if (!inBlock) {
|
|
164
|
+
const openMatch = /^ {0,3}([`~]{3,})/.exec(line);
|
|
165
|
+
if (openMatch) {
|
|
166
|
+
inBlock = true;
|
|
167
|
+
fenceChar = openMatch[1][0] ?? null;
|
|
168
|
+
fenceLen = openMatch[1].length;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
kept.push(line);
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const closeMatch = /^ {0,3}([`~]{3,})\s*$/.exec(line);
|
|
175
|
+
if (closeMatch && closeMatch[1][0] === fenceChar && closeMatch[1].length >= fenceLen) {
|
|
176
|
+
inBlock = false;
|
|
177
|
+
fenceChar = null;
|
|
178
|
+
fenceLen = 0;
|
|
179
|
+
}
|
|
180
|
+
// else: still inside the fence — drop the line
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
const noFences = kept.join('\n');
|
|
184
|
+
return stripInlineCode ? noFences.replace(/`[^`\n]+`/g, '') : noFences;
|
|
185
|
+
}
|
|
186
|
+
// ─── Main detector ────────────────────────────────────────────────────────────
|
|
187
|
+
/**
|
|
188
|
+
* Detect sections that may contain stale or outdated instructions.
|
|
189
|
+
*
|
|
190
|
+
* Returns one issue per offending section (multiple patterns in the same
|
|
191
|
+
* section are merged into a single issue).
|
|
192
|
+
*/
|
|
193
|
+
export function detectStaleInstructions(files) {
|
|
194
|
+
const issues = [];
|
|
195
|
+
const seen = new Set();
|
|
196
|
+
for (const file of files) {
|
|
197
|
+
for (const section of file.sections) {
|
|
198
|
+
// BUG-A1: Skip history/changelog/release-notes sections — old year references
|
|
199
|
+
// in these sections are historical records, not actionable instructions.
|
|
200
|
+
if (section.heading && HISTORY_SECTION_RE.test(section.heading))
|
|
201
|
+
continue;
|
|
202
|
+
const text = section.text;
|
|
203
|
+
const textNoCode = stripCodeBlocks(text);
|
|
204
|
+
const textNoFencedCode = stripCodeBlocks(text, false);
|
|
205
|
+
const evidence = [];
|
|
206
|
+
let confidence = 0;
|
|
207
|
+
const sectionKey = `${file.path}:${section.startLine}`;
|
|
208
|
+
// 1. Stale years — only in prose, not inside code blocks (confidence 0.6)
|
|
209
|
+
const yearMatches = collectMatches(textNoCode, STALE_YEAR_RE);
|
|
210
|
+
if (yearMatches.length > 0) {
|
|
211
|
+
evidence.push(`Year reference(s) that may be outdated: ${[...new Set(yearMatches)].join(', ')}`);
|
|
212
|
+
confidence = Math.max(confidence, 0.6);
|
|
213
|
+
}
|
|
214
|
+
// 2. Cleanup keywords (confidence 0.6)
|
|
215
|
+
const cleanupMatches = collectMatches(textNoFencedCode, CLEANUP_KEYWORD_RE);
|
|
216
|
+
if (cleanupMatches.length > 0) {
|
|
217
|
+
evidence.push(`Cleanup keyword(s): ${[...new Set(cleanupMatches.map((m) => m.trim()))].join(', ')}`);
|
|
218
|
+
confidence = Math.max(confidence, 0.6);
|
|
219
|
+
}
|
|
220
|
+
// 3. "deprecated" near version/tool (confidence 0.7)
|
|
221
|
+
const deprecatedMatches = collectMatches(textNoFencedCode, DEPRECATED_NEAR_VERSION_RE);
|
|
222
|
+
if (deprecatedMatches.length > 0) {
|
|
223
|
+
evidence.push(`"deprecated" near version/tool: ${snippet(deprecatedMatches[0] ?? '', 80)}`);
|
|
224
|
+
confidence = Math.max(confidence, 0.7);
|
|
225
|
+
}
|
|
226
|
+
// 4. Old framework versions (confidence 0.7)
|
|
227
|
+
// BUG-013: Skip matches that appear in a negation context
|
|
228
|
+
// ("do not add Vue 2 compat", "avoid Vue 2", etc.) — those are current rules,
|
|
229
|
+
// not stale instructions.
|
|
230
|
+
for (const { re, label } of OLD_VERSION_PATTERNS) {
|
|
231
|
+
const hits = collectMatchesWithIndex(textNoCode, re);
|
|
232
|
+
const relevantHits = hits.filter(({ index }) => !isVersionInNegationContext(textNoCode, index));
|
|
233
|
+
if (relevantHits.length > 0) {
|
|
234
|
+
evidence.push(`Old version reference: ${label} ("${relevantHits[0].match}")`);
|
|
235
|
+
confidence = Math.max(confidence, 0.7);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// 5. BUG-004: Dated TODO/FIXME/WORKAROUND in HTML comments.
|
|
239
|
+
// The main STALE_YEAR_RE skips ISO dates (2022-03-10) by design; this catches them
|
|
240
|
+
// specifically when they appear as a timestamp inside an HTML comment keyword.
|
|
241
|
+
const htmlTodoMatches = collectOldHtmlTodoMatches(textNoFencedCode);
|
|
242
|
+
if (htmlTodoMatches.length > 0) {
|
|
243
|
+
evidence.push(`Dated ${htmlTodoMatches[0].match(/TODO|FIXME|WORKAROUND|HACK|NOTE/i)?.[0] ?? 'TODO'} ` +
|
|
244
|
+
`marker in HTML comment: ${snippet(htmlTodoMatches[0] ?? '', 80)}`);
|
|
245
|
+
confidence = Math.max(confidence, 0.65);
|
|
246
|
+
}
|
|
247
|
+
if (evidence.length === 0)
|
|
248
|
+
continue;
|
|
249
|
+
if (seen.has(sectionKey))
|
|
250
|
+
continue;
|
|
251
|
+
seen.add(sectionKey);
|
|
252
|
+
issues.push({
|
|
253
|
+
id: issueId(section, 'stale'),
|
|
254
|
+
severity: 'warning',
|
|
255
|
+
category: 'stale_instruction',
|
|
256
|
+
title: 'Instruction may reference outdated content',
|
|
257
|
+
summary: 'This instruction may reference outdated content. Review and update or remove it.',
|
|
258
|
+
filePaths: [file.path],
|
|
259
|
+
locations: [{ filePath: file.path, startLine: section.startLine, endLine: section.endLine }],
|
|
260
|
+
evidence: [`Section: "${snippet(text, 100)}"`, ...evidence],
|
|
261
|
+
recommendation: 'Review this section for accuracy. Update any outdated version numbers, tool references, ' +
|
|
262
|
+
'or remove temporary notes that are no longer relevant.',
|
|
263
|
+
confidence,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return issues;
|
|
268
|
+
}
|
|
269
|
+
//# sourceMappingURL=stale-instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stale-instructions.js","sourceRoot":"","sources":["../src/stale-instructions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inline suppression annotations for PromptCI.
|
|
3
|
+
*
|
|
4
|
+
* Annotation formats supported in any instruction file:
|
|
5
|
+
*
|
|
6
|
+
* Section-scoped (suppresses the section containing or immediately following):
|
|
7
|
+
* <!-- promptci-ignore: <category>
|
|
8
|
+
* reason: <required explanation> -->
|
|
9
|
+
*
|
|
10
|
+
* Range-scoped (suppresses everything between start and end markers):
|
|
11
|
+
* <!-- promptci-ignore-start: <category>
|
|
12
|
+
* reason: <required explanation> -->
|
|
13
|
+
* ...content...
|
|
14
|
+
* <!-- promptci-ignore-end -->
|
|
15
|
+
*
|
|
16
|
+
* Rules:
|
|
17
|
+
* - `reason` is required. Missing reason → warning issue, issue is NOT suppressed.
|
|
18
|
+
* - `category` must be a valid IssueCategory value or the special token `all`.
|
|
19
|
+
* - Invalid category → warning issue, annotation does not suppress anything.
|
|
20
|
+
* - An unpaired `promptci-ignore-start` (no matching end) → warning issue.
|
|
21
|
+
*/
|
|
22
|
+
import type { IssueCategory, InstructionFile, PromptCiIssue } from './types.js';
|
|
23
|
+
export type SuppressionAnnotation = {
|
|
24
|
+
filePath: string;
|
|
25
|
+
category: IssueCategory | 'all';
|
|
26
|
+
reason: string;
|
|
27
|
+
startLine: number;
|
|
28
|
+
/** Last line (inclusive) within the suppression scope. */
|
|
29
|
+
endLine: number;
|
|
30
|
+
/** false = malformed annotation; still tracked so we can emit a warning issue. */
|
|
31
|
+
valid: boolean;
|
|
32
|
+
validationMessage?: string;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Parse all suppression annotations from a set of instruction files.
|
|
36
|
+
* Returns both valid and invalid annotations; call `buildValidationIssues`
|
|
37
|
+
* to surface invalid ones as actual scan issues.
|
|
38
|
+
*/
|
|
39
|
+
export declare function parseSuppressions(files: InstructionFile[]): SuppressionAnnotation[];
|
|
40
|
+
/**
|
|
41
|
+
* Convert invalid suppression annotations into PromptCiIssue warning objects
|
|
42
|
+
* so they appear in the scan report and count against the health score.
|
|
43
|
+
* This ensures bad suppressions are visible rather than silently ignored.
|
|
44
|
+
*/
|
|
45
|
+
export declare function buildValidationIssues(annotations: SuppressionAnnotation[]): PromptCiIssue[];
|
|
46
|
+
/**
|
|
47
|
+
* Partition a flat issues array into active and suppressed based on the
|
|
48
|
+
* provided annotations.
|
|
49
|
+
*
|
|
50
|
+
* Matching rules:
|
|
51
|
+
* - Category match: annotation.category === 'all' OR === issue.category
|
|
52
|
+
* - Location match (issue HAS locations): at least one location's filePath +
|
|
53
|
+
* line range overlaps with the annotation's scope
|
|
54
|
+
* - Location match (issue has EMPTY locations, e.g. agent_practices): match
|
|
55
|
+
* by filePath alone (any of issue.filePaths matches annotation.filePath)
|
|
56
|
+
*
|
|
57
|
+
* Only valid annotations are used for matching; invalid ones emit warning issues
|
|
58
|
+
* that are never themselves suppressed.
|
|
59
|
+
*/
|
|
60
|
+
export declare function applySuppressions(issues: PromptCiIssue[], annotations: SuppressionAnnotation[]): {
|
|
61
|
+
active: PromptCiIssue[];
|
|
62
|
+
suppressed: PromptCiIssue[];
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=suppression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"suppression.d.ts","sourceRoot":"","sources":["../src/suppression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AA0BpG,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,aAAa,GAAG,KAAK,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,kFAAkF;IAClF,KAAK,EAAE,OAAO,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AAuQF;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,EAAE,GAAG,qBAAqB,EAAE,CAEnF;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,qBAAqB,EAAE,GACnC,aAAa,EAAE,CAiBjB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,aAAa,EAAE,EACvB,WAAW,EAAE,qBAAqB,EAAE,GACnC;IAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IAAC,UAAU,EAAE,aAAa,EAAE,CAAA;CAAE,CA4C1D"}
|