@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.
- package/dist/action-pinning.d.ts +37 -0
- package/dist/action-pinning.d.ts.map +1 -0
- package/dist/action-pinning.js +277 -0
- package/dist/action-pinning.js.map +1 -0
- package/dist/agent-practices.d.ts +1 -1
- package/dist/agent-practices.d.ts.map +1 -1
- package/dist/agent-practices.js +107 -43
- package/dist/agent-practices.js.map +1 -1
- package/dist/ai-config.d.ts +42 -3
- package/dist/ai-config.d.ts.map +1 -1
- package/dist/ai-config.js +210 -12
- package/dist/ai-config.js.map +1 -1
- package/dist/alias-files.d.ts +33 -0
- package/dist/alias-files.d.ts.map +1 -0
- package/dist/alias-files.js +60 -0
- package/dist/alias-files.js.map +1 -0
- package/dist/buried-critical.d.ts.map +1 -1
- package/dist/buried-critical.js +4 -9
- package/dist/buried-critical.js.map +1 -1
- package/dist/canonical-owner.d.ts.map +1 -1
- package/dist/canonical-owner.js +45 -25
- package/dist/canonical-owner.js.map +1 -1
- package/dist/ci-alignment.d.ts.map +1 -1
- package/dist/ci-alignment.js +3 -2
- package/dist/ci-alignment.js.map +1 -1
- package/dist/command-validity.d.ts +16 -0
- package/dist/command-validity.d.ts.map +1 -1
- package/dist/command-validity.js +337 -63
- package/dist/command-validity.js.map +1 -1
- package/dist/conflicts.d.ts.map +1 -1
- package/dist/conflicts.js +3 -2
- package/dist/conflicts.js.map +1 -1
- package/dist/context-bloat.d.ts +1 -1
- package/dist/context-bloat.d.ts.map +1 -1
- package/dist/context-bloat.js +18 -7
- package/dist/context-bloat.js.map +1 -1
- package/dist/context-optimizer.d.ts.map +1 -1
- package/dist/context-optimizer.js +5 -2
- package/dist/context-optimizer.js.map +1 -1
- package/dist/custom-rules.d.ts.map +1 -1
- package/dist/custom-rules.js +6 -1
- package/dist/custom-rules.js.map +1 -1
- package/dist/dead-references.d.ts +16 -2
- package/dist/dead-references.d.ts.map +1 -1
- package/dist/dead-references.js +635 -77
- package/dist/dead-references.js.map +1 -1
- package/dist/dependency-staleness.d.ts +35 -0
- package/dist/dependency-staleness.d.ts.map +1 -0
- package/dist/dependency-staleness.js +1001 -0
- package/dist/dependency-staleness.js.map +1 -0
- package/dist/detectors.d.ts.map +1 -1
- package/dist/detectors.js +31 -6
- package/dist/detectors.js.map +1 -1
- package/dist/duplicates.d.ts.map +1 -1
- package/dist/duplicates.js +5 -4
- package/dist/duplicates.js.map +1 -1
- package/dist/evidence.d.ts +11 -0
- package/dist/evidence.d.ts.map +1 -1
- package/dist/evidence.js +40 -0
- package/dist/evidence.js.map +1 -1
- package/dist/finding-id.d.ts +21 -0
- package/dist/finding-id.d.ts.map +1 -0
- package/dist/finding-id.js +31 -0
- package/dist/finding-id.js.map +1 -0
- package/dist/frameworks/dotnet.js +2 -2
- package/dist/frameworks/dotnet.js.map +1 -1
- package/dist/frameworks/rust.d.ts.map +1 -1
- package/dist/frameworks/rust.js +2 -1
- package/dist/frameworks/rust.js.map +1 -1
- package/dist/git-symlinks.d.ts +30 -0
- package/dist/git-symlinks.d.ts.map +1 -0
- package/dist/git-symlinks.js +161 -0
- package/dist/git-symlinks.js.map +1 -0
- package/dist/gitignore.d.ts +22 -0
- package/dist/gitignore.d.ts.map +1 -0
- package/dist/gitignore.js +157 -0
- package/dist/gitignore.js.map +1 -0
- package/dist/health-score.d.ts.map +1 -1
- package/dist/health-score.js +34 -5
- package/dist/health-score.js.map +1 -1
- package/dist/index.d.ts +9 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/makefile.d.ts +37 -0
- package/dist/makefile.d.ts.map +1 -0
- package/dist/makefile.js +156 -0
- package/dist/makefile.js.map +1 -0
- package/dist/manifest-consistency.d.ts.map +1 -1
- package/dist/manifest-consistency.js +52 -8
- package/dist/manifest-consistency.js.map +1 -1
- package/dist/negative-instructions.d.ts.map +1 -1
- package/dist/negative-instructions.js +4 -9
- package/dist/negative-instructions.js.map +1 -1
- package/dist/path-containment.d.ts +29 -0
- package/dist/path-containment.d.ts.map +1 -1
- package/dist/path-containment.js +70 -0
- package/dist/path-containment.js.map +1 -1
- package/dist/prompt-cache.d.ts.map +1 -1
- package/dist/prompt-cache.js +8 -6
- package/dist/prompt-cache.js.map +1 -1
- package/dist/repo-context.d.ts +53 -0
- package/dist/repo-context.d.ts.map +1 -1
- package/dist/repo-context.js +134 -11
- package/dist/repo-context.js.map +1 -1
- package/dist/report.d.ts +7 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +36 -7
- package/dist/report.js.map +1 -1
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +41 -2
- package/dist/scan.js.map +1 -1
- package/dist/scanner.d.ts +49 -1
- package/dist/scanner.d.ts.map +1 -1
- package/dist/scanner.js +323 -38
- package/dist/scanner.js.map +1 -1
- package/dist/security-pack.d.ts.map +1 -1
- package/dist/security-pack.js +6 -4
- package/dist/security-pack.js.map +1 -1
- package/dist/skill-supply-chain.d.ts +132 -0
- package/dist/skill-supply-chain.d.ts.map +1 -0
- package/dist/skill-supply-chain.js +2954 -0
- package/dist/skill-supply-chain.js.map +1 -0
- package/dist/skills-detector.d.ts +7 -3
- package/dist/skills-detector.d.ts.map +1 -1
- package/dist/skills-detector.js +98 -22
- package/dist/skills-detector.js.map +1 -1
- package/dist/stale-instructions.d.ts.map +1 -1
- package/dist/stale-instructions.js +2 -1
- package/dist/stale-instructions.js.map +1 -1
- package/dist/suppression.d.ts +2 -0
- package/dist/suppression.d.ts.map +1 -1
- package/dist/suppression.js +5 -2
- package/dist/suppression.js.map +1 -1
- package/dist/types.d.ts +35 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +22 -0
- package/dist/types.js.map +1 -1
- package/dist/vague-guidance.d.ts.map +1 -1
- package/dist/vague-guidance.js +2 -1
- package/dist/vague-guidance.js.map +1 -1
- package/dist/windsurf-detector.d.ts.map +1 -1
- package/dist/windsurf-detector.js +15 -6
- package/dist/windsurf-detector.js.map +1 -1
- package/dist/within-section-dedup.d.ts.map +1 -1
- package/dist/within-section-dedup.js +4 -9
- package/dist/within-section-dedup.js.map +1 -1
- package/dist/workspace-manifests.d.ts +80 -0
- package/dist/workspace-manifests.d.ts.map +1 -0
- package/dist/workspace-manifests.js +333 -0
- package/dist/workspace-manifests.js.map +1 -0
- 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"}
|