milens 0.6.5 → 0.6.7
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/.agents/skills/adapters/SKILL.md +14 -14
- package/.agents/skills/analyzer/SKILL.md +26 -24
- package/.agents/skills/apps/SKILL.md +10 -8
- package/.agents/skills/docs/SKILL.md +14 -8
- package/.agents/skills/milens/SKILL.md +164 -43
- package/.agents/skills/milens-security-review/SKILL.md +224 -224
- package/.agents/skills/orchestrator/SKILL.md +3 -1
- package/.agents/skills/parser/SKILL.md +16 -15
- package/.agents/skills/root/SKILL.md +20 -20
- package/.agents/skills/security/SKILL.md +1 -0
- package/.agents/skills/server/SKILL.md +13 -12
- package/.agents/skills/store/SKILL.md +12 -12
- package/.agents/skills/test/SKILL.md +57 -26
- package/README.md +170 -171
- package/adapters/claude-code/CLAUDE.md +36 -15
- package/adapters/codex/.codex/codex.md +38 -23
- package/adapters/copilot/.github/copilot-instructions.md +29 -22
- package/adapters/gemini/.gemini/context.md +33 -10
- package/adapters/opencode/AGENTS.md +36 -15
- package/dist/agents-md.d.ts.map +1 -1
- package/dist/agents-md.js +51 -2
- package/dist/agents-md.js.map +1 -1
- package/dist/analyzer/engine.d.ts +3 -0
- package/dist/analyzer/engine.d.ts.map +1 -1
- package/dist/analyzer/engine.js +342 -8
- package/dist/analyzer/engine.js.map +1 -1
- package/dist/analyzer/resolver.d.ts +2 -0
- package/dist/analyzer/resolver.d.ts.map +1 -1
- package/dist/analyzer/resolver.js +187 -9
- package/dist/analyzer/resolver.js.map +1 -1
- package/dist/analyzer/review.d.ts.map +1 -1
- package/dist/analyzer/review.js +254 -32
- package/dist/analyzer/review.js.map +1 -1
- package/dist/analyzer/scope-resolver.d.ts +42 -0
- package/dist/analyzer/scope-resolver.d.ts.map +1 -0
- package/dist/analyzer/scope-resolver.js +687 -0
- package/dist/analyzer/scope-resolver.js.map +1 -0
- package/dist/cli.js +294 -1
- package/dist/cli.js.map +1 -1
- package/dist/parser/extract.d.ts +6 -1
- package/dist/parser/extract.d.ts.map +1 -1
- package/dist/parser/extract.js +14 -2
- package/dist/parser/extract.js.map +1 -1
- package/dist/parser/lang-css.d.ts.map +1 -1
- package/dist/parser/lang-css.js +7 -1
- package/dist/parser/lang-css.js.map +1 -1
- package/dist/parser/lang-go.d.ts.map +1 -1
- package/dist/parser/lang-go.js +16 -0
- package/dist/parser/lang-go.js.map +1 -1
- package/dist/parser/lang-html.d.ts +4 -0
- package/dist/parser/lang-html.d.ts.map +1 -1
- package/dist/parser/lang-html.js +40 -1
- package/dist/parser/lang-html.js.map +1 -1
- package/dist/parser/lang-java.d.ts.map +1 -1
- package/dist/parser/lang-java.js +12 -0
- package/dist/parser/lang-java.js.map +1 -1
- package/dist/parser/lang-js.d.ts.map +1 -1
- package/dist/parser/lang-js.js +3 -0
- package/dist/parser/lang-js.js.map +1 -1
- package/dist/parser/lang-php.d.ts.map +1 -1
- package/dist/parser/lang-php.js +11 -0
- package/dist/parser/lang-php.js.map +1 -1
- package/dist/parser/lang-py.d.ts.map +1 -1
- package/dist/parser/lang-py.js +14 -0
- package/dist/parser/lang-py.js.map +1 -1
- package/dist/parser/lang-ruby.d.ts.map +1 -1
- package/dist/parser/lang-ruby.js +20 -0
- package/dist/parser/lang-ruby.js.map +1 -1
- package/dist/parser/lang-rust.d.ts.map +1 -1
- package/dist/parser/lang-rust.js +27 -4
- package/dist/parser/lang-rust.js.map +1 -1
- package/dist/parser/lang-ts.d.ts.map +1 -1
- package/dist/parser/lang-ts.js +3 -0
- package/dist/parser/lang-ts.js.map +1 -1
- package/dist/parser/lang-vue.d.ts +17 -1
- package/dist/parser/lang-vue.d.ts.map +1 -1
- package/dist/parser/lang-vue.js +177 -0
- package/dist/parser/lang-vue.js.map +1 -1
- package/dist/parser/language-provider.d.ts +27 -0
- package/dist/parser/language-provider.d.ts.map +1 -0
- package/dist/parser/language-provider.js +2 -0
- package/dist/parser/language-provider.js.map +1 -0
- package/dist/server/mcp.d.ts.map +1 -1
- package/dist/server/mcp.js +224 -50
- package/dist/server/mcp.js.map +1 -1
- package/dist/server/watcher.d.ts +8 -0
- package/dist/server/watcher.d.ts.map +1 -1
- package/dist/server/watcher.js +10 -8
- package/dist/server/watcher.js.map +1 -1
- package/dist/skills.js +163 -42
- package/dist/skills.js.map +1 -1
- package/dist/store/schema.sql +1 -1
- package/dist/ui/progress.d.ts +28 -0
- package/dist/ui/progress.d.ts.map +1 -0
- package/dist/ui/progress.js +100 -0
- package/dist/ui/progress.js.map +1 -0
- package/dist/uninstall.d.ts +54 -0
- package/dist/uninstall.d.ts.map +1 -0
- package/dist/uninstall.js +795 -0
- package/dist/uninstall.js.map +1 -0
- package/docs/README.md +4 -1
- package/package.json +1 -1
|
@@ -1,224 +1,224 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: milens-security-review
|
|
3
|
-
description: Security Audit — scan for secrets, hidden unicode, dangerous patterns, data leaks, and produce a security report
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# milens-security-review — Security Audit
|
|
7
|
-
|
|
8
|
-
Scan the codebase for security vulnerabilities: exposed secrets, hidden unicode (Trojan Source), dangerous code patterns, data leakage, and unexpected file changes.
|
|
9
|
-
|
|
10
|
-
## Tools Required
|
|
11
|
-
|
|
12
|
-
| Tool | Purpose |
|
|
13
|
-
|---|---|
|
|
14
|
-
| `mcp_milens_review_pr` | Initial risk assessment of changed files and symbols |
|
|
15
|
-
| `mcp_milens_grep` | Pattern search for secrets, unicode, dangerous calls, data leaks |
|
|
16
|
-
| `mcp_milens_review_symbol` | Deep-dive risk analysis on high-risk symbols |
|
|
17
|
-
| `mcp_milens_detect_changes` | Verify only expected files changed |
|
|
18
|
-
|
|
19
|
-
> **CRITICAL:** All milens MCP tool calls MUST include the `repo` parameter set to the **absolute path of the workspace root**.
|
|
20
|
-
|
|
21
|
-
## Workflow
|
|
22
|
-
|
|
23
|
-
### Step 1: Initial Risk Assessment
|
|
24
|
-
|
|
25
|
-
Start with a PR-level overview to identify high-risk areas.
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
mcp_milens_review_pr({repo: "<workspaceRoot>"})
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Focus on:
|
|
32
|
-
- **New files** — highest risk for secrets or vulnerabilities
|
|
33
|
-
- **Modified config files** — `.env`, `config.*`, settings files
|
|
34
|
-
- **Auth/routing files** — middleware, guards, session handlers
|
|
35
|
-
- **CRITICAL-rated symbols** — these get deep-dived in Step 6
|
|
36
|
-
|
|
37
|
-
### Step 2: Secret Detection
|
|
38
|
-
|
|
39
|
-
Search for hardcoded secrets and credentials.
|
|
40
|
-
|
|
41
|
-
```
|
|
42
|
-
mcp_milens_grep({pattern: "password|secret|api_key|token|private_key|AUTH_TOKEN", scope: "code", repo: "<workspaceRoot>"})
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Key patterns to flag:
|
|
46
|
-
- **Assignments to secrets** — `const apiKey = "sk-..."` (critical)
|
|
47
|
-
- **Config values** — `password: "admin123"` (high)
|
|
48
|
-
- **Variable names only** — `const apiKey = process.env.KEY` (low — already env-var'd)
|
|
49
|
-
- **Test fixtures** — `const testPassword = "..."` (verify it's not a real password)
|
|
50
|
-
|
|
51
|
-
### Step 3: Hidden Unicode Detection (Trojan Source)
|
|
52
|
-
|
|
53
|
-
Search for invisible and bidirectional Unicode characters used in supply-chain attacks.
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
mcp_milens_grep({pattern: "[\\u200B\\u200C\\u200D\\u2060\\uFEFF\\u202A-\\u202E]", scope: "code", isRegex: true, repo: "<workspaceRoot>"})
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
These characters can:
|
|
60
|
-
- Make code look like one thing but compile as another
|
|
61
|
-
- Hide backdoors in copy-pasted code
|
|
62
|
-
- Exploit bidirectional text in string literals and comments
|
|
63
|
-
|
|
64
|
-
**Any match is a CRITICAL finding** — flag for immediate removal.
|
|
65
|
-
|
|
66
|
-
### Step 4: Dangerous Code Patterns
|
|
67
|
-
|
|
68
|
-
Search for patterns that enable code injection or arbitrary execution.
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
mcp_milens_grep({pattern: "eval\\(|exec\\(|child_process|Function\\(", scope: "code", isRegex: true, repo: "<workspaceRoot>"})
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Severity guidance:
|
|
75
|
-
- `eval()` / `exec()` with user input — **CRITICAL**
|
|
76
|
-
- `child_process.exec()` with dynamic arguments — **CRITICAL**
|
|
77
|
-
- `new Function()` — **HIGH** (eval equivalent)
|
|
78
|
-
- `child_process.spawn()` with fixed arguments — **LOW** (safer than exec)
|
|
79
|
-
|
|
80
|
-
### Step 5: Data Leak Detection
|
|
81
|
-
|
|
82
|
-
Find logging statements that may expose sensitive data.
|
|
83
|
-
|
|
84
|
-
```
|
|
85
|
-
mcp_milens_grep({pattern: "console\\.(log|debug|info)\\(", scope: "code", isRegex: true, repo: "<workspaceRoot>"})
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Flag any `console.log` that logs:
|
|
89
|
-
- User data (emails, names, PII)
|
|
90
|
-
- Tokens, passwords, keys
|
|
91
|
-
- Request bodies or headers
|
|
92
|
-
- Database query results with user data
|
|
93
|
-
|
|
94
|
-
### Step 6: Deep-Dive on Critical Symbols
|
|
95
|
-
|
|
96
|
-
For any symbol flagged as CRITICAL in Step 1, run a deep-dive.
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
mcp_milens_review_symbol({name: "<symbolName>", repo: "<workspaceRoot>"})
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
This provides:
|
|
103
|
-
- **Role** — what the symbol does (auth, routing, data access)
|
|
104
|
-
- **Heat** — how frequently it changes (volatile code = higher risk)
|
|
105
|
-
- **Dependents** — blast radius if compromised
|
|
106
|
-
- **Test status** — whether its behavior is verified
|
|
107
|
-
|
|
108
|
-
### Step 7: Verify Change Scope
|
|
109
|
-
|
|
110
|
-
Confirm that only expected files were modified.
|
|
111
|
-
|
|
112
|
-
```
|
|
113
|
-
mcp_milens_detect_changes({repo: "<workspaceRoot>"})
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
This catches:
|
|
117
|
-
- Unintended file modifications (config drift)
|
|
118
|
-
- Stray files included in the commit
|
|
119
|
-
- Missing or extra changes vs. expectations
|
|
120
|
-
|
|
121
|
-
### Step 8: Produce Security Audit Report
|
|
122
|
-
|
|
123
|
-
Consolidate into a structured report:
|
|
124
|
-
|
|
125
|
-
1. **Executive Summary** — overall risk level, critical findings count
|
|
126
|
-
2. **Secret Scan Results** — each match with file, line, severity, and remediation
|
|
127
|
-
3. **Unicode Scan Results** — each match (any match is critical)
|
|
128
|
-
4. **Dangerous Patterns** — each `eval`/`exec`/`Function` usage with justification
|
|
129
|
-
5. **Data Leak Findings** — each `console.log` that logs sensitive data
|
|
130
|
-
6. **Symbol Risk Deep-Dives** — per CRITICAL symbol from Step 6
|
|
131
|
-
7. **Change Scope Verification** — expected vs. actual changed files
|
|
132
|
-
8. **Remediation Plan** — ordered by severity, with specific fix recommendations
|
|
133
|
-
9. **Verdict** — PASSED / NEEDS REMEDIATION / BLOCKED
|
|
134
|
-
|
|
135
|
-
## Example Session
|
|
136
|
-
|
|
137
|
-
### Input
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
"run a security audit before the release"
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
### Tool Calls
|
|
144
|
-
|
|
145
|
-
**Step 1 — PR overview:**
|
|
146
|
-
```
|
|
147
|
-
mcp_milens_review_pr({repo: "/home/user/project"})
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Output:** 8 changed files, 2 CRITICAL symbols (`authHandler`, `paymentProcessor`).
|
|
151
|
-
|
|
152
|
-
**Step 2 — Secret detection:**
|
|
153
|
-
```
|
|
154
|
-
mcp_milens_grep({pattern: "password|secret|api_key|token|private_key|AUTH_TOKEN", scope: "code", repo: "/home/user/project"})
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
**Output:**
|
|
158
|
-
```
|
|
159
|
-
src/config.ts:12 apiKey: "sk-prod-abc123..." ← CRITICAL: hardcoded API key
|
|
160
|
-
src/auth/login.ts:34 const password = req.body.pass ← LOW: variable assignment
|
|
161
|
-
src/__tests__/helpers.ts:8 const testToken = "test" ← OK: test fixture
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
**Step 3 — Unicode scan:**
|
|
165
|
-
```
|
|
166
|
-
mcp_milens_grep({pattern: "[\\u200B\\u200C\\u200D\\u2060\\uFEFF\\u202A-\\u202E]", scope: "code", isRegex: true, repo: "/home/user/project"})
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
**Output:** 0 matches. Clean.
|
|
170
|
-
|
|
171
|
-
**Step 4 — Dangerous patterns:**
|
|
172
|
-
```
|
|
173
|
-
mcp_milens_grep({pattern: "eval\\(|exec\\(|child_process|Function\\(", scope: "code", isRegex: true, repo: "/home/user/project"})
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
**Output:**
|
|
177
|
-
```
|
|
178
|
-
src/scripts/migrate.ts:22 exec(`pg_dump ${dbName}`) ← CRITICAL: dynamic args
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
**Step 5 — Data leak:**
|
|
182
|
-
```
|
|
183
|
-
mcp_milens_grep({pattern: "console\\.(log|debug|info)\\(", scope: "code", isRegex: true, repo: "/home/user/project"})
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
**Output:**
|
|
187
|
-
```
|
|
188
|
-
src/auth/login.ts:28 console.log("User login:", email) ← HIGH: logs PII
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
**Step 6 — Deep-dive:**
|
|
192
|
-
```
|
|
193
|
-
mcp_milens_review_symbol({name: "authHandler", repo: "/home/user/project"})
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
**Output:** Core auth entry point, 23 dependents, 0 tests — very high risk.
|
|
197
|
-
|
|
198
|
-
**Step 7 — Verify scope:**
|
|
199
|
-
```
|
|
200
|
-
mcp_milens_detect_changes({repo: "/home/user/project"})
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
**Output:** 8 files changed — matches expectations.
|
|
204
|
-
|
|
205
|
-
**Step 8 — Report produced** (see report format above). Verdict: **NEEDS REMEDIATION** (1 critical secret, 1 critical dangerous pattern, 1 high data leak).
|
|
206
|
-
|
|
207
|
-
## Best Practices
|
|
208
|
-
|
|
209
|
-
1. **Don't assume variable names are safe.** `const password = process.env.DB_PASS` is fine; `const password = "admin123"` is not. Read the value, not just the name.
|
|
210
|
-
2. **Unicode scan is non-negotiable.** Trojan Source attacks are invisible to human reviewers. Even a single zero-width character match is a blocking finding.
|
|
211
|
-
3. **Test fixtures get a pass — but verify.** `const testApiKey = "test-key"` is acceptable, but `const testApiKey = "sk-live-..."` is a leaked production key.
|
|
212
|
-
4. **Dynamic exec/Function is almost always wrong.** If `exec()` takes user-controlled input, it's remote code execution. The only acceptable pattern is fully-hardcoded command strings.
|
|
213
|
-
5. **Detect changes verifies the boundary.** If `detect_changes` shows files you didn't touch, something went wrong — config drift, lockfile churn, or accidental staging.
|
|
214
|
-
|
|
215
|
-
## Quality Gate
|
|
216
|
-
|
|
217
|
-
| Criteria | Pass | Fail |
|
|
218
|
-
|---|---|---|
|
|
219
|
-
| Secret scan | No hardcoded secrets found outside test fixtures | Any production secret in code |
|
|
220
|
-
| Unicode scan | Zero matches | Any hidden unicode character found |
|
|
221
|
-
| Dangerous patterns | No `eval`/`exec` with dynamic input | Any dynamic `exec()` or `Function()` call |
|
|
222
|
-
| Data leak | No PII/credentials in `console.log` | Sensitive data logged to console |
|
|
223
|
-
| Change scope | `detect_changes` matches expectations | Unexpected files in the diff |
|
|
224
|
-
| All scans completed | All 7 steps executed | Any tool call skipped or failed |
|
|
1
|
+
---
|
|
2
|
+
name: milens-security-review
|
|
3
|
+
description: Security Audit — scan for secrets, hidden unicode, dangerous patterns, data leaks, and produce a security report
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# milens-security-review — Security Audit
|
|
7
|
+
|
|
8
|
+
Scan the codebase for security vulnerabilities: exposed secrets, hidden unicode (Trojan Source), dangerous code patterns, data leakage, and unexpected file changes.
|
|
9
|
+
|
|
10
|
+
## Tools Required
|
|
11
|
+
|
|
12
|
+
| Tool | Purpose |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `mcp_milens_review_pr` | Initial risk assessment of changed files and symbols |
|
|
15
|
+
| `mcp_milens_grep` | Pattern search for secrets, unicode, dangerous calls, data leaks |
|
|
16
|
+
| `mcp_milens_review_symbol` | Deep-dive risk analysis on high-risk symbols |
|
|
17
|
+
| `mcp_milens_detect_changes` | Verify only expected files changed |
|
|
18
|
+
|
|
19
|
+
> **CRITICAL:** All milens MCP tool calls MUST include the `repo` parameter set to the **absolute path of the workspace root**.
|
|
20
|
+
|
|
21
|
+
## Workflow
|
|
22
|
+
|
|
23
|
+
### Step 1: Initial Risk Assessment
|
|
24
|
+
|
|
25
|
+
Start with a PR-level overview to identify high-risk areas.
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
mcp_milens_review_pr({repo: "<workspaceRoot>"})
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Focus on:
|
|
32
|
+
- **New files** — highest risk for secrets or vulnerabilities
|
|
33
|
+
- **Modified config files** — `.env`, `config.*`, settings files
|
|
34
|
+
- **Auth/routing files** — middleware, guards, session handlers
|
|
35
|
+
- **CRITICAL-rated symbols** — these get deep-dived in Step 6
|
|
36
|
+
|
|
37
|
+
### Step 2: Secret Detection
|
|
38
|
+
|
|
39
|
+
Search for hardcoded secrets and credentials.
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
mcp_milens_grep({pattern: "password|secret|api_key|token|private_key|AUTH_TOKEN", scope: "code", repo: "<workspaceRoot>"})
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Key patterns to flag:
|
|
46
|
+
- **Assignments to secrets** — `const apiKey = "sk-..."` (critical)
|
|
47
|
+
- **Config values** — `password: "admin123"` (high)
|
|
48
|
+
- **Variable names only** — `const apiKey = process.env.KEY` (low — already env-var'd)
|
|
49
|
+
- **Test fixtures** — `const testPassword = "..."` (verify it's not a real password)
|
|
50
|
+
|
|
51
|
+
### Step 3: Hidden Unicode Detection (Trojan Source)
|
|
52
|
+
|
|
53
|
+
Search for invisible and bidirectional Unicode characters used in supply-chain attacks.
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
mcp_milens_grep({pattern: "[\\u200B\\u200C\\u200D\\u2060\\uFEFF\\u202A-\\u202E]", scope: "code", isRegex: true, repo: "<workspaceRoot>"})
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
These characters can:
|
|
60
|
+
- Make code look like one thing but compile as another
|
|
61
|
+
- Hide backdoors in copy-pasted code
|
|
62
|
+
- Exploit bidirectional text in string literals and comments
|
|
63
|
+
|
|
64
|
+
**Any match is a CRITICAL finding** — flag for immediate removal.
|
|
65
|
+
|
|
66
|
+
### Step 4: Dangerous Code Patterns
|
|
67
|
+
|
|
68
|
+
Search for patterns that enable code injection or arbitrary execution.
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
mcp_milens_grep({pattern: "eval\\(|exec\\(|child_process|Function\\(", scope: "code", isRegex: true, repo: "<workspaceRoot>"})
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Severity guidance:
|
|
75
|
+
- `eval()` / `exec()` with user input — **CRITICAL**
|
|
76
|
+
- `child_process.exec()` with dynamic arguments — **CRITICAL**
|
|
77
|
+
- `new Function()` — **HIGH** (eval equivalent)
|
|
78
|
+
- `child_process.spawn()` with fixed arguments — **LOW** (safer than exec)
|
|
79
|
+
|
|
80
|
+
### Step 5: Data Leak Detection
|
|
81
|
+
|
|
82
|
+
Find logging statements that may expose sensitive data.
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
mcp_milens_grep({pattern: "console\\.(log|debug|info)\\(", scope: "code", isRegex: true, repo: "<workspaceRoot>"})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Flag any `console.log` that logs:
|
|
89
|
+
- User data (emails, names, PII)
|
|
90
|
+
- Tokens, passwords, keys
|
|
91
|
+
- Request bodies or headers
|
|
92
|
+
- Database query results with user data
|
|
93
|
+
|
|
94
|
+
### Step 6: Deep-Dive on Critical Symbols
|
|
95
|
+
|
|
96
|
+
For any symbol flagged as CRITICAL in Step 1, run a deep-dive.
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
mcp_milens_review_symbol({name: "<symbolName>", repo: "<workspaceRoot>"})
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
This provides:
|
|
103
|
+
- **Role** — what the symbol does (auth, routing, data access)
|
|
104
|
+
- **Heat** — how frequently it changes (volatile code = higher risk)
|
|
105
|
+
- **Dependents** — blast radius if compromised
|
|
106
|
+
- **Test status** — whether its behavior is verified
|
|
107
|
+
|
|
108
|
+
### Step 7: Verify Change Scope
|
|
109
|
+
|
|
110
|
+
Confirm that only expected files were modified.
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
mcp_milens_detect_changes({repo: "<workspaceRoot>"})
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
This catches:
|
|
117
|
+
- Unintended file modifications (config drift)
|
|
118
|
+
- Stray files included in the commit
|
|
119
|
+
- Missing or extra changes vs. expectations
|
|
120
|
+
|
|
121
|
+
### Step 8: Produce Security Audit Report
|
|
122
|
+
|
|
123
|
+
Consolidate into a structured report:
|
|
124
|
+
|
|
125
|
+
1. **Executive Summary** — overall risk level, critical findings count
|
|
126
|
+
2. **Secret Scan Results** — each match with file, line, severity, and remediation
|
|
127
|
+
3. **Unicode Scan Results** — each match (any match is critical)
|
|
128
|
+
4. **Dangerous Patterns** — each `eval`/`exec`/`Function` usage with justification
|
|
129
|
+
5. **Data Leak Findings** — each `console.log` that logs sensitive data
|
|
130
|
+
6. **Symbol Risk Deep-Dives** — per CRITICAL symbol from Step 6
|
|
131
|
+
7. **Change Scope Verification** — expected vs. actual changed files
|
|
132
|
+
8. **Remediation Plan** — ordered by severity, with specific fix recommendations
|
|
133
|
+
9. **Verdict** — PASSED / NEEDS REMEDIATION / BLOCKED
|
|
134
|
+
|
|
135
|
+
## Example Session
|
|
136
|
+
|
|
137
|
+
### Input
|
|
138
|
+
|
|
139
|
+
```
|
|
140
|
+
"run a security audit before the release"
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Tool Calls
|
|
144
|
+
|
|
145
|
+
**Step 1 — PR overview:**
|
|
146
|
+
```
|
|
147
|
+
mcp_milens_review_pr({repo: "/home/user/project"})
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Output:** 8 changed files, 2 CRITICAL symbols (`authHandler`, `paymentProcessor`).
|
|
151
|
+
|
|
152
|
+
**Step 2 — Secret detection:**
|
|
153
|
+
```
|
|
154
|
+
mcp_milens_grep({pattern: "password|secret|api_key|token|private_key|AUTH_TOKEN", scope: "code", repo: "/home/user/project"})
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Output:**
|
|
158
|
+
```
|
|
159
|
+
src/config.ts:12 apiKey: "sk-prod-abc123..." ← CRITICAL: hardcoded API key
|
|
160
|
+
src/auth/login.ts:34 const password = req.body.pass ← LOW: variable assignment
|
|
161
|
+
src/__tests__/helpers.ts:8 const testToken = "test" ← OK: test fixture
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Step 3 — Unicode scan:**
|
|
165
|
+
```
|
|
166
|
+
mcp_milens_grep({pattern: "[\\u200B\\u200C\\u200D\\u2060\\uFEFF\\u202A-\\u202E]", scope: "code", isRegex: true, repo: "/home/user/project"})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
**Output:** 0 matches. Clean.
|
|
170
|
+
|
|
171
|
+
**Step 4 — Dangerous patterns:**
|
|
172
|
+
```
|
|
173
|
+
mcp_milens_grep({pattern: "eval\\(|exec\\(|child_process|Function\\(", scope: "code", isRegex: true, repo: "/home/user/project"})
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Output:**
|
|
177
|
+
```
|
|
178
|
+
src/scripts/migrate.ts:22 exec(`pg_dump ${dbName}`) ← CRITICAL: dynamic args
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**Step 5 — Data leak:**
|
|
182
|
+
```
|
|
183
|
+
mcp_milens_grep({pattern: "console\\.(log|debug|info)\\(", scope: "code", isRegex: true, repo: "/home/user/project"})
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
**Output:**
|
|
187
|
+
```
|
|
188
|
+
src/auth/login.ts:28 console.log("User login:", email) ← HIGH: logs PII
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
**Step 6 — Deep-dive:**
|
|
192
|
+
```
|
|
193
|
+
mcp_milens_review_symbol({name: "authHandler", repo: "/home/user/project"})
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Output:** Core auth entry point, 23 dependents, 0 tests — very high risk.
|
|
197
|
+
|
|
198
|
+
**Step 7 — Verify scope:**
|
|
199
|
+
```
|
|
200
|
+
mcp_milens_detect_changes({repo: "/home/user/project"})
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
**Output:** 8 files changed — matches expectations.
|
|
204
|
+
|
|
205
|
+
**Step 8 — Report produced** (see report format above). Verdict: **NEEDS REMEDIATION** (1 critical secret, 1 critical dangerous pattern, 1 high data leak).
|
|
206
|
+
|
|
207
|
+
## Best Practices
|
|
208
|
+
|
|
209
|
+
1. **Don't assume variable names are safe.** `const password = process.env.DB_PASS` is fine; `const password = "admin123"` is not. Read the value, not just the name.
|
|
210
|
+
2. **Unicode scan is non-negotiable.** Trojan Source attacks are invisible to human reviewers. Even a single zero-width character match is a blocking finding.
|
|
211
|
+
3. **Test fixtures get a pass — but verify.** `const testApiKey = "test-key"` is acceptable, but `const testApiKey = "sk-live-..."` is a leaked production key.
|
|
212
|
+
4. **Dynamic exec/Function is almost always wrong.** If `exec()` takes user-controlled input, it's remote code execution. The only acceptable pattern is fully-hardcoded command strings.
|
|
213
|
+
5. **Detect changes verifies the boundary.** If `detect_changes` shows files you didn't touch, something went wrong — config drift, lockfile churn, or accidental staging.
|
|
214
|
+
|
|
215
|
+
## Quality Gate
|
|
216
|
+
|
|
217
|
+
| Criteria | Pass | Fail |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| Secret scan | No hardcoded secrets found outside test fixtures | Any production secret in code |
|
|
220
|
+
| Unicode scan | Zero matches | Any hidden unicode character found |
|
|
221
|
+
| Dangerous patterns | No `eval`/`exec` with dynamic input | Any dynamic `exec()` or `Function()` call |
|
|
222
|
+
| Data leak | No PII/credentials in `console.log` | Sensitive data logged to console |
|
|
223
|
+
| Change scope | `detect_changes` matches expectations | Unexpected files in the diff |
|
|
224
|
+
| All scans completed | All 7 steps executed | Any tool call skipped or failed |
|
|
@@ -39,20 +39,22 @@ Contains 22 symbols (7 exported) across 2 files.
|
|
|
39
39
|
|
|
40
40
|
## Entry Points
|
|
41
41
|
- **`Orchestrator`** [class] — 6 incoming references
|
|
42
|
+
- **`e`** [function] — 5 incoming references
|
|
42
43
|
- **`OrchestratorReport`** [interface] — 5 incoming references
|
|
43
44
|
- **`formatReport`** [function] — 4 incoming references
|
|
44
45
|
- **`snapshot`** [method] — 3 incoming references
|
|
45
|
-
- **`run`** [method] — 3 incoming references
|
|
46
46
|
|
|
47
47
|
## Dependencies
|
|
48
48
|
- **store**: `Database`, `findSymbolByName`, `findUpstream`, `clear`, `getTestCoverageGaps`, `findDeadCode`, `close`
|
|
49
49
|
- **analyzer**: `reviewPr`, `ReviewResult`, `SymbolRisk`
|
|
50
50
|
- **root**: `CodeSymbol`, `has`
|
|
51
|
+
- **test**: `add`
|
|
51
52
|
|
|
52
53
|
## Used By
|
|
53
54
|
- **root**: `Orchestrator`, `subscribe`, `runAndFormat`
|
|
54
55
|
- **server**: `Orchestrator`, `snapshot`, `compare`, `runAndFormat`
|
|
55
56
|
- **test**: `Orchestrator`, `formatReport`, `OrchestratorReport`, `subscribe`, `run`, `snapshot`, `compare`, `cancel` (+3 more)
|
|
57
|
+
- **apps**: `e`
|
|
56
58
|
|
|
57
59
|
## Files
|
|
58
60
|
- src/orchestrator/orchestrator.ts
|
|
@@ -26,27 +26,27 @@ When working with code in **parser/**, follow these mandatory safety rules:
|
|
|
26
26
|
| See file symbols | `mcp_milens_get_file_symbols` |
|
|
27
27
|
|
|
28
28
|
## Overview
|
|
29
|
-
Contains
|
|
29
|
+
Contains 83 symbols (31 exported) across 16 files.
|
|
30
30
|
|
|
31
31
|
## Key Symbols
|
|
32
|
-
- **`LangSpec`** [interface] (src/parser/extract.ts:6) —
|
|
32
|
+
- **`LangSpec`** [interface] (src/parser/extract.ts:6) — 32 refs
|
|
33
33
|
- **`loadLanguage`** [function] (src/parser/loader.ts:21) — 14 refs
|
|
34
34
|
- **`getParser`** [function] (src/parser/loader.ts:32) — 13 refs
|
|
35
|
-
- **`extractFromTree`** [function] (src/parser/extract.ts:
|
|
35
|
+
- **`extractFromTree`** [function] (src/parser/extract.ts:256) — 8 refs
|
|
36
36
|
- **`supportedExtensions`** [function] (src/parser/languages.ts:29) — 6 refs
|
|
37
|
-
- **`extractHtmlScripts`** [function] (src/parser/lang-html.ts:
|
|
37
|
+
- **`extractHtmlScripts`** [function] (src/parser/lang-html.ts:38) — 5 refs
|
|
38
38
|
- **`extractMarkdown`** [function] (src/parser/lang-md.ts:34) — 5 refs
|
|
39
39
|
- **`spec`** [variable] (src/parser/lang-ts.ts:5) — 5 refs
|
|
40
|
-
- **`extractVueScript`** [function] (src/parser/lang-vue.ts:
|
|
40
|
+
- **`extractVueScript`** [function] (src/parser/lang-vue.ts:19) — 5 refs
|
|
41
41
|
- **`initTreeSitter`** [function] (src/parser/loader.ts:15) — 5 refs
|
|
42
|
-
- **`clearQueryCache`** [function] (src/parser/extract.ts:
|
|
43
|
-
- **`extractHtmlRefs`** [function] (src/parser/lang-html.ts:
|
|
44
|
-
- **`
|
|
45
|
-
- **`
|
|
46
|
-
- **`
|
|
42
|
+
- **`clearQueryCache`** [function] (src/parser/extract.ts:72) — 4 refs
|
|
43
|
+
- **`extractHtmlRefs`** [function] (src/parser/lang-html.ts:57) — 4 refs
|
|
44
|
+
- **`extractHtmlLinks`** [function] (src/parser/lang-html.ts:99) — 4 refs
|
|
45
|
+
- **`extractVueTemplateRefs`** [function] (src/parser/lang-vue.ts:38) — 4 refs
|
|
46
|
+
- **`extractVueTemplateAst`** [function] (src/parser/lang-vue.ts:90) — 4 refs
|
|
47
47
|
|
|
48
48
|
## Entry Points
|
|
49
|
-
- **`LangSpec`** [interface] —
|
|
49
|
+
- **`LangSpec`** [interface] — 32 incoming references
|
|
50
50
|
- **`loadLanguage`** [function] — 14 incoming references
|
|
51
51
|
- **`getParser`** [function] — 13 incoming references
|
|
52
52
|
- **`extractFromTree`** [function] — 8 incoming references
|
|
@@ -54,14 +54,14 @@ Contains 76 symbols (26 exported) across 15 files.
|
|
|
54
54
|
|
|
55
55
|
## Dependencies
|
|
56
56
|
- **root**: `CodeSymbol`, `RawImport`, `RawCall`, `RawHeritage`, `RawReExport`, `RawTypeBinding`, `RawAssignmentBinding`, `RawReturnType` (+4 more)
|
|
57
|
-
- **test**: `lang`, `parser`
|
|
58
|
-
- **analyzer**: `
|
|
57
|
+
- **test**: `lang`, `add`, `parser`
|
|
58
|
+
- **analyzer**: `resolve`
|
|
59
59
|
- **store**: `load`
|
|
60
60
|
|
|
61
61
|
## Used By
|
|
62
|
-
- **analyzer**: `langForFile`, `supportedExtensions`, `getParser`, `loadLanguage`, `extractFromTree`, `clearQueryCache`, `extractVueScript`, `extractVueTemplateRefs` (+
|
|
62
|
+
- **analyzer**: `langForFile`, `supportedExtensions`, `getParser`, `loadLanguage`, `extractFromTree`, `clearQueryCache`, `extractVueScript`, `extractVueTemplateRefs` (+9 more)
|
|
63
63
|
- **server**: `getParser`, `loadLanguage`, `ALL_LANGS`
|
|
64
|
-
- **test**: `getParser`, `loadLanguage`, `extractFromTree`, `extractVueScript`, `extractVueTemplateRefs`, `
|
|
64
|
+
- **test**: `getParser`, `loadLanguage`, `extractFromTree`, `extractVueScript`, `extractVueTemplateRefs`, `extractVueCompositionApi`, `extractVueTemplateAst`, `spec` (+11 more)
|
|
65
65
|
|
|
66
66
|
## Files
|
|
67
67
|
- src/parser/extract.ts
|
|
@@ -77,5 +77,6 @@ Contains 76 symbols (26 exported) across 15 files.
|
|
|
77
77
|
- src/parser/lang-rust.ts
|
|
78
78
|
- src/parser/lang-ts.ts
|
|
79
79
|
- src/parser/lang-vue.ts
|
|
80
|
+
- src/parser/language-provider.ts
|
|
80
81
|
- src/parser/languages.ts
|
|
81
82
|
- src/parser/loader.ts
|
|
@@ -26,47 +26,47 @@ When working with code in **root/**, follow these mandatory safety rules:
|
|
|
26
26
|
| See file symbols | `mcp_milens_get_file_symbols` |
|
|
27
27
|
|
|
28
28
|
## Overview
|
|
29
|
-
Contains
|
|
29
|
+
Contains 229 symbols (153 exported) across 13 files.
|
|
30
30
|
|
|
31
31
|
## Key Symbols
|
|
32
|
-
- **`CodeSymbol`** [interface] (src/types.ts:8) —
|
|
33
|
-
- **`SymbolLink`** [interface] (src/types.ts:26) —
|
|
34
|
-
- **`
|
|
35
|
-
- **`
|
|
36
|
-
- **`RawImport`** [interface] (src/types.ts:35) —
|
|
32
|
+
- **`CodeSymbol`** [interface] (src/types.ts:8) — 53 refs
|
|
33
|
+
- **`SymbolLink`** [interface] (src/types.ts:26) — 24 refs
|
|
34
|
+
- **`RawCall`** [interface] (src/types.ts:44) — 15 refs
|
|
35
|
+
- **`isTestFile`** [function] (src/utils.ts:2) — 12 refs
|
|
36
|
+
- **`RawImport`** [interface] (src/types.ts:35) — 9 refs
|
|
37
|
+
- **`RawHeritage`** [interface] (src/types.ts:52) — 7 refs
|
|
37
38
|
- **`ExtractionResult`** [interface] (src/types.ts:60) — 6 refs
|
|
39
|
+
- **`RawTypeBinding`** [interface] (src/types.ts:80) — 6 refs
|
|
40
|
+
- **`RawAssignmentBinding`** [interface] (src/types.ts:88) — 6 refs
|
|
41
|
+
- **`RawReturnType`** [interface] (src/types.ts:96) — 5 refs
|
|
42
|
+
- **`RawCallResultBinding`** [interface] (src/types.ts:104) — 5 refs
|
|
38
43
|
- **`generateAgentsMd`** [function] (src/agents-md.ts:43) — 4 refs
|
|
39
44
|
- **`computeMetrics`** [function] (src/metrics.ts:21) — 4 refs
|
|
40
45
|
- **`formatMetricsReport`** [function] (src/metrics.ts:62) — 4 refs
|
|
41
46
|
- **`MilensMetrics`** [interface] (src/metrics.ts:4) — 4 refs
|
|
42
|
-
- **`generateSkills`** [function] (src/skills.ts:19) — 4 refs
|
|
43
|
-
- **`RawHeritage`** [interface] (src/types.ts:52) — 4 refs
|
|
44
|
-
- **`RawTypeBinding`** [interface] (src/types.ts:80) — 4 refs
|
|
45
|
-
- **`RawAssignmentBinding`** [interface] (src/types.ts:88) — 4 refs
|
|
46
|
-
- **`RawReturnType`** [interface] (src/types.ts:96) — 4 refs
|
|
47
47
|
|
|
48
48
|
## Entry Points
|
|
49
|
-
- **`CodeSymbol`** [interface] —
|
|
50
|
-
- **`has`** [function] —
|
|
51
|
-
- **`SymbolLink`** [interface] —
|
|
52
|
-
- **`
|
|
53
|
-
- **`
|
|
49
|
+
- **`CodeSymbol`** [interface] — 53 incoming references
|
|
50
|
+
- **`has`** [function] — 47 incoming references
|
|
51
|
+
- **`SymbolLink`** [interface] — 24 incoming references
|
|
52
|
+
- **`RawCall`** [interface] — 15 incoming references
|
|
53
|
+
- **`isTestFile`** [function] — 12 incoming references
|
|
54
54
|
|
|
55
55
|
## Dependencies
|
|
56
|
-
- **store**: `Database`, `RepoRegistry`, `AnnotationStore`, `runDecayPass`, `getIncomingLinks`, `getAllSymbols`, `getCodebaseSummary`, `register` (+
|
|
56
|
+
- **store**: `Database`, `RepoRegistry`, `AnnotationStore`, `runDecayPass`, `getIncomingLinks`, `getAllSymbols`, `getCodebaseSummary`, `register` (+24 more)
|
|
57
57
|
- **analyzer**: `loadAliases`, `analyze`, `resolve`, `clear`
|
|
58
58
|
- **server**: `startHttp`, `startStdio`, `HookManager`, `get`, `enableHook`, `loadConfig`, `saveConfig`, `disableHook`
|
|
59
59
|
- **security**: `loadRules`, `auditDependencies`
|
|
60
60
|
- **orchestrator**: `Orchestrator`, `subscribe`, `runAndFormat`
|
|
61
|
+
- **test**: `add`, `dbPath`
|
|
61
62
|
- **scripts**: `outDir`
|
|
62
|
-
- **test**: `dbPath`
|
|
63
63
|
|
|
64
64
|
## Used By
|
|
65
65
|
- **analyzer**: `isTestFile`, `CodeSymbol`, `ExtractionResult`, `RawImport`, `RawCall`, `RawHeritage`, `RawReExport`, `RawTypeBinding` (+8 more)
|
|
66
66
|
- **orchestrator**: `CodeSymbol`, `has`
|
|
67
67
|
- **parser**: `CodeSymbol`, `RawImport`, `RawCall`, `RawHeritage`, `RawReExport`, `RawTypeBinding`, `RawAssignmentBinding`, `RawReturnType` (+4 more)
|
|
68
68
|
- **store**: `Annotation`, `AnnotationKey`, `Session`, `EvolutionEvent`, `CodeSymbol`, `SymbolLink`, `RepoEntry`, `has` (+1 more)
|
|
69
|
-
- **test**: `generateAgentsMd`, `AnnotationKey`, `CodeSymbol`, `SymbolLink`, `computeMetrics`, `formatMetricsReport`, `MilensMetrics`, `RawImport` (+
|
|
69
|
+
- **test**: `generateAgentsMd`, `AnnotationKey`, `CodeSymbol`, `SymbolLink`, `computeMetrics`, `formatMetricsReport`, `MilensMetrics`, `RawImport` (+17 more)
|
|
70
70
|
- **security**: `has`
|
|
71
71
|
- **server**: `has`
|
|
72
72
|
|
|
@@ -76,11 +76,11 @@ Contains 198 symbols (147 exported) across 13 files.
|
|
|
76
76
|
- CONTRIBUTING.md
|
|
77
77
|
- DEPLOY.md
|
|
78
78
|
- README.md
|
|
79
|
-
- milens-generate-skills-issue.md
|
|
80
79
|
- src/agents-md.ts
|
|
81
80
|
- src/cli.ts
|
|
82
81
|
- src/metrics.ts
|
|
83
82
|
- src/skills.ts
|
|
84
83
|
- src/types.ts
|
|
84
|
+
- src/uninstall.ts
|
|
85
85
|
- src/utils.ts
|
|
86
86
|
- vitest.config.ts
|