chore(knip): remove unused dependencies (PR-Knip-2)#280
Conversation
Knip flagged 11 unused dependencies in #267. After per-dep verification (grep + transitive-dep audit), 6 are genuinely unused in scope. Removing them shrinks the lockfile by ~120 lines. apps/desktop production deps removed: - highlight.js — rehype-highlight uses lowlight, not highlight.js - pino-roll — logger.ts uses createWriteStream directly, no roll - react-resizable-panels — no imports anywhere - unist-util-visit — no imports anywhere apps/desktop dev deps removed: - @types/mdast — no imports anywhere - pino-pretty — logger.ts doesn't pipe through a transport packages/sync-core: drop @readied/core dependency - src/* has no imports of @readied/core; the workspace link was stale packages/wikilinks: drop unified - src/* uses unist-util-visit directly (kept) but never imports unified Skipped (apps/web — out of audit scope): - @radix-ui/react-separator - next-themes - tailwindcss-animate Validates: - pnpm install --ignore-scripts — succeeds; pre-existing peer warnings about electron-builder + electron-vite are unrelated - pnpm -r typecheck — green - pnpm test — 17/17 packages Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. 🗂️ Base branches to auto review (2)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
c7ecd17
into
chore/knip-unused-files
…ge layer (PR-F3-Wiring) (#281) ## Summary Wires the verification primitive from #276 into the desktop's \`FileLicenseStorage\`. The path from server → disk → in-memory now has a real Ed25519 verification step at read time, with **lenient fallthrough** during the migration window. ## Changes ### \`packages/licensing/src/types.ts\` \`StoredSubscriptionData\` now allows an optional \`signedEnvelope\`: \`\`\`ts interface StoredSubscriptionData { readonly subscription: SubscriptionInfo; readonly lastVerified: string; readonly cacheExpiresAt: string; readonly signedEnvelope?: SignedSubscriptionEnvelope; // NEW } \`\`\` Both can coexist during migration. Long-term, the unsigned \`subscription\` field becomes a derived view of the envelope payload. ### \`apps/desktop/src/main/services/fileLicenseStorage.ts\` \`readSubscriptionData\` now branches on envelope presence: | State on disk | Behavior | |---|---| | **Envelope present + signature valid** | Return cache as-is | | **Envelope present + signature invalid** | Log error, **refuse the cache** (return null). Next caller fetches fresh from the API | | **Envelope absent** | Log warning, accept the cache (lenient migration mode) | Plus a \`SUBSCRIPTION_PUBLIC_KEY\` constant at the top of the file with a **REPLACE BEFORE SHIPPING** note. The all-zeros placeholder means any real envelope will fail verification — that's the *correct* failure mode while the placeholder is in place. The lenient "no envelope" branch is what runs today. ## What's NOT in this PR (still pending the server team) - \`ApiClient.getSubscriptionStatus\` does not yet return an envelope. When it does, \`mapApiToSubscriptionData\` in \`licenseHandlers.ts\` grows one more field (\`signedEnvelope\`) and \`writeSubscriptionData\` persists it. That change is one-liner plumbing, blocked only on the API contract being updated. - The placeholder public key gets swapped for the real server key in the release that first ships signed envelopes. ## Behavior matrix | Disk state | Today (placeholder key) | After server rollout (real key) | |---|---|---| | Empty | null returned, no log | null returned, no log | | Old shape (no envelope) | Warning logged, accepted | Warning logged, accepted (until strict mode) | | Real envelope, valid sig | Cannot occur (server isn't signing yet) | Silently accepted | | Real envelope, invalid sig | Will fail (placeholder key) → refused → refetch | Refused → refetch | | Tampered envelope | Refused → refetch | Refused → refetch | ## Test plan - [x] \`pnpm -r typecheck\` — green - [x] \`pnpm test\` — 17/17 packages (the 18 signature tests from #276 cover the verify path; this PR just calls into them) - [ ] Manual: edit \`subscription.json\` to flip a single byte in the cached \`subscription.subscriptionId\` field. Reopen the app. Once server signs envelopes: expect error log + refetch. Today: warning log + cache accepted (no envelope to verify). ## Stack context Stacked on **PR-Knip-2** (#280) → PR-Knip-1 (#279) → PR-G (#278) → PR-E (#277) → ... down to PR-B (#265). **17 PRs deep.** 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…Repository (#282) ## Summary **Phase 1 of the SQLiteNoteRepository split.** Pure helpers come out to their own file so future sub-repositories (sync, tag, archive) can reuse them without inheriting from the 1000-line class. | Metric | Before | After | |---|---|---| | \`SQLiteNoteRepository.ts\` | 1121 lines | **1038 lines** (-7%) | | \`noteMapping.ts\` | — | 133 lines (new) | ## Extracted | Symbol | Kind | Notes | |---|---|---| | \`NoteRow\`, \`TagRow\`, \`TagWithColorRow\`, \`BacklinkInfo\` | Row types | Re-exported by SQLiteNoteRepository so external imports keep working | | \`rowToNote(row, tags) -> Note\` | Pure mapper | Reconstructs a domain Note from a SQLite row + its tags | | \`prepareFtsQuery(input) -> string\` | Pure helper | FTS5 query escaper + tokenizer | | \`archivedConditionSql(filter, alias) -> string\` | Pure helper | SQL fragment for archived filtering | Call sites swapped from \`this.<helper>()\` to plain function imports. **The public class signature is unchanged** — \`BacklinkInfo\` is re-exported so external consumers (e.g. \`apps/desktop/src/main/handlers/types.ts\`) keep working without edits. ## What this PR DELIBERATELY does NOT do - **Extract sync methods** (\`getPendingChanges\` through \`getSyncHistory\` ~430 lines) into a \`SQLiteNoteSyncRepository\`. Those share state — tag queries, transactions, FTS sync triggers — with the main class in ways that need real-DB integration coverage to refactor safely. The helpers extracted here are the foundation: a follow-up PR can build the sync sub-repo on top of them without touching the helpers again. - **Extract tag methods** (\`setManualTags\`, \`renameTag\`, \`getAllTagsWithColors\`, etc.) for the same reason. The audit aspired to a 4-way split (NoteCrudRepository + NoteTagRepository + NoteArchiveRepository + NoteSyncRepository). That remains the destination. This PR ships the **foundation** that makes those splits low-risk; each can ride its own PR with focused review. ## Test plan - [x] \`pnpm -r typecheck\` — green - [x] \`pnpm test\` — 17/17 packages - [ ] Manual: launch the desktop, exercise notes CRUD + search + tag operations. Behavior should be identical (no observable change). ## Stack context Stacked on **PR-F3 wiring** (#281) → PR-Knip-2 (#280) → PR-Knip-1 (#279) → PR-G (#278) → PR-E (#277) → ... down to PR-B (#265). **18 PRs deep.** 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary
**Phase 1 of the MarkdownEditor split.** Pure theme + markdown
HighlightStyle move to their own file so further extractions (extensions
array, keymap bindings) can ride on top without merging against a
churn-prone component shell.
| Metric | Before | After |
|---|---|---|
| \`MarkdownEditor.tsx\` | 737 lines | **612 lines** (-17%) |
| \`editorTheme.ts\` | — | 139 lines (new) |
## Extracted
| Symbol | Kind |
|---|---|
| \`SCROLL_PAST_END_PADDING\` | constant |
| \`createEditorTheme(fontSize, fontFamily, lineHeight)\` | factory
returning \`EditorView.theme({...})\` |
| \`markdownHighlighting\` | \`HighlightStyle.define([...])\` with all
tag styles for markdown |
## Imports cleaned up
- Drop \`HighlightStyle\` from \`@codemirror/language\` import (no
longer referenced in this file)
- Drop \`tags\` from \`@lezer/highlight\` (moved into editorTheme.ts)
## What this PR DELIBERATELY does NOT do
- **Extract the extensions array** (~96 lines of \`createExtensions\`).
It closes over user settings (\`lineNumbersCompartment\` etc.) and mixes
context-coupled values like \`wikilinkAutocomplete\` from a hook. Safely
pulling that out requires either passing the closure context via a
builder, or moving the whole \`useMemo\` into its own hook. **Better
done under Playwright coverage (PR-E #277) so renderer regressions
surface.**
- **Extract the keymap.** Same reason — bindings reference
view-imperatives + the command-registry which are constructed inside the
React tree.
## Test plan
- [x] \`pnpm -r typecheck\` — green (renderer + e2e tsconfigs)
- [x] \`pnpm test\` — 17/17 packages
- [ ] Manual: open the editor, type in a markdown note with headings,
emphasis, lists, code blocks. The look must be identical (theme is
byte-for-byte the same; just moved).
## Stack context
Stacked on **note repo split** (#282) → PR-F3 wiring (#281) → PR-Knip-2
(#280) → PR-Knip-1 (#279) → PR-G (#278) → PR-E (#277) → ... down to PR-B
(#265). **19 PRs deep.**
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
## Summary Promotes `develop` to `main` for **v0.15.0**. Originally opened 2026-04-24; now refreshed with the 19-PR tech-debt audit shipped via #285 plus the accumulated dependabot bumps reconciled. `semantic-release` will pick the version bump. Expected: **minor (v0.14.x → v0.15.0)** because of multiple \`feat:\` commits. ## What ships (audit highlights, from #285) ### Runtime fixes (user-facing) - **Editor no longer crashes on table-containing notes** (#266) — \`Decoration.replace\` over multi-line ranges moved from a ViewPlugin to a StateField, plus an EditorView.exceptionSink so any future plugin error no longer tears down the EditorView. - **AI keys survive sleep/wake** (#275) — \`aiKeyStorage\` stopped silently deleting the encrypted store when the keychain was temporarily locked after macOS sleep. - **Backup restore is now safe** (#271) — restored DBs go through \`PRAGMA integrity_check\` before being swapped in; corrupt backups roll back to the safety copy. - **MCP server runs without electron-builder rebuilds** (#264 → #270) — migrated from native \`better-sqlite3\` to built-in \`node:sqlite\` (Node 22.5+), updated to the new \`registerTool\` MCP SDK API. ### Security - **Typed IPC boundary** (#272 + #273 + #274) — 130+ IPC channels now validated with Zod tuples at the main↔renderer boundary. Garbage in fails fast with \`IpcValidationError\` instead of corrupting downstream code. - **Ed25519 license verification scaffolding** (#276 + #281 + #284) — \`signSubscriptionPayload\` / \`verifySubscriptionSignature\` helpers ship in \`@readied/licensing\`, wired into \`FileLicenseStorage.readSubscriptionData\` with lenient fallthrough during migration. Real public key embedded (\`d04901…\`). Server-side \`LICENSE_SIGNING_PRIVATE_KEY\` already set in Cloudflare staging + production. ### Developer experience - **Husky → Lefthook** (#267) plus lint-staged that now runs ESLint, not just Prettier. - **\`knip\` added** (#267) + 12 unused files deleted (#279) + 6 unused deps dropped (#280). - **Playwright Electron E2E scaffold** (#277) with smoke + notes-IPC specs and a Linux+xvfb CI job (\`continue-on-error: true\` while it stabilises). - **Vitest coverage baseline** (#269) — 12 packages share a coverage config; smoke tests added for \`@readied/commands\`. ### Refactor (no behavior change) - **Zustand selectors migration** (#268) — 3 components stopped destructuring entire stores. - **God-file extractions**: - \`main/index.ts\` 1065 → 950 lines (#278) — \`FileLicenseStorage\`, \`windowState\` extracted to services - \`SQLiteNoteRepository.ts\` 1121 → 1038 lines (#282) — pure helpers extracted to \`noteMapping.ts\` - \`MarkdownEditor.tsx\` 737 → 612 lines (#283) — theme + markdownHighlighting extracted to \`editorTheme.ts\` ## Deploys triggered | Workflow | Trigger | What happens | |---|---|---| | \`deploy-api.yml\` | Auto on \`push\` to main affecting \`packages/api/**\` | Tests + deploys \`@readied/api\` to Cloudflare Workers (\`readied-api-production\`). This stack only touched \`wrangler.toml\` + \`.dev.vars\` docs, no production code change. | | \`release.yml\` | Manual \`workflow_dispatch\` post-merge | \`semantic-release\` analyses conventional commits, bumps version, creates GitHub Release draft + tag | | \`build.yml\` | Auto on tag push from release.yml | mac / windows / linux parallel builds, artefacts attached to the GitHub Release | ## Pre-merge verification (local, this branch) - ✅ \`pnpm -r typecheck\` — green across 18 workspace projects - ✅ \`pnpm test\` — 17/17 packages - ✅ Merge resolved: take develop versions for 19 conflicted package.jsons (develop has equal or newer deps than main's dependabot bumps) ## Post-merge action items (operator) 1. **Deploy API to staging first** (smoke test): \`\`\` gh workflow run deploy-api.yml -f environment=staging \`\`\` 2. Confirm staging API responds correctly (subscription endpoint with new \`LICENSE_SIGNING_PRIVATE_KEY\` secret already set in CF). 3. Merge this PR → auto-deploys API to production. 4. Trigger Release workflow: GitHub → Actions → Release → "Run workflow" → main. 5. Watch Build workflow for mac/win/linux completion. 6. Confirm the release un-drafts itself. ## Known risks / follow-ups - **Pre-existing Vercel preview failure for \`apps/web\`** — marketing site, scheduled to be extracted to its own repo (P3 in the roadmap). - **\`SUBSCRIPTION_PUBLIC_KEY\` is dev-grade** — generated in a Claude session. Before the licensing server emits envelopes for real paid users, rotate the keypair from a trusted machine and ship a follow-up release. - **Branch protection should require CodeRabbit completion before automerge** — added to the roadmap as a process item; this very PR was BLOCKED correctly because of that policy gap being closed. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Summary
Phase 2 of knip cleanup. Knip flagged 11 unused dependencies in #267; per-dep verification confirmed 6 are genuinely unused in our scope. Removing them shrinks the lockfile by ~120 lines.
Removed
`apps/desktop` production
`apps/desktop` dev
`packages`
Skipped (out of audit scope)
`apps/web`: `@radix-ui/react-separator`, `next-themes`, `tailwindcss-animate` — marketing site, separate pass.
Test plan
Stack context
Stacked on PR-Knip-1 (#279) → PR-G (#278) → PR-E (#277) → ... down to PR-B (#265). 16 PRs deep.
🤖 Generated with Claude Code