Personal sites are in a new era: IDE, agents, and git cover a lot of ground that used to mean "open WordPress" or "log into the CMS." You still own the words — you're often not starting in a hosted dashboard.
bagusfikri.me was never a resume. It's one place for long articles, half-formed ideas, and crafts (OSS, demos, anything easier to show than to thread).
This post is mainly about how I work — Cursor, agents, and git as one loop — and this repo is the case study. The shell and the stack are what fell out of that loop. The long-form contract for agents and humans is still project.md.
The setup
The mandate I kept pointing agents at — not a spec deck, just a line I could paste when output drifted:
dark first, terminal, Palantir-flavored — matte field for type; monospace rhythm, grid logic, sharp corners; session, not bounce. "Palantir" here means discipline — color as signal, quiet chrome, precision over novelty — not enterprise clutter. The reading column should feel like a tool, not a gradient brochure.
Stack stays boring on purpose: Next.js App Router, React, TypeScript, Tailwind v4, Geist Mono, tokens in src/app/globals.css. Low surface area matters for the loop — fewer sharp corners for an agent patch to graze, same affordances for me as for an autonomous edit.
How I work
No hosted CMS as source of truth — git wins. content/articles/ holds numbered stages 00–04, templates, CATEGORIES.md, README — planning and taxonomy in the repo, not a dashboard.
Shipped posts: one .ts module each in src/content/posts/ — typed Post, routed via writing/[slug], registered in index.ts. Markdown plans; .ts ships — typed, reviewed, diffable. Crafts can be routes in the same app. Work starts in content/articles/; when it's ready, it graduates to src/content/posts/. Vercel deploys; agents patch the tree like I would. That's what I mean by agent as CMS — still need constraints and judgment; LLM-assisted + static often beats a second database here.
Cursor is the editor, the review surface, and the place where intent turns into diffs. AGENTS.md and project.md steer agents off generic "startup landing" output. New behavior usually starts as a plain-language prompt — intent, limits, what to skip. The agent proposes types and file touches; I review.
Example from a real session: scroll to top + copy URL for sharing.
The same loop updates rules and philosophy, not only UI. project.md is the long-form contract for voice, layout, tokens, and what to refuse; AGENTS.md points agents at it and the Next.js guardrails. I extend both with the same plain-language asks I use for features — so agents don't just ship code; they inherit how to write and design this site. Below: adding thread-paced article prose.
Some error is expected. Article bodies live in .ts as template literals; markdown-style backticks inside the string can kill the build fast. I screenshot the overlay, ask the agent to fix it, and keep going — same loop as features.
Raw captures live in photo-video/; copies for this piece sit in public/media/the-new-era-of-blog-building-and-writing-agent-as-cms/.
What it produced
The shell is dark first, terminal, Palantir-flavored in the sense above — low chrome, high clarity, matte field for type. That isn't decoration layered on at the end; it's what the loop kept converging on once project.md had teeth.
ASCII header — a living signal, not a hero still. AsciiHeader cycles generated patterns: abstract, biased toward how I think, not stock hacker wallpaper. Most raw thinking lives in Obsidian; Cursor and agents interpret it under the same rules.
The animation sits in the corner, ambient and peripheral. Hard to read at a glance is intentional — tone control, not content.
Reading column — single column, max-w-2xl, px-4; Geist Mono, small body, relaxed leading — a log, not a terminal dump. Tokens in globals.css; copy survives daylight; tags on AI, DESIGN, META, THINKING, READS; radius zero; subtle link hovers. No auto-scroll, auto-focus, or redirects.
The more useful question than "best stack?" is what you won't do. I refuse marketing silhouette and hero motion that shows off cleverness at the expense of reading. The ASCII header is the opposite — slow, peripheral, aligned with the brief. I refuse body gray that only reads on a calibrated display. I refuse a personal site that performs success instead of documenting work.
One workspace
One editor, one repo, one deploy — the view below is the same object the session screenshots came from. The animation playground is a scratchpad route for motion before it touches the main shell.
What I'm adding next
Still reading-first, but useful — not just PDFs of thought.
- Code / live demos beside prose.
- @bagus_bot on this site for depth without noisy widgets.
- Comments — slow, optional, per post.
- Light analytics — signal, not obsession.
No fixed timeline — shape only.
Articles, ideas, crafts — public without performance. You're reading one moment in that log.
This is the beginning. I'll keep developing how to produce content and improve the site — including improving my writing. It's so bad, I know.