@promptci/core 0.1.0 → 0.2.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 (152) hide show
  1. package/dist/action-pinning.d.ts +37 -0
  2. package/dist/action-pinning.d.ts.map +1 -0
  3. package/dist/action-pinning.js +277 -0
  4. package/dist/action-pinning.js.map +1 -0
  5. package/dist/agent-practices.d.ts +1 -1
  6. package/dist/agent-practices.d.ts.map +1 -1
  7. package/dist/agent-practices.js +107 -43
  8. package/dist/agent-practices.js.map +1 -1
  9. package/dist/ai-config.d.ts +42 -3
  10. package/dist/ai-config.d.ts.map +1 -1
  11. package/dist/ai-config.js +210 -12
  12. package/dist/ai-config.js.map +1 -1
  13. package/dist/alias-files.d.ts +33 -0
  14. package/dist/alias-files.d.ts.map +1 -0
  15. package/dist/alias-files.js +60 -0
  16. package/dist/alias-files.js.map +1 -0
  17. package/dist/buried-critical.d.ts.map +1 -1
  18. package/dist/buried-critical.js +4 -9
  19. package/dist/buried-critical.js.map +1 -1
  20. package/dist/canonical-owner.d.ts.map +1 -1
  21. package/dist/canonical-owner.js +45 -25
  22. package/dist/canonical-owner.js.map +1 -1
  23. package/dist/ci-alignment.d.ts.map +1 -1
  24. package/dist/ci-alignment.js +3 -2
  25. package/dist/ci-alignment.js.map +1 -1
  26. package/dist/command-validity.d.ts +16 -0
  27. package/dist/command-validity.d.ts.map +1 -1
  28. package/dist/command-validity.js +337 -63
  29. package/dist/command-validity.js.map +1 -1
  30. package/dist/conflicts.d.ts.map +1 -1
  31. package/dist/conflicts.js +3 -2
  32. package/dist/conflicts.js.map +1 -1
  33. package/dist/context-bloat.d.ts +1 -1
  34. package/dist/context-bloat.d.ts.map +1 -1
  35. package/dist/context-bloat.js +18 -7
  36. package/dist/context-bloat.js.map +1 -1
  37. package/dist/context-optimizer.d.ts.map +1 -1
  38. package/dist/context-optimizer.js +5 -2
  39. package/dist/context-optimizer.js.map +1 -1
  40. package/dist/custom-rules.d.ts.map +1 -1
  41. package/dist/custom-rules.js +6 -1
  42. package/dist/custom-rules.js.map +1 -1
  43. package/dist/dead-references.d.ts +16 -2
  44. package/dist/dead-references.d.ts.map +1 -1
  45. package/dist/dead-references.js +635 -77
  46. package/dist/dead-references.js.map +1 -1
  47. package/dist/dependency-staleness.d.ts +35 -0
  48. package/dist/dependency-staleness.d.ts.map +1 -0
  49. package/dist/dependency-staleness.js +1001 -0
  50. package/dist/dependency-staleness.js.map +1 -0
  51. package/dist/detectors.d.ts.map +1 -1
  52. package/dist/detectors.js +31 -6
  53. package/dist/detectors.js.map +1 -1
  54. package/dist/duplicates.d.ts.map +1 -1
  55. package/dist/duplicates.js +5 -4
  56. package/dist/duplicates.js.map +1 -1
  57. package/dist/evidence.d.ts +11 -0
  58. package/dist/evidence.d.ts.map +1 -1
  59. package/dist/evidence.js +40 -0
  60. package/dist/evidence.js.map +1 -1
  61. package/dist/finding-id.d.ts +21 -0
  62. package/dist/finding-id.d.ts.map +1 -0
  63. package/dist/finding-id.js +31 -0
  64. package/dist/finding-id.js.map +1 -0
  65. package/dist/frameworks/dotnet.js +2 -2
  66. package/dist/frameworks/dotnet.js.map +1 -1
  67. package/dist/frameworks/rust.d.ts.map +1 -1
  68. package/dist/frameworks/rust.js +2 -1
  69. package/dist/frameworks/rust.js.map +1 -1
  70. package/dist/git-symlinks.d.ts +30 -0
  71. package/dist/git-symlinks.d.ts.map +1 -0
  72. package/dist/git-symlinks.js +161 -0
  73. package/dist/git-symlinks.js.map +1 -0
  74. package/dist/gitignore.d.ts +22 -0
  75. package/dist/gitignore.d.ts.map +1 -0
  76. package/dist/gitignore.js +157 -0
  77. package/dist/gitignore.js.map +1 -0
  78. package/dist/health-score.d.ts.map +1 -1
  79. package/dist/health-score.js +34 -5
  80. package/dist/health-score.js.map +1 -1
  81. package/dist/index.d.ts +9 -3
  82. package/dist/index.d.ts.map +1 -1
  83. package/dist/index.js +5 -2
  84. package/dist/index.js.map +1 -1
  85. package/dist/makefile.d.ts +37 -0
  86. package/dist/makefile.d.ts.map +1 -0
  87. package/dist/makefile.js +156 -0
  88. package/dist/makefile.js.map +1 -0
  89. package/dist/manifest-consistency.d.ts.map +1 -1
  90. package/dist/manifest-consistency.js +52 -8
  91. package/dist/manifest-consistency.js.map +1 -1
  92. package/dist/negative-instructions.d.ts.map +1 -1
  93. package/dist/negative-instructions.js +4 -9
  94. package/dist/negative-instructions.js.map +1 -1
  95. package/dist/path-containment.d.ts +29 -0
  96. package/dist/path-containment.d.ts.map +1 -1
  97. package/dist/path-containment.js +70 -0
  98. package/dist/path-containment.js.map +1 -1
  99. package/dist/prompt-cache.d.ts.map +1 -1
  100. package/dist/prompt-cache.js +8 -6
  101. package/dist/prompt-cache.js.map +1 -1
  102. package/dist/repo-context.d.ts +53 -0
  103. package/dist/repo-context.d.ts.map +1 -1
  104. package/dist/repo-context.js +134 -11
  105. package/dist/repo-context.js.map +1 -1
  106. package/dist/report.d.ts +7 -0
  107. package/dist/report.d.ts.map +1 -1
  108. package/dist/report.js +36 -7
  109. package/dist/report.js.map +1 -1
  110. package/dist/scan.d.ts.map +1 -1
  111. package/dist/scan.js +41 -2
  112. package/dist/scan.js.map +1 -1
  113. package/dist/scanner.d.ts +49 -1
  114. package/dist/scanner.d.ts.map +1 -1
  115. package/dist/scanner.js +323 -38
  116. package/dist/scanner.js.map +1 -1
  117. package/dist/security-pack.d.ts.map +1 -1
  118. package/dist/security-pack.js +6 -4
  119. package/dist/security-pack.js.map +1 -1
  120. package/dist/skill-supply-chain.d.ts +132 -0
  121. package/dist/skill-supply-chain.d.ts.map +1 -0
  122. package/dist/skill-supply-chain.js +2954 -0
  123. package/dist/skill-supply-chain.js.map +1 -0
  124. package/dist/skills-detector.d.ts +7 -3
  125. package/dist/skills-detector.d.ts.map +1 -1
  126. package/dist/skills-detector.js +98 -22
  127. package/dist/skills-detector.js.map +1 -1
  128. package/dist/stale-instructions.d.ts.map +1 -1
  129. package/dist/stale-instructions.js +2 -1
  130. package/dist/stale-instructions.js.map +1 -1
  131. package/dist/suppression.d.ts +2 -0
  132. package/dist/suppression.d.ts.map +1 -1
  133. package/dist/suppression.js +5 -2
  134. package/dist/suppression.js.map +1 -1
  135. package/dist/types.d.ts +35 -2
  136. package/dist/types.d.ts.map +1 -1
  137. package/dist/types.js +22 -0
  138. package/dist/types.js.map +1 -1
  139. package/dist/vague-guidance.d.ts.map +1 -1
  140. package/dist/vague-guidance.js +2 -1
  141. package/dist/vague-guidance.js.map +1 -1
  142. package/dist/windsurf-detector.d.ts.map +1 -1
  143. package/dist/windsurf-detector.js +15 -6
  144. package/dist/windsurf-detector.js.map +1 -1
  145. package/dist/within-section-dedup.d.ts.map +1 -1
  146. package/dist/within-section-dedup.js +4 -9
  147. package/dist/within-section-dedup.js.map +1 -1
  148. package/dist/workspace-manifests.d.ts +80 -0
  149. package/dist/workspace-manifests.d.ts.map +1 -0
  150. package/dist/workspace-manifests.js +333 -0
  151. package/dist/workspace-manifests.js.map +1 -0
  152. package/package.json +1 -1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Skill supply-chain scan
3
+ *
4
+ * An Agent Skill is instructions (SKILL.md plus reference docs) and bundled
5
+ * scripts that an agent loads on demand and runs with the user's permissions.
6
+ * Installing a third-party skill is installing code. The structural skills
7
+ * detector (skills-detector.ts) checks that a skill *loads*; this detector
8
+ * reads the same skill — and every file bundled in its directory — as plain
9
+ * text and flags content characteristic of supply-chain abuse.
10
+ *
11
+ * Static only. Nothing here executes, imports, fetches or resolves anything:
12
+ * skill content is matched against fixed patterns, so the same files always
13
+ * produce the same findings (no network, no clock, no LLM).
14
+ *
15
+ * Rules (tag `skill-supply-chain` + the rule id below):
16
+ *
17
+ * remote-exec fetched content piped into a shell (`curl … |
18
+ * bash`, by path, via env/sudo/busybox/xargs — an
19
+ * `env A=…` assignment of any length — in a
20
+ * subshell, through any number of pipe stages),
21
+ * into `tee >(bash)`, into an interpreter that runs
22
+ * its own stdin (`node -e "eval(readFileSync(0))"`,
23
+ * `python -c 'exec(sys.stdin.read())'`, `ruby -e`,
24
+ * `perl -e`, `node /dev/stdin`), or into a `while
25
+ * read l; do eval "$l"; done` loop; process/here-
26
+ * string substitution, `iex (iwr …)`, or a
27
+ * downloaded file executed later in the same
28
+ * command without first being verified high
29
+ * encoded-exec decoded or transformed content executed (`base64
30
+ * -d | sh`, `xxd -r -p | sh`, `rev | sh`, a rot13
31
+ * `tr`, `base32 -d`, a run of `\x63\x75…` escapes,
32
+ * decode-to-file then run, `eval "$(… | base64
33
+ * -d)"`, `exec(b64decode(…))`, `powershell -enc`) high
34
+ * remote-eval eval of fetched code (also in SKILL.md code,
35
+ * including a fetch function imported under another
36
+ * name: `urlopen as u`, `import requests as r`), or
37
+ * a script that both evaluates dynamic code AND
38
+ * makes network calls high
39
+ * dynamic-eval eval/exec/new Function/iex, no network call warning
40
+ * credential-exfil credential-store read or environment dump AND
41
+ * network calls in the same file high
42
+ * exfil-instruction prose sending secrets to a destination high/warning
43
+ * instruction-override prompt-injection text high
44
+ * conceal-from-user prose hiding actions from the user high/warning
45
+ * permission-bypass flags/prose disabling permission prompts warning
46
+ * hidden-unicode tag characters, bidi controls (high); other
47
+ * invisible/format/control characters (warning)
48
+ * hidden-html-comment agent-directed text inside an HTML comment warning
49
+ * hidden-html-element text hidden by `display:none`/`hidden` warning
50
+ * encoded-blob a large base64 blob in instruction text warning
51
+ * unpinned-remote-dep a remote dependency with no pinned version warning
52
+ * missing-script the SKILL.md runs a script that exists nowhere
53
+ * warning, ai_config
54
+ * unscanned-files content this scan could not fully read, named:
55
+ * binaries/archives/executables, compiled-language
56
+ * sources, files over the cap or budget, oversized
57
+ * files (head and tail read), overlong continuation
58
+ * chains (warning); dependency directories and
59
+ * include-filtered files (info)
60
+ *
61
+ * Hostile input: every regex uses bounded quantifiers and runs over lines in
62
+ * overlapping 2000-character windows behind cheap prefilters, and every rule
63
+ * whose span can exceed the window overlap (pipes, command chains) is matched
64
+ * procedurally over the whole logical command, so results do not depend on
65
+ * window alignment. HTML comments and tags are found with indexOf walks. A
66
+ * rule keeps scanning past its evidence cap (a flood of low-severity matches
67
+ * cannot hide a later high-severity one). Documents are loaded, scanned and
68
+ * dropped one at a time under a per-scan byte, file and line budget, SKILL.md
69
+ * files and scripts/executables first; a priority file the budget cannot
70
+ * reach is reported at HIGH (fail closed). There is deliberately no
71
+ * wall-clock budget: output must not depend on the clock.
72
+ *
73
+ * Documentation vs directive (the false-positive controls). Outside fenced
74
+ * code — prose, inline code, table rows — a negation or discussion word only
75
+ * counts when it directly GOVERNS the match: an imperative negation with
76
+ * nothing or one executing verb between ("never run `curl … | bash`"), a
77
+ * discussion word right before it ("this skill detects `curl | bash`" — a
78
+ * `Label:` is not governance), or a predicate right after it ("… is
79
+ * dangerous"). Governance ends at but / and / then / instead / so and at
80
+ * clause punctuation; "never forget/hesitate/stop/skip/fail/neglect/mind" is
81
+ * not a negation. Even then, context NEVER drops a match, or lowers its
82
+ * severity, when the match names a concrete target — a URL, a host (dotted,
83
+ * IPv4/IPv6, host:port, defanged or quote-split), a host/path, a `$VARIABLE`
84
+ * or `$(…)`, or any address-like argument or config/list flag given to
85
+ * curl/wget/iwr, or a dot-less host (`wget intranet`) that is the fetcher's
86
+ * first non-flag argument while the same text pipes into a shell or runs the
87
+ * download (a bare word elsewhere is prose: "pipe curl into bash") — it only
88
+ * lowers confidence (0.4) and notes "looks like documentation". Target-less
89
+ * exec documentation ("never run `curl | bash`")
90
+ * is dropped; target-less override/concealment/bypass text is dropped only
91
+ * when the governed phrase is itself set off in a code span, quotes or a
92
+ * table cell (otherwise it is kept at low confidence), and quoted text after
93
+ * an adoption phrase ("your new rule is \"…\"") is never data. The trade-off: a
94
+ * security skill quoting a real installer URL is reported (high, low
95
+ * confidence); the escape hatch is the baseline or a config `exclude`. A
96
+ * documented example whose governing word the rules do not recognise ("Instead
97
+ * of `curl URL | bash`", a table of risky patterns, a "bad example" fence)
98
+ * stays at full confidence; the benign-documentation corpus in
99
+ * skill-supply-chain.test.ts pins both behaviours.
100
+ * Other controls: one named API key sent to an API is not exfiltration;
101
+ * dynamic require/import only counts next to network access; emoji ZWJ, a
102
+ * single variation selector after a non-ASCII character, flag tag sequences,
103
+ * RTL marks in RTL text, a leading BOM and `data:` URIs are ignored; `npx
104
+ * tool` without a version is not flagged; a table row whose first cell is just
105
+ * a flag, and whose other cells direct nothing, documents that flag.
106
+ *
107
+ * Findings list the file they were found in plus the owning SKILL.md in
108
+ * `filePaths`, with `locations` at the exact line. Inline `promptci-ignore`
109
+ * annotations inside a skill directory never suppress these findings
110
+ * (scan.ts). Evidence quotes the matched text with every invisible or control
111
+ * character shown as `<U+XXXX>` and tag-character payloads decoded. No finding
112
+ * is auto-fixable: repairing a skill needs a human-reviewed diff.
113
+ */
114
+ import type { RepoContext } from './repo-context.js';
115
+ import type { PromptCiIssue } from './types.js';
116
+ /** First entry of every finding's `tags`. */
117
+ export declare const SKILL_SUPPLY_CHAIN_TAG = "skill-supply-chain";
118
+ /** Total bytes of skill content read per scan; the rest is reported, not read. */
119
+ export declare const MAX_SCAN_BYTES: number;
120
+ /** Total skill files read per scan. */
121
+ export declare const MAX_SCAN_FILES = 2000;
122
+ export type SkillSupplyChainRule = 'remote-exec' | 'encoded-exec' | 'remote-eval' | 'dynamic-eval' | 'credential-exfil' | 'exfil-instruction' | 'instruction-override' | 'conceal-from-user' | 'permission-bypass' | 'hidden-unicode' | 'hidden-html-comment' | 'hidden-html-element' | 'encoded-blob' | 'unpinned-remote-dep' | 'missing-script' | 'unscanned-files';
123
+ /** Total lines examined per scan: bounds per-line work however the bytes are shaped (e.g. megabytes of newlines). */
124
+ export declare const MAX_SCAN_LINES = 3000000;
125
+ /** Per-scan budget overrides (tests exercise budget exhaustion without generating gigabytes). */
126
+ export type SkillScanLimits = Partial<{
127
+ bytes: number;
128
+ files: number;
129
+ lines: number;
130
+ }>;
131
+ export declare function detectSkillSupplyChain(context: RepoContext, limits?: SkillScanLimits): PromptCiIssue[];
132
+ //# sourceMappingURL=skill-supply-chain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-supply-chain.d.ts","sourceRoot":"","sources":["../src/skill-supply-chain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgHG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAgC,aAAa,EAAE,MAAM,YAAY,CAAC;AAgB9E,6CAA6C;AAC7C,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D,kFAAkF;AAClF,eAAO,MAAM,cAAc,QAAmB,CAAC;AAC/C,uCAAuC;AACvC,eAAO,MAAM,cAAc,OAAO,CAAC;AAiCnC,MAAM,MAAM,oBAAoB,GAC5B,aAAa,GACb,cAAc,GACd,aAAa,GACb,cAAc,GACd,kBAAkB,GAClB,mBAAmB,GACnB,sBAAsB,GACtB,mBAAmB,GACnB,mBAAmB,GACnB,gBAAgB,GAChB,qBAAqB,GACrB,qBAAqB,GACrB,cAAc,GACd,qBAAqB,GACrB,gBAAgB,GAChB,iBAAiB,CAAC;AAq9EtB,qHAAqH;AACrH,eAAO,MAAM,cAAc,UAAY,CAAC;AA+OxC,iGAAiG;AACjG,MAAM,MAAM,eAAe,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEvF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,WAAW,EAAE,MAAM,GAAE,eAAoB,GAAG,aAAa,EAAE,CAqG1G"}