codymaster 4.1.0 → 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 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.use(express_1.default.json());
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.0",
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": {
@@ -18,7 +18,6 @@
18
18
  },
19
19
  "scripts": {
20
20
  "build": "tsc",
21
- "prepare": "npm run build",
22
21
  "start": "ts-node src/index.ts",
23
22
  "test:gate": "vitest run --reporter=verbose",
24
23
  "build:html": "node scripts/inject-header.js && node scripts/inject-footer.js && node scripts/inject-ga.js",
@@ -60,20 +59,20 @@
60
59
  "access": "public"
61
60
  },
62
61
  "dependencies": {
63
- "@clack/prompts": "^1.1.0",
64
- "@types/node": "^25.5.0",
65
62
  "chalk": "^5.6.2",
66
63
  "commander": "^14.0.3",
67
64
  "express": "^5.2.1",
68
- "prompts": "^2.4.2",
69
- "ts-node": "^10.9.2",
70
- "typescript": "^5.9.3"
65
+ "prompts": "^2.4.2"
71
66
  },
72
67
  "devDependencies": {
68
+ "@clack/prompts": "^1.1.0",
73
69
  "@types/express": "^5.0.6",
70
+ "@types/node": "^25.5.0",
74
71
  "@types/prompts": "^2.4.9",
75
72
  "acorn": "^8.16.0",
76
73
  "jsdom": "^29.0.1",
74
+ "ts-node": "^10.9.2",
75
+ "typescript": "^5.9.3",
77
76
  "vitest": "^4.1.0"
78
77
  }
79
- }
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
  |-------|-------------|
@@ -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('&lt;script&gt;');
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
  ```