|
| 1 | +# Changelog |
| 2 | + |
| 3 | +All notable changes to LoopKit are documented here. The format follows |
| 4 | +[Keep a Changelog](https://keepachangelog.com/), and this project |
| 5 | +adheres to [Semantic Versioning](https://semver.org/). |
| 6 | + |
| 7 | +## [0.2.0] — 2026-06-12 |
| 8 | + |
| 9 | +The "Loop Closes Both Ways" release. v0.2.0 is what happens when the |
| 10 | +CLI and the dashboard stop being two different products and start being |
| 11 | +two ends of the same loop. |
| 12 | + |
| 13 | +### Added |
| 14 | + |
| 15 | +- **`loopkit sync [status|retry]`** — surface CLI→dashboard sync failures |
| 16 | + with a banner in `track`/`ship`/`loop` when 3+ consecutive pushes |
| 17 | + have failed. Closes the "free-tier users never knew their dashboard |
| 18 | + was empty" problem. |
| 19 | +- **`loopkit audit [--weeks N] [--export md|pdf]`** — the founder |
| 20 | + therapy command. Reads 8 weeks of loop logs + ships + pulse, |
| 21 | + surfaces the one pattern you keep avoiding, the non-obvious |
| 22 | + insight the data shows, and one concrete change for next month. |
| 23 | + Blunt, not motivational. Optional PDF export. |
| 24 | +- **`loopkit price [--local] [--export md] [--experiment N]`** — |
| 25 | + pricing copilot. Recommends 2-3 tier model + 30-day validation |
| 26 | + experiment based on the brief, pulse pricing signals, and |
| 27 | + pay-intent phrases. Detects 7 model types (freemium, one-time, |
| 28 | + subscription, usage-based, tiered, donation, open-core). |
| 29 | +- **`loopkit celebrate --annual [year]`** — year-in-review preview |
| 30 | + with a 4×13 heatmap, headline metrics, and inferred archetype |
| 31 | + (All-Star / Marathoner / Sprinter / Perfectionist / Reactor). |
| 32 | +- **`loopkit voice [--max N] [--no-preview]`** — record a 60s standup |
| 33 | + → transcribed via OpenAI Whisper → tasks extracted via AI → appended |
| 34 | + to `tasks.md`. Records via `rec` (sox) / `arecord` / `ffmpeg`. |
| 35 | + Graceful fallback if no backend or API key. |
| 36 | +- **`/onboarding`** — 5-step web onboarding flow (product, problem, |
| 37 | + success metric, install, first task). State persists in |
| 38 | + sessionStorage. Generates `npx loopkit init <slug> --from-web <base64>` |
| 39 | + for one-click continuation. |
| 40 | +- **`/wins`, `/wins/[handle]`, `/wins/[handle]/[year]/card`** — public |
| 41 | + distribution engine. Real-time feed of `celebrate --share` posts, |
| 42 | + per-handle profiles, and screenshot-ready year-in-review cards. |
| 43 | + Sample data on day 1 for populated feel. |
| 44 | +- **Bidirectional task sync** — `loopkit track --push / --pull / --sync` |
| 45 | + CLI flags + `/dashboard/tasks` web page. Convex `tasks` table with |
| 46 | + LWW (last-write-wins) on `updatedAt`. CLI is canonical seed for |
| 47 | + new tasks; web mutations override when newer. CLI/WEB badge on |
| 48 | + every task shows provenance. |
| 49 | +- **9 new schemas in `@loopkit/shared`**: `AuditReportSchema`, |
| 50 | + `AuditCohortSchema`, `AuditPatternEvolutionSchema`, |
| 51 | + `PricingRecommendationSchema`, `PricingTierSchema`, `PricingModelEnum`, |
| 52 | + `syncStatus` (in `ConfigSchema`). |
| 53 | +- **YAML frontmatter in loop logs** — analytics modules read structured |
| 54 | + fields instead of regex. Old logs still parse via legacy fallback. |
| 55 | + |
| 56 | +### Changed |
| 57 | + |
| 58 | +- **Labs flag for 4 commands** — `radar`, `keywords`, `timing`, `update` |
| 59 | + are gated behind `loopkit labs on` (or `LOOPKIT_LABS=1`). The 5 |
| 60 | + core loop commands are unaffected. `update` is now also marked |
| 61 | + deprecated. |
| 62 | +- **Hardcoded mock counts removed** — "70% of founders quit by week 2" |
| 63 | + and "47 other founders ran loopkit loop yesterday" replaced with |
| 64 | + honest copy. Mocking future founders to coach present ones is |
| 65 | + bad product. |
| 66 | +- **CLI bundle: 364KB → 16KB** (22.7x reduction). Lazy-loaded all |
| 67 | + 15 command bodies. Cold start for `loopkit --help`: 194ms. |
| 68 | +- **Refactored `commands/loop.ts`** — 1,074 lines → 839 lines. Extracted |
| 69 | + to `commands/loop/{helpers,frontmatter,saveLoopLog,revenue-flag, |
| 70 | + post-actions}.ts`. Pure helpers, single-responsibility orchestrator. |
| 71 | +- **Removed dynamic imports** in `loop.ts` — static `import` for |
| 72 | + `writeTasksFile` and `writeConfig`. 3 fewer roundtrips per loop. |
| 73 | +- **`loop --async` grace window** tightened to 7 days (was unbounded). |
| 74 | +- **Help output** has a dedicated `Labs` section separating gated |
| 75 | + commands. Primary command help shows top 3 flags only. |
| 76 | + |
| 77 | +### Fixed |
| 78 | + |
| 79 | +- **CLI auth was breaking on Vercel** (SEC-3) — replaced in-memory |
| 80 | + sessions with persistent Convex `cliAuth` table. Survives |
| 81 | + serverless cold starts. |
| 82 | +- **Dashboard widget hardcoded localhost** (SEC-4) — uses |
| 83 | + `NEXT_PUBLIC_APP_URL` with `loopkit.dev` fallback. |
| 84 | +- **Cross-user data access** (SEC-1) — every Convex query/mutation |
| 85 | + now verifies project ownership via `userOwnsProject`. |
| 86 | +- **Subscription expiration not checked** (SEC-5) — `users.me` |
| 87 | + downgrades expired subscriptions to `free`. |
| 88 | +- **Unbounded Convex queries** (PERF-1) — `listByProject` and |
| 89 | + `getResponses` paginated (max 100-500). |
| 90 | +- **Turbopack workspace warning** — cosmetic, no functional impact. |
| 91 | + |
| 92 | +### Security |
| 93 | + |
| 94 | +- **CSRF protection** on all `/api/sync/*` routes (Origin header check). |
| 95 | +- **IP rate limiting** on public pulse form (3 req/min via |
| 96 | + `getClientIp` + trusted-proxy env var). |
| 97 | +- **AES-256-GCM token encryption** for `auth.apiKey` and |
| 98 | + `anthropicKey` in `config.json` (host-derived key, scrypt). |
| 99 | +- **Convex auth on every query/mutation** — no query accepts a raw |
| 100 | + `projectId` or `userId` from the client without ownership check. |
| 101 | + |
| 102 | +### Performance |
| 103 | + |
| 104 | +- **CLI cold start**: 364KB → 16KB (22.7x). 194ms for `--help`. |
| 105 | +- **Loop log reads**: frontmatter-based, no more regex. |
| 106 | +- **Convex queries**: paginated, indexed. |
| 107 | +- **AI calls**: cached at 7-day TTL via `(command, system, prompt, |
| 108 | + schema)` hash. |
| 109 | + |
| 110 | +### Tests |
| 111 | + |
| 112 | +- **438 CLI tests** (was 327 → +111 new in v0.2.0) |
| 113 | +- **43 web tests** (was 37 → +6) |
| 114 | +- **101 shared tests** (was 75 → +26) |
| 115 | +- **582 total tests** across the monorepo, all passing |
| 116 | +- All commands have `isCancel()` graceful exits on Ctrl+C |
| 117 | +- All Convex mutations auth-check project ownership |
| 118 | + |
| 119 | +## [0.1.0] — 2026-04-25 |
| 120 | + |
| 121 | +Initial public release. 15 CLI commands, 5-core-loop ritual, |
| 122 | +Convex-backed dashboard, share-in-public wins, billing via Polar.sh. |
| 123 | + |
| 124 | +--- |
| 125 | + |
| 126 | +[0.2.0]: https://github.com/loopkit/loopkit/compare/v0.1.0...v0.2.0 |
| 127 | +[0.1.0]: https://github.com/loopkit/loopkit/releases/tag/v0.1.0 |
0 commit comments