skillsio 1.0.1 → 1.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.
Files changed (3) hide show
  1. package/README.md +120 -10
  2. package/dist/cli.mjs +1370 -200
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -15,7 +15,7 @@ security gate so you can still move fast without running untrusted code.
15
15
  ## What It Does
16
16
 
17
17
  Every `skillsio add` command runs a local security scan **before** anything is installed. The scanner applies ~52 regex
18
- rules derived from the Snyk and ClawHavoc research, organized into 8 threat categories:
18
+ rules and a correlation engine derived from the Snyk and ClawHavoc research, organized into 8 threat categories:
19
19
 
20
20
  | Category | What it catches |
21
21
  | --- | --- |
@@ -81,17 +81,111 @@ VT_API_KEY=YOUR_API_KEY npx skillsio add owner/repo
81
81
 
82
82
  `--vt-key` flag takes precedence over `VT_API_KEY` env var.
83
83
 
84
+ ### External Rules
85
+
86
+ You can extend the built-in scanner with your own rules using the `--rules` flag. This is useful for enforcing
87
+ organization-specific policies — for example, blocking references to internal infrastructure or flagging deprecated
88
+ tools.
89
+
90
+ Rules are defined in JSON files with a simple format:
91
+
92
+ ```json
93
+ {
94
+ "rules": [
95
+ {
96
+ "id": "no-internal-api",
97
+ "severity": "critical",
98
+ "description": "References internal API — may leak infrastructure details",
99
+ "pattern": "https?://internal\\.company\\.com",
100
+ "flags": "i"
101
+ },
102
+ {
103
+ "id": "no-sudo",
104
+ "severity": "high",
105
+ "description": "Skill should not require sudo access",
106
+ "pattern": "\\bsudo\\s+"
107
+ }
108
+ ]
109
+ }
110
+ ```
111
+
112
+ Each rule requires `id`, `severity` (`critical`/`high`/`medium`/`low`/`info`), `description`, and `pattern` (a regex
113
+ string). The optional `flags` field defaults to `"i"` (case-insensitive).
114
+
115
+ ```bash
116
+ # Load rules from a single file
117
+ npx skillsio add owner/repo --rules ./my-rules.json
118
+
119
+ # Load all .json rule files from a directory
120
+ npx skillsio add owner/repo --rules ./rules/
121
+ ```
122
+
123
+ External rules are applied **in addition to** the built-in ~52 rules — they never replace them. Findings from external
124
+ rules follow the same severity-based prompt flow as built-in findings.
125
+
126
+ See [docs/EXTERNAL-RULES.md](docs/EXTERNAL-RULES.md) for the full format reference, more examples, and tips for writing
127
+ rules.
128
+
129
+ ### Deep Taint Analysis (`--deep-scan`)
130
+
131
+ Regex rules detect individual dangerous patterns, but sophisticated attacks hide data flows across variables and
132
+ functions. The `--deep-scan` flag enables a lightweight taint analysis engine that tracks how data moves from
133
+ **sources** (environment variables, credential files) through variable assignments to **sinks** (network calls, exec,
134
+ file writes).
135
+
136
+ ```bash
137
+ npx skillsio add owner/repo --deep-scan
138
+ ```
139
+
140
+ What it catches that regex cannot:
141
+
142
+ ```python
143
+ # Variable-mediated exfiltration — regex sees the pieces but can't link them
144
+ key = os.environ["SECRET"] # source: env-access
145
+ encoded = b64encode(key) # taint propagates through assignment
146
+ payload = json.dumps(encoded) # ...and another hop
147
+ requests.post(url, data=payload) # sink: network → deep-env-access-to-network (critical)
148
+ ```
149
+
150
+ ```python
151
+ # getattr trick — regex misses the source entirely
152
+ env = getattr(os, 'environ') # source: getattr-trick (evades os.environ regex)
153
+ data = str(env)
154
+ requests.post(url, data=data) # → deep-getattr-trick-to-network (high)
155
+ ```
156
+
157
+ ```python
158
+ # Cross-file attack — collector.py harvests, exfil.py sends
159
+ # collector.py # exfil.py
160
+ import os # from .collector import data
161
+ secrets = os.environ.copy() # requests.post(url, data=payload)
162
+ # → deep-cross-env-access-to-network (critical)
163
+ ```
164
+
165
+ The analysis covers Python (`.py`) and JavaScript/TypeScript (`.js`, `.ts`) files. It adds zero dependencies — the
166
+ tokenizer is regex-based, not AST-based, keeping the bundle small. See [docs/deep-scan.md](docs/deep-scan.md) for
167
+ architecture details.
168
+
169
+ Deep scan findings appear alongside regex findings in the same severity-based prompt. All cross-file flows are
170
+ automatically classified as critical.
171
+
84
172
  ## Quick Start
85
173
 
86
174
  ```bash
87
175
  # Install a skill (scanned automatically)
88
176
  npx skillsio add vercel-labs/agent-skills
89
177
 
178
+ # Enable deep taint analysis for Python/JS/TS files
179
+ npx skillsio add owner/repo --deep-scan
180
+
90
181
  # Skip the scan if you trust the source
91
182
  npx skillsio add vercel-labs/agent-skills --skip-scan
92
183
 
93
184
  # Scan with VirusTotal threat intelligence
94
185
  VT_API_KEY=xxx npx skillsio add owner/repo
186
+
187
+ # Scan with custom organization rules
188
+ npx skillsio add owner/repo --rules ./company-rules.json
95
189
  ```
96
190
 
97
191
  ## CLI Reference
@@ -116,6 +210,8 @@ npx skillsio add ./my-local-skills # Local path
116
210
  | `-y, --yes` | Skip confirmation prompts |
117
211
  | `--all` | Install all skills to all agents without prompts |
118
212
  | `--skip-scan` | Skip the security scan before installation |
213
+ | `--rules <path>` | Load additional scan rules from a JSON file or directory (see [External Rules](#external-rules)) |
214
+ | `--deep-scan` | Enable deep taint analysis on Python/JS/TS files |
119
215
  | `--vt-key <key>` | VirusTotal API key for additional threat intelligence |
120
216
  | `--full-depth` | Search all subdirectories even when a root SKILL.md exists |
121
217
 
@@ -146,21 +242,21 @@ Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [35 more](#su
146
242
  <!-- supported-agents:start -->
147
243
  | Agent | `--agent` | Project Path | Global Path |
148
244
  |-------|-----------|--------------|-------------|
149
- | Amp, Kimi Code CLI | `amp`, `kimi-cli` | `.agents/skills/` | `~/.config/agents/skills/` |
245
+ | Amp, Kimi Code CLI, Replit | `amp`, `kimi-cli`, `replit` | `.agents/skills/` | `~/.config/agents/skills/` |
150
246
  | Antigravity | `antigravity` | `.agent/skills/` | `~/.gemini/antigravity/skills/` |
151
- | Augment | `augment` | `.augment/rules/` | `~/.augment/rules/` |
247
+ | Augment | `augment` | `.augment/skills/` | `~/.augment/skills/` |
152
248
  | Claude Code | `claude-code` | `.claude/skills/` | `~/.claude/skills/` |
153
249
  | OpenClaw | `openclaw` | `skills/` | `~/.moltbot/skills/` |
154
250
  | Cline | `cline` | `.cline/skills/` | `~/.cline/skills/` |
155
251
  | CodeBuddy | `codebuddy` | `.codebuddy/skills/` | `~/.codebuddy/skills/` |
156
- | Codex | `codex` | `.codex/skills/` | `~/.codex/skills/` |
252
+ | Codex | `codex` | `.agents/skills/` | `~/.codex/skills/` |
157
253
  | Command Code | `command-code` | `.commandcode/skills/` | `~/.commandcode/skills/` |
158
254
  | Continue | `continue` | `.continue/skills/` | `~/.continue/skills/` |
159
255
  | Crush | `crush` | `.crush/skills/` | `~/.config/crush/skills/` |
160
256
  | Cursor | `cursor` | `.cursor/skills/` | `~/.cursor/skills/` |
161
257
  | Droid | `droid` | `.factory/skills/` | `~/.factory/skills/` |
162
- | Gemini CLI | `gemini-cli` | `.gemini/skills/` | `~/.gemini/skills/` |
163
- | GitHub Copilot | `github-copilot` | `.github/skills/` | `~/.copilot/skills/` |
258
+ | Gemini CLI | `gemini-cli` | `.agents/skills/` | `~/.gemini/skills/` |
259
+ | GitHub Copilot | `github-copilot` | `.agents/skills/` | `~/.copilot/skills/` |
164
260
  | Goose | `goose` | `.goose/skills/` | `~/.config/goose/skills/` |
165
261
  | Junie | `junie` | `.junie/skills/` | `~/.junie/skills/` |
166
262
  | iFlow CLI | `iflow-cli` | `.iflow/skills/` | `~/.iflow/skills/` |
@@ -170,12 +266,11 @@ Supports **OpenCode**, **Claude Code**, **Codex**, **Cursor**, and [35 more](#su
170
266
  | MCPJam | `mcpjam` | `.mcpjam/skills/` | `~/.mcpjam/skills/` |
171
267
  | Mistral Vibe | `mistral-vibe` | `.vibe/skills/` | `~/.vibe/skills/` |
172
268
  | Mux | `mux` | `.mux/skills/` | `~/.mux/skills/` |
173
- | OpenCode | `opencode` | `.opencode/skills/` | `~/.config/opencode/skills/` |
269
+ | OpenCode | `opencode` | `.agents/skills/` | `~/.config/opencode/skills/` |
174
270
  | OpenHands | `openhands` | `.openhands/skills/` | `~/.openhands/skills/` |
175
271
  | Pi | `pi` | `.pi/skills/` | `~/.pi/agent/skills/` |
176
272
  | Qoder | `qoder` | `.qoder/skills/` | `~/.qoder/skills/` |
177
273
  | Qwen Code | `qwen-code` | `.qwen/skills/` | `~/.qwen/skills/` |
178
- | Replit | `replit` | `.agents/skills/` | N/A (project-only) |
179
274
  | Roo Code | `roo` | `.roo/skills/` | `~/.roo/skills/` |
180
275
  | Trae | `trae` | `.trae/skills/` | `~/.trae/skills/` |
181
276
  | Trae CN | `trae-cn` | `.trae/skills/` | `~/.trae-cn/skills/` |
@@ -210,17 +305,32 @@ pnpm format # Format code with Prettier
210
305
 
211
306
  ### Scanner Architecture
212
307
 
213
- - `src/scanner.ts` — Rules engine. Defines ~52 regex rules across 8 threat categories, runs them against all skill
214
- files (.md, .txt, .yaml, .json, .sh, .py, .js, .ts, .ps1, .bat, .cmd).
308
+ - `src/scanner.ts` — Rules engine. Defines ~52 regex rules across 8 threat categories, a correlation engine for
309
+ multi-signal detection, and optional deep taint analysis integration. Supports loading external rules from JSON
310
+ files via `--rules`.
215
311
  - `src/scanner-ui.ts` — Presentation layer. Displays findings by severity, runs optional VT lookups, handles
216
312
  escalation logic and user confirmation prompts.
217
313
  - `src/vt.ts` — VirusTotal API client. SHA-256 hashing, `GET /api/v3/files/{hash}` lookup, verdict mapping, graceful
218
314
  error handling.
315
+ - `src/deep-scan/` — Deep taint analysis engine (enabled via `--deep-scan`). Regex-based tokenizers extract sources,
316
+ sinks, and assignments from Python/JS/TS files; a forward taint tracker propagates data flow; a cross-file analyzer
317
+ detects multi-file attack patterns via import graph analysis. See [docs/deep-scan.md](docs/deep-scan.md).
219
318
  - `src/add.ts` — Integration point. The scanner is wired into all 4 install paths (GitHub/git repos, remote providers,
220
319
  well-known endpoints, legacy Mintlify).
221
320
 
222
321
  ## Changelog
223
322
 
323
+ ### 1.1.0
324
+
325
+ - Added `--rules <path>` flag to load external scan rules from JSON files or directories
326
+ - External rules are applied alongside built-in rules, supporting organization-specific policies
327
+ - See [docs/EXTERNAL-RULES.md](docs/EXTERNAL-RULES.md) for format documentation and examples
328
+ - **Deep taint analysis** (`--deep-scan`): lightweight forward taint propagation for Python and JS/TS files
329
+ - Tracks data flow from sources (env vars, credential files, getattr tricks) through variable chains to sinks (network
330
+ calls, exec, file writes)
331
+ - Cross-file analysis detects multi-file exfiltration patterns via import graph resolution
332
+ - Zero new dependencies — regex-based tokenizers keep the bundle small
333
+
224
334
  ### 1.0.1
225
335
 
226
336
  - Critical security prompts now default to **No** — users must explicitly confirm to install skills flagged as malicious