@boshu2/vibe-check 1.5.0 → 1.6.1

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 (148) hide show
  1. package/.agents/bundles/insight-mining-dashboard-research-2025-11-30.md +400 -0
  2. package/.agents/bundles/storage-enhancement-research-2025-11-30.md +292 -0
  3. package/.agents/bundles/timeline-feature-research-complete-2025-11-30.md +301 -0
  4. package/.agents/plans/insight-dashboard-plan-2025-11-30.md +1130 -0
  5. package/.agents/plans/json-storage-enhancement-plan.md +717 -0
  6. package/.agents/plans/storage-hardening-and-cache-plan.md +592 -0
  7. package/.agents/plans/test-coverage-gaps-plan.md +1117 -0
  8. package/.agents/plans/timeline-feature-plan.md +193 -0
  9. package/.agents/plans/vibe_timeline_research_findings.md +553 -0
  10. package/.claude/settings.local.json +1 -0
  11. package/.vibe-check/.gitignore +6 -0
  12. package/CHANGELOG.md +46 -0
  13. package/CLAUDE.md +24 -0
  14. package/CONTRIBUTING.md +227 -0
  15. package/README.md +165 -144
  16. package/claude-progress.json +191 -9
  17. package/claude-progress.txt +257 -0
  18. package/dashboard/app.js +75 -2
  19. package/dashboard/dashboard-data.json +653 -0
  20. package/dashboard/index.html +13 -0
  21. package/dashboard/styles.css +61 -0
  22. package/dist/analysis/cross-session-analysis.d.ts +68 -0
  23. package/dist/analysis/cross-session-analysis.d.ts.map +1 -0
  24. package/dist/analysis/cross-session-analysis.js +174 -0
  25. package/dist/analysis/cross-session-analysis.js.map +1 -0
  26. package/dist/analysis/index.d.ts +2 -0
  27. package/dist/analysis/index.d.ts.map +1 -0
  28. package/dist/analysis/index.js +12 -0
  29. package/dist/analysis/index.js.map +1 -0
  30. package/dist/cli.js +10 -1
  31. package/dist/cli.js.map +1 -1
  32. package/dist/commands/analyze.d.ts +2 -0
  33. package/dist/commands/analyze.d.ts.map +1 -1
  34. package/dist/commands/analyze.js +105 -2
  35. package/dist/commands/analyze.js.map +1 -1
  36. package/dist/commands/cache.d.ts +6 -0
  37. package/dist/commands/cache.d.ts.map +1 -0
  38. package/dist/commands/cache.js +168 -0
  39. package/dist/commands/cache.js.map +1 -0
  40. package/dist/commands/dashboard.d.ts +8 -0
  41. package/dist/commands/dashboard.d.ts.map +1 -0
  42. package/dist/commands/dashboard.js +109 -0
  43. package/dist/commands/dashboard.js.map +1 -0
  44. package/dist/commands/index.d.ts +3 -0
  45. package/dist/commands/index.d.ts.map +1 -1
  46. package/dist/commands/index.js +8 -1
  47. package/dist/commands/index.js.map +1 -1
  48. package/dist/commands/timeline.d.ts +14 -0
  49. package/dist/commands/timeline.d.ts.map +1 -0
  50. package/dist/commands/timeline.js +462 -0
  51. package/dist/commands/timeline.js.map +1 -0
  52. package/dist/git.d.ts +24 -0
  53. package/dist/git.d.ts.map +1 -1
  54. package/dist/git.js +94 -0
  55. package/dist/git.js.map +1 -1
  56. package/dist/insights/generators.d.ts +44 -0
  57. package/dist/insights/generators.d.ts.map +1 -0
  58. package/dist/insights/generators.js +289 -0
  59. package/dist/insights/generators.js.map +1 -0
  60. package/dist/insights/index.d.ts +16 -0
  61. package/dist/insights/index.d.ts.map +1 -0
  62. package/dist/insights/index.js +171 -0
  63. package/dist/insights/index.js.map +1 -0
  64. package/dist/insights/types.d.ts +93 -0
  65. package/dist/insights/types.d.ts.map +1 -0
  66. package/dist/insights/types.js +6 -0
  67. package/dist/insights/types.js.map +1 -0
  68. package/dist/output/timeline-html.d.ts +6 -0
  69. package/dist/output/timeline-html.d.ts.map +1 -0
  70. package/dist/output/timeline-html.js +389 -0
  71. package/dist/output/timeline-html.js.map +1 -0
  72. package/dist/output/timeline-markdown.d.ts +6 -0
  73. package/dist/output/timeline-markdown.d.ts.map +1 -0
  74. package/dist/output/timeline-markdown.js +167 -0
  75. package/dist/output/timeline-markdown.js.map +1 -0
  76. package/dist/output/timeline.d.ts +9 -0
  77. package/dist/output/timeline.d.ts.map +1 -0
  78. package/dist/output/timeline.js +318 -0
  79. package/dist/output/timeline.js.map +1 -0
  80. package/dist/patterns/detour.d.ts +32 -0
  81. package/dist/patterns/detour.d.ts.map +1 -0
  82. package/dist/patterns/detour.js +137 -0
  83. package/dist/patterns/detour.js.map +1 -0
  84. package/dist/patterns/flow-state.d.ts +16 -0
  85. package/dist/patterns/flow-state.d.ts.map +1 -0
  86. package/dist/patterns/flow-state.js +40 -0
  87. package/dist/patterns/flow-state.js.map +1 -0
  88. package/dist/patterns/index.d.ts +8 -0
  89. package/dist/patterns/index.d.ts.map +1 -0
  90. package/dist/patterns/index.js +22 -0
  91. package/dist/patterns/index.js.map +1 -0
  92. package/dist/patterns/intervention-effectiveness.d.ts +42 -0
  93. package/dist/patterns/intervention-effectiveness.d.ts.map +1 -0
  94. package/dist/patterns/intervention-effectiveness.js +196 -0
  95. package/dist/patterns/intervention-effectiveness.js.map +1 -0
  96. package/dist/patterns/late-night.d.ts +30 -0
  97. package/dist/patterns/late-night.d.ts.map +1 -0
  98. package/dist/patterns/late-night.js +141 -0
  99. package/dist/patterns/late-night.js.map +1 -0
  100. package/dist/patterns/post-delete-sprint.d.ts +28 -0
  101. package/dist/patterns/post-delete-sprint.d.ts.map +1 -0
  102. package/dist/patterns/post-delete-sprint.js +85 -0
  103. package/dist/patterns/post-delete-sprint.js.map +1 -0
  104. package/dist/patterns/spiral-regression.d.ts +49 -0
  105. package/dist/patterns/spiral-regression.d.ts.map +1 -0
  106. package/dist/patterns/spiral-regression.js +219 -0
  107. package/dist/patterns/spiral-regression.js.map +1 -0
  108. package/dist/patterns/thrashing.d.ts +25 -0
  109. package/dist/patterns/thrashing.d.ts.map +1 -0
  110. package/dist/patterns/thrashing.js +111 -0
  111. package/dist/patterns/thrashing.js.map +1 -0
  112. package/dist/storage/atomic.d.ts +40 -0
  113. package/dist/storage/atomic.d.ts.map +1 -0
  114. package/dist/storage/atomic.js +155 -0
  115. package/dist/storage/atomic.js.map +1 -0
  116. package/dist/storage/commit-log.d.ts +35 -0
  117. package/dist/storage/commit-log.d.ts.map +1 -0
  118. package/dist/storage/commit-log.js +128 -0
  119. package/dist/storage/commit-log.js.map +1 -0
  120. package/dist/storage/index.d.ts +5 -0
  121. package/dist/storage/index.d.ts.map +1 -0
  122. package/dist/storage/index.js +33 -0
  123. package/dist/storage/index.js.map +1 -0
  124. package/dist/storage/schema.d.ts +32 -0
  125. package/dist/storage/schema.d.ts.map +1 -0
  126. package/dist/storage/schema.js +37 -0
  127. package/dist/storage/schema.js.map +1 -0
  128. package/dist/storage/timeline-store.d.ts +117 -0
  129. package/dist/storage/timeline-store.d.ts.map +1 -0
  130. package/dist/storage/timeline-store.js +438 -0
  131. package/dist/storage/timeline-store.js.map +1 -0
  132. package/dist/types.d.ts +96 -0
  133. package/dist/types.d.ts.map +1 -1
  134. package/docs/ARCHITECTURE.md +458 -0
  135. package/docs/DATA-ARCHITECTURE.md +565 -0
  136. package/docs/GAMIFICATION.md +564 -0
  137. package/docs/JSON-STORAGE-PATTERNS.md +512 -0
  138. package/docs/METRICS-EXPLAINED.md +394 -0
  139. package/docs/UNIFIED-ECOSYSTEM.md +560 -0
  140. package/docs/VIBE-ECOSYSTEM.md +406 -0
  141. package/docs/images/dashboard.png +0 -0
  142. package/feature-list.json +48 -0
  143. package/package.json +2 -1
  144. package/vitest.config.ts +1 -5
  145. package/.vibe-check/calibration.json +0 -38
  146. package/.vibe-check/latest.json +0 -114
  147. package/.vibe-check/sessions.json +0 -44
  148. package/PLAN-ultimate-game.md +0 -1362
@@ -0,0 +1,592 @@
1
+ # Storage Hardening & Cache Command Plan
2
+
3
+ **Type:** Plan
4
+ **Created:** 2025-11-30
5
+ **Depends On:** storage-enhancement-research-2025-11-30.md
6
+ **Loop:** Middle (bridges research to implementation)
7
+ **Tags:** security, storage, cache, hardening
8
+
9
+ ---
10
+
11
+ ## Overview
12
+
13
+ Implement Phase 1 (hardening) and partial Phase 2 (cache command) from the storage enhancement research:
14
+
15
+ 1. **Fix schema versioning** - Use CURRENT_SCHEMA_VERSION instead of hardcoded '1.0.0'
16
+ 2. **Improve NDJSON error handling** - Skip bad lines instead of failing entire file
17
+ 3. **Add .gitignore enforcement** - Warn if .vibe-check/ not in .gitignore
18
+ 4. **Add cache command** - `vibe-check cache status` and `vibe-check cache clear`
19
+
20
+ **Scope:** Security hardening + cache management UX. No analytics features yet.
21
+
22
+ ---
23
+
24
+ ## Approach Selected
25
+
26
+ From research, implement these quick wins:
27
+ - Schema version fix (5 min)
28
+ - NDJSON error recovery (15 min)
29
+ - Cache status/clear commands (30 min)
30
+ - .gitignore warning (10 min)
31
+
32
+ **Total estimated:** ~1 hour
33
+
34
+ ---
35
+
36
+ ## PDC Strategy
37
+
38
+ ### Prevent
39
+ - [x] Research completed (3-agent synthesis)
40
+ - [ ] All changes are additive (backward compatible)
41
+
42
+ ### Detect
43
+ - [ ] Build passes after each change
44
+ - [ ] Tests pass after all changes
45
+ - [ ] Manual test of cache commands
46
+
47
+ ### Correct
48
+ - [ ] Rollback procedure documented
49
+ - [ ] No breaking changes to existing data
50
+
51
+ ---
52
+
53
+ ## Files to Create
54
+
55
+ ### 1. `src/commands/cache.ts`
56
+
57
+ **Purpose:** Cache management commands (status, clear)
58
+
59
+ ```typescript
60
+ import { Command } from 'commander';
61
+ import chalk from 'chalk';
62
+ import * as fs from 'fs';
63
+ import * as path from 'path';
64
+ import { getStoreDir, getStorePath, loadStore } from '../storage';
65
+ import { getCommitLogPath } from '../storage/commit-log';
66
+
67
+ export interface CacheOptions {
68
+ repo: string;
69
+ }
70
+
71
+ export function createCacheCommand(): Command {
72
+ const cmd = new Command('cache')
73
+ .description('Manage vibe-check cache (.vibe-check/ directory)')
74
+ .option('-r, --repo <path>', 'Repository path', process.cwd());
75
+
76
+ // Subcommand: status
77
+ cmd
78
+ .command('status')
79
+ .description('Show cache status and size')
80
+ .action(async () => {
81
+ const options = cmd.opts() as CacheOptions;
82
+ await showCacheStatus(options);
83
+ });
84
+
85
+ // Subcommand: clear
86
+ cmd
87
+ .command('clear')
88
+ .description('Clear all cached data')
89
+ .option('--force', 'Skip confirmation prompt')
90
+ .action(async (clearOptions) => {
91
+ const options = cmd.opts() as CacheOptions;
92
+ await clearCache(options, clearOptions.force);
93
+ });
94
+
95
+ // Default action: show status
96
+ cmd.action(async () => {
97
+ const options = cmd.opts() as CacheOptions;
98
+ await showCacheStatus(options);
99
+ });
100
+
101
+ return cmd;
102
+ }
103
+
104
+ async function showCacheStatus(options: CacheOptions): Promise<void> {
105
+ const { repo } = options;
106
+ const storeDir = getStoreDir(repo);
107
+
108
+ console.log('');
109
+ console.log(chalk.bold.cyan('═'.repeat(50)));
110
+ console.log(chalk.bold.cyan(' VIBE-CHECK CACHE STATUS'));
111
+ console.log(chalk.bold.cyan('═'.repeat(50)));
112
+ console.log('');
113
+
114
+ if (!fs.existsSync(storeDir)) {
115
+ console.log(chalk.yellow(' No cache directory found.'));
116
+ console.log(chalk.gray(` Run 'vibe-check timeline' to create cache.`));
117
+ console.log('');
118
+ return;
119
+ }
120
+
121
+ // Calculate directory size
122
+ const files = fs.readdirSync(storeDir);
123
+ let totalSize = 0;
124
+ const fileInfo: { name: string; size: number }[] = [];
125
+
126
+ for (const file of files) {
127
+ const filePath = path.join(storeDir, file);
128
+ const stats = fs.statSync(filePath);
129
+ if (stats.isFile()) {
130
+ totalSize += stats.size;
131
+ fileInfo.push({ name: file, size: stats.size });
132
+ }
133
+ }
134
+
135
+ console.log(chalk.white(` 📁 Location: ${storeDir}`));
136
+ console.log(chalk.white(` 📊 Total size: ${formatBytes(totalSize)}`));
137
+ console.log('');
138
+
139
+ // Show file breakdown
140
+ console.log(chalk.gray(' Files:'));
141
+ for (const file of fileInfo) {
142
+ console.log(chalk.gray(` ${file.name}: ${formatBytes(file.size)}`));
143
+ }
144
+ console.log('');
145
+
146
+ // Show store details if timeline.json exists
147
+ const storePath = getStorePath(repo);
148
+ if (fs.existsSync(storePath)) {
149
+ try {
150
+ const store = loadStore(repo);
151
+ console.log(chalk.white(' 📈 Timeline data:'));
152
+ console.log(chalk.gray(` Sessions: ${store.sessions.length}`));
153
+ console.log(chalk.gray(` Insights: ${store.insights.length}`));
154
+ console.log(chalk.gray(` Last updated: ${store.lastUpdated}`));
155
+ console.log(chalk.gray(` Last commit: ${store.lastCommitHash || 'none'}`));
156
+
157
+ if (store.sessions.length > 0) {
158
+ const dates = store.sessions.map(s => s.date).sort();
159
+ console.log(chalk.gray(` Date range: ${dates[0]} to ${dates[dates.length - 1]}`));
160
+ }
161
+ } catch {
162
+ console.log(chalk.yellow(' ⚠ Could not read timeline data'));
163
+ }
164
+ }
165
+
166
+ // Check .gitignore status
167
+ console.log('');
168
+ const gitignorePath = path.join(repo, '.gitignore');
169
+ if (fs.existsSync(gitignorePath)) {
170
+ const gitignore = fs.readFileSync(gitignorePath, 'utf-8');
171
+ if (gitignore.includes('.vibe-check')) {
172
+ console.log(chalk.green(' ✓ .vibe-check/ is in .gitignore'));
173
+ } else {
174
+ console.log(chalk.yellow(' ⚠ .vibe-check/ is NOT in .gitignore'));
175
+ console.log(chalk.gray(' Add ".vibe-check/" to .gitignore to avoid committing cache'));
176
+ }
177
+ } else {
178
+ console.log(chalk.yellow(' ⚠ No .gitignore file found'));
179
+ }
180
+
181
+ console.log('');
182
+ }
183
+
184
+ async function clearCache(options: CacheOptions, force: boolean): Promise<void> {
185
+ const { repo } = options;
186
+ const storeDir = getStoreDir(repo);
187
+
188
+ if (!fs.existsSync(storeDir)) {
189
+ console.log(chalk.yellow('No cache to clear.'));
190
+ return;
191
+ }
192
+
193
+ if (!force) {
194
+ // Show what will be deleted
195
+ const files = fs.readdirSync(storeDir);
196
+ console.log('');
197
+ console.log(chalk.yellow('The following files will be deleted:'));
198
+ for (const file of files) {
199
+ console.log(chalk.gray(` - ${file}`));
200
+ }
201
+ console.log('');
202
+ console.log(chalk.yellow('Run with --force to confirm deletion.'));
203
+ return;
204
+ }
205
+
206
+ // Delete all files in .vibe-check/
207
+ const files = fs.readdirSync(storeDir);
208
+ for (const file of files) {
209
+ const filePath = path.join(storeDir, file);
210
+ fs.unlinkSync(filePath);
211
+ }
212
+
213
+ // Remove directory
214
+ fs.rmdirSync(storeDir);
215
+
216
+ console.log(chalk.green('✓ Cache cleared successfully.'));
217
+ }
218
+
219
+ function formatBytes(bytes: number): string {
220
+ if (bytes < 1024) return `${bytes} B`;
221
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
222
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
223
+ }
224
+ ```
225
+
226
+ **Validation:**
227
+ ```bash
228
+ npm run build
229
+ npm run dev -- cache status
230
+ npm run dev -- cache clear
231
+ ```
232
+
233
+ ---
234
+
235
+ ## Files to Modify
236
+
237
+ ### 1. `src/storage/timeline-store.ts:139`
238
+
239
+ **Purpose:** Use CURRENT_SCHEMA_VERSION instead of hardcoded '1.0.0'
240
+
241
+ **Before:**
242
+ ```typescript
243
+ export function createInitialStore(): TimelineStore {
244
+ return {
245
+ version: '1.0.0',
246
+ ```
247
+
248
+ **After:**
249
+ ```typescript
250
+ import { CURRENT_SCHEMA_VERSION } from './schema';
251
+
252
+ // ... (in createInitialStore)
253
+ export function createInitialStore(): TimelineStore {
254
+ return {
255
+ version: CURRENT_SCHEMA_VERSION,
256
+ ```
257
+
258
+ **Reason:** Schema versioning exists but isn't used correctly
259
+ **Validation:** `npm run build`
260
+
261
+ ---
262
+
263
+ ### 2. `src/storage/timeline-store.ts:1-8` (add import)
264
+
265
+ **Purpose:** Import CURRENT_SCHEMA_VERSION
266
+
267
+ **Before:**
268
+ ```typescript
269
+ import * as path from 'path';
270
+ import {
271
+ TimelineResult,
272
+ TimelineSession,
273
+ TimelineDay,
274
+ TimelineEvent,
275
+ } from '../types';
276
+ import { atomicWriteSync, safeReadJsonSync } from './atomic';
277
+ ```
278
+
279
+ **After:**
280
+ ```typescript
281
+ import * as path from 'path';
282
+ import {
283
+ TimelineResult,
284
+ TimelineSession,
285
+ TimelineDay,
286
+ TimelineEvent,
287
+ } from '../types';
288
+ import { atomicWriteSync, safeReadJsonSync } from './atomic';
289
+ import { CURRENT_SCHEMA_VERSION } from './schema';
290
+ ```
291
+
292
+ **Reason:** Need schema version constant
293
+ **Validation:** `npm run build`
294
+
295
+ ---
296
+
297
+ ### 3. `src/storage/atomic.ts:47-56`
298
+
299
+ **Purpose:** Improve NDJSON error handling - skip bad lines instead of failing
300
+
301
+ **Before:**
302
+ ```typescript
303
+ export function readNdjsonSync<T>(filePath: string): T[] {
304
+ if (!fs.existsSync(filePath)) {
305
+ return [];
306
+ }
307
+
308
+ const content = fs.readFileSync(filePath, 'utf-8');
309
+ const lines = content.split('\n').filter(line => line.trim().length > 0);
310
+
311
+ return lines.map(line => JSON.parse(line) as T);
312
+ }
313
+ ```
314
+
315
+ **After:**
316
+ ```typescript
317
+ export function readNdjsonSync<T>(filePath: string): T[] {
318
+ if (!fs.existsSync(filePath)) {
319
+ return [];
320
+ }
321
+
322
+ const content = fs.readFileSync(filePath, 'utf-8');
323
+ const lines = content.split('\n').filter(line => line.trim().length > 0);
324
+
325
+ const results: T[] = [];
326
+ for (const line of lines) {
327
+ try {
328
+ results.push(JSON.parse(line) as T);
329
+ } catch {
330
+ // Skip malformed lines instead of failing entire file
331
+ console.warn(`Warning: Skipping malformed NDJSON line: ${line.substring(0, 50)}...`);
332
+ }
333
+ }
334
+ return results;
335
+ }
336
+ ```
337
+
338
+ **Reason:** One bad line shouldn't corrupt entire file read
339
+ **Validation:** `npm run build`
340
+
341
+ ---
342
+
343
+ ### 4. `src/commands/index.ts`
344
+
345
+ **Purpose:** Export cache command
346
+
347
+ **Before:**
348
+ ```typescript
349
+ export { createAnalyzeCommand, runAnalyze, AnalyzeOptions } from './analyze';
350
+ export { createStartCommand } from './start';
351
+ export { createProfileCommand } from './profile';
352
+ export { createInitHookCommand } from './init-hook';
353
+ export { createWatchCommand } from './watch';
354
+ export { createInterveneCommand } from './intervene';
355
+ export { createTimelineCommand, runTimeline, TimelineOptions } from './timeline';
356
+ ```
357
+
358
+ **After:**
359
+ ```typescript
360
+ export { createAnalyzeCommand, runAnalyze, AnalyzeOptions } from './analyze';
361
+ export { createStartCommand } from './start';
362
+ export { createProfileCommand } from './profile';
363
+ export { createInitHookCommand } from './init-hook';
364
+ export { createWatchCommand } from './watch';
365
+ export { createInterveneCommand } from './intervene';
366
+ export { createTimelineCommand, runTimeline, TimelineOptions } from './timeline';
367
+ export { createCacheCommand } from './cache';
368
+ ```
369
+
370
+ **Reason:** Register new cache command
371
+ **Validation:** `npm run build`
372
+
373
+ ---
374
+
375
+ ### 5. `src/cli.ts:4`
376
+
377
+ **Purpose:** Import cache command
378
+
379
+ **Before:**
380
+ ```typescript
381
+ import { createAnalyzeCommand, createStartCommand, createProfileCommand, createInitHookCommand, createWatchCommand, createInterveneCommand, createTimelineCommand, runAnalyze } from './commands';
382
+ ```
383
+
384
+ **After:**
385
+ ```typescript
386
+ import { createAnalyzeCommand, createStartCommand, createProfileCommand, createInitHookCommand, createWatchCommand, createInterveneCommand, createTimelineCommand, createCacheCommand, runAnalyze } from './commands';
387
+ ```
388
+
389
+ **Reason:** Import new command
390
+ **Validation:** `npm run build`
391
+
392
+ ---
393
+
394
+ ### 6. `src/cli.ts:25` (add command registration)
395
+
396
+ **Purpose:** Register cache command with CLI
397
+
398
+ **Before:**
399
+ ```typescript
400
+ program.addCommand(createTimelineCommand());
401
+
402
+ // Default behavior: if no subcommand, run analyze with passed options
403
+ ```
404
+
405
+ **After:**
406
+ ```typescript
407
+ program.addCommand(createTimelineCommand());
408
+ program.addCommand(createCacheCommand());
409
+
410
+ // Default behavior: if no subcommand, run analyze with passed options
411
+ ```
412
+
413
+ **Reason:** Make cache command available
414
+ **Validation:** `npm run dev -- cache --help`
415
+
416
+ ---
417
+
418
+ ### 7. `src/commands/timeline.ts:43-52`
419
+
420
+ **Purpose:** Improve help text for --no-cache and --insights flags
421
+
422
+ **Before:**
423
+ ```typescript
424
+ export function createTimelineCommand(): Command {
425
+ const cmd = new Command('timeline')
426
+ .description('View your coding journey as a timeline with sessions and patterns')
427
+ .option('--since <date>', 'Start date for analysis (default: "1 week ago")', '1 week ago')
428
+ .option('--until <date>', 'End date for analysis (default: now)')
429
+ .option('-f, --format <type>', 'Output format: terminal, json, markdown, html', 'terminal')
430
+ .option('-r, --repo <path>', 'Repository path', process.cwd())
431
+ .option('-v, --verbose', 'Show verbose output', false)
432
+ .option('--expand [date]', 'Expand day details (all or specific date like "Nov-29")')
433
+ .option('--no-cache', 'Skip cache and fetch fresh data from git')
434
+ .option('--insights', 'Show compounding insights from historical data')
435
+ ```
436
+
437
+ **After:**
438
+ ```typescript
439
+ export function createTimelineCommand(): Command {
440
+ const cmd = new Command('timeline')
441
+ .description('View your coding journey as a timeline with sessions and patterns')
442
+ .option('--since <date>', 'Start date for analysis (default: "1 week ago")', '1 week ago')
443
+ .option('--until <date>', 'End date for analysis (default: now)')
444
+ .option('-f, --format <type>', 'Output format: terminal, json, markdown, html', 'terminal')
445
+ .option('-r, --repo <path>', 'Repository path', process.cwd())
446
+ .option('-v, --verbose', 'Show verbose output', false)
447
+ .option('--expand [date]', 'Expand day details (all or specific date like "Nov-29")')
448
+ .option('--no-cache', 'Force fresh git analysis (bypass .vibe-check/ cache)')
449
+ .option('--insights', 'Show compounding insights (patterns detected over 3+ sessions)')
450
+ ```
451
+
452
+ **Reason:** Better documentation of features
453
+ **Validation:** `npm run dev -- timeline --help`
454
+
455
+ ---
456
+
457
+ ## Implementation Order
458
+
459
+ **CRITICAL: Sequence matters. Do not reorder.**
460
+
461
+ | Step | Action | Validation | Rollback |
462
+ |------|--------|------------|----------|
463
+ | 1 | Modify `timeline-store.ts` imports | `npm run build` | Revert |
464
+ | 2 | Fix schema version in `createInitialStore` | `npm run build` | Revert |
465
+ | 3 | Improve NDJSON error handling in `atomic.ts` | `npm run build` | Revert |
466
+ | 4 | Create `src/commands/cache.ts` | `npm run build` | Delete |
467
+ | 5 | Update `src/commands/index.ts` exports | `npm run build` | Revert |
468
+ | 6 | Update `src/cli.ts` imports | `npm run build` | Revert |
469
+ | 7 | Register cache command in `cli.ts` | `npm run build` | Revert |
470
+ | 8 | Improve timeline help text | `npm run build` | Revert |
471
+ | 9 | Run full test suite | `npm test` | Revert all |
472
+ | 10 | Manual test cache commands | See below | Revert all |
473
+
474
+ ---
475
+
476
+ ## Validation Strategy
477
+
478
+ ### Syntax Validation
479
+ ```bash
480
+ npm run build
481
+ # Expected: No errors
482
+ ```
483
+
484
+ ### Unit Tests
485
+ ```bash
486
+ npm test
487
+ # Expected: All 26 tests pass
488
+ ```
489
+
490
+ ### Manual Integration Tests
491
+ ```bash
492
+ # Test cache status
493
+ npm run dev -- cache status
494
+ # Expected: Shows cache info or "no cache"
495
+
496
+ # Test cache status with existing cache
497
+ npm run dev -- timeline --since "1 week ago"
498
+ npm run dev -- cache status
499
+ # Expected: Shows sessions count, file sizes, date range
500
+
501
+ # Test cache clear (dry run)
502
+ npm run dev -- cache clear
503
+ # Expected: Lists files that would be deleted, asks for --force
504
+
505
+ # Test cache clear (actual)
506
+ npm run dev -- cache clear --force
507
+ # Expected: "Cache cleared successfully"
508
+ npm run dev -- cache status
509
+ # Expected: "No cache directory found"
510
+
511
+ # Test timeline help
512
+ npm run dev -- timeline --help
513
+ # Expected: Shows improved descriptions for --no-cache and --insights
514
+ ```
515
+
516
+ ---
517
+
518
+ ## Rollback Procedure
519
+
520
+ **Time to rollback:** ~2 minutes
521
+
522
+ ### Full Rollback
523
+ ```bash
524
+ # Step 1: Revert all modifications
525
+ git checkout src/storage/timeline-store.ts
526
+ git checkout src/storage/atomic.ts
527
+ git checkout src/commands/index.ts
528
+ git checkout src/commands/timeline.ts
529
+ git checkout src/cli.ts
530
+
531
+ # Step 2: Remove new file
532
+ rm -f src/commands/cache.ts
533
+
534
+ # Step 3: Verify
535
+ npm run build
536
+ npm test
537
+ ```
538
+
539
+ ---
540
+
541
+ ## Failure Pattern Risks
542
+
543
+ | Pattern | Risk | Prevention in Plan |
544
+ |---------|------|-------------------|
545
+ | Tests Passing Lie | LOW | Manual cache command tests |
546
+ | Instruction Drift | LOW | Precise file:line specs |
547
+ | Bridge Torching | LOW | Backward compatible changes |
548
+
549
+ ---
550
+
551
+ ## Risk Assessment
552
+
553
+ ### Low Risk: Import Ordering
554
+ - **What:** Circular imports
555
+ - **Mitigation:** New cache.ts imports from storage (same as other commands)
556
+ - **Detection:** Build fails
557
+ - **Recovery:** Fix import order
558
+
559
+ ### Low Risk: fs operations
560
+ - **What:** Permission errors on cache clear
561
+ - **Mitigation:** Only operates on .vibe-check/ we created
562
+ - **Detection:** Error message
563
+ - **Recovery:** User fixes permissions manually
564
+
565
+ ---
566
+
567
+ ## Approval Checklist
568
+
569
+ **Human must verify before /implement:**
570
+
571
+ - [ ] Every file specified precisely (file:line)
572
+ - [ ] All templates complete (no placeholders)
573
+ - [ ] Validation commands provided
574
+ - [ ] Rollback procedure complete
575
+ - [ ] Implementation order is correct
576
+ - [ ] Risks identified and mitigated
577
+ - [ ] Cache command is additive (no breaking changes)
578
+
579
+ ---
580
+
581
+ ## Next Step
582
+
583
+ Once approved: `/implement storage-hardening-and-cache-plan.md`
584
+
585
+ ---
586
+
587
+ ## Future Work (Not in This Plan)
588
+
589
+ 1. **Cross-session queries** - `vibe-check analyze --all-time`
590
+ 2. **Scope analysis** - `vibe-check analyze --scope auth`
591
+ 3. **Regression detection** - Alert when spirals return
592
+ 4. **Intervention effectiveness** - Score what breaks spirals