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.
- package/README.md +120 -10
- package/dist/cli.mjs +1370 -200
- 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/
|
|
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` | `.
|
|
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` | `.
|
|
163
|
-
| GitHub Copilot | `github-copilot` | `.
|
|
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` | `.
|
|
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,
|
|
214
|
-
|
|
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
|