codeprobe-scanner 1.0.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 (96) hide show
  1. package/.claude/settings.local.json +19 -0
  2. package/.dockerignore +17 -0
  3. package/.env.development +8 -0
  4. package/.env.example +20 -0
  5. package/.env.setup +214 -0
  6. package/.github/workflows/codeprobe-scan.yml +137 -0
  7. package/.github/workflows/codeprobe.yml +84 -0
  8. package/.github/workflows/scan-schedule.yml +28 -0
  9. package/ANALYSIS_SUMMARY.md +365 -0
  10. package/API_INTEGRATIONS.md +469 -0
  11. package/BUILD_PLAYBOOK.md +349 -0
  12. package/CLAUDE.md +106 -0
  13. package/DEPLOY.md +452 -0
  14. package/DEPLOYMENT_STATUS.md +240 -0
  15. package/DEPLOY_CHECKLIST.md +316 -0
  16. package/Dockerfile +24 -0
  17. package/EXECUTION_PLAN.html +1086 -0
  18. package/IMPLEMENTATION_COMPLETE.md +288 -0
  19. package/IMPLEMENTATION_SUMMARY.md +443 -0
  20. package/INTERACTIVE_FIX_FLOW.md +308 -0
  21. package/MIGRATION_COMPLETE.md +327 -0
  22. package/ORCHESTRATOR_SYNTHESIS.json +80 -0
  23. package/PENDING_WORK.md +308 -0
  24. package/PREFLIGHT_PLAN.md +182 -0
  25. package/QUICKSTART.md +305 -0
  26. package/README.md +15 -0
  27. package/STAGE_1_SETUP_ENGINE.md +245 -0
  28. package/STAGE_2_ARCHITECTURE.md +714 -0
  29. package/STAGE_2_CLI_VERIFICATION.md +269 -0
  30. package/STAGE_2_COMPLETE.md +332 -0
  31. package/STAGE_2_IMPLEMENTATION_PLAN.md +679 -0
  32. package/STAGE_3_COMPLETE.md +246 -0
  33. package/STAGE_3_DASHBOARD_POLISH.md +371 -0
  34. package/STAGE_3_SETUP.md +155 -0
  35. package/VIDEODB_INTEGRATION.md +237 -0
  36. package/archived/DASHBOARD_UI_WALKTHROUGH.md +392 -0
  37. package/archived/FRONTEND_SETUP.md +236 -0
  38. package/archived/auth.ts +40 -0
  39. package/archived/dashboard/components/BusinessImpactCard.tsx +48 -0
  40. package/archived/dashboard/components/CVETable.tsx +104 -0
  41. package/archived/dashboard/components/ErrorBoundary.tsx +48 -0
  42. package/archived/dashboard/components/PatchDiffViewer.tsx +43 -0
  43. package/archived/dashboard/components/RiskGauge.tsx +64 -0
  44. package/archived/dashboard/frontend.tsx +104 -0
  45. package/archived/dashboard/hooks/useAuth.ts +32 -0
  46. package/archived/dashboard/hooks/useScan.ts +65 -0
  47. package/archived/dashboard/index.html +15 -0
  48. package/archived/dashboard/pages/LoginPage.tsx +28 -0
  49. package/archived/dashboard/pages/ScanDetailPage.tsx +143 -0
  50. package/archived/dashboard/pages/ScansListPage.tsx +160 -0
  51. package/bin/install-and-run.sh +91 -0
  52. package/bun.lock +603 -0
  53. package/codeprobe-prd.md +674 -0
  54. package/cve-cache.json +25 -0
  55. package/demo-vulnerable-app/.github/workflows/codeprobe.yml +32 -0
  56. package/demo-vulnerable-app/README.md +70 -0
  57. package/demo-vulnerable-app/package-lock.json +27 -0
  58. package/demo-vulnerable-app/package.json +15 -0
  59. package/demo-vulnerable-app/server.js +34 -0
  60. package/demo.sh +45 -0
  61. package/index.ts +19 -0
  62. package/package.json +28 -0
  63. package/patches.json +12 -0
  64. package/serve-dashboard.ts +23 -0
  65. package/src/api/server-cli.ts +270 -0
  66. package/src/api/server.ts +293 -0
  67. package/src/bot/server.ts +113 -0
  68. package/src/cli/commands/report.ts +92 -0
  69. package/src/cli/commands/scan-with-fix.ts +123 -0
  70. package/src/cli/commands/scan.ts +137 -0
  71. package/src/cli/config.ts +188 -0
  72. package/src/cli/errors.ts +120 -0
  73. package/src/cli/index.ts +137 -0
  74. package/src/cli/progress.ts +119 -0
  75. package/src/cli-server.ts +523 -0
  76. package/src/engine/index.ts +90 -0
  77. package/src/engine/matcher.ts +115 -0
  78. package/src/engine/parser.ts +91 -0
  79. package/src/engine/patcher.ts +280 -0
  80. package/src/engine/report.ts +137 -0
  81. package/src/engine/sandbox.ts +222 -0
  82. package/src/engine/scraper.ts +122 -0
  83. package/src/integrations/videodb.ts +153 -0
  84. package/src/mcp/server.ts +149 -0
  85. package/src/scraper-cron.ts +103 -0
  86. package/src/shared/constants.ts +88 -0
  87. package/src/shared/types.ts +123 -0
  88. package/src/shared/utils.ts +80 -0
  89. package/src/test/cli.test.ts +211 -0
  90. package/src/test/dashboard.test.ts +38 -0
  91. package/src/test/demo-scan.json +32 -0
  92. package/src/test/engine.test.ts +157 -0
  93. package/tailwind.config.js +11 -0
  94. package/tsconfig.json +30 -0
  95. package/verify-dashboard.ts +87 -0
  96. package/verify-env.sh +98 -0
@@ -0,0 +1,679 @@
1
+ # CodeProbe Stage 2: Detailed Implementation Plan
2
+ **CLI + Verification + Fallbacks**
3
+
4
+ **Status**: Ready for execution (pending token encryption decision)
5
+ **Duration**: 2–4 hours (with Stage 1 contract locked)
6
+ **Dependencies**: Stage 1 engine interface finalized
7
+
8
+ ---
9
+
10
+ ## Executive Summary
11
+
12
+ Stage 2 (CLI + Verification) is a **2-4 hour deliverable IF Stage 1 is complete**. The critical blocker is not the CLI code itself but Stage 1's core engine exports. This plan:
13
+
14
+ 1. Front-loads the **interface contract** that Stage 2 codes against
15
+ 2. Enables **parallel work** with mocked engines (CLI surface buildable before Stage 1 finishes)
16
+ 3. Flags the **encryption decision** (SHA256 is broken — needs real choice)
17
+ 4. Addresses all **ORCHESTRATOR risks** inline with concrete mitigations
18
+ 5. Provides **hour-by-hour breakdown** with file names + test strategy
19
+
20
+ **Timeline Assessment**: 2-3h CLI surface + 30m Stage 1 integration = 3-4h total Stage 2 (honest estimate, vs 2-4h in original spec)
21
+
22
+ ---
23
+
24
+ ## Part 1: Stage 1 Dependency Contract
25
+
26
+ ### 1.1 Interface Specification (Stage 2 Codes Against This)
27
+
28
+ **File: `/src/engine/index.ts`** — Stage 1 must export:
29
+
30
+ ```typescript
31
+ // Event emitter: Core integration seam for Stage 2 progress.ts
32
+ export interface ScanEvent {
33
+ phase:
34
+ | 'parsing'
35
+ | 'scraping'
36
+ | 'matching'
37
+ | 'sandboxing'
38
+ | 'verification'
39
+ | 'patching'
40
+ | 'report';
41
+ status: 'start' | 'progress' | 'complete' | 'error';
42
+ message: string;
43
+ timestamp: string;
44
+ level: 'info' | 'warn' | 'error' | 'success';
45
+ metadata?: Record<string, unknown>;
46
+ }
47
+
48
+ // Core types (from src/shared/types.ts)
49
+ export type Scan = {
50
+ id: string;
51
+ timestamp: string;
52
+ repo_url: string;
53
+ cves: CVE[];
54
+ risk_score: number; // 0-10
55
+ patches_available: number;
56
+ };
57
+
58
+ export type CVE = {
59
+ id: string;
60
+ package: string;
61
+ version_vulnerable: string;
62
+ severity: 'CRITICAL' | 'HIGH' | 'MEDIUM' | 'LOW';
63
+ cvss: number; // 0.0-10.0
64
+ exploitable: boolean; // Key: Stage 2 reads this
65
+ exploit_evidence: string; // sandbox stdout
66
+ patch_diff?: string;
67
+ patch_version?: string;
68
+ };
69
+
70
+ export type Report = {
71
+ scan: Scan;
72
+ summary: {
73
+ exploitable_count: number;
74
+ theoretical_count: number;
75
+ };
76
+ };
77
+
78
+ // Main entry point Stage 2 calls
79
+ export async function runFullScan(
80
+ repoPath: string,
81
+ options?: {
82
+ verbose?: boolean;
83
+ onEvent?: (event: ScanEvent) => void;
84
+ }
85
+ ): Promise<Report>;
86
+ ```
87
+
88
+ **Stage 1 Delivery Checklist:**
89
+ - ✓ `runFullScan()` returns valid `Report` matching type schema
90
+ - ✓ Event emitter fires events with correct `ScanEvent` shape
91
+ - ✓ CVE.exploitable boolean correctly reflects sandbox success/failure
92
+ - ✓ Report saved to `~/.codeprobe/scans/{id}.json`
93
+ - ✓ `latest.json` symlink updated by engine
94
+
95
+ ---
96
+
97
+ ### 1.2 Critical Gate: Token Storage (DECISION REQUIRED)
98
+
99
+ **PROBLEM**: STAGE_2_CLI_VERIFICATION.md lines 99-102 claim "Encryption: SHA256 + salt"
100
+
101
+ SHA256 is **one-way hash** — you cannot recover a GitHub token from `SHA256(token + salt)`. Token must be retrievable for `git push` in `--fix`.
102
+
103
+ **Options (Choose One):**
104
+
105
+ | Option | Security | Complexity | Cross-Platform |
106
+ |--------|----------|-----------|-----------------|
107
+ | **A: OS Keychain** | Best | Medium | No (macOS/Linux only) |
108
+ | **B: AES-256-GCM** | Good | Medium | Yes |
109
+ | **C: Plaintext + 0600** | Poor | Low | Yes |
110
+
111
+ **Recommended (MVP)**: **Option B (AES-256-GCM with machine ID)**
112
+ - Works cross-platform (no system setup required)
113
+ - Reasonable security for MVP
114
+ - Fallback to plaintext at runtime if key derivation fails
115
+
116
+ **User Decision Needed:** Confirm choice before implementing `config.ts`
117
+
118
+ ---
119
+
120
+ ## Part 2: Hourly Breakdown
121
+
122
+ ### Stage 2 Can Start Immediately (No Stage 1 Dependency)
123
+
124
+ These tasks are buildable right now with mocked engine:
125
+
126
+ - ✓ `config.ts` — local filesystem only
127
+ - ✓ `progress.ts` — mock events
128
+ - ✓ `errors.ts` — generic error handling
129
+ - ✓ Unit tests with mocked engine
130
+ - ✓ CLI entry point skeleton
131
+
132
+ ### Stage 2 Blocked Until Stage 1 Delivers
133
+
134
+ - ✗ `scan.ts` full implementation (needs `runFullScan()`)
135
+ - ✗ `scan-with-fix.ts` (needs Stage 1 patcher + sandbox)
136
+ - ✗ E2E test (`demo.sh` with real exploit)
137
+ - ✗ Acceptance criteria validation
138
+
139
+ ---
140
+
141
+ ### Hour-by-Hour Breakdown
142
+
143
+ #### **HOUR 0: Setup & Contract Lock (30 min)**
144
+
145
+ **Deliverables:**
146
+ - Confirm Stage 1 contract matches spec above
147
+ - **Lock encryption decision** (A, B, or C)
148
+ - Scaffold project structure
149
+
150
+ **Files:**
151
+ - `/src/cli/index.ts` (empty stub)
152
+ - `/src/cli/config.ts` (empty stub)
153
+ - `/src/cli/commands/scan.ts` (empty stub)
154
+ - `/src/cli/progress.ts` (empty stub)
155
+ - `/src/cli/errors.ts` (empty stub)
156
+ - `/src/test/cli.test.ts` (empty stub)
157
+ - `package.json`: add deps (chalk, table-cli, dayjs, zod, axios)
158
+
159
+ **Parallel Start**: Stage 1 team begins parser + scraper
160
+
161
+ ---
162
+
163
+ #### **HOUR 1: CLI Bootstrap + Config (60 min)**
164
+
165
+ **Deliverables:**
166
+
167
+ 1. **`config.ts`** (20 min)
168
+ - Load/save `~/.codeprobe/config.json`
169
+ - Encrypt GitHub token (using chosen method from Hour 0 decision)
170
+ - Methods: `getConfig()`, `setConfig()`, `clearConfig()`
171
+ - Env var fallback: `BRIGHT_DATA_API_KEY` precedence over config file
172
+
173
+ 2. **`index.ts`** (15 min)
174
+ - Entry point: dispatch commands (scan, report, help)
175
+ - Exit codes: 0=success, 1=vulns, 2=failed
176
+ - Usage text for no args
177
+
178
+ 3. **`scan.ts` skeleton** (15 min)
179
+ - Parse CLI args (repo path, defaults to `.`)
180
+ - Stub that shows placeholder output
181
+ - Test: `bun run src/cli/index.ts scan .` exits 0
182
+
183
+ 4. **`progress.ts` + `errors.ts` stubs** (10 min)
184
+ - Mock event handler
185
+ - Generic error categorization
186
+
187
+ ---
188
+
189
+ #### **HOUR 2: Real-Time Output + Error Handling (60 min)**
190
+
191
+ **Deliverables:**
192
+
193
+ 1. **`progress.ts`** (20 min)
194
+ - Consume Stage 1 events
195
+ - Format → CLI output (colors, timestamps)
196
+ - Example: "[12:34:56] ✓ Found 3 CVEs"
197
+
198
+ 2. **`errors.ts`** (20 min)
199
+ - Catch errors, map to friendly messages
200
+ - Fallback triggers: Bright Data timeout → cache, Daytona crash → continue
201
+ - All errors logged + user guidance shown
202
+
203
+ 3. **`scan.ts` (full)** (15 min)
204
+ - Implement: parse → runFullScan → format → save → exit
205
+ - Handle `--json` and `--verbose` flags
206
+ - Test with mocked engine
207
+
208
+ 4. **Unit tests with mocked engine** (5 min)
209
+ - `test("scan exits 1 on vulns found")`
210
+ - `test("--json outputs valid JSON")`
211
+ - Run: `bun test src/test/cli.test.ts`
212
+
213
+ **Can run in parallel**: Stage 1 on sandbox + reporting
214
+
215
+ ---
216
+
217
+ #### **HOUR 3: Fallbacks + Git Integration (90 min)**
218
+
219
+ **Deliverables:**
220
+
221
+ 1. **`scan-with-fix.ts`** (40 min)
222
+ - Scan first → extract exploitable CVEs
223
+ - Git flow: check status, create branch, commit patches
224
+ - Error handling: dirty repo, patch apply fails
225
+ - Test with mocked engine + mocked git
226
+
227
+ 2. **Integration tests** (30 min)
228
+ - `test("--fix creates git branch")`
229
+ - `test("fallback: Bright Data fails → cache used")`
230
+ - `test("error: dirty repo → abort")`
231
+ - Run: `bun test src/test/cli.test.ts` (all 9+ tests)
232
+
233
+ 3. **`report.ts`** (15 min — can defer to Hour 3.5)
234
+ - Read `~/.codeprobe/scans/latest.json`
235
+ - Format as table
236
+ - Test formatting
237
+
238
+ 4. **Edge cases + polishing** (5 min)
239
+ - Config edge cases
240
+ - Permission checks
241
+ - Error message quality
242
+
243
+ ---
244
+
245
+ #### **HOUR 3.5–4: E2E Test + Demo Rehearsal (60 min, AFTER Stage 1)**
246
+
247
+ **Deliverables:**
248
+
249
+ 1. **E2E Integration Test** (20 min)
250
+ - File: `/src/test/e2e.cli.test.ts`
251
+ - Test: `bun run src/cli/index.ts scan ./demo-vulnerable-app`
252
+ - Assertions:
253
+ - Exit code = 1 (vulns found)
254
+ - Output contains "CVE-2023-44487"
255
+ - Output contains "CONFIRMED EXPLOITABLE"
256
+ - `~/.codeprobe/scans/latest.json` exists
257
+ - Run: `bun test src/test/e2e.cli.test.ts`
258
+ - **BLOCKER**: Requires Stage 1 working
259
+
260
+ 2. **Demo Script** (15 min)
261
+ - File: `/demo.sh`
262
+ - Clear cache, run scan, show report, verify branch
263
+ - Time it: `time bash demo.sh` (target <3 min)
264
+
265
+ 3. **Rehearsal** (25 min)
266
+ - Run demo 3-5 times
267
+ - Measure actual timing per phase
268
+ - Record fallback video (e.g., Bright Data timeout)
269
+
270
+ ---
271
+
272
+ ## Part 3: Parallel Work Diagram
273
+
274
+ ```
275
+ Hour 0: Setup
276
+ ├─ Stage 1: Parser + Scraper (1-2h)
277
+ └─ Stage 2: Config + CLI skeleton (immediate)
278
+
279
+ Hour 1: CLI Bootstrap
280
+ ├─ Stage 1: Sandbox integration (45m)
281
+ └─ Stage 2: Config + progress + errors (60m, parallel)
282
+
283
+ Hour 2: Integration
284
+ ├─ Stage 1: Report builder (30m)
285
+ └─ Stage 2: Full scan command + unit tests (60m)
286
+
287
+ Hour 3: Fallbacks + Git
288
+ ├─ Stage 1: Patcher + final polish (30m, done)
289
+ └─ Stage 2: --fix command + integration tests (90m)
290
+
291
+ Hour 3.5+: E2E + Demo (after both complete)
292
+ ├─ Stage 2 E2E test (20m, requires Stage 1 ready)
293
+ └─ Demo rehearsal (45m)
294
+
295
+ Total: 3.5–4h wall time (if parallelized)
296
+ Critical Path: Stage 1 engine (blocks E2E)
297
+ ```
298
+
299
+ ---
300
+
301
+ ## Part 4: Addressing ORCHESTRATOR Risks
302
+
303
+ ### 4.1 Timeline Risk: "5h vs 12-24h needed"
304
+
305
+ **Assessment:**
306
+ - **Stage 2 alone**: 2-3h (CLI + tests)
307
+ - **Stage 1 alone**: 2-4h (engine)
308
+ - **Combined (parallel)**: 3-4h (both teams)
309
+ - **Plus dashboard**: +2-3h (not in this scope)
310
+ - **Plus GitHub bot**: +2-3h (not in this scope)
311
+
312
+ **Honest Timeline**: Original 5h for MVP is unrealistic if dashboard + bot included. But **Stage 2 CLI alone is 3-4h**, which fits.
313
+
314
+ **Cuts if time tight**:
315
+ 1. Drop `report.ts` command (keep scan only)
316
+ 2. Skip fancy progress bar (keep simple ASCII)
317
+ 3. Skip PDF export (not in Stage 2 anyway)
318
+
319
+ ---
320
+
321
+ ### 4.2 Test Infrastructure Risk: "Zero test infrastructure"
322
+
323
+ **Stage 2 Test Coverage:**
324
+
325
+ | Test | File | Type | Status |
326
+ |------|------|------|--------|
327
+ | CLI entry point | cli.test.ts | Unit | ✓ Can run now |
328
+ | Config encryption | cli.test.ts | Unit | ⏳ Pending encryption decision |
329
+ | Error handling | cli.test.ts | Unit | ✓ Can run now |
330
+ | Progress formatting | cli.test.ts | Unit | ✓ Mock events |
331
+ | Scan command (mocked) | cli.test.ts | Integration | ✓ Can run now |
332
+ | --fix command (mocked) | cli.test.ts | Integration | ✓ Can run now |
333
+ | Fallback: cache | cli.test.ts | Integration | ✓ Mock timeout |
334
+ | Fallback: sandbox | cli.test.ts | Integration | ✓ Mock crash |
335
+ | **E2E (real engine)** | e2e.cli.test.ts | E2E | ✗ Blocked on Stage 1 |
336
+ | **Demo timing** | (bash script) | Manual | ✗ Blocked on Stage 1 |
337
+
338
+ **Success Criteria:**
339
+ - `bun test src/test/cli.test.ts` all pass (mocked, runnable now)
340
+ - `bun test src/test/e2e.cli.test.ts` all pass (real engine, after Stage 1)
341
+ - `demo.sh` completes <3 min (after Stage 1)
342
+
343
+ ---
344
+
345
+ ### 4.3 Security Risk: "Dashboard auth undefined, Dashboard public"
346
+
347
+ **Stage 2 Scope**: Store scans locally with file permissions:
348
+
349
+ ```ts
350
+ // In report.ts after saving
351
+ fs.chmodSync(scanPath, 0o600); // readable/writable by owner only
352
+ ```
353
+
354
+ **API Key Precedence** (Stage 2):
355
+ 1. Env vars first (BRIGHT_DATA_API_KEY, etc.)
356
+ 2. Config file fallback
357
+ 3. If neither: error with helpful message
358
+
359
+ **Auth/Dashboard**: Stage 3 responsibility (GitHub OAuth, session management)
360
+
361
+ ---
362
+
363
+ ### 4.4 Patch Validation Risk: "Pre-baked patches OK, but what validates?"
364
+
365
+ **Responsibility Split:**
366
+
367
+ | Gate | Owner | How |
368
+ |------|-------|-----|
369
+ | Patch compiles | **Stage 1** | patcher.ts runs compiler |
370
+ | Re-run PoC | **Stage 1** | patcher.ts verifies fix works |
371
+ | **Patch applies cleanly** | **Stage 2** | scan-with-fix.ts runs `git apply --check` |
372
+ | User reviews before merge | User | Manual PR review |
373
+
374
+ **Stage 2 Specific**: Do NOT blindly apply patches. Validate with `git apply --check` first. If fails: show error + suggest manual review.
375
+
376
+ ---
377
+
378
+ ## Part 5: Security & Encryption Decision
379
+
380
+ ### 5.1 GitHub Token Storage (CRITICAL BLOCKER)
381
+
382
+ **Three Options** (User Chooses One):
383
+
384
+ **Option A: OS Keychain**
385
+ ```
386
+ Pros:
387
+ - Most secure (OS-managed storage)
388
+ - Standard practice (used by git, GitHub CLI)
389
+ Cons:
390
+ - Requires system setup
391
+ - Linux: libsecret (extra dependency)
392
+ - May fail in headless/Docker environments
393
+ - Migration to new machine requires re-auth
394
+ ```
395
+
396
+ **Option B: AES-256-GCM with Machine ID** (RECOMMENDED)
397
+ ```
398
+ Pros:
399
+ - Cross-platform (works on all OSes)
400
+ - No system setup required
401
+ - Reasonable security (symmetric encryption)
402
+ - Fallback to plaintext if key derivation fails
403
+ Cons:
404
+ - Key derived from machine fingerprint
405
+ - Migration requires re-auth
406
+ - Bun native crypto support (bun:crypto)
407
+ ```
408
+
409
+ **Option C: Plaintext + 0600 Permissions**
410
+ ```
411
+ Pros:
412
+ - Simplest (MVP honest)
413
+ - No extra dependencies
414
+ - Works immediately
415
+ Cons:
416
+ - Secret stored on disk unencrypted
417
+ - Anyone with filesystem access can read it
418
+ - Not suitable for production
419
+ - Only acceptable for hackathon MVP
420
+ ```
421
+
422
+ **Recommended Choice**: **Option B (AES-256-GCM)**
423
+
424
+ ---
425
+
426
+ ### 5.2 File Permissions (Stage 2 Specific)
427
+
428
+ ```ts
429
+ // ~/.codeprobe/ directory permissions
430
+ fs.mkdirSync(path.join(os.homedir(), '.codeprobe', 'scans'), {
431
+ mode: 0o700, // drwx------: only owner can read/write/execute
432
+ recursive: true
433
+ });
434
+
435
+ // Scan result file permissions
436
+ fs.writeFileSync(scanPath, JSON.stringify(report));
437
+ fs.chmodSync(scanPath, 0o600); // -rw------: only owner can read/write
438
+ ```
439
+
440
+ **Audit Test:**
441
+ ```bash
442
+ ls -la ~/.codeprobe/
443
+ # Should show: drwx------ ... .codeprobe
444
+ # Should show: -rw------- ... scans/latest.json
445
+ ```
446
+
447
+ ---
448
+
449
+ ### 5.3 API Key Precedence (Config vs Environment)
450
+
451
+ ```ts
452
+ // src/cli/config.ts
453
+ export async function getApiKey(
454
+ service: 'BRIGHT_DATA' | 'DAYTONA' | 'NOSANA'
455
+ ): Promise<string> {
456
+ // 1. Check env var (takes precedence)
457
+ const envKey = process.env[`${service}_API_KEY`];
458
+ if (envKey) {
459
+ console.log(`[info] Using ${service} key from environment variable`);
460
+ return envKey;
461
+ }
462
+
463
+ // 2. Check config.json (falls back)
464
+ const config = await loadConfig();
465
+ const configKey = config[`${service.toLowerCase()}_api_key`];
466
+ if (configKey) {
467
+ console.log(`[info] Using ${service} key from ~/.codeprobe/config.json`);
468
+ return decryptToken(configKey); // using chosen encryption method
469
+ }
470
+
471
+ // 3. Neither found: throw helpful error
472
+ throw new Error(
473
+ `No ${service} API key found.\n` +
474
+ `Set env var: export ${service}_API_KEY=<key>\n` +
475
+ `Or run: codeprobe config set ${service}_API_KEY <key>`
476
+ );
477
+ }
478
+ ```
479
+
480
+ ---
481
+
482
+ ## Part 6: Known Risks + Mitigations
483
+
484
+ | Risk | Likelihood | Stage 2 Mitigation | Test |
485
+ |------|------------|-------------------|------|
486
+ | Bright Data timeout during demo | Medium | Log warning, use cache (cve-cache.json) | Mock timeout in unit test |
487
+ | Daytona sandbox slow | Low | Timeout 60s (Stage 1); mark failed, continue | Measure real startup time |
488
+ | Git repo dirty on --fix | Medium | Detect `git status`, warn user, abort | Mock dirty repo in test |
489
+ | Network failure mid-scan | Low | Graceful error + cache partial results | Mock network error in test |
490
+ | Bun startup cold (<5s) | Low | Pre-warm before demo (run once offline) | Measure: `time bun src/cli/index.ts --help` |
491
+ | Config encryption fails | Medium | Fall back to plaintext + warn at runtime | Test encrypt/decrypt roundtrip |
492
+ | Stage 1 slips past Hour 2 | **HIGH** | Build Stage 2 with mocks, delay E2E | Plan assumes Stage 1 ready by Hour 2 |
493
+ | Patch apply fails (conflict) | Low | Show failed diff, suggest manual merge | Mock conflicting patch in test |
494
+
495
+ ---
496
+
497
+ ## Part 7: Test Strategy
498
+
499
+ ### Test Coverage Matrix
500
+
501
+ ```
502
+ Layer | Test File | Type | Runnable Now?
503
+ ─────────────────────────────────────────────────────────────────────────
504
+ CLI entry point | cli.test.ts | Unit | Yes (stub)
505
+ Config read/write | cli.test.ts | Unit | Yes
506
+ Config encryption | cli.test.ts | Unit | ⏳ (pending decision)
507
+ Error handling | cli.test.ts | Unit | Yes
508
+ Progress formatting | cli.test.ts | Unit | Yes (mock events)
509
+ Scan command (mocked) | cli.test.ts | Integration | Yes
510
+ Report formatting | cli.test.ts | Unit | Yes (mock report)
511
+ --fix git flow (mocked) | cli.test.ts | Integration | Yes
512
+ Fallback: cache | cli.test.ts | Integration | Yes (mock timeout)
513
+ Fallback: sandbox crash | cli.test.ts | Integration | Yes (mock crash)
514
+ ─────────────────────────────────────────────────────────────────────────
515
+ End-to-End (real engine) | e2e.cli.test | E2E | No (Stage 1 blocker)
516
+ Demo script timing | (bash script) | Manual | No (Stage 1 blocker)
517
+ ```
518
+
519
+ ### Test Execution Plan
520
+
521
+ **Phase 1 (Hours 0-2, parallel with Stage 1):**
522
+ ```bash
523
+ # Test with mocked engine
524
+ bun test src/test/cli.test.ts
525
+ # Expected: ~12 tests pass (1 skipped if encryption pending)
526
+ ```
527
+
528
+ **Phase 2 (Hour 3+, after Stage 1 ready):**
529
+ ```bash
530
+ # End-to-end test
531
+ bun test src/test/e2e.cli.test.ts
532
+ # Expected: 3 tests pass (scan, report, --fix)
533
+ ```
534
+
535
+ **Phase 3 (Hour 3.5+, before demo):**
536
+ ```bash
537
+ # Full demo
538
+ bash demo.sh
539
+ # Expected: <3 minutes, no errors
540
+ time bash demo.sh
541
+ ```
542
+
543
+ ---
544
+
545
+ ## Part 8: Files to Create/Modify
546
+
547
+ ### NEW Files (Stage 2):
548
+
549
+ ```
550
+ src/cli/index.ts Main entry point
551
+ src/cli/commands/scan.ts `codeprobe scan` implementation
552
+ src/cli/commands/scan-with-fix.ts `codeprobe scan --fix` (git)
553
+ src/cli/commands/report.ts `codeprobe report` command
554
+ src/cli/config.ts Config + token management
555
+ src/cli/progress.ts Event → CLI output formatting
556
+ src/cli/errors.ts Error handling + fallbacks
557
+ src/shared/constants.ts API timeouts, paths, defaults
558
+ src/shared/utils.ts Helpers (format score, colorize, etc.)
559
+ src/test/cli.test.ts Unit + integration tests (mocked)
560
+ src/test/e2e.cli.test.ts E2E test (real engine)
561
+ demo.sh Demo script (bash)
562
+ .env.example Template for API keys
563
+ ```
564
+
565
+ ### MODIFY Files (Existing):
566
+
567
+ ```
568
+ package.json Add: chalk, table-cli, dayjs, zod, axios, crypto
569
+ Add bin: "codeprobe": "src/cli/index.ts"
570
+ tsconfig.json Ensure strict: true
571
+ ```
572
+
573
+ ### REFERENCE Files (Stage 1 Output):
574
+
575
+ ```
576
+ src/engine/index.ts runFullScan, ScanEvent interface
577
+ src/shared/types.ts Report, CVE, Scan types
578
+ cve-cache.json Fallback CVE data
579
+ patches.json Pre-baked patches
580
+ demo-vulnerable-app/ Demo repo
581
+ ```
582
+
583
+ ---
584
+
585
+ ## Part 9: Acceptance Criteria (Stage 2)
586
+
587
+ **Must Pass (Non-Negotiable):**
588
+
589
+ 1. ✓ `bun test src/test/cli.test.ts` all pass (unit + integration with mocks)
590
+ 2. ✓ `bun run src/cli/index.ts scan ./demo-vulnerable-app` exits code 1 (vulns found)
591
+ 3. ✓ Output includes "CVE-2023-44487" and "CONFIRMED EXPLOITABLE"
592
+ 4. ✓ JSON report saved to `~/.codeprobe/scans/{id}.json` with valid schema
593
+ 5. ✓ `scan --fix` creates git branch matching pattern `codeprobe-fix-*`
594
+ 6. ✓ `scan --json` outputs valid, parseable JSON
595
+ 7. ✓ File permissions: `~/.codeprobe/scans/` is `0700`, files are `0600`
596
+ 8. ✓ Fallback works: If Bright Data times out, scan continues with cached data
597
+ 9. ✓ `demo.sh` completes in <3 minutes without errors
598
+ 10. ✓ `bun test src/test/e2e.cli.test.ts` passes (E2E, after Stage 1)
599
+
600
+ ---
601
+
602
+ ## Part 10: Open Decisions (User Confirmation Needed)
603
+
604
+ | Decision | Options | Blocker? |
605
+ |----------|---------|----------|
606
+ | **Token encryption method** | A: Keychain / B: AES-256-GCM / C: Plaintext | **YES** |
607
+ | API key precedence | Env-first (recommended) vs config-first | Medium |
608
+ | E2E environment | Local + real Daytona vs mocked | Low |
609
+ | Demo repo location | Subdirectory vs separate repo | Low |
610
+ | Scan history limit | Keep all or limit to N recent | Low |
611
+ | Pre-baked patches | Bake into codebase vs fetch from S3 | Low |
612
+
613
+ ---
614
+
615
+ ## Part 11: Critical Path Summary
616
+
617
+ ### Sequential Dependency Chain
618
+
619
+ ```
620
+ Stage 1 Contract Locked
621
+
622
+ Stage 2 Scaffolding (immediate, 30m)
623
+
624
+ Stage 1 Engine Works (Hour 2)
625
+
626
+ Stage 2 Real Integration (Hour 2.5–3)
627
+
628
+ Stage 2 E2E Test (Hour 3.5)
629
+
630
+ Demo Rehearsal (Hour 4+)
631
+ ```
632
+
633
+ ### Critical Gates
634
+
635
+ 1. **Gate 1: Token Encryption Decision** → Unblocks config.ts (due end of Hour 0)
636
+ 2. **Gate 2: Stage 1 Engine Contract** → Unblocks real scan.ts (due Hour 1)
637
+ 3. **Gate 3: Stage 1 Sandbox Working** → Unblocks E2E test (due Hour 2.5)
638
+ 4. **Gate 4: Demo Repo Ready** → Unblocks demo.sh (due Hour 3)
639
+
640
+ ---
641
+
642
+ ## Part 12: Post-Hack ton Roadmap (Out of Scope)
643
+
644
+ - Multi-language support (Python, Rust, Java)
645
+ - GitHub bot auto-commenting on PRs
646
+ - CI/CD GitHub Action (SARIF export)
647
+ - MCP server for Claude Desktop
648
+ - Database + user accounts
649
+ - Supply chain monitoring
650
+ - Executive dashboard view
651
+ - Team collaboration
652
+
653
+ ---
654
+
655
+ ## Summary & Next Steps
656
+
657
+ ### Do Now (Hour 0):
658
+
659
+ - [ ] Confirm Stage 1 contract with Stage 1 team
660
+ - [ ] **CRITICAL: Lock token encryption decision** (A/B/C)
661
+ - [ ] Scaffold Stage 2 directory structure + stubs
662
+ - [ ] Install dependencies: `bun install`
663
+
664
+ ### During Build (Hours 0-3):
665
+
666
+ - [ ] Stage 2: Build config, CLI, progress, errors (mocked engine)
667
+ - [ ] Stage 1: Build parser, scraper, sandbox, report (parallel)
668
+ - [ ] Run `bun test src/test/cli.test.ts` frequently (mocked tests)
669
+
670
+ ### After Stage 1 Ready (Hour 3+):
671
+
672
+ - [ ] Wire Stage 2 to real Stage 1 engine (replace mocks)
673
+ - [ ] Run `bun test src/test/e2e.cli.test.ts` (real engine)
674
+ - [ ] Run `bash demo.sh` 3-5 times (timing + rehearsal)
675
+ - [ ] Record fallback video (cache scenario)
676
+
677
+ ---
678
+
679
+ **Status**: Ready to implement. Awaiting token encryption decision + Stage 1 contract confirmation.