codymaster 4.1.1 → 4.1.2
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/CHANGELOG.md +16 -0
- package/dist/dashboard.js +2 -1
- package/package.json +2 -2
- package/skills/cm-code-review/SKILL.md +27 -0
- package/skills/cm-execution/SKILL.md +38 -0
- package/skills/cm-planning/SKILL.md +4 -0
- package/skills/cm-project-bootstrap/SKILL.md +7 -1
- package/skills/cm-quality-gate/SKILL.md +52 -0
- package/skills/cm-tdd/SKILL.md +38 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,22 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
Categories: 🚀 **Improvements** | 🐛 **Bug Fixes**
|
|
6
6
|
|
|
7
|
+
## [4.1.1] - 2026-03-24
|
|
8
|
+
|
|
9
|
+
### 🚀 Improvements
|
|
10
|
+
- Documentation Changelog Integration — automated changelog generation added to VitePress docs
|
|
11
|
+
- Setup NPM Publishing — configured package for npmjs.com publishing
|
|
12
|
+
- CLI Interface Redesign — premium mobile-optimized ASCII art banner
|
|
13
|
+
- Parallel Coding Page — added visual comparison and full i18n support
|
|
14
|
+
- Open Source Docs — added section acknowledging referenced GitHub repositories
|
|
15
|
+
|
|
16
|
+
### 🐛 Bug Fixes
|
|
17
|
+
- Security Vulnerability Remediation — resolved Snyk Code findings including DOM XSS and Path Traversal
|
|
18
|
+
- Fixed 401 Unauthorized authentication error for `/cm:cm-start` command
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
|
|
7
23
|
## [4.1.0] - 2026-03-23
|
|
8
24
|
|
|
9
25
|
### 🚀 Improvements
|
package/dist/dashboard.js
CHANGED
|
@@ -17,7 +17,8 @@ const skill_chain_1 = require("./skill-chain");
|
|
|
17
17
|
// ─── Dashboard Server ───────────────────────────────────────────────────────
|
|
18
18
|
function launchDashboard(port = data_1.DEFAULT_PORT, silent = false) {
|
|
19
19
|
const app = (0, express_1.default)();
|
|
20
|
-
app.
|
|
20
|
+
app.disable('x-powered-by');
|
|
21
|
+
app.use(express_1.default.json({ limit: '1mb' }));
|
|
21
22
|
const publicDir = path_1.default.join(__dirname, '..', 'public', 'dashboard');
|
|
22
23
|
app.use(express_1.default.static(publicDir));
|
|
23
24
|
// ─── Project API ────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codymaster",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"description": "34 Skills. Ship 10x faster. AI-powered coding skill kit for Claude, Cursor, Gemini & more.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"repository": {
|
|
@@ -75,4 +75,4 @@
|
|
|
75
75
|
"typescript": "^5.9.3",
|
|
76
76
|
"vitest": "^4.1.0"
|
|
77
77
|
}
|
|
78
|
-
}
|
|
78
|
+
}
|
|
@@ -119,6 +119,33 @@ When implementation is complete and all tests pass.
|
|
|
119
119
|
|
|
120
120
|
---
|
|
121
121
|
|
|
122
|
+
## Part D: Security Review Checklist (Learned: March 2026)
|
|
123
|
+
|
|
124
|
+
> **Every code review MUST include a security pass.** Check these patterns:
|
|
125
|
+
|
|
126
|
+
### Frontend
|
|
127
|
+
- [ ] No `innerHTML` with unescaped dynamic data
|
|
128
|
+
- [ ] `sanitize.js` loaded before any JS that uses `innerHTML`
|
|
129
|
+
- [ ] URLs from params validated against allowlist
|
|
130
|
+
- [ ] No `eval()`, `new Function()`, or `document.write()` with user data
|
|
131
|
+
|
|
132
|
+
### Backend (Python)
|
|
133
|
+
- [ ] All file paths from config/input use `safe_resolve(base, path)`
|
|
134
|
+
- [ ] No `subprocess.run(..., shell=True)` with dynamic args
|
|
135
|
+
- [ ] No `open(user_input)` without path validation
|
|
136
|
+
|
|
137
|
+
### Backend (Node/Express)
|
|
138
|
+
- [ ] `app.disable('x-powered-by')` set
|
|
139
|
+
- [ ] Body size limits configured
|
|
140
|
+
- [ ] No `Object.assign(config, userInput)` (prototype pollution)
|
|
141
|
+
- [ ] API error responses don't leak stack traces
|
|
142
|
+
|
|
143
|
+
### General
|
|
144
|
+
- [ ] No secrets/API keys in committed code
|
|
145
|
+
- [ ] `.snyk` exclusions documented with mitigation rationale
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
122
149
|
### Step FINAL: Record Review Learnings
|
|
123
150
|
|
|
124
151
|
After processing review feedback, ALWAYS update `.cm/CONTINUITY.md`:
|
|
@@ -245,6 +245,44 @@ After EVERY phase, you MUST:
|
|
|
245
245
|
|
|
246
246
|
---
|
|
247
247
|
|
|
248
|
+
## Security Rules (Learned: March 2026)
|
|
249
|
+
|
|
250
|
+
> **Code that touches files, subprocesses, or the DOM MUST follow these rules. No exceptions.**
|
|
251
|
+
|
|
252
|
+
### Frontend — DOM Safety
|
|
253
|
+
|
|
254
|
+
| Pattern | Risk | Fix |
|
|
255
|
+
|---------|------|-----|
|
|
256
|
+
| `innerHTML = \`...\${data}...\`` | DOM XSS | `innerHTML = \`...\${esc(data)}...\`` |
|
|
257
|
+
| `innerHTML = variable` | DOM XSS | `textContent = variable` |
|
|
258
|
+
| `eval(input)` / `new Function(input)` | Code injection | Avoid entirely |
|
|
259
|
+
| `document.write(data)` | DOM XSS | Use DOM API |
|
|
260
|
+
| `el.setAttribute('on*', data)` | Event injection | `el.addEventListener()` |
|
|
261
|
+
|
|
262
|
+
**Always:** Escape before innerHTML, prefer `textContent`, validate URLs via allowlist.
|
|
263
|
+
|
|
264
|
+
### Backend — Python
|
|
265
|
+
|
|
266
|
+
| Pattern | Risk | Fix |
|
|
267
|
+
|---------|------|-----|
|
|
268
|
+
| `Path(user_input) / "file"` | Path Traversal | `safe_resolve(base, user_input)` |
|
|
269
|
+
| `subprocess.run(f"cmd {arg}", shell=True)` | Command Injection | `subprocess.run(["cmd", arg])` |
|
|
270
|
+
| `open(config["path"])` | Path Traversal | `safe_open(base, config["path"])` |
|
|
271
|
+
| `json.load()` → paths unvalidated | Path Traversal | Validate ALL paths from config via `safe_resolve()` |
|
|
272
|
+
|
|
273
|
+
**Always:** Import `safe_path`, validate EVERY path from CLI/config/API against a base directory.
|
|
274
|
+
|
|
275
|
+
### Backend — Express/Node
|
|
276
|
+
|
|
277
|
+
| Pattern | Risk | Fix |
|
|
278
|
+
|---------|------|-----|
|
|
279
|
+
| Missing `app.disable('x-powered-by')` | Info leak | Add after `express()` |
|
|
280
|
+
| No body size limit | DoS | `express.json({ limit: '1mb' })` |
|
|
281
|
+
| `path.resolve(userInput)` without validation | Path Traversal | Check null bytes + `relative_to(baseDir)` |
|
|
282
|
+
| `Object.assign(config, userInput)` | Prototype Pollution | Filter `__proto__`, `constructor` keys |
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
|
|
248
286
|
## Integration
|
|
249
287
|
|
|
250
288
|
| Skill | When |
|
|
@@ -35,6 +35,10 @@ description: "You MUST use this before any creative work or multi-step task. Exp
|
|
|
35
35
|
- Must-haves vs nice-to-haves
|
|
36
36
|
- Edge cases to handle
|
|
37
37
|
- Edge cases to explicitly NOT handle
|
|
38
|
+
- **Security (if frontend):** How will dynamic data be rendered?
|
|
39
|
+
- `textContent` (preferred) or `innerHTML` with `escapeHtml()`?
|
|
40
|
+
- Is `sanitize.js` loaded in all affected HTML pages?
|
|
41
|
+
- Are URLs/params validated against allowlists?
|
|
38
42
|
|
|
39
43
|
4. **Skill Coverage Audit** — Do I have the right skills?
|
|
40
44
|
- List all technologies/frameworks/tools referenced in the scope
|
|
@@ -46,12 +46,18 @@ description: Use when starting any new project from scratch. Asks for project id
|
|
|
46
46
|
|
|
47
47
|
## Phase 0.5: Security Foundation 🛡️
|
|
48
48
|
|
|
49
|
-
> Calls `cm-secret-shield` for setup.
|
|
49
|
+
> Calls `cm-secret-shield` for setup + adds code-level security utilities.
|
|
50
50
|
|
|
51
51
|
1. Create `.gitleaks.toml` with Supabase + generic high-entropy rules
|
|
52
52
|
2. Setup pre-commit hook (`.git/hooks/pre-commit`) — scans staged files
|
|
53
53
|
3. Add `security:scan` script to `package.json`
|
|
54
54
|
4. Create `.dev.vars.example` template (committed). `.dev.vars` = real secrets (gitignored)
|
|
55
|
+
5. **[NEW] Security Utilities (Learned: March 2026):**
|
|
56
|
+
- **Python projects:** Copy `safe_path.py` to `scripts/` — provides `safe_resolve()`, `safe_join()`, `safe_open()` for path traversal prevention
|
|
57
|
+
- **JS/TS frontend:** Add `esc()` function to sanitize HTML — prevent DOM XSS
|
|
58
|
+
- **Express apps:** Add `app.disable('x-powered-by')` + `express.json({ limit: '1mb' })`
|
|
59
|
+
- **Create `.snyk`** policy file for managing false positives
|
|
60
|
+
- **Rule:** ALL paths from CLI/config/API → `safe_resolve()`. ALL innerHTML → `esc()`. No exceptions.
|
|
55
61
|
|
|
56
62
|
## Phase 1: Project Type Detection 🔍
|
|
57
63
|
|
|
@@ -133,6 +133,32 @@ Setting up or enhancing test suites for projects with frontend JavaScript/TypeSc
|
|
|
133
133
|
| 5. Corruption Patterns | Known bad patterns (empty functions, truncation) | Required |
|
|
134
134
|
| 6. Import/Export | Module references resolve | Recommended |
|
|
135
135
|
| 7. CSS Validation | CSS files parse correctly | Recommended |
|
|
136
|
+
| 8. XSS/Injection Safety | No unescaped innerHTML with dynamic data | **CRITICAL** |
|
|
137
|
+
|
|
138
|
+
### Layer 8: XSS/Injection Safety (Learned: March 2026)
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
import { execSync } from 'child_process';
|
|
142
|
+
|
|
143
|
+
test('no unescaped innerHTML with dynamic data', () => {
|
|
144
|
+
// Scan all JS files for innerHTML with template literals NOT using escape
|
|
145
|
+
const result = execSync(
|
|
146
|
+
`grep -rn 'innerHTML.*\\\${' public/js/*.js | grep -v 'esc\\|SecurityUtils' || true`,
|
|
147
|
+
{ encoding: 'utf-8' }
|
|
148
|
+
);
|
|
149
|
+
expect(result.trim()).toBe(''); // Must be empty = all escaped
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
test('sanitize.js loaded in all HTML pages', () => {
|
|
153
|
+
const htmlFiles = execSync('ls public/*.html', { encoding: 'utf-8' }).trim().split('\n');
|
|
154
|
+
for (const file of htmlFiles) {
|
|
155
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
156
|
+
if (content.includes('kit.js')) {
|
|
157
|
+
expect(content).toContain('sanitize.js'); // Must load before kit.js
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
```
|
|
136
162
|
|
|
137
163
|
### Setup
|
|
138
164
|
|
|
@@ -205,6 +231,32 @@ After all gates execute, output a numeric quality score:
|
|
|
205
231
|
|
|
206
232
|
---
|
|
207
233
|
|
|
234
|
+
### Gate 6: Security Scan (Snyk Code) (Added: March 2026)
|
|
235
|
+
|
|
236
|
+
> Run SAST scan to catch path traversal, XSS, injection, and other vulnerabilities BEFORE deploy.
|
|
237
|
+
|
|
238
|
+
```bash
|
|
239
|
+
# If snyk CLI installed:
|
|
240
|
+
snyk code test --severity-threshold=high
|
|
241
|
+
|
|
242
|
+
# Gate decision:
|
|
243
|
+
# 0 HIGH findings → proceed
|
|
244
|
+
# Any HIGH findings → STOP. Fix before deploy.
|
|
245
|
+
# MEDIUM findings → review, add to .snyk if mitigated
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**When findings are false positives:**
|
|
249
|
+
1. Verify the mitigation is real (e.g., `safe_resolve()` for path traversal, `esc()` for XSS)
|
|
250
|
+
2. Add to `.snyk` exclude with documentation explaining the mitigation
|
|
251
|
+
3. Never suppress without documenting WHY
|
|
252
|
+
|
|
253
|
+
**Scoring:**
|
|
254
|
+
| Component | Max | How to Score |
|
|
255
|
+
|-----------|-----|-------------|
|
|
256
|
+
| Security Scan | 10 | 10 = 0 HIGH, −5 per HIGH, −1 per unreviewed MEDIUM |
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
208
260
|
## Integration
|
|
209
261
|
| Skill | Relationship |
|
|
210
262
|
|-------|-------------|
|
package/skills/cm-tdd/SKILL.md
CHANGED
|
@@ -360,6 +360,44 @@ Bug found? Write failing test reproducing it. Follow TDD cycle. Test proves fix
|
|
|
360
360
|
|
|
361
361
|
Never fix bugs without a test.
|
|
362
362
|
|
|
363
|
+
## Security TDD (Learned: March 2026)
|
|
364
|
+
|
|
365
|
+
> **Security bugs get tests too.** Every XSS, path traversal, or injection fix starts with a failing test.
|
|
366
|
+
|
|
367
|
+
### Example: XSS Prevention
|
|
368
|
+
|
|
369
|
+
**RED**
|
|
370
|
+
```javascript
|
|
371
|
+
test('escapeHtml prevents script injection', () => {
|
|
372
|
+
const malicious = '<script>alert("xss")</script>';
|
|
373
|
+
const result = escapeHtml(malicious);
|
|
374
|
+
expect(result).not.toContain('<script>');
|
|
375
|
+
expect(result).toContain('<script>');
|
|
376
|
+
});
|
|
377
|
+
|
|
378
|
+
test('no unescaped innerHTML with dynamic data in JS files', () => {
|
|
379
|
+
const result = execSync(
|
|
380
|
+
`grep -rn 'innerHTML.*\\\${' public/js/*.js | grep -v 'esc\\|SecurityUtils' || true`,
|
|
381
|
+
{ encoding: 'utf-8' }
|
|
382
|
+
);
|
|
383
|
+
expect(result.trim()).toBe('');
|
|
384
|
+
});
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Example: Path Traversal Prevention
|
|
388
|
+
|
|
389
|
+
**RED**
|
|
390
|
+
```python
|
|
391
|
+
def test_safe_resolve_blocks_traversal():
|
|
392
|
+
with pytest.raises(ValueError, match="Path traversal detected"):
|
|
393
|
+
safe_resolve("/app/data", "../../etc/passwd")
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Rule
|
|
397
|
+
- **Every security fix = failing test first**
|
|
398
|
+
- Test the ATTACK, not just the happy path
|
|
399
|
+
- Security regression tests are permanent — never delete
|
|
400
|
+
|
|
363
401
|
## Final Rule
|
|
364
402
|
|
|
365
403
|
```
|