- Add `cacheLife("max")` to `getLocalImage` (OG image) and `getStaticRoutes` (sitemap) so entries are held as long as possible during prerender instead of expiring at the default TTL
- Update AGENTS.md to distinguish build-time reads (catch inside the cached function, return a fallback, use a short `cacheLife` on the error path) from request-time reads (may throw from the cached function since they never run during prerender)
- Expand the `getCachedComments` comment to explain why throwing is only safe there: a throw inside `"use cache"` during prerender fails the build even if the caller catches it
- Replace `"use cache"` with `"use cache: remote"` on functions that run inside dynamic holes (`getContributions`, `getRepos`, `getPostStats`, `getCachedComments`) so entries are shared across server instances
- Switch comment and view server actions from `revalidatePath`/`revalidateTag` to `updateTag` + `refresh` for read-your-writes invalidation
- Extract a `commentsTag(pageSlug)` helper so each page's comment cache is expired independently instead of blowing the whole "comments" tag
- Refactor `getComments` to delegate to a cached inner function that throws on failure (so errors are never cached); `getCommentCount` now reuses that cache entry instead of issuing a separate COUNT query
- Drop `lib/data/views.ts` (`getAllViewCounts`) — the `/api/hits` route now calls `getPostStats()` instead
- Remove `revalidateTag("views")` from `incrementViews`; view counts in `getPostStats` are allowed to lag by a cache TTL
- Remove the `Suspense`/`Skeleton` wrapper on the projects page since `getContributions` is now a remote-cached call
- Replace CommentFormContext/Provider with a plain `useCommentFormState` hook; the context abstraction was unused outside the file
- Narrow auth-client exports to only `signIn`; `authClient` and `useSession` are no longer exported
- Add `getPosts()` as a canonical sorted-posts helper and use it in `getFrontMatter` and `buildFeed`, removing the redundant sort in the latter
- Drop JSON feed support from `createFeedHandler` since no JSON feed route exists
- Rewrite `FrontMatter` as a `Pick` over the content-collections `Post` type to stay in sync automatically
Split the scroll shell, home link and theme toggle into small client
components so the contact popover markup and icon SVGs render on the
server instead of shipping in the client bundle.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reads no longer live in "use server" files (which made them public
endpoints). /notes stats come from one cached query pair rendered on the
server; the post page comment count streams in as a dynamic hole.
revalidateTag("views"/"comments") now invalidates the cached stats.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Move cacheLife into the success/failure branches so a transient fetch
failure is retried after ~1 hour instead of being cached for 30 days.
Also catch thrown fetch errors in Gist so they no longer fail the build.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Names and avatars come from GitHub at sign-up; prevent signed-in users
from renaming themselves to impersonate other commenters.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- Replace single `<ViewTransition>` wrapper in layout with `FadeTransition` and `DirectionalTransition` components applied per page
- Add `components/page-transition.tsx` with reusable transition wrappers
- Expand view transition CSS with named classes: fade, slide, nav-forward/back, morph, text-morph, scale — all driven by CSS custom property durations
- Use React `<ViewTransition name=... share="text-morph">` for shared note title element between list and detail views
- Wrap comments suspense boundary with enter/exit slide transitions
- Add `persistent-nav` and `persistent-footer` view-transition-name groups to keep chrome static during navigation
- Fix reduced-motion override to target delay and duration instead of `animation: none`
- Add tracking-tight and letter-spacing tweaks to home page typography
- Bump versions for @base-ui/react, better-auth, react-activity-calendar, and other dependencies.
- Introduce new 'jarvis-ui' project in the home page with an associated icon.
- Update pnpm-lock.yaml to reflect changes in dependency versions.
Vercel's build infra was intermittently hitting ETIMEDOUT against
fonts.googleapis.com, causing OG image generation errors during
prerender. Ship the Inter .woff files with the function via
outputFileTracingIncludes so the build is network-free. Also add
turbopackIgnore hints on process.cwd() calls to silence an NFT warning
that was over-tracing next.config.ts into the route bundle.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace root page with new (home) route featuring a project showcase (Domainstack, Sofa, Versioneer, Snoozle)
- Remove /birthday and /hillary video pages
- Replace custom hand-rolled .prose styles with @tailwindcss/typography via a .markdown utility class
- Remove heading-anchor component and .nvmrc
- Bump better-auth, shadcn, oxfmt, oxlint, postcss, and pnpm to latest versions
- Add mise.toml to pin Node 24 as the project runtime
- Restrict claude-code-review to non-draft, non-bot, non-fork PRs; pin model to claude-opus-4-6 and scope allowed tools
- Set claude-opus-4-6 as default model in the main Claude workflow
- Replace Biome with oxlint + oxfmt (OXC toolchain) for linting and formatting
- Add .oxlintrc.json and .oxfmtrc.json configuration files
- Update VS Code settings and devcontainer to use oxc-vscode extension
- Remove contact form, Resend email integration, and related server action/schema
- Remove unused UI components (accordion, alert, card, tabs, toggle, etc.)
- Updated repository limit from 12 to 24 in getRepos function.
- Added new icons and adjusted styles for better visual consistency in the page component.
- Modified text sizes and spacing for improved layout and readability.
- Replaced GeistSans and GeistMono with Inter and JetBrainsMono in globals.css and layout.tsx.
- Updated font variable names to reflect the new font choices in fonts.ts.
The ::view-transition-old(*) and ::view-transition-new(*) rules were
applying fade animations to the root snapshot (header/footer/chrome)
in addition to the main-content transition, causing a double fade
effect and blocking interactivity during navigation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Changed font weight from 'font-semibold' to 'font-medium' for better visual consistency.
- Added 'not-prose' class to improve layout handling.
- Updated Link component's class to include 'text-foreground' for enhanced visibility.
- Replace manual state management with @tanstack/react-form
- Add proper Field/FieldLabel components for accessibility
- Simplify server action (remove useActionState signature)
- Remove use-debounce dependency
- Update PGP key links and minor styling tweaks
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add aria-hidden to decorative SVG icons
- Add title attributes to iframe embeds (CodePen, Gist, YouTube)
- Add aria-labels to comment form textareas
- Use proper button element for Markdown help popover trigger
- Use proper ellipsis character in placeholders
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Refactored CommentActions to use a state machine for managing action modes (replying, editing, deleting).
- Introduced CommentAvatar component for better avatar handling in comments.
- Updated CommentForm to use context for managing form state, allowing for better state sharing among components.
- Enhanced styling in next.config.ts for improved prose formatting.
- Adjusted CommentSingle to utilize the new CommentAvatar component for consistency.
- Introduced a new PostStats component to handle view and comment counts, replacing the previous async implementation with a client-side approach.
- Updated CommentCount component to use client-side state management for fetching comment counts.
- Removed unnecessary caching logic from view and comment fetching functions.
- Simplified date formatting by moving it inline, enhancing performance and readability.