Repository navigation
refactor: ponytail audit cuts 3,633 net lines and 7 dependencies - #61
Conversation
The app mounted two complete toast stacks side by side: a hand-rolled
Radix reducer (toast.tsx + hooks/use-toast.ts + toaster.tsx + a
re-export shim, 326 lines, 20 call sites) and sonner (5 call sites).
Keep sonner. hooks/use-toast.ts becomes a 27-line adapter that preserves
the `{ title, description, variant }` call shape, so the 94 existing call
sites are untouched. AskPage's one ToastAction becomes a sonner action
object.
next-themes was imported only by ui/sonner.tsx, and its provider was
never mounted, so useTheme() always returned the "system" default.
Read the real theme from settings-store instead.
Also removed, all with zero importers:
- ui/form.tsx (133 lines); all four forms use react-hook-form directly
- src/App.css (42 lines of Vite template leftovers)
- components/landing/index.ts barrel (one consumer, blocked tree-shaking)
- 10 unused CSS classes and their keyframes in index.css (-97 lines)
- public/favicon copy.{ico,png,jpeg} (724 KB unreferenced)
-2 deps: next-themes, @radix-ui/react-toast
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Each of these was a dependency doing what the platform or an existing module already does. - date-fns: one formatDistanceToNow call. Added formatRelativeTime to lib/date-format.ts using Intl.RelativeTimeFormat, next to the existing Intl formatters. - file-saver: five saveAs calls. Added a 10-line saveBlob helper using URL.createObjectURL and <a download>. Tests now capture downloads through the real DOM path instead of mocking the module. - react-window: one <List> over a personal source library, with no measurement justifying virtualization. Plain overflow-y-auto map. SourceRow now takes a source instead of index/style/aria plumbing. - async-mutex: per-document locks in the collaboration service. Replaced with an 18-line promise-chain acquireLock that keeps the same beforeSync-acquire / afterHandleMessage-release handoff. All 10 collaboration tests pass, including crash and lock-loss cases. - @jam.dev/sdk: the published SDK only assigns a callback to window.__jam__.exports.metadata. Inlined that; the recorder itself already loads via script tags in jam-loader.ts. Also collapsed the AIProvider interface and DEFAULT_PROVIDERS array, which held exactly one provider whose isAvailable() returned true, into AVAILABLE_MODELS plus a PROVIDER_ID constant. ModelSelector computed a providerName it never rendered. Its test mocked the entire 10-model catalog by hand; it now uses the real one. New tests: formatRelativeTime units and fallback, jam metadata global. -6 deps: date-fns, file-saver, @types/file-saver, react-window, async-mutex, @jam.dev/sdk Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
ALLOWED_ORIGINS + getCorsHeaders were copy-pasted into 11 edge functions and had already drifted. ai-stream/ carried a reworded copy of ai/'s entitlement gating, and the two had diverged on the gift-trial fallback. - _shared/cors.ts: one origin list, opt-in dev origins, per-function methods - _shared/entitlements.ts: ai/'s (stricter, gift-trial-aware) implementation - demo-code-login: guard sanitizeRedirectTo against the non-http capacitor scheme the shared list now carries - native-cors.test.ts replaced with behavioural cors.test.ts + entitlements.test.ts 190 edge tests pass; all 11 functions typecheck under deno.
Every request routes through OpenRouter, which reports the authoritative account charge per response. calculateRequestCost returned on the openrouter branch before any pricing lookup, so the transcribed per-model rate table, its long-context/cache-TTL math, the three direct-provider usage normalizers, and the refresh script were all dead. - delete _shared/model-pricing.ts and scripts/update-model-pricing.ts - collapse calculateRequestCost to the reachable OpenRouter path - drop normalizeOpenAI/Anthropic/Google usage and their dead-branch tests - drop the tsx dev dependency, which existed only for the refresh script - keep docs/pricing-snapshots/ as historical evidence; note the supersession in plans/model-cost-accounting.md 184 edge tests pass, docs:check/lint/typecheck clean.
The mock provider let the app answer AI calls without leaving the browser, which meant the tests exercising it skipped the request path and the schema validation that ship to users. e2e now intercepts the edge-function call instead, so the real client code runs against canned payloads. The Deno compat shim existed so Vitest could re-run edge-function tests under jsdom. `npm run test:edge` already runs them under the runtime they ship on. Meta-tests trimmed to the assertions that guard something: the Vercel file keeps the CSP/security headers and noindex rules and drops the restatement of build config and cache rules; runtime-contracts keeps the Sentry capability probe and the staging-capture policy and drops the deploy-workflow greps. security-hardening.test.ts is repointed at _shared/entitlements.ts rather than deleted, since it guards the entitlement-bypass fix.
806 lines of Playwright matrix driver that ran twice, in September 2026, to produce docs/performance/smooth-navigation-baseline/. Nothing calls it: no script entry, no workflow, only the README that documents its output. The evidence it captured stays; the README now points at the commit to recover the harness from if the matrix is ever re-run. Its only test greped the source for a variable assignment, so it goes too.
settings-store had four files (819 lines, 56 tests) and session-store had three (1,309 lines, 51 tests), all mocking the same Supabase client and re-asserting the same setters from different angles. Each is now one file: 26 settings tests and 34 session tests. Coverage of both stores is unchanged or better, verified per file: settings-store 94.21% stmts / 91.52% branch with the same uncovered lines; session-store 87.88% stmts / 86.23% funcs / 90.88% lines, branches 75.31% (was 74.89%), no newly-uncovered function or branch. The handful of assertions that only the deleted files reached (folder rename/delete, setFolderActive, removeSource, the loading setters, getFeatureConfig hit, system-prompt persistence) were carried over rather than dropped.
Keys no key lookup can reach: not a literal `t('...')`, not the prefix of any
template-literal key the app builds (`nav.${item.key}` and friends), not a
plural sibling of a used base, and not a `labelKey`/`nameKey` string anywhere
in src or e2e. Mostly leftovers from renamed keys (`generate.title` after
`generate.saveCase`, `login.email` after `login.emailLabel`) and two removed
screens' worth of crossfire and sparring.setup copy.
Three locale files shrink by 112 lines each. i18n.test.ts still passes: the
three files stay key-for-key identical with no empty values.
formatSparringDuration and the five sparring label getters were byte-identical in export-utils.ts and pdf-export-utils.ts. One module now, imported by both. The audit also proposed collapsing all three exporters behind a single sections(result) model with thin emitters. Measured, that premise does not hold: outside these helpers and the import block, DOCX and PDF share 6 identical lines, and each shares under 10 with the Google Docs function. The three emit genuinely different document models — jsPDF draws 7 tables plus accent bars and manual page-break arithmetic, docx builds Paragraph/TextRun trees with no tables at all, and export-gdoc emits index-ranged Google Docs API requests from Deno, where it cannot import from src/ anyway. A shared section IR would be a fourth representation to translate three ways, not a deletion.
…e AI fixture The deleted mock provider delayed 1-2s per feature and sized its contention list from the requested length. Fulfilling instantly meant loading states never rendered, and a fixed 2 contentions failed the client's expectedContentionCount check for standard/comprehensive runs. All 4 animation-polish tests pass.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Free Run ID: 📒 Files selected for processing (1)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe changes consolidate AI routing on OpenRouter and centralize Edge Function CORS and entitlement logic. They update browser toast and download handling, gate collaboration routes, remove selected client utilities, and revise tests and measurement tooling. ChangesAI Requests and Usage
Shared Edge Function CORS
Browser UI and Utilities
Test and Measurement Cleanup
Estimated code review effort: 5 (Critical) | ~110 minutes Note 🎁 Summarized by CodeRabbit FreeYour organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing. Comment |
|
@coderabbitai review |
|
Preserve the Ponytail deletions while retaining current model routing, localization, date formatting, and collaboration test requirements from main.\n\nCo-Authored-By: Claude Code <noreply@anthropic.com>
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
@coderabbitai review |
|
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
@coderabbitai review |
|
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
@coderabbitai review |
✅ Action performedReview finished.
|
Completes the ponytail audit against current
main. The current diff removes 3,633 net lines across 90 files and drops 7 dependencies while preserving the active workspace evidence and practice release.What changed
aiandai-stream.tsxconsumer.mainand preserved workspace evidence and practice support in AI requests.VITE_COLLABORATION_URLis absent. Production no longer sends users into an editor that cannot connect. A later collaboration deployment can enable the routes by configuring a WSS endpoint and allowing its origin in CSP.Verification on the current head
npm run docs:checknpm run lintnpm run typecheckThe latest local database replay gate could not start because another active workspace trial owns the repository-wide Supabase lock. The previous gate passed 262 pgTAP checks, concurrency checks, and both real collaboration journeys. The PR's isolated
database-testscheck is running on this head and remains required before merge.The persistent collaboration service still has no Milestone 1 production deployment. This PR fails closed by hiding those routes unless a collaboration endpoint is configured; it does not invent or publish an unsupported WebSocket target.
🤖 Generated with Claude Code
Summary by CodeRabbit
Bug Fixes
Updates