@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.
Files changed (179) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +30 -0
  3. package/dist/agent-practices.d.ts +22 -0
  4. package/dist/agent-practices.d.ts.map +1 -0
  5. package/dist/agent-practices.js +582 -0
  6. package/dist/agent-practices.js.map +1 -0
  7. package/dist/baseline.d.ts +40 -0
  8. package/dist/baseline.d.ts.map +1 -0
  9. package/dist/baseline.js +172 -0
  10. package/dist/baseline.js.map +1 -0
  11. package/dist/canonical-owner.d.ts +3 -0
  12. package/dist/canonical-owner.d.ts.map +1 -0
  13. package/dist/canonical-owner.js +131 -0
  14. package/dist/canonical-owner.js.map +1 -0
  15. package/dist/cheap-model-routing.d.ts +4 -0
  16. package/dist/cheap-model-routing.d.ts.map +1 -0
  17. package/dist/cheap-model-routing.js +43 -0
  18. package/dist/cheap-model-routing.js.map +1 -0
  19. package/dist/ci-alignment.d.ts +10 -0
  20. package/dist/ci-alignment.d.ts.map +1 -0
  21. package/dist/ci-alignment.js +343 -0
  22. package/dist/ci-alignment.js.map +1 -0
  23. package/dist/cli-output-filter.d.ts +16 -0
  24. package/dist/cli-output-filter.d.ts.map +1 -0
  25. package/dist/cli-output-filter.js +88 -0
  26. package/dist/cli-output-filter.js.map +1 -0
  27. package/dist/command-validity.d.ts +12 -0
  28. package/dist/command-validity.d.ts.map +1 -0
  29. package/dist/command-validity.js +543 -0
  30. package/dist/command-validity.js.map +1 -0
  31. package/dist/conflicts.d.ts +49 -0
  32. package/dist/conflicts.d.ts.map +1 -0
  33. package/dist/conflicts.js +1065 -0
  34. package/dist/conflicts.js.map +1 -0
  35. package/dist/context-analysis.d.ts +15 -0
  36. package/dist/context-analysis.d.ts.map +1 -0
  37. package/dist/context-analysis.js +24 -0
  38. package/dist/context-analysis.js.map +1 -0
  39. package/dist/context-bloat.d.ts +17 -0
  40. package/dist/context-bloat.d.ts.map +1 -0
  41. package/dist/context-bloat.js +148 -0
  42. package/dist/context-bloat.js.map +1 -0
  43. package/dist/context-cost.d.ts +4 -0
  44. package/dist/context-cost.d.ts.map +1 -0
  45. package/dist/context-cost.js +70 -0
  46. package/dist/context-cost.js.map +1 -0
  47. package/dist/context-optimizer.d.ts +14 -0
  48. package/dist/context-optimizer.d.ts.map +1 -0
  49. package/dist/context-optimizer.js +219 -0
  50. package/dist/context-optimizer.js.map +1 -0
  51. package/dist/context-recommender.d.ts +3 -0
  52. package/dist/context-recommender.d.ts.map +1 -0
  53. package/dist/context-recommender.js +329 -0
  54. package/dist/context-recommender.js.map +1 -0
  55. package/dist/dead-references.d.ts +33 -0
  56. package/dist/dead-references.d.ts.map +1 -0
  57. package/dist/dead-references.js +607 -0
  58. package/dist/dead-references.js.map +1 -0
  59. package/dist/detectors.d.ts +11 -0
  60. package/dist/detectors.d.ts.map +1 -0
  61. package/dist/detectors.js +160 -0
  62. package/dist/detectors.js.map +1 -0
  63. package/dist/duplicates.d.ts +36 -0
  64. package/dist/duplicates.d.ts.map +1 -0
  65. package/dist/duplicates.js +436 -0
  66. package/dist/duplicates.js.map +1 -0
  67. package/dist/fix-engine.d.ts +16 -0
  68. package/dist/fix-engine.d.ts.map +1 -0
  69. package/dist/fix-engine.js +179 -0
  70. package/dist/fix-engine.js.map +1 -0
  71. package/dist/framework-packs.d.ts +8 -0
  72. package/dist/framework-packs.d.ts.map +1 -0
  73. package/dist/framework-packs.js +22 -0
  74. package/dist/framework-packs.js.map +1 -0
  75. package/dist/frameworks/dotnet.d.ts +4 -0
  76. package/dist/frameworks/dotnet.d.ts.map +1 -0
  77. package/dist/frameworks/dotnet.js +77 -0
  78. package/dist/frameworks/dotnet.js.map +1 -0
  79. package/dist/frameworks/go.d.ts +4 -0
  80. package/dist/frameworks/go.d.ts.map +1 -0
  81. package/dist/frameworks/go.js +39 -0
  82. package/dist/frameworks/go.js.map +1 -0
  83. package/dist/frameworks/nextjs.d.ts +4 -0
  84. package/dist/frameworks/nextjs.d.ts.map +1 -0
  85. package/dist/frameworks/nextjs.js +66 -0
  86. package/dist/frameworks/nextjs.js.map +1 -0
  87. package/dist/frameworks/python.d.ts +4 -0
  88. package/dist/frameworks/python.d.ts.map +1 -0
  89. package/dist/frameworks/python.js +66 -0
  90. package/dist/frameworks/python.js.map +1 -0
  91. package/dist/frameworks/rust.d.ts +4 -0
  92. package/dist/frameworks/rust.d.ts.map +1 -0
  93. package/dist/frameworks/rust.js +72 -0
  94. package/dist/frameworks/rust.js.map +1 -0
  95. package/dist/frameworks/unity.d.ts +4 -0
  96. package/dist/frameworks/unity.d.ts.map +1 -0
  97. package/dist/frameworks/unity.js +74 -0
  98. package/dist/frameworks/unity.js.map +1 -0
  99. package/dist/health-score.d.ts +37 -0
  100. package/dist/health-score.d.ts.map +1 -0
  101. package/dist/health-score.js +164 -0
  102. package/dist/health-score.js.map +1 -0
  103. package/dist/index.d.ts +31 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +23 -0
  106. package/dist/index.js.map +1 -0
  107. package/dist/llm.d.ts +6 -0
  108. package/dist/llm.d.ts.map +1 -0
  109. package/dist/llm.js +67 -0
  110. package/dist/llm.js.map +1 -0
  111. package/dist/manifest-consistency.d.ts +37 -0
  112. package/dist/manifest-consistency.d.ts.map +1 -0
  113. package/dist/manifest-consistency.js +659 -0
  114. package/dist/manifest-consistency.js.map +1 -0
  115. package/dist/mcp-detector.d.ts +4 -0
  116. package/dist/mcp-detector.d.ts.map +1 -0
  117. package/dist/mcp-detector.js +131 -0
  118. package/dist/mcp-detector.js.map +1 -0
  119. package/dist/missing-context.d.ts +15 -0
  120. package/dist/missing-context.d.ts.map +1 -0
  121. package/dist/missing-context.js +517 -0
  122. package/dist/missing-context.js.map +1 -0
  123. package/dist/native-tool-preference.d.ts +20 -0
  124. package/dist/native-tool-preference.d.ts.map +1 -0
  125. package/dist/native-tool-preference.js +94 -0
  126. package/dist/native-tool-preference.js.map +1 -0
  127. package/dist/output-verbosity.d.ts +3 -0
  128. package/dist/output-verbosity.d.ts.map +1 -0
  129. package/dist/output-verbosity.js +83 -0
  130. package/dist/output-verbosity.js.map +1 -0
  131. package/dist/product-boundary.d.ts +11 -0
  132. package/dist/product-boundary.d.ts.map +1 -0
  133. package/dist/product-boundary.js +301 -0
  134. package/dist/product-boundary.js.map +1 -0
  135. package/dist/project-type.d.ts +15 -0
  136. package/dist/project-type.d.ts.map +1 -0
  137. package/dist/project-type.js +116 -0
  138. package/dist/project-type.js.map +1 -0
  139. package/dist/prompt-cache.d.ts +3 -0
  140. package/dist/prompt-cache.d.ts.map +1 -0
  141. package/dist/prompt-cache.js +151 -0
  142. package/dist/prompt-cache.js.map +1 -0
  143. package/dist/repo-context.d.ts +37 -0
  144. package/dist/repo-context.d.ts.map +1 -0
  145. package/dist/repo-context.js +221 -0
  146. package/dist/repo-context.js.map +1 -0
  147. package/dist/report.d.ts +87 -0
  148. package/dist/report.d.ts.map +1 -0
  149. package/dist/report.js +558 -0
  150. package/dist/report.js.map +1 -0
  151. package/dist/scan.d.ts +7 -0
  152. package/dist/scan.d.ts.map +1 -0
  153. package/dist/scan.js +43 -0
  154. package/dist/scan.js.map +1 -0
  155. package/dist/scanner.d.ts +3 -0
  156. package/dist/scanner.d.ts.map +1 -0
  157. package/dist/scanner.js +216 -0
  158. package/dist/scanner.js.map +1 -0
  159. package/dist/security-pack.d.ts +4 -0
  160. package/dist/security-pack.d.ts.map +1 -0
  161. package/dist/security-pack.js +403 -0
  162. package/dist/security-pack.js.map +1 -0
  163. package/dist/stale-instructions.d.ts +20 -0
  164. package/dist/stale-instructions.d.ts.map +1 -0
  165. package/dist/stale-instructions.js +269 -0
  166. package/dist/stale-instructions.js.map +1 -0
  167. package/dist/suppression.d.ts +64 -0
  168. package/dist/suppression.d.ts.map +1 -0
  169. package/dist/suppression.js +338 -0
  170. package/dist/suppression.js.map +1 -0
  171. package/dist/types.d.ts +128 -0
  172. package/dist/types.d.ts.map +1 -0
  173. package/dist/types.js +3 -0
  174. package/dist/types.js.map +1 -0
  175. package/dist/vague-guidance.d.ts +12 -0
  176. package/dist/vague-guidance.d.ts.map +1 -0
  177. package/dist/vague-guidance.js +235 -0
  178. package/dist/vague-guidance.js.map +1 -0
  179. package/package.json +54 -0
@@ -0,0 +1,607 @@
1
+ /**
2
+ * Dead-reference detector for PromptCI.
3
+ *
4
+ * Scans instruction files for references to other local files and flags
5
+ * ones that don't exist on disk. Catches:
6
+ * - Markdown links: [text](./path/to/file.md)
7
+ * - Reference-style links: [text][ref] with a `[ref]: path` definition
8
+ * - @-file refs: @AGENTS.md | @docs/guide.md
9
+ *
10
+ * External URLs (http/https), anchor-only links (#section), and mailto:
11
+ * are always skipped. Only paths with a recognisable file extension are
12
+ * checked to avoid false-positiving on badge shields, npm package names, etc.
13
+ *
14
+ * Findings are heuristic — wording is intentionally cautious.
15
+ */
16
+ import * as fs from 'node:fs';
17
+ import * as path from 'node:path';
18
+ import * as crypto from 'node:crypto';
19
+ // ── Patterns ──────────────────────────────────────────────────────────────────
20
+ /** Matches markdown inline links: [label](target) — captures target (may include a title). */
21
+ const MD_LINK_RE = /\[(?:[^\]]*)\]\(([^)]+)\)/g;
22
+ const NESTED_MD_LINK_RE = /\[(?:[^\]]|\]\([^)]*\))*\]\(([^)]+)\)/g;
23
+ /**
24
+ * Matches markdown reference-style link definitions: `[ref]: path/to/file.md "Title"`
25
+ * These are easy to miss because the usage site `[text][ref]` never carries the path —
26
+ * only the definition line does.
27
+ */
28
+ const LINK_REF_DEF_RE = /^[ \t]{0,3}\[[^\]]+\]:\s*(\S+)/gm;
29
+ /**
30
+ * Matches @-file references: @AGENTS.md, @./path/file.ts, @docs/guide.md
31
+ * Only captures paths that have a recognisable file extension.
32
+ */
33
+ const AT_FILE_RE = /(?<!\w)@((?:\.{1,2}\/)?[\w./\\-]+\.(?:md|ts|js|mjs|cjs|tsx|jsx|json|yml|yaml|toml|txt|sh|py|cs|go|rs))/g;
34
+ /**
35
+ * Matches backtick-enclosed file paths: `scripts/setup-dev.sh`, `Assets/Scripts/Foo.cs`
36
+ * Only fires when the content looks like a file path:
37
+ * - No spaces (commands like `npm run build` are excluded)
38
+ * - Has a recognisable extension
39
+ * This catches prose references like "see `docs/guide.md`" that aren't markdown links.
40
+ * An optional trailing `:line` or `:line:col` suffix (e.g. `src/gone.ts:42`) is allowed
41
+ * after the extension but excluded from the captured path.
42
+ */
43
+ const BACKTICK_PATH_RE = /`([^\s`\n]+\.(?:md|sh|py|ts|js|tsx|jsx|mjs|cjs|json|yml|yaml|toml|cs|go|rs|txt|lock|env|png|jpg|jpeg|gif|svg|webp|pdf))(?::\d+(?::\d+)?)?`/g;
44
+ /**
45
+ * BUG-004: Bullet-list bare file paths in Repository Layout / Project Structure sections.
46
+ * Catches lines like:
47
+ * - docs/runbook.md
48
+ * * src/middleware/auth.rs
49
+ * Requires at least one slash (directory component) to avoid false-positiving on
50
+ * single-word filenames.
51
+ */
52
+ const BULLET_PATH_RE = /^[ \t]*[-*+]\s+((?:[\w.-]+\/)+[\w.-]+\.(?:md|ts|js|tsx|jsx|mjs|cjs|json|yml|yaml|toml|sh|py|cs|go|rs|txt|png|jpg|jpeg|gif|svg|webp|pdf))\b/gm;
53
+ /**
54
+ * BUG-004: ASCII/Unicode directory-tree listing paths.
55
+ * Catches Unicode tree drawings:
56
+ * ├── docs/runbook.md
57
+ * └── rate-limiting.md
58
+ * and their common ASCII-art equivalents:
59
+ * |-- docs/runbook.md
60
+ * `-- rate-limiting.md
61
+ * The Unicode connector chars are unambiguous, so a bare space run after them is enough.
62
+ * The ASCII fallback chars (`|`, `+`, backtick) are also ordinary punctuation elsewhere
63
+ * (table pipes, code spans), so we require at least one dash in the connector to avoid
64
+ * misreading a markdown table cell as a tree entry.
65
+ */
66
+ /**
67
+ * BUG-004: Headings that indicate a repository/file layout section.
68
+ * When a file contains a heading matching this pattern, we also scan for
69
+ * bare paths in bullet lists and directory tree listings.
70
+ *
71
+ * Matches both real markdown headings (`## Project Structure`) and bolded
72
+ * pseudo-headings on their own line (`**Project Structure**`), since authors
73
+ * commonly use bold text in lieu of a heading for this kind of section.
74
+ */
75
+ const LAYOUT_KEYWORDS_SRC = 'repository\\s+layout|project\\s+structure|file\\s+structure|folder\\s+structure|' +
76
+ 'directory\\s+(?:structure|layout|tree|overview)|project\\s+tree|repo\\s+(?:structure|layout|map)|' +
77
+ 'file\\s+tree|files?\\s+overview|codebase\\s+(?:map|overview|structure|layout)|layout';
78
+ const LAYOUT_SECTION_HEADING_RE = new RegExp(`^(?:#{1,4}\\s+.*\\b(?:${LAYOUT_KEYWORDS_SRC})\\b|\\*\\*[^*\\n]*\\b(?:${LAYOUT_KEYWORDS_SRC})\\b[^*\\n]*\\*\\*\\s*)`, 'im');
79
+ /**
80
+ * BUG-D1: Creation-intent phrasing. A reference introduced by an instruction to
81
+ * CREATE a file ("Create a file named `.github/workflows/promptci.yml` in your
82
+ * repository") is a template for the reader's own repo, not a claim that the
83
+ * file exists here — so its absence must not be flagged as a broken reference.
84
+ * Requires a creation verb + a file-ish noun + a connector, keeping it specific
85
+ * enough to avoid suppressing ordinary "see `docs/guide.md`" references.
86
+ *
87
+ * The trailing group captures the introduced target path so ONLY that ref is
88
+ * suppressed — an unrelated broken ref that merely shares the line (e.g.
89
+ * "Create a file named `ci.yml`, like the one in `docs/other.md`") is still
90
+ * flagged.
91
+ */
92
+ const CREATION_INTENT_RE = /\b(?:create|add|generate|scaffold|place|put|save|make)\s+(?:a\s+|an\s+|the\s+|your\s+|this\s+|new\s+)*(?:file|workflow|config(?:uration)?|script|action|manifest|template|module|component)\b[^.\n]*?\b(?:named|called|at|as|in|to|like)\s+[`'"(]*([^\s`'"()]+)/i;
93
+ /** Normalizes a ref for creation-target comparison (slashes, ./ prefix, case). */
94
+ function normalizeRefPath(ref) {
95
+ return stripFragment(ref).replace(/\\/g, '/').replace(/^\.\//, '').toLowerCase();
96
+ }
97
+ /** File extensions we consider worth checking. */
98
+ const CHECKABLE_EXTENSIONS = new Set([
99
+ '.md', '.ts', '.js', '.mjs', '.cjs', '.tsx', '.jsx',
100
+ '.json', '.yml', '.yaml', '.toml', '.txt', '.sh', '.py', '.cs', '.go', '.rs',
101
+ // BUG-006: image and document links (e.g. [./docs/architecture.png]) were previously
102
+ // ignored because their extensions weren't in this set.
103
+ '.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.pdf',
104
+ ]);
105
+ // ── Helpers ───────────────────────────────────────────────────────────────────
106
+ function isExternalRef(ref) {
107
+ return /^https?:\/\/|^mailto:|^#|^data:/.test(ref.trimStart());
108
+ }
109
+ /**
110
+ * Strips a markdown link title from a raw link target.
111
+ * `docs/missing.md "The Guide"` → `docs/missing.md`
112
+ * `docs/missing.md 'The Guide'` → `docs/missing.md`
113
+ * Titles are only recognised when quoted, per the CommonMark link title grammar.
114
+ */
115
+ function stripLinkTitle(raw) {
116
+ const trimmed = raw.trim();
117
+ const angleMatch = /^<([^>]+)>(?:\s+(?:"[^"]*"|'[^']*'))?\s*$/.exec(trimmed);
118
+ if (angleMatch)
119
+ return angleMatch[1];
120
+ const titleMatch = /^(\S+)\s+(?:"[^"]*"|'[^']*')\s*$/.exec(trimmed);
121
+ return titleMatch ? titleMatch[1] : trimmed;
122
+ }
123
+ /**
124
+ * BUG-009 / BUG-012: Placeholder / example filenames and template paths.
125
+ *
126
+ * Skipped cases:
127
+ * - Common placeholder stems: foo.ts, bar.go, example.py, sample.md
128
+ * - ComponentName-style templates: ComponentName.tsx, MyComponent.tsx
129
+ * - Angle-bracket templates: src/features/<domain>/slice.ts
130
+ * - Numeric-suffix patterns: file1.ts, file2.go
131
+ */
132
+ const PLACEHOLDER_STEM_RE = /^(foo|bar|baz|qux|quux|example|sample|placeholder|stub|demo|test|your[-_]?file|my[-_]?file|filename|file[-_]?name)(\.\w+)?$/i;
133
+ /**
134
+ * BUG-C2: Generic bare filenames that commonly appear as naming-convention examples
135
+ * in instruction files (e.g. "name your files like `tokens.json`") rather than as
136
+ * references to specific existing files. Only suppressed when the reference has NO
137
+ * directory prefix — `src/tokens.json` is specific enough to check.
138
+ */
139
+ const GENERIC_BARE_FILENAMES = new Set([
140
+ 'tokens.json', 'config.json', 'settings.json', 'schema.json', 'manifest.json',
141
+ 'types.ts', 'types.d.ts', 'index.ts', 'index.js', 'main.ts', 'main.go',
142
+ 'app.ts', 'app.js', 'constants.ts', 'utils.ts', 'helpers.ts', 'globals.ts',
143
+ 'routes.ts', 'store.ts', 'models.ts', 'services.ts',
144
+ // Universal project root files — always present in their respective ecosystems;
145
+ // flagging them as dead references is always a false positive in real projects.
146
+ 'package.json', 'package-lock.json', 'pnpm-lock.yaml', 'yarn.lock',
147
+ 'tsconfig.json', 'tsconfig.base.json',
148
+ 'pyproject.toml', 'cargo.toml',
149
+ // Framework config roots
150
+ 'next.config.js', 'next.config.ts', 'next.config.mjs',
151
+ 'vite.config.ts', 'vite.config.js', 'vite.config.mjs',
152
+ 'eslint.config.js', 'eslint.config.mjs', 'eslint.config.cjs',
153
+ '.eslintrc.json', '.eslintrc.js', '.eslintrc.yml',
154
+ 'jest.config.ts', 'jest.config.js', 'jest.config.mjs',
155
+ 'vitest.config.ts', 'vitest.config.mts',
156
+ ]);
157
+ /**
158
+ * BUG-012: Component/entity name templates used in naming-convention examples.
159
+ * Matches PascalCase names that are clearly "fill in the blank" placeholders.
160
+ */
161
+ // Allow multiple extension segments so ComponentName.test.tsx is also caught
162
+ const COMPONENT_TEMPLATE_RE = /^(ComponentName|MyComponent|YourComponent|WidgetName|FeatureName|ModuleName|ServiceName|ModelName|EntityName|ResourceName|DomainName|ControllerName|ScreenName|PageName)(?:\.\w+)*$/i;
163
+ function isPlaceholderRef(ref) {
164
+ // BUG-012: Angle-bracket template placeholders: src/features/<domain>/slice.ts
165
+ if (/<[A-Za-z][A-Za-z0-9_-]*>/.test(ref))
166
+ return true;
167
+ // BUG-009: Curly-brace template variables: public/locales/{locale}/{namespace}.json
168
+ // These are pattern descriptions, not real file paths.
169
+ if (/\{[A-Za-z][A-Za-z0-9_-]*\}/.test(ref))
170
+ return true;
171
+ // BUG-006 (eval): Ellipsis segments ("...") are glob placeholders, not real path components.
172
+ // e.g. "src/test/java/.../unit/" is a structural description, not a literal path.
173
+ if (ref.split('/').includes('...'))
174
+ return true;
175
+ const base = path.basename(stripFragment(ref));
176
+ // "Real" directory means a path segment beyond a bare `./` or `.\` prefix.
177
+ // `./sample.md` → dir = '.' → no real directory (still a bare ref)
178
+ // `scripts/test.sh` → dir = 'scripts' → real directory
179
+ const dir = path.dirname(stripFragment(ref));
180
+ const hasRealDirectory = dir !== '.' && dir !== '' && dir !== '.\\' && dir !== './';
181
+ // Common generic placeholder stems — only suppress when there is no real directory prefix.
182
+ // A path like `scripts/test.sh` is a real reference even though "test" is a generic stem;
183
+ // a bare `test.sh` or `./test.sh` is almost certainly a naming-convention example.
184
+ if (!hasRealDirectory && PLACEHOLDER_STEM_RE.test(base))
185
+ return true;
186
+ // BUG-012: PascalCase component/entity name templates
187
+ if (COMPONENT_TEMPLATE_RE.test(base))
188
+ return true;
189
+ const hasDirectoryComponent = hasRealDirectory;
190
+ if (!hasDirectoryComponent && GENERIC_BARE_FILENAMES.has(base.toLowerCase()))
191
+ return true;
192
+ // BUG-005 (eval): Filenames whose stem literally contains a naming-convention term
193
+ // (camelCase, PascalCase, kebab-case, snake_case) are almost certainly illustrative
194
+ // examples in a naming-convention section, not references to real project files.
195
+ // e.g. "useCamelCase.ts", "camelCase.types.ts", "my-kebab-case-component.tsx"
196
+ if (/camelCase|CamelCase|PascalCase|pascalCase|kebab[-_]?[Cc]ase|snake_?[Cc]ase/.test(base))
197
+ return true;
198
+ return false;
199
+ }
200
+ /**
201
+ * BUG-008: Commonly gitignored credential and environment config files, plus
202
+ * known tool output directories whose contents are never committed.
203
+ *
204
+ * These files/paths are intentionally absent from the repo. Flagging them as
205
+ * dead references is a false positive; instruction files legitimately reference
206
+ * them as "where to put your credentials / local config / tool output".
207
+ *
208
+ * Matched against the full ref path (not just basename) so that
209
+ * `config/secrets.py` and `secrets.py` are both caught.
210
+ */
211
+ const GITIGNORED_CREDENTIAL_PATTERNS = [
212
+ // PromptCI output directory — config and reports are user-created, never committed
213
+ /(?:^|[/\\])\.promptci[/\\]/,
214
+ // Python secrets / credentials
215
+ /(?:^|[\\/])secrets?\.\w+$/i,
216
+ /(?:^|[\\/])credentials?\.\w+$/i,
217
+ // .NET environment-specific appsettings (Development / Production are always gitignored)
218
+ /appsettings\.(?:Development|Production|Staging|Local)\.\w+$/i,
219
+ // .env files of any form
220
+ /(?:^|[\\/])\.env(?:\.\w+)?$/i,
221
+ // Generic local-override configs
222
+ /(?:^|[\\/])local\.(?:json|yaml|yml|toml|ini|conf|config)$/i,
223
+ /\.local\.\w+$/i,
224
+ // Named private-key files without a cert/key extension (e.g. ~/.ssh/id_rsa)
225
+ /(?:^|[\\/])(?:private(?:key)?|id_rsa|id_ed25519)(?:\.\w+)?$/i,
226
+ // Certificate/key file EXTENSIONS, regardless of stem — `certs/server.pem`,
227
+ // `config/client.key`, and a bare `.pem` must all be treated the same way.
228
+ /\.(?:pem|key|pfx|p12)$/i,
229
+ ];
230
+ function isGitignored(ref) {
231
+ const normalised = ref.replace(/\\/g, '/');
232
+ return GITIGNORED_CREDENTIAL_PATTERNS.some((re) => re.test(normalised));
233
+ }
234
+ function hasCheckableExtension(ref) {
235
+ const ext = path.extname(ref.split('#')[0] ?? '').toLowerCase();
236
+ return CHECKABLE_EXTENSIONS.has(ext);
237
+ }
238
+ /** Strip query strings and anchor fragments from a path reference. */
239
+ function stripFragment(ref) {
240
+ return ref.split('#')[0].split('?')[0].trim();
241
+ }
242
+ function fileExists(p) {
243
+ try {
244
+ return fs.existsSync(p);
245
+ }
246
+ catch {
247
+ return false;
248
+ }
249
+ }
250
+ /**
251
+ * BUG-C1: Source-code file extensions. When a path has one of these extensions
252
+ * and its parent directory exists (but the file itself doesn't), the reference
253
+ * is likely architecture documentation — reduce confidence accordingly.
254
+ */
255
+ const SOURCE_CODE_EXTENSIONS = new Set([
256
+ '.go', '.cs', '.ts', '.tsx', '.js', '.jsx', '.mjs', '.cjs',
257
+ '.py', '.rs', '.sh', '.java', '.kt', '.swift',
258
+ ]);
259
+ /**
260
+ * BUG-002: Compiled/native source extensions that, when encountered as backtick
261
+ * inline spans (NOT markdown links or @-refs) in any instruction file type,
262
+ * should be skipped. These are almost always architecture documentation, not real
263
+ * file references — e.g. `internal/client/errors.go`, `src/components/Button.tsx`,
264
+ * `pkg/registry/`, `PlayerController.cs`.
265
+ *
266
+ * NOTE: .sh, .py, .js are intentionally excluded — shell/Python/JS scripts are often
267
+ * legitimately referenced by name in instruction files (e.g. `scripts/setup-dev.sh`).
268
+ */
269
+ const BACKTICK_SKIP_SOURCE_EXTENSIONS = new Set([
270
+ '.go', '.rs', '.cs', '.java', '.kt', '.swift',
271
+ '.ts', '.tsx', // TypeScript source — not config/test scripts
272
+ ]);
273
+ /**
274
+ * Backtick source paths are usually architecture descriptions, but explicit
275
+ * legacy/old/deprecated/archive examples are often stale file references that
276
+ * should be checked.
277
+ */
278
+ const STALE_SOURCE_REF_RE = /(?:^|[/\\])(?:legacy|old|deprecated|archive|archived)(?:[/\\]|[-_.])/i;
279
+ /**
280
+ * File types for which backtick-enclosed compiled/native source paths should be
281
+ * skipped. All instruction file types are included because architecture
282
+ * descriptions appear in all of them.
283
+ *
284
+ * BUG-002: Expanded from readme-only to all instruction file types.
285
+ *
286
+ * NOTE: this covers every FileType value, which also means backtick-quoted bare
287
+ * *directory* paths (no extension, e.g. `pkg/registry/`) are always treated as
288
+ * architecture descriptions rather than checked — that is intentional per
289
+ * BUG-002, not an oversight.
290
+ */
291
+ const SKIP_SOURCE_BACKTICK_FILE_TYPES = new Set([
292
+ 'readme', 'claude', 'agents', 'cursor', 'copilot', 'docs', 'prompt', 'unknown',
293
+ ]);
294
+ /** Minimum confidence to emit a dead-reference issue. Below this the signal is too noisy. */
295
+ const MIN_CONFIDENCE = 0.45;
296
+ function parentDirExists(p) {
297
+ try {
298
+ return fs.existsSync(path.dirname(p));
299
+ }
300
+ catch {
301
+ return false;
302
+ }
303
+ }
304
+ function issueId(normRef) {
305
+ const key = `dead-ref:${normRef}`;
306
+ const hash = crypto.createHash('sha1').update(key).digest('hex').slice(0, 12);
307
+ return `dead-ref-${hash}`;
308
+ }
309
+ // ── Line-number tracking ────────────────────────────────────────────────────
310
+ /** Offsets (into `content`) at which each line starts. `lineOffsets[i]` is line `i + 1`. */
311
+ function buildLineOffsets(content) {
312
+ const offsets = [0];
313
+ for (let i = 0; i < content.length; i++) {
314
+ if (content[i] === '\n')
315
+ offsets.push(i + 1);
316
+ }
317
+ return offsets;
318
+ }
319
+ /** 1-indexed line number containing the given character offset. */
320
+ function lineForOffset(lineOffsets, offset) {
321
+ let lo = 0;
322
+ let hi = lineOffsets.length - 1;
323
+ while (lo < hi) {
324
+ const mid = (lo + hi + 1) >> 1;
325
+ if (lineOffsets[mid] <= offset)
326
+ lo = mid;
327
+ else
328
+ hi = mid - 1;
329
+ }
330
+ return lo + 1;
331
+ }
332
+ /**
333
+ * BUG-002 (eval): Extract implied documentation paths from fenced code blocks inside
334
+ * Repository Layout sections. Handles listings where a parent directory line
335
+ * ("docs/") is followed by indented child file entries (" runbook.md").
336
+ *
337
+ * Only extracts .md files — source code file references in layout blocks are
338
+ * intentionally skipped to avoid false positives in test/instruction-only repos
339
+ * where no source files are present on disk.
340
+ *
341
+ * Called only when the file is known to have a layout section heading.
342
+ */
343
+ const CODE_BLOCK_LAYOUT_EXT_RE = /\.(?:md|png|jpg|jpeg|gif|svg|webp|pdf)$/i;
344
+ function parseLayoutEntry(rawLine) {
345
+ const withoutComment = rawLine.replace(/\s*#.*$/, '');
346
+ const verticalPrefix = withoutComment.match(/^[ \t│|]*/)?.[0] ?? '';
347
+ const indent = verticalPrefix.replace(/[│|]/g, ' ').length;
348
+ const trimmed = withoutComment.trim();
349
+ if (!trimmed)
350
+ return null;
351
+ const connectorMatch = /^(?:[│|]\s*)*(?:[├└][-─\s]+|[|+`][-─]+\s*)(.+)$/.exec(trimmed);
352
+ const entry = (connectorMatch ? connectorMatch[1] : trimmed)?.trim() ?? '';
353
+ if (!entry)
354
+ return null;
355
+ if (!connectorMatch && /\s/.test(entry))
356
+ return null;
357
+ return {
358
+ entry,
359
+ indent,
360
+ hasConnector: Boolean(connectorMatch),
361
+ };
362
+ }
363
+ function collectLayoutEntryPaths(lines, lineOffsets, startOffset) {
364
+ const results = [];
365
+ const stack = [];
366
+ let lineOffset = startOffset;
367
+ for (const rawLine of lines) {
368
+ const thisLineOffset = lineOffset;
369
+ lineOffset += rawLine.length + 1;
370
+ const parsed = parseLayoutEntry(rawLine);
371
+ if (!parsed)
372
+ continue;
373
+ const entry = parsed.entry;
374
+ const isDir = /\/$/.test(entry);
375
+ if (isDir) {
376
+ const parent = [...stack].reverse().find((item) => item.indent < parsed.indent || (item.indent === parsed.indent && item.plain));
377
+ const dirPath = `${parent?.path ?? ''}${entry}`;
378
+ while (stack.length > 0 && stack[stack.length - 1].indent >= parsed.indent) {
379
+ stack.pop();
380
+ }
381
+ stack.push({ indent: parsed.indent, path: dirPath, plain: !parsed.hasConnector });
382
+ continue;
383
+ }
384
+ if (!CODE_BLOCK_LAYOUT_EXT_RE.test(entry))
385
+ continue;
386
+ const parent = [...stack].reverse().find((item) => item.indent < parsed.indent || (item.indent === parsed.indent && item.plain));
387
+ const ref = /[/\\]/.test(entry) ? entry : `${parent?.path ?? ''}${entry}`;
388
+ results.push({
389
+ ref,
390
+ evidence: rawLine.trim(),
391
+ line: lineForOffset(lineOffsets, thisLineOffset),
392
+ });
393
+ }
394
+ return results;
395
+ }
396
+ function extractCodeBlockLayoutPaths(content, lineOffsets) {
397
+ const results = [];
398
+ const fenceRe = /^```[^\n]*\n([\s\S]*?)^```/gm;
399
+ let blockMatch;
400
+ while ((blockMatch = fenceRe.exec(content)) !== null) {
401
+ const blockText = blockMatch[1] ?? '';
402
+ const firstLineEnd = content.indexOf('\n', blockMatch.index);
403
+ let lineOffset = firstLineEnd === -1 ? blockMatch.index : firstLineEnd + 1;
404
+ const lines = blockText.split('\n');
405
+ results.push(...collectLayoutEntryPaths(lines, lineOffsets, lineOffset));
406
+ }
407
+ return results;
408
+ }
409
+ function extractLayoutTreePaths(content, lineOffsets) {
410
+ return collectLayoutEntryPaths(content.split('\n'), lineOffsets, 0);
411
+ }
412
+ function collectRefs(content, opts = {}) {
413
+ const found = [];
414
+ const lineOffsets = buildLineOffsets(content);
415
+ // Markdown links: [label](target) or [label](target "Title")
416
+ let m;
417
+ const linkRe = new RegExp(MD_LINK_RE.source, MD_LINK_RE.flags);
418
+ while ((m = linkRe.exec(content)) !== null) {
419
+ if (m.index >= 2 && content[m.index - 2] === '[' && content[m.index - 1] === '!')
420
+ continue;
421
+ const raw = m[1] ?? '';
422
+ const ref = stripFragment(stripLinkTitle(raw));
423
+ if (ref && !isExternalRef(ref) && hasCheckableExtension(ref)) {
424
+ found.push({ ref, evidence: `[...](${raw})`, line: lineForOffset(lineOffsets, m.index) });
425
+ }
426
+ }
427
+ const nestedLinkRe = new RegExp(NESTED_MD_LINK_RE.source, NESTED_MD_LINK_RE.flags);
428
+ while ((m = nestedLinkRe.exec(content)) !== null) {
429
+ const labelPart = m[0].slice(0, m[0].lastIndexOf(']('));
430
+ if (!labelPart.includes(']('))
431
+ continue;
432
+ const raw = m[1] ?? '';
433
+ const ref = stripFragment(stripLinkTitle(raw));
434
+ if (ref && !isExternalRef(ref) && hasCheckableExtension(ref)) {
435
+ found.push({ ref, evidence: `[...](${raw})`, line: lineForOffset(lineOffsets, m.index) });
436
+ }
437
+ }
438
+ // Reference-style link definitions: [ref]: docs/missing.md "Title"
439
+ const linkDefRe = new RegExp(LINK_REF_DEF_RE.source, LINK_REF_DEF_RE.flags);
440
+ while ((m = linkDefRe.exec(content)) !== null) {
441
+ const raw = m[1] ?? '';
442
+ const ref = stripFragment(raw);
443
+ if (ref && !isExternalRef(ref) && hasCheckableExtension(ref)) {
444
+ found.push({ ref, evidence: m[0].trim(), line: lineForOffset(lineOffsets, m.index) });
445
+ }
446
+ }
447
+ // @-file refs
448
+ const atRe = new RegExp(AT_FILE_RE.source, AT_FILE_RE.flags);
449
+ while ((m = atRe.exec(content)) !== null) {
450
+ const ref = m[1] ?? '';
451
+ if (ref && !isExternalRef(ref)) {
452
+ found.push({ ref, evidence: `@${ref}`, line: lineForOffset(lineOffsets, m.index) });
453
+ }
454
+ }
455
+ // Backtick file paths: `scripts/setup-dev.sh`, `Assets/Scripts/Foo.cs`
456
+ // No spaces = file path not a command; must have a recognisable extension.
457
+ // Skip glob patterns (contain * or ?) — those are pattern documentation, not file refs.
458
+ // BUG-002: In all instruction file types (CLAUDE.md, AGENTS.md, .cursorrules, copilot, etc.)
459
+ // skip backtick-quoted compiled/native source files — they are almost always architecture
460
+ // descriptions (e.g. `internal/client/errors.go`), not references to committed files.
461
+ // Shell (.sh), Python (.py), and JS files are kept because they CAN be real script refs.
462
+ const btRe = new RegExp(BACKTICK_PATH_RE.source, BACKTICK_PATH_RE.flags);
463
+ while ((m = btRe.exec(content)) !== null) {
464
+ const ref = m[1] ?? '';
465
+ if (ref && !isExternalRef(ref) && !ref.includes('*') && !ref.includes('?')) {
466
+ if (opts.skipSourceBackticks) {
467
+ const ext = path.extname(ref).toLowerCase();
468
+ if (BACKTICK_SKIP_SOURCE_EXTENSIONS.has(ext) && !STALE_SOURCE_REF_RE.test(ref))
469
+ continue;
470
+ }
471
+ found.push({ ref, evidence: `\`${ref}\``, line: lineForOffset(lineOffsets, m.index) });
472
+ }
473
+ }
474
+ // BUG-004: Bare paths in Repository Layout / Project Structure sections.
475
+ // These appear as bullet list items or ASCII tree lines without backticks.
476
+ if (LAYOUT_SECTION_HEADING_RE.test(content)) {
477
+ const bulletRe = new RegExp(BULLET_PATH_RE.source, BULLET_PATH_RE.flags);
478
+ while ((m = bulletRe.exec(content)) !== null) {
479
+ const ref = m[1] ?? '';
480
+ if (ref && !isExternalRef(ref)) {
481
+ found.push({ ref, evidence: m[0].trim(), line: lineForOffset(lineOffsets, m.index) });
482
+ }
483
+ }
484
+ found.push(...extractLayoutTreePaths(content, lineOffsets));
485
+ // BUG-002 (eval): Fenced code blocks in layout sections may list documentation
486
+ // files as indented children under a parent directory line ("docs/\n runbook.md").
487
+ for (const item of extractCodeBlockLayoutPaths(content, lineOffsets)) {
488
+ found.push(item);
489
+ }
490
+ }
491
+ // BUG-D1: Drop only the reference the line instructs the reader to CREATE
492
+ // (a template for their repo), not every ref that happens to share the line.
493
+ const contentLines = content.split('\n');
494
+ return found.filter(({ ref, line }) => {
495
+ const lineText = contentLines[line - 1] ?? '';
496
+ const m = CREATION_INTENT_RE.exec(lineText);
497
+ if (!m)
498
+ return true;
499
+ const target = normalizeRefPath(m[1] ?? '');
500
+ if (!target)
501
+ return true;
502
+ const refNorm = normalizeRefPath(ref);
503
+ // Suppress the ref that IS the creation target (allow basename-level match so
504
+ // a `path/to/x.yml` ref matches a captured `x.yml` and vice-versa).
505
+ const isTarget = refNorm === target ||
506
+ refNorm.endsWith(`/${target}`) ||
507
+ target.endsWith(`/${refNorm}`);
508
+ return !isTarget;
509
+ });
510
+ }
511
+ // ── Detector ─────────────────────────────────────────────────────────────────
512
+ /**
513
+ * Detect broken file references across all instruction files.
514
+ *
515
+ * @param files Instruction files to scan.
516
+ * @param repoRoot Absolute path to repo root — used as a second resolution base.
517
+ */
518
+ /**
519
+ * BUG-004 / BUG-005: Group all unresolved references by their normalised path so
520
+ * that the same dead reference appearing in multiple instruction files produces ONE
521
+ * consolidated issue (listing all referencing files) instead of N separate issues.
522
+ *
523
+ * Previously each (filePath, ref) pair produced its own issue — a single dead path
524
+ * referenced in both CLAUDE.md and AGENTS.md would fire twice, inflating issue counts
525
+ * and health-score penalties.
526
+ */
527
+ export function detectDeadReferences(files, repoRoot) {
528
+ // normRef → { displayRef, filePaths, fileLines, evidenceLines, minConfidence }
529
+ const byRef = new Map();
530
+ for (const file of files) {
531
+ const fileDir = path.dirname(file.path);
532
+ const refs = collectRefs(file.content, {
533
+ skipSourceBackticks: SKIP_SOURCE_BACKTICK_FILE_TYPES.has(file.fileType),
534
+ });
535
+ for (const { ref, evidence, line } of refs) {
536
+ // BUG-009: Skip obvious placeholder/example filenames (foo.ts, bar.go, etc.)
537
+ if (isPlaceholderRef(ref))
538
+ continue;
539
+ // BUG-008: Skip intentionally gitignored credential/config files.
540
+ if (isGitignored(ref))
541
+ continue;
542
+ // Resolve relative to the instruction file first, then repo root.
543
+ const candidates = [
544
+ path.resolve(fileDir, ref),
545
+ path.resolve(repoRoot, ref),
546
+ ];
547
+ if (candidates.some(fileExists))
548
+ continue;
549
+ // BUG-C1: Source-code paths whose parent directory exists → lower confidence
550
+ // (likely documentation references, not broken links).
551
+ const ext = path.extname(ref.split('#')[0] ?? '').toLowerCase();
552
+ const isSourceCodeRef = SOURCE_CODE_EXTENSIONS.has(ext);
553
+ const anyParentExists = candidates.some(parentDirExists);
554
+ const confidence = isSourceCodeRef && anyParentExists ? 0.5 : 0.85;
555
+ // Normalise for deduplication (case-insensitive, forward slashes)
556
+ const normRef = ref.toLowerCase().replace(/\\/g, '/');
557
+ const evidenceLine = `Reference: ${evidence}`;
558
+ if (!byRef.has(normRef)) {
559
+ byRef.set(normRef, {
560
+ displayRef: ref,
561
+ filePaths: new Set(),
562
+ fileLines: new Map(),
563
+ evidenceLines: [],
564
+ minConfidence: confidence,
565
+ });
566
+ }
567
+ const entry = byRef.get(normRef);
568
+ entry.filePaths.add(file.path);
569
+ const existingLine = entry.fileLines.get(file.path);
570
+ if (existingLine === undefined || line < existingLine) {
571
+ entry.fileLines.set(file.path, line);
572
+ }
573
+ if (!entry.evidenceLines.includes(evidenceLine)) {
574
+ entry.evidenceLines.push(evidenceLine);
575
+ }
576
+ entry.minConfidence = Math.min(entry.minConfidence, confidence);
577
+ }
578
+ }
579
+ const issues = [];
580
+ const MIN_CONFIDENCE_THRESHOLD = MIN_CONFIDENCE;
581
+ for (const [normRef, { displayRef, filePaths, fileLines, evidenceLines, minConfidence }] of byRef) {
582
+ // BUG-002: Skip findings below the minimum confidence threshold.
583
+ // Low-confidence source-code path references are almost certainly architecture docs.
584
+ if (minConfidence < MIN_CONFIDENCE_THRESHOLD)
585
+ continue;
586
+ const allFilePaths = [...filePaths];
587
+ issues.push({
588
+ id: issueId(normRef),
589
+ severity: 'warning',
590
+ category: 'structure',
591
+ title: `Broken file reference: ${path.basename(stripFragment(displayRef))}`,
592
+ summary: `This instruction file references "${displayRef}" which does not appear to exist. ` +
593
+ `The file may have been renamed, moved, or deleted.`,
594
+ filePaths: allFilePaths,
595
+ locations: allFilePaths.map((fp) => {
596
+ const startLine = fileLines.get(fp);
597
+ return startLine !== undefined ? { filePath: fp, startLine } : { filePath: fp };
598
+ }),
599
+ evidence: evidenceLines,
600
+ recommendation: 'Verify the path is correct relative to the instruction file location, ' +
601
+ 'or remove the reference if the file no longer exists.',
602
+ confidence: minConfidence,
603
+ });
604
+ }
605
+ return issues;
606
+ }
607
+ //# sourceMappingURL=dead-references.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dead-references.js","sourceRoot":"","sources":["../src/dead-references.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { PromptCiIssue } from './types.js';
2
+ import type { RepoContext } from './repo-context.js';
3
+ export type DetectorGroup = 'scan' | 'context';
4
+ export type DetectorDefinition = {
5
+ id: string;
6
+ group: DetectorGroup;
7
+ run: (context: RepoContext) => PromptCiIssue[];
8
+ };
9
+ export declare const DETECTORS: DetectorDefinition[];
10
+ export declare function runDetectors(context: RepoContext, group: DetectorGroup): PromptCiIssue[];
11
+ //# sourceMappingURL=detectors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.d.ts","sourceRoot":"","sources":["../src/detectors.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;AAE/C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;IACrB,GAAG,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,aAAa,EAAE,CAAC;CAChD,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,kBAAkB,EAmIzC,CAAC;AAEF,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,aAAa,GAAG,aAAa,EAAE,CAIxF"}