@promptci/core 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +29 -30
- package/dist/agent-practices.d.ts +2 -0
- package/dist/agent-practices.d.ts.map +1 -1
- package/dist/agent-practices.js +91 -51
- package/dist/agent-practices.js.map +1 -1
- package/dist/ai-config.d.ts +139 -0
- package/dist/ai-config.d.ts.map +1 -0
- package/dist/ai-config.js +523 -0
- package/dist/ai-config.js.map +1 -0
- package/dist/baseline.d.ts +17 -1
- package/dist/baseline.d.ts.map +1 -1
- package/dist/baseline.js +5 -1
- package/dist/baseline.js.map +1 -1
- package/dist/buried-critical.d.ts +17 -0
- package/dist/buried-critical.d.ts.map +1 -0
- package/dist/buried-critical.js +112 -0
- package/dist/buried-critical.js.map +1 -0
- package/dist/canonical-owner.d.ts.map +1 -1
- package/dist/canonical-owner.js +18 -8
- package/dist/canonical-owner.js.map +1 -1
- package/dist/command-validity.d.ts.map +1 -1
- package/dist/command-validity.js +53 -74
- package/dist/command-validity.js.map +1 -1
- package/dist/conflicts.d.ts.map +1 -1
- package/dist/conflicts.js +1 -42
- package/dist/conflicts.js.map +1 -1
- package/dist/context-analysis.d.ts.map +1 -1
- package/dist/context-analysis.js +13 -2
- package/dist/context-analysis.js.map +1 -1
- package/dist/context-bloat.d.ts +19 -0
- package/dist/context-bloat.d.ts.map +1 -1
- package/dist/context-bloat.js +82 -9
- package/dist/context-bloat.js.map +1 -1
- package/dist/context-optimizer.d.ts.map +1 -1
- package/dist/context-optimizer.js +15 -54
- package/dist/context-optimizer.js.map +1 -1
- package/dist/copilot-instructions-detector.d.ts +24 -0
- package/dist/copilot-instructions-detector.d.ts.map +1 -0
- package/dist/copilot-instructions-detector.js +145 -0
- package/dist/copilot-instructions-detector.js.map +1 -0
- package/dist/cursor-rules-detector.d.ts +17 -0
- package/dist/cursor-rules-detector.d.ts.map +1 -0
- package/dist/cursor-rules-detector.js +110 -0
- package/dist/cursor-rules-detector.js.map +1 -0
- package/dist/custom-rules.d.ts +52 -0
- package/dist/custom-rules.d.ts.map +1 -0
- package/dist/custom-rules.js +298 -0
- package/dist/custom-rules.js.map +1 -0
- package/dist/dead-references.js +11 -9
- package/dist/dead-references.js.map +1 -1
- package/dist/detectors.d.ts +1 -3
- package/dist/detectors.d.ts.map +1 -1
- package/dist/detectors.js +46 -53
- package/dist/detectors.js.map +1 -1
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +10 -5
- package/dist/duplicates.js.map +1 -1
- package/dist/evidence.d.ts +28 -0
- package/dist/evidence.d.ts.map +1 -0
- package/dist/evidence.js +38 -0
- package/dist/evidence.js.map +1 -0
- package/dist/fix-engine.d.ts +11 -0
- package/dist/fix-engine.d.ts.map +1 -1
- package/dist/fix-engine.js +88 -71
- package/dist/fix-engine.js.map +1 -1
- package/dist/frameworks/python.d.ts.map +1 -1
- package/dist/frameworks/python.js +5 -2
- package/dist/frameworks/python.js.map +1 -1
- package/dist/health-score.d.ts.map +1 -1
- package/dist/health-score.js +1 -0
- package/dist/health-score.js.map +1 -1
- package/dist/hooks-settings-detector.d.ts +17 -0
- package/dist/hooks-settings-detector.d.ts.map +1 -0
- package/dist/hooks-settings-detector.js +228 -0
- package/dist/hooks-settings-detector.js.map +1 -0
- package/dist/index.d.ts +22 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -6
- package/dist/index.js.map +1 -1
- package/dist/manifest-consistency.d.ts +6 -0
- package/dist/manifest-consistency.d.ts.map +1 -1
- package/dist/manifest-consistency.js +26 -5
- package/dist/manifest-consistency.js.map +1 -1
- package/dist/markdown-fences.d.ts +112 -0
- package/dist/markdown-fences.d.ts.map +1 -0
- package/dist/markdown-fences.js +174 -0
- package/dist/markdown-fences.js.map +1 -0
- package/dist/mcp-config-detector.d.ts +20 -0
- package/dist/mcp-config-detector.d.ts.map +1 -0
- package/dist/mcp-config-detector.js +237 -0
- package/dist/mcp-config-detector.js.map +1 -0
- package/dist/missing-context.d.ts.map +1 -1
- package/dist/missing-context.js +2 -52
- package/dist/missing-context.js.map +1 -1
- package/dist/model-budgets.d.ts +69 -0
- package/dist/model-budgets.d.ts.map +1 -0
- package/dist/model-budgets.js +110 -0
- package/dist/model-budgets.js.map +1 -0
- package/dist/negative-instructions.d.ts +26 -0
- package/dist/negative-instructions.d.ts.map +1 -0
- package/dist/negative-instructions.js +174 -0
- package/dist/negative-instructions.js.map +1 -0
- package/dist/path-containment.d.ts +12 -0
- package/dist/path-containment.d.ts.map +1 -0
- package/dist/path-containment.js +53 -0
- package/dist/path-containment.js.map +1 -0
- package/dist/project-type.d.ts +12 -2
- package/dist/project-type.d.ts.map +1 -1
- package/dist/project-type.js +25 -12
- package/dist/project-type.js.map +1 -1
- package/dist/prompt-cache.d.ts.map +1 -1
- package/dist/prompt-cache.js +26 -19
- package/dist/prompt-cache.js.map +1 -1
- package/dist/promptci-gitignore.d.ts +34 -0
- package/dist/promptci-gitignore.d.ts.map +1 -0
- package/dist/promptci-gitignore.js +42 -0
- package/dist/promptci-gitignore.js.map +1 -0
- package/dist/repo-context.d.ts +27 -0
- package/dist/repo-context.d.ts.map +1 -1
- package/dist/repo-context.js +42 -11
- package/dist/repo-context.js.map +1 -1
- package/dist/report.d.ts +1 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +132 -61
- package/dist/report.js.map +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +7 -3
- package/dist/scan.js.map +1 -1
- package/dist/scanner.d.ts +13 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +49 -37
- package/dist/scanner.js.map +1 -1
- package/dist/security-pack.d.ts +20 -0
- package/dist/security-pack.d.ts.map +1 -1
- package/dist/security-pack.js +27 -10
- package/dist/security-pack.js.map +1 -1
- package/dist/skills-detector.d.ts +19 -0
- package/dist/skills-detector.d.ts.map +1 -0
- package/dist/skills-detector.js +203 -0
- package/dist/skills-detector.js.map +1 -0
- package/dist/stale-instructions.d.ts +4 -1
- package/dist/stale-instructions.d.ts.map +1 -1
- package/dist/stale-instructions.js +51 -54
- package/dist/stale-instructions.js.map +1 -1
- package/dist/subagents-detector.d.ts +19 -0
- package/dist/subagents-detector.d.ts.map +1 -0
- package/dist/subagents-detector.js +155 -0
- package/dist/subagents-detector.js.map +1 -0
- package/dist/suppression.d.ts.map +1 -1
- package/dist/suppression.js +11 -45
- package/dist/suppression.js.map +1 -1
- package/dist/types.d.ts +28 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +25 -1
- package/dist/types.js.map +1 -1
- package/dist/vague-guidance.d.ts +15 -2
- package/dist/vague-guidance.d.ts.map +1 -1
- package/dist/vague-guidance.js +42 -40
- package/dist/vague-guidance.js.map +1 -1
- package/dist/windsurf-detector.d.ts +22 -0
- package/dist/windsurf-detector.d.ts.map +1 -0
- package/dist/windsurf-detector.js +87 -0
- package/dist/windsurf-detector.js.map +1 -0
- package/dist/within-section-dedup.d.ts +16 -0
- package/dist/within-section-dedup.d.ts.map +1 -0
- package/dist/within-section-dedup.js +153 -0
- package/dist/within-section-dedup.js.map +1 -0
- package/package.json +11 -8
- package/dist/cheap-model-routing.d.ts +0 -4
- package/dist/cheap-model-routing.d.ts.map +0 -1
- package/dist/cheap-model-routing.js +0 -43
- package/dist/cheap-model-routing.js.map +0 -1
- package/dist/cli-output-filter.d.ts +0 -16
- package/dist/cli-output-filter.d.ts.map +0 -1
- package/dist/cli-output-filter.js +0 -88
- package/dist/cli-output-filter.js.map +0 -1
- package/dist/context-cost.d.ts +0 -4
- package/dist/context-cost.d.ts.map +0 -1
- package/dist/context-cost.js +0 -70
- package/dist/context-cost.js.map +0 -1
- package/dist/context-recommender.d.ts +0 -3
- package/dist/context-recommender.d.ts.map +0 -1
- package/dist/context-recommender.js +0 -329
- package/dist/context-recommender.js.map +0 -1
- package/dist/llm.d.ts +0 -6
- package/dist/llm.d.ts.map +0 -1
- package/dist/llm.js +0 -67
- package/dist/llm.js.map +0 -1
- package/dist/mcp-detector.d.ts +0 -4
- package/dist/mcp-detector.d.ts.map +0 -1
- package/dist/mcp-detector.js +0 -131
- package/dist/mcp-detector.js.map +0 -1
- package/dist/native-tool-preference.d.ts +0 -20
- package/dist/native-tool-preference.d.ts.map +0 -1
- package/dist/native-tool-preference.js +0 -94
- package/dist/native-tool-preference.js.map +0 -1
- package/dist/output-verbosity.d.ts +0 -3
- package/dist/output-verbosity.d.ts.map +0 -1
- package/dist/output-verbosity.js +0 -83
- package/dist/output-verbosity.js.map +0 -1
- package/dist/product-boundary.d.ts +0 -11
- package/dist/product-boundary.d.ts.map +0 -1
- package/dist/product-boundary.js +0 -301
- package/dist/product-boundary.js.map +0 -1
package/dist/scan.js
CHANGED
|
@@ -9,11 +9,15 @@ import { computeHealthScore, selectTopFixes } from './health-score.js';
|
|
|
9
9
|
import { filterNewIssues } from './baseline.js';
|
|
10
10
|
export async function scan(input) {
|
|
11
11
|
const context = await buildRepoContext(input);
|
|
12
|
-
const issues = runDetectors(context
|
|
12
|
+
const issues = runDetectors(context);
|
|
13
|
+
// On-demand skill/agent bodies are held out of context.files so the prose
|
|
14
|
+
// detectors skip them, but they still appear in the report inventory and can
|
|
15
|
+
// carry inline suppression annotations for ai_config findings on their path.
|
|
16
|
+
const allScannedFiles = [...context.files, ...context.onDemandFiles];
|
|
13
17
|
// Apply inline suppression annotations.
|
|
14
18
|
// Invalid annotations are surfaced as warning issues (count against score).
|
|
15
19
|
// Suppressed issues are excluded from health score and topFixes.
|
|
16
|
-
const annotations = parseSuppressions(
|
|
20
|
+
const annotations = parseSuppressions(allScannedFiles);
|
|
17
21
|
const allIssues = [...issues, ...buildValidationIssues(annotations)];
|
|
18
22
|
const { active, suppressed } = applySuppressions(allIssues, annotations);
|
|
19
23
|
const healthScore = computeHealthScore(active);
|
|
@@ -32,7 +36,7 @@ export async function scan(input) {
|
|
|
32
36
|
projectType: context.projectType,
|
|
33
37
|
healthScore,
|
|
34
38
|
metrics: context.metrics,
|
|
35
|
-
filesScanned:
|
|
39
|
+
filesScanned: allScannedFiles,
|
|
36
40
|
issues: active,
|
|
37
41
|
topFixes,
|
|
38
42
|
newIssues,
|
package/dist/scan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAAgB;IACzC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,
|
|
1
|
+
{"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,KAAgB;IACzC,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IAErC,0EAA0E;IAC1E,6EAA6E;IAC7E,6EAA6E;IAC7E,MAAM,eAAe,GAAG,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAErE,wCAAwC;IACxC,4EAA4E;IAC5E,iEAAiE;IACjE,MAAM,WAAW,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAAC,CAAC;IACrE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,iBAAiB,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IAEzE,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAExC,IAAI,SAAS,CAAC;IACd,IAAI,eAAe,CAAC;IAEpB,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACnB,MAAM,QAAQ,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC3E,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC;QAC/B,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;IAC7C,CAAC;IAED,OAAO;QACL,aAAa,EAAE,KAAK;QACpB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW;QACX,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,YAAY,EAAE,eAAe;QAC7B,MAAM,EAAE,MAAM;QACd,QAAQ;QACR,SAAS;QACT,eAAe;QACf,gBAAgB,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;KACjE,CAAC;AACJ,CAAC"}
|
package/dist/scanner.d.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
import type { InstructionFile, ScanInput } from './types.js';
|
|
1
|
+
import type { InstructionFile, InstructionSection, ScanInput } from './types.js';
|
|
2
|
+
export declare const MAX_FILE_SIZE: number;
|
|
3
|
+
export declare const BINARY_CHECK_BYTES = 512;
|
|
4
|
+
/**
|
|
5
|
+
* Splits markdown into heading-delimited sections.
|
|
6
|
+
*
|
|
7
|
+
* Exported because context-optimizer previously carried a forked copy with a
|
|
8
|
+
* naive fence toggle (any ``` line flipped the flag, so ~~~ fences and longer
|
|
9
|
+
* ``` runs desynchronised it) — and that copy decided which sections get moved
|
|
10
|
+
* out of a user's instruction files.
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseSections(content: string, filePath: string): InstructionSection[];
|
|
13
|
+
export declare function isBinary(buffer: Buffer): boolean;
|
|
2
14
|
export declare function scanFiles(input: ScanInput): Promise<InstructionFile[]>;
|
|
3
15
|
//# sourceMappingURL=scanner.d.ts.map
|
package/dist/scanner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,eAAe,
|
|
1
|
+
{"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAY,eAAe,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA+C3F,eAAO,MAAM,aAAa,QAAa,CAAC;AACxC,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAuDtC;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAsDrF;AAED,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAMhD;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CA4D5E"}
|
package/dist/scanner.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import fg from 'fast-glob';
|
|
2
2
|
import * as fs from 'node:fs/promises';
|
|
3
3
|
import * as path from 'node:path';
|
|
4
|
+
import { scanFencedLines } from './markdown-fences.js';
|
|
5
|
+
import { isWithinRoot } from './path-containment.js';
|
|
4
6
|
const DEFAULT_PATTERNS = [
|
|
5
7
|
// Core AI instruction files
|
|
6
8
|
'CLAUDE.md',
|
|
@@ -40,17 +42,42 @@ const DEFAULT_PATTERNS = [
|
|
|
40
42
|
// dir used by other agent tooling) — these are full copies of the repo and
|
|
41
43
|
// would otherwise be scanned as duplicate instruction-file trees.
|
|
42
44
|
const IGNORE_DIRS = ['.git', 'node_modules', 'Library', 'Temp', 'bin', 'obj', 'dist', 'build', 'worktrees', '.worktrees'];
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
// Exported so ai_config discovery (ai-config.ts) applies the exact same
|
|
46
|
+
// size/binary policy as this scanner — one definition of "scannable file".
|
|
47
|
+
export const MAX_FILE_SIZE = 500 * 1024;
|
|
48
|
+
export const BINARY_CHECK_BYTES = 512;
|
|
49
|
+
// Takes the repo-root-relative path (not the absolute path): classification must
|
|
50
|
+
// depend only on where a file sits INSIDE the scanned repo. Using the absolute
|
|
51
|
+
// path let the checkout location leak in — a repo checked out under an external
|
|
52
|
+
// `.../.claude/worktrees/<branch>/` path (e.g. a Claude Code worktree) made every
|
|
53
|
+
// scanned file match `/.claude/` and get classified 'claude', producing bogus
|
|
54
|
+
// findings like "No behavioral guidance in CLAUDE.md" against README.md.
|
|
55
|
+
//
|
|
56
|
+
// A root-relative path has no leading slash (e.g. `.claude/foo.md`), so normalise
|
|
57
|
+
// to a leading-slash, forward-slash form before the directory-substring checks.
|
|
58
|
+
function deriveFileType(relPath) {
|
|
59
|
+
const norm = '/' + relPath.replace(/\\/g, '/').replace(/^\/+/, '');
|
|
60
|
+
const base = norm.slice(norm.lastIndexOf('/') + 1);
|
|
48
61
|
if (base === 'AGENTS.md')
|
|
49
62
|
return 'agents';
|
|
50
63
|
if (base === '.cursorrules' || norm.includes('/.cursor/rules/'))
|
|
51
64
|
return 'cursor';
|
|
65
|
+
// BUG-19: `.windsurfrules` is in DEFAULT_PATTERNS above, so it was always read
|
|
66
|
+
// and counted toward context-bloat totals — but with no branch here it fell
|
|
67
|
+
// through to 'unknown', which every filetype-gated detector's allowlist omits.
|
|
68
|
+
// The file was scanned and then silently ignored by ~6 detectors.
|
|
69
|
+
if (base === '.windsurfrules')
|
|
70
|
+
return 'windsurf';
|
|
52
71
|
if (base === 'copilot-instructions.md' || norm.includes('/.github/instructions/'))
|
|
53
72
|
return 'copilot';
|
|
73
|
+
// Load-on-demand Claude Code config surfaces. Classified before the generic
|
|
74
|
+
// '/.claude/' → 'claude' rule below so a skill's SKILL.md and its reference
|
|
75
|
+
// files (and every agent definition) are treated as on-demand, not as
|
|
76
|
+
// always-loaded prose — the ai_config detectors audit them structurally.
|
|
77
|
+
if (norm.includes('/.claude/agents/'))
|
|
78
|
+
return 'agent';
|
|
79
|
+
if (norm.includes('/.claude/skills/'))
|
|
80
|
+
return 'skill';
|
|
54
81
|
if (base === 'CLAUDE.md' || norm.includes('/.claude/'))
|
|
55
82
|
return 'claude';
|
|
56
83
|
if (base === 'README.md')
|
|
@@ -78,7 +105,15 @@ function splitLines(content) {
|
|
|
78
105
|
}
|
|
79
106
|
return rawLines;
|
|
80
107
|
}
|
|
81
|
-
|
|
108
|
+
/**
|
|
109
|
+
* Splits markdown into heading-delimited sections.
|
|
110
|
+
*
|
|
111
|
+
* Exported because context-optimizer previously carried a forked copy with a
|
|
112
|
+
* naive fence toggle (any ``` line flipped the flag, so ~~~ fences and longer
|
|
113
|
+
* ``` runs desynchronised it) — and that copy decided which sections get moved
|
|
114
|
+
* out of a user's instruction files.
|
|
115
|
+
*/
|
|
116
|
+
export function parseSections(content, filePath) {
|
|
82
117
|
const lines = splitLines(content);
|
|
83
118
|
const sections = [];
|
|
84
119
|
let currentHeading = undefined;
|
|
@@ -97,35 +132,13 @@ function parseSections(content, filePath) {
|
|
|
97
132
|
normalizedText: text.toLowerCase().trim(),
|
|
98
133
|
});
|
|
99
134
|
};
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
135
|
+
// Fenced lines are kept in the section text but never read as headings —
|
|
136
|
+
// otherwise a bash comment (`# text`) inside a code block splits the section.
|
|
137
|
+
const fenceLines = scanFencedLines(content);
|
|
103
138
|
for (let i = 0; i < lines.length; i++) {
|
|
104
139
|
const lineNum = i + 1;
|
|
105
140
|
const line = lines[i] ?? '';
|
|
106
|
-
|
|
107
|
-
// headings. A closing fence must use the same fence character (``` vs ~~~
|
|
108
|
-
// are not interchangeable) and be at least as long as the opening fence,
|
|
109
|
-
// per CommonMark. Up to 3 leading spaces are allowed on either fence.
|
|
110
|
-
if (!inCodeBlock) {
|
|
111
|
-
const openMatch = /^ {0,3}([`~]{3,})/.exec(line);
|
|
112
|
-
if (openMatch) {
|
|
113
|
-
inCodeBlock = true;
|
|
114
|
-
fenceChar = openMatch[1][0] ?? null;
|
|
115
|
-
fenceLen = openMatch[1].length;
|
|
116
|
-
currentLines.push(line);
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
else {
|
|
121
|
-
const closeMatch = /^ {0,3}([`~]{3,})\s*$/.exec(line);
|
|
122
|
-
if (closeMatch && closeMatch[1][0] === fenceChar && closeMatch[1].length >= fenceLen) {
|
|
123
|
-
inCodeBlock = false;
|
|
124
|
-
fenceChar = null;
|
|
125
|
-
fenceLen = 0;
|
|
126
|
-
currentLines.push(line);
|
|
127
|
-
continue;
|
|
128
|
-
}
|
|
141
|
+
if (fenceLines[i]?.inFence) {
|
|
129
142
|
currentLines.push(line);
|
|
130
143
|
continue;
|
|
131
144
|
}
|
|
@@ -147,7 +160,7 @@ function parseSections(content, filePath) {
|
|
|
147
160
|
}
|
|
148
161
|
return sections;
|
|
149
162
|
}
|
|
150
|
-
function isBinary(buffer) {
|
|
163
|
+
export function isBinary(buffer) {
|
|
151
164
|
const end = Math.min(buffer.length, BINARY_CHECK_BYTES);
|
|
152
165
|
for (let i = 0; i < end; i++) {
|
|
153
166
|
if (buffer[i] === 0)
|
|
@@ -178,9 +191,8 @@ export async function scanFiles(input) {
|
|
|
178
191
|
const results = [];
|
|
179
192
|
for (const relPath of relativePaths) {
|
|
180
193
|
const absPath = path.resolve(repoRoot, relPath);
|
|
181
|
-
// Path traversal guard
|
|
182
|
-
|
|
183
|
-
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
194
|
+
// Path traversal guard: skip anything a glob result resolves outside the root.
|
|
195
|
+
if (!isWithinRoot(repoRoot, absPath)) {
|
|
184
196
|
continue;
|
|
185
197
|
}
|
|
186
198
|
try {
|
|
@@ -198,7 +210,7 @@ export async function scanFiles(input) {
|
|
|
198
210
|
const charCount = content.length;
|
|
199
211
|
results.push({
|
|
200
212
|
path: absPath,
|
|
201
|
-
fileType: deriveFileType(
|
|
213
|
+
fileType: deriveFileType(relPath),
|
|
202
214
|
content,
|
|
203
215
|
sections,
|
|
204
216
|
lineCount,
|
package/dist/scanner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,WAAW,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"scanner.js","sourceRoot":"","sources":["../src/scanner.ts"],"names":[],"mappings":"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"}
|
package/dist/security-pack.d.ts
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import type { PromptCiIssue } from './types.js';
|
|
2
2
|
import type { RepoContext } from './repo-context.js';
|
|
3
|
+
/**
|
|
4
|
+
* SP3: does this .gitignore LINE actually ignore `target` (a bare directory
|
|
5
|
+
* or dotfile name, no slashes)?
|
|
6
|
+
*
|
|
7
|
+
* Old behavior used `clean.includes(target)` as a catch-all fallback, which
|
|
8
|
+
* was wrong two ways:
|
|
9
|
+
* 1. A NEGATION line ("!.promptci/") re-includes a path (un-ignores it) in
|
|
10
|
+
* gitignore syntax, but `"!.promptci".includes(".promptci")` is true, so
|
|
11
|
+
* the negation was misread as "yes, this is ignored".
|
|
12
|
+
* 2. Substring matching let an unrelated entry satisfy the check —
|
|
13
|
+
* "distribution.md".includes("dist") and "builds-notes/".includes("build")
|
|
14
|
+
* are both true, so those unrelated lines were misread as ignoring
|
|
15
|
+
* "dist"/"build", masking a real unignored-directory finding (FN).
|
|
16
|
+
*
|
|
17
|
+
* Fixed by rejecting negation lines outright, then requiring an EXACT path
|
|
18
|
+
* SEGMENT match (splitting on '/' so a leading globstar segment doesn't
|
|
19
|
+
* block the match, but a differently-named file/dir never accidentally
|
|
20
|
+
* satisfies it).
|
|
21
|
+
*/
|
|
22
|
+
export declare function gitignoreLineMatchesTarget(line: string, target: string): boolean;
|
|
3
23
|
export declare function detectSecurityPack(context: RepoContext): PromptCiIssue[];
|
|
4
24
|
//# sourceMappingURL=security-pack.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-pack.d.ts","sourceRoot":"","sources":["../src/security-pack.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"security-pack.d.ts","sourceRoot":"","sources":["../src/security-pack.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAiIrD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAKhF;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CA6TxE"}
|
package/dist/security-pack.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
3
|
import * as fs from 'node:fs';
|
|
4
|
+
import { matchEvidence } from './evidence.js';
|
|
5
|
+
import { PROMPTCI_GITIGNORE_BLOCK, PROMPTCI_GITIGNORE_LINES } from './promptci-gitignore.js';
|
|
4
6
|
const SECURITY_CHECKS = [
|
|
5
7
|
{
|
|
6
8
|
id: 'no-secret-safeguard',
|
|
@@ -119,7 +121,7 @@ function matchesAny(text, patterns) {
|
|
|
119
121
|
* block the match, but a differently-named file/dir never accidentally
|
|
120
122
|
* satisfies it).
|
|
121
123
|
*/
|
|
122
|
-
function gitignoreLineMatchesTarget(line, target) {
|
|
124
|
+
export function gitignoreLineMatchesTarget(line, target) {
|
|
123
125
|
if (line.startsWith('!'))
|
|
124
126
|
return false;
|
|
125
127
|
const clean = line.replace(/^\/+|\/+$/g, '');
|
|
@@ -287,8 +289,18 @@ export function detectSecurityPack(context) {
|
|
|
287
289
|
filePaths: ['.gitignore'],
|
|
288
290
|
locations: [],
|
|
289
291
|
evidence: ['.promptci/ entry not found in .gitignore'],
|
|
290
|
-
|
|
291
|
-
|
|
292
|
+
// BUG-7: recommend the carve-out, not a bare `.promptci/`. Ignoring the
|
|
293
|
+
// whole directory also ignores baseline.json, and `--baseline` /
|
|
294
|
+
// `--fail-on-new` need that file committed and readable in CI.
|
|
295
|
+
recommendation: 'Add the following to `.gitignore` so generated reports stay out of git while the shared ' +
|
|
296
|
+
'baseline and config remain committed:\n' +
|
|
297
|
+
PROMPTCI_GITIGNORE_LINES.map((l) => ` ${l}`).join('\n') +
|
|
298
|
+
'\n\nUse `.promptci/*` rather than `.promptci/` — git does not descend into an ignored ' +
|
|
299
|
+
'directory, so the `!` negations only work against the directory\'s contents.',
|
|
300
|
+
fixRecipe: PROMPTCI_GITIGNORE_BLOCK,
|
|
301
|
+
// `applyFixRecipe` appends the baseline-preserving stanza deterministically
|
|
302
|
+
// — a mechanical, reversible edit, so `promptci fix` may auto-apply it.
|
|
303
|
+
autoApplySafe: true,
|
|
292
304
|
confidence: 0.9,
|
|
293
305
|
});
|
|
294
306
|
}
|
|
@@ -324,6 +336,9 @@ export function detectSecurityPack(context) {
|
|
|
324
336
|
evidence: unignoredDirs.map((d) => `Directory "${d}" exists but is not ignored in .gitignore.`),
|
|
325
337
|
recommendation: `Add generated directories to .gitignore. For example: "${unignoredDirs.map((d) => `${d}/`).join(', ')}"`,
|
|
326
338
|
fixRecipe: unignoredDirs.map((d) => `echo "${d}/" >> .gitignore`).join('\n'),
|
|
339
|
+
// `applyFixRecipe` appends each missing directory to .gitignore — a
|
|
340
|
+
// mechanical, reversible edit, so `promptci fix` may auto-apply it.
|
|
341
|
+
autoApplySafe: true,
|
|
327
342
|
confidence: 0.8,
|
|
328
343
|
});
|
|
329
344
|
}
|
|
@@ -368,15 +383,17 @@ export function detectSecurityPack(context) {
|
|
|
368
383
|
}
|
|
369
384
|
// 9. Inspect generated reports before source docs (Cost 9)
|
|
370
385
|
for (const file of files) {
|
|
386
|
+
// BUG-20: each pattern carries a human label so evidence can quote the
|
|
387
|
+
// matched instruction text instead of the regex source.
|
|
371
388
|
const inspectBeforePatterns = [
|
|
372
|
-
/read\s+.*\.promptci\s+before/i,
|
|
373
|
-
/inspect\s+.*\.promptci\s+before/i,
|
|
374
|
-
/check\s+.*\.promptci\s+before/i,
|
|
375
|
-
/read\s+.*report.*\s+before\s+.*(source|docs|code)/i,
|
|
376
|
-
/inspect\s+.*report.*\s+before\s+.*(source|docs|code)/i,
|
|
389
|
+
{ re: /read\s+.*\.promptci\s+before/i, label: 'Instruction to read .promptci reports first' },
|
|
390
|
+
{ re: /inspect\s+.*\.promptci\s+before/i, label: 'Instruction to inspect .promptci reports first' },
|
|
391
|
+
{ re: /check\s+.*\.promptci\s+before/i, label: 'Instruction to check .promptci reports first' },
|
|
392
|
+
{ re: /read\s+.*report.*\s+before\s+.*(source|docs|code)/i, label: 'Instruction to read generated reports before source' },
|
|
393
|
+
{ re: /inspect\s+.*report.*\s+before\s+.*(source|docs|code)/i, label: 'Instruction to inspect generated reports before source' },
|
|
377
394
|
];
|
|
378
395
|
for (const pat of inspectBeforePatterns) {
|
|
379
|
-
if (pat.test(file.content)) {
|
|
396
|
+
if (pat.re.test(file.content)) {
|
|
380
397
|
issues.push({
|
|
381
398
|
// SP1 / B3: was a constant id inside this per-file loop — the
|
|
382
399
|
// `break` below only exits the pattern loop, not the file loop, so
|
|
@@ -389,7 +406,7 @@ export function detectSecurityPack(context) {
|
|
|
389
406
|
`generated reports before source files, which can cause circular or outdated guidance ingestion.`,
|
|
390
407
|
filePaths: [file.path],
|
|
391
408
|
locations: [],
|
|
392
|
-
evidence: [
|
|
409
|
+
evidence: [matchEvidence(file.content, pat.re, pat.label)],
|
|
393
410
|
recommendation: 'Recommend linking to latest reports or directing the agent to read source documents first instead of generated reports.',
|
|
394
411
|
fixRecipe: 'Update the instruction to prioritize reading source files and configuration rather than relying on generated reports.',
|
|
395
412
|
confidence: 0.7,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security-pack.js","sourceRoot":"","sources":["../src/security-pack.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"security-pack.js","sourceRoot":"","sources":["../src/security-pack.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills Detector (issue #23)
|
|
3
|
+
*
|
|
4
|
+
* Audits Agent Skills — `SKILL.md` files under `.claude/` (project skills and
|
|
5
|
+
* plugin-bundled skills) — against filesystem reality:
|
|
6
|
+
*
|
|
7
|
+
* - Frontmatter validity: present, closed, required `name`/`description`, and
|
|
8
|
+
* `name` matching the skill's directory (how Claude resolves a skill).
|
|
9
|
+
* - Trigger descriptions: an empty `description` never triggers the skill; two
|
|
10
|
+
* skills sharing a description compete for the same triggers.
|
|
11
|
+
* - Dead file references: paths in the skill body (scripts, references) that
|
|
12
|
+
* point at bundled files which do not exist.
|
|
13
|
+
*
|
|
14
|
+
* All checks are deterministic and offline. Findings are cautiously worded.
|
|
15
|
+
*/
|
|
16
|
+
import type { RepoContext } from './repo-context.js';
|
|
17
|
+
import type { PromptCiIssue } from './types.js';
|
|
18
|
+
export declare function detectSkills(context: RepoContext): PromptCiIssue[];
|
|
19
|
+
//# sourceMappingURL=skills-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skills-detector.d.ts","sourceRoot":"","sources":["../src/skills-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAsFhD,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,EAAE,CA2FlE"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skills Detector (issue #23)
|
|
3
|
+
*
|
|
4
|
+
* Audits Agent Skills — `SKILL.md` files under `.claude/` (project skills and
|
|
5
|
+
* plugin-bundled skills) — against filesystem reality:
|
|
6
|
+
*
|
|
7
|
+
* - Frontmatter validity: present, closed, required `name`/`description`, and
|
|
8
|
+
* `name` matching the skill's directory (how Claude resolves a skill).
|
|
9
|
+
* - Trigger descriptions: an empty `description` never triggers the skill; two
|
|
10
|
+
* skills sharing a description compete for the same triggers.
|
|
11
|
+
* - Dead file references: paths in the skill body (scripts, references) that
|
|
12
|
+
* point at bundled files which do not exist.
|
|
13
|
+
*
|
|
14
|
+
* All checks are deterministic and offline. Findings are cautiously worded.
|
|
15
|
+
*/
|
|
16
|
+
import * as path from 'node:path';
|
|
17
|
+
import { parseFrontmatter, readTextWithinRoot, isFileWithinRoot, shortHash, toPosix, withScannerPaths, aiConfigIssue as base, frontmatterStructureIssues, } from './ai-config.js';
|
|
18
|
+
/** A description shorter than this (after trimming) is treated as effectively empty. */
|
|
19
|
+
const MIN_DESCRIPTION_CHARS = 12;
|
|
20
|
+
const SURFACE = {
|
|
21
|
+
idPrefix: 'skill',
|
|
22
|
+
noun: 'Skill',
|
|
23
|
+
why: 'A skill needs `name` and `description` frontmatter or it will not load.',
|
|
24
|
+
recommendation: 'Add a frontmatter block with `name` and `description` at the top of the SKILL.md file.',
|
|
25
|
+
};
|
|
26
|
+
function id(kind, filePath, extra = '') {
|
|
27
|
+
return `ai-config-skill-${kind}-${shortHash(`${filePath}|${extra}`)}`;
|
|
28
|
+
}
|
|
29
|
+
function normalizeDescription(text) {
|
|
30
|
+
return text
|
|
31
|
+
.toLowerCase()
|
|
32
|
+
.replace(/[`*_~]/g, '')
|
|
33
|
+
.replace(/[^a-z0-9]+/g, ' ')
|
|
34
|
+
.trim();
|
|
35
|
+
}
|
|
36
|
+
// ── Dead-reference extraction (scoped to a skill body) ────────────────────────
|
|
37
|
+
/** Looks like a relative file reference to a bundled resource, not prose or a URL. */
|
|
38
|
+
function isBundledFileRef(ref) {
|
|
39
|
+
if (!ref)
|
|
40
|
+
return false;
|
|
41
|
+
const r = ref.trim();
|
|
42
|
+
if (/^(https?:|mailto:|#|\/\/)/i.test(r))
|
|
43
|
+
return false; // URL / anchor
|
|
44
|
+
if (r.startsWith('/') || /^[a-zA-Z]:[\\/]/.test(r))
|
|
45
|
+
return false; // absolute
|
|
46
|
+
if (/[<>{}*?|"\s]/.test(r))
|
|
47
|
+
return false; // placeholder / glob / whitespace
|
|
48
|
+
if (r.includes('..'))
|
|
49
|
+
return false; // don't chase parent escapes
|
|
50
|
+
const withoutAnchor = r.split('#')[0];
|
|
51
|
+
const hasSlash = withoutAnchor.includes('/');
|
|
52
|
+
const hasExt = /\.[a-z0-9]{1,6}$/i.test(withoutAnchor);
|
|
53
|
+
// Require a directory segment AND an extension — high-confidence file paths only.
|
|
54
|
+
return hasSlash && hasExt;
|
|
55
|
+
}
|
|
56
|
+
function extractFileRefs(content) {
|
|
57
|
+
const refs = [];
|
|
58
|
+
// Keyed on the anchor-STRIPPED path — `docs/x.md#one` and `docs/x.md#two`
|
|
59
|
+
// name the same file and must yield one finding, not two with equal ids.
|
|
60
|
+
const seen = new Set();
|
|
61
|
+
const record = (target, line) => {
|
|
62
|
+
if (!isBundledFileRef(target))
|
|
63
|
+
return;
|
|
64
|
+
const ref = target.split('#')[0];
|
|
65
|
+
if (seen.has(ref))
|
|
66
|
+
return;
|
|
67
|
+
seen.add(ref);
|
|
68
|
+
refs.push({ ref, line });
|
|
69
|
+
};
|
|
70
|
+
const lines = content.split(/\r?\n/);
|
|
71
|
+
for (let i = 0; i < lines.length; i++) {
|
|
72
|
+
const line = lines[i];
|
|
73
|
+
// Markdown links: [text](path)
|
|
74
|
+
for (const m of line.matchAll(/\[[^\]]*\]\(([^)]+)\)/g)) {
|
|
75
|
+
record(m[1].split(/\s+/)[0].replace(/^<|>$/g, ''), i + 1);
|
|
76
|
+
}
|
|
77
|
+
// Inline code paths: `scripts/foo.py`
|
|
78
|
+
for (const m of line.matchAll(/`([^`]+)`/g)) {
|
|
79
|
+
record(m[1].trim(), i + 1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return refs;
|
|
83
|
+
}
|
|
84
|
+
// ── Detector ──────────────────────────────────────────────────────────────────
|
|
85
|
+
export function detectSkills(context) {
|
|
86
|
+
const issues = [];
|
|
87
|
+
const parsed = [];
|
|
88
|
+
for (const filePath of context.aiConfig.skills) {
|
|
89
|
+
const content = readTextWithinRoot(context.repoRoot, filePath);
|
|
90
|
+
if (content === undefined)
|
|
91
|
+
continue;
|
|
92
|
+
const dirName = toPosix(path.dirname(filePath)).split('/').pop() ?? '';
|
|
93
|
+
const fm = parseFrontmatter(content);
|
|
94
|
+
issues.push(...frontmatterStructureIssues(filePath, content, fm, SURFACE));
|
|
95
|
+
if (!fm.present)
|
|
96
|
+
continue;
|
|
97
|
+
const name = typeof fm.data.name === 'string' ? fm.data.name.trim() : undefined;
|
|
98
|
+
const description = typeof fm.data.description === 'string' ? fm.data.description.trim() : undefined;
|
|
99
|
+
if (!name) {
|
|
100
|
+
issues.push(base({
|
|
101
|
+
id: id('missing-name', filePath),
|
|
102
|
+
title: 'Skill frontmatter is missing `name`',
|
|
103
|
+
summary: `${filePath} has no \`name\` field. Claude uses \`name\` to identify and invoke the skill.`,
|
|
104
|
+
filePaths: [filePath],
|
|
105
|
+
locations: [{ filePath, startLine: 1, endLine: fm.fenceEndLine > 0 ? fm.fenceEndLine : 1 }],
|
|
106
|
+
evidence: [`Keys present: ${Object.keys(fm.data).join(', ') || '(none)'}`],
|
|
107
|
+
recommendation: 'Add a `name` field to the frontmatter matching the skill directory name.',
|
|
108
|
+
confidence: 0.85,
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
else if (name !== dirName && dirName) {
|
|
112
|
+
issues.push(base({
|
|
113
|
+
id: id('name-dir-mismatch', filePath),
|
|
114
|
+
title: 'Skill `name` does not match its directory',
|
|
115
|
+
summary: `${filePath}: frontmatter \`name: ${name}\` does not match the skill directory \`${dirName}/\`. Claude resolves skills by directory name.`,
|
|
116
|
+
filePaths: [filePath],
|
|
117
|
+
locations: [{ filePath, startLine: fm.keyLines.name ?? 1, endLine: fm.keyLines.name ?? 1 }],
|
|
118
|
+
evidence: [`name: ${name}`, `directory: ${dirName}`],
|
|
119
|
+
recommendation: 'Rename the directory or the `name` field so they match.',
|
|
120
|
+
confidence: 0.6,
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
if (!description) {
|
|
124
|
+
issues.push(base({
|
|
125
|
+
id: id('missing-description', filePath),
|
|
126
|
+
title: 'Skill frontmatter is missing `description`',
|
|
127
|
+
summary: `${filePath} has no \`description\`. The description is the trigger text Claude matches against — without it the skill rarely activates.`,
|
|
128
|
+
filePaths: [filePath],
|
|
129
|
+
locations: [{ filePath, startLine: 1, endLine: fm.fenceEndLine > 0 ? fm.fenceEndLine : 1 }],
|
|
130
|
+
evidence: [`Keys present: ${Object.keys(fm.data).join(', ') || '(none)'}`],
|
|
131
|
+
recommendation: 'Add a `description` that says what the skill does and when to use it.',
|
|
132
|
+
confidence: 0.85,
|
|
133
|
+
}));
|
|
134
|
+
}
|
|
135
|
+
else if (description.length < MIN_DESCRIPTION_CHARS) {
|
|
136
|
+
issues.push(base({
|
|
137
|
+
id: id('empty-description', filePath),
|
|
138
|
+
title: 'Skill `description` is too short to trigger reliably',
|
|
139
|
+
summary: `${filePath}: \`description\` is only ${description.length} characters. Claude matches the description against the user's request to decide when to invoke the skill.`,
|
|
140
|
+
filePaths: [filePath],
|
|
141
|
+
locations: [{ filePath, startLine: fm.keyLines.description ?? 1, endLine: fm.keyLines.description ?? 1 }],
|
|
142
|
+
evidence: [`description: ${description}`],
|
|
143
|
+
recommendation: 'Expand the description to describe the task and its trigger conditions.',
|
|
144
|
+
confidence: 0.7,
|
|
145
|
+
}));
|
|
146
|
+
}
|
|
147
|
+
// Dead file references in the body.
|
|
148
|
+
const skillDir = toPosix(path.dirname(filePath));
|
|
149
|
+
for (const { ref, line } of extractFileRefs(content)) {
|
|
150
|
+
const resolved = skillDir === '.' ? ref : `${skillDir}/${ref}`;
|
|
151
|
+
if (!isFileWithinRoot(context.repoRoot, resolved)) {
|
|
152
|
+
issues.push(base({
|
|
153
|
+
id: id('dead-ref', filePath, ref),
|
|
154
|
+
title: 'Skill references a bundled file that does not exist',
|
|
155
|
+
summary: `${filePath} references \`${ref}\`, but no such file exists relative to the skill directory.`,
|
|
156
|
+
filePaths: [filePath],
|
|
157
|
+
locations: [{ filePath, startLine: line, endLine: line }],
|
|
158
|
+
evidence: [`Reference: ${ref}`, `Resolved to: ${resolved}`],
|
|
159
|
+
recommendation: 'Add the referenced file, fix the path, or remove the reference.',
|
|
160
|
+
confidence: 0.75,
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
if (description)
|
|
165
|
+
parsed.push({ filePath, description });
|
|
166
|
+
}
|
|
167
|
+
// Overlapping / duplicate trigger descriptions across skills.
|
|
168
|
+
issues.push(...detectOverlappingDescriptions(parsed));
|
|
169
|
+
// Scanner-form paths so inline suppressions can match (see withScannerPaths).
|
|
170
|
+
return withScannerPaths(context.repoRoot, issues);
|
|
171
|
+
}
|
|
172
|
+
function detectOverlappingDescriptions(skills) {
|
|
173
|
+
const issues = [];
|
|
174
|
+
const byNorm = new Map();
|
|
175
|
+
for (const skill of skills) {
|
|
176
|
+
if (skill.description.length < MIN_DESCRIPTION_CHARS)
|
|
177
|
+
continue;
|
|
178
|
+
const norm = normalizeDescription(skill.description);
|
|
179
|
+
if (!norm)
|
|
180
|
+
continue;
|
|
181
|
+
const group = byNorm.get(norm) ?? [];
|
|
182
|
+
group.push(skill);
|
|
183
|
+
byNorm.set(norm, group);
|
|
184
|
+
}
|
|
185
|
+
for (const group of byNorm.values()) {
|
|
186
|
+
if (group.length < 2)
|
|
187
|
+
continue;
|
|
188
|
+
const sorted = [...group].sort((a, b) => a.filePath.localeCompare(b.filePath));
|
|
189
|
+
const paths = sorted.map((s) => s.filePath);
|
|
190
|
+
issues.push(base({
|
|
191
|
+
id: id('overlap', paths.join('|')),
|
|
192
|
+
title: 'Multiple skills share the same trigger description',
|
|
193
|
+
summary: `${paths.length} skills have effectively identical \`description\` text, so Claude cannot tell which to invoke for a given request.`,
|
|
194
|
+
filePaths: paths,
|
|
195
|
+
locations: sorted.map((s) => ({ filePath: s.filePath, startLine: 1, endLine: 1 })),
|
|
196
|
+
evidence: [`Shared description: ${sorted[0].description}`, `Skills: ${paths.join(', ')}`],
|
|
197
|
+
recommendation: 'Give each skill a distinct description that states its unique trigger conditions.',
|
|
198
|
+
confidence: 0.75,
|
|
199
|
+
}));
|
|
200
|
+
}
|
|
201
|
+
return issues;
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=skills-detector.js.map
|