This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a personal website built with Astro and themed after TUIs (Text User Interfaces). The site features blog posts, projects, research notes, and an RSS feed. It's deployed to Cloudflare Workers.
This project uses mise for managing development tools. The mise configuration is in mise.toml.
# Install mise (if not already installed)
curl https://mise.run | sh
# Install project dependencies
mise installThis project uses Bun as the runtime for scripts in the scripts/ directory. Before adding new dependencies for common tasks, check if Bun has built-in support:
- YAML: Import with
import { YAML } from "bun";and useYAML.parse()andYAML.stringify()instead of external YAML libraries - File operations: Bun's
node:fshas enhanced performance - Testing: Bun has built-in test runner, though this project uses Vitest
- HTTP:
fetch()is built-in - SQLite:
bun:sqliteis built-in
Always prefer Bun's built-in APIs over adding new npm dependencies. Check the Bun documentation for available built-in modules.
All development commands should be run through mise:
# Start development server (runs on localhost:4321)
mise run dev
# Build for production
mise run build
# Preview production build
mise run preview
# Format code with Prettier
mise run fmt
# Lint code with oxlint
mise run lint
# Lint and auto-fix issues
mise run lint:fix
# Run tests
mise run test
# Run tests with UI
mise run test:ui
# Ensure content files have codes in frontmatter
mise run gen-codes
# Generate URL manifest mapping slugs to codes
mise run gen-url-manifest
# Deploy to Cloudflare Workers
mise run deployThe site uses Astro's content collections with file-based loaders defined in src/content.config.ts:
- blog: Blog posts in
src/content/blog/with title, description, date, tags, and draft status - projects: Project entries in
src/content/projects/with status (active, completed, archived, maintenance) - research: Research notes in
src/content/research/with draft/published/archived status and topics - pages: General pages in
src/content/pages/(including the homepage) - devtools: External RSS feed from devtools.fm podcast
The site uses MDC (Markdown Components) syntax from Nuxt Content, converted to MDX via a custom remark plugin (src/plugins/remark-mdc-to-mdx.ts). This enables component usage in markdown:
::card→ block component:icon→ inline component[text]{.class}→ span with class- Component attributes can be bound with
:attr="frontmatter.path"
The plugin automatically imports components from src/components/ based on usage.
The site supports beautiful ASCII art rendering of Mermaid diagrams using the beautiful-mermaid library. Write mermaid diagrams using standard code fences:
graph TD
A --> B
At build time, the remark-mermaid-ascii plugin automatically converts Mermaid code blocks into ASCII art using Unicode box-drawing characters. This happens during the MDX processing pipeline before the content is rendered.
See docs/mermaid.md for full documentation including Zed editor syntax highlighting configuration.
Content files use simple slug-based filenames: {slug}.mdx
Each file has a code field in its frontmatter containing a unique identifier:
- Kind prefix:
b(blog),r(research),p(projects),t(talks) - Hex date: 4-character lowercase hex timestamp derived from the date field
- Format:
{kind}{hex-date}(e.g.,b232e) - The
mise run gen-codesscript ensures all files have a code in frontmatter
Example filename: building-a-deno-desktop-framework.mdx with code: b232e in frontmatter
The site implements a URL manifest system for permanent short code URLs. For each content item:
- Canonical URL:
/{collection}/{slug}(e.g.,/blog/apis-in-the-age-of-ai)- Simple slug-based URL generated by Astro
- This is the primary URL shown in browsers
- Short code URL:
/{code}(e.g.,/b2405) → redirects to canonical- Provides short, permanent URLs based on content codes
- Looks up slug in manifest and redirects to canonical URL
The URL manifest (src/content/url-manifest.yaml) maps content codes to their slug-based URLs and is:
- Generated before each build via
mise run gen-url-manifest - Loaded as an Astro content collection using Bun's native YAML parser
- Used by middleware (
src/middleware.ts) to redirect short code URLs - Structured with codes as keys and arrays of slugs as values (supports multiple slugs per code)
This ensures permanent short URLs never break, while keeping canonical URLs clean and slug-based.
The project uses a custom UnoCSS configuration (uno.config.ts) that integrates with WebTUI CSS variables:
- Spacing: Uses
ch(character width) for horizontal andlh(line height) for vertical spacing - Colors: Maps to WebTUI CSS variables (e.g.,
var(--foreground0)) - Custom rules:
px-1= 1ch padding,py-1= 1lh padding, etc. - Custom variants:
hocus:(hover + focus),group-hocus:
The site includes a client-side keyboard shortcut system (src/client/keyboard-shortcuts.ts) that:
- Finds elements with
data-keyattributes - Binds global keyboard shortcuts
- Ignores shortcuts when typing in inputs or when meta key is pressed
- Can be refreshed via
window.refreshKeyboardShortcuts()
The site is deployed to Cloudflare Workers with configuration in wrangler.toml:
- Static assets in
./dist - Custom domain:
just-be.dev - Observability enabled
- src/pages/: Route pages (dynamic routes for blog, projects, research)
- src/components/: Reusable Astro components
- src/layouts/: Page layout templates
- src/content/: MDX content files organized by collection
- src/plugins/: Custom remark plugins
- src/utils/: Utility functions (code generation, date formatting)
- src/client/: Client-side JavaScript
- scripts/: Build scripts and utilities
Lefthook is configured (lefthook.yml) to run Prettier on staged files before commit. It's automatically installed via mise postinstall hook.
The project uses Bun's built-in test runner. Tests are located in *.test.ts files alongside the source code.
Sentry is integrated for error tracking. Configuration requires:
PUBLIC_SENTRY_DSN(public DSN)SENTRY_PROJECT(project name)SENTRY_AUTH_TOKEN(for source map uploads)
Do not use emojis in README files, documentation, code comments, or any other project files. Keep all written content professional and text-based. This applies to:
- README.md and other documentation files
- Code comments
- Commit messages
- Configuration files
- Content files (blog posts, pages, etc.)
Use clear, descriptive text instead of emojis to convey meaning.