This is the source for Luca Pipolo's personal portfolio website, statically built with Astro.
src/
├── pages/[...locale]/ routes, one tree per locale
├── content/ content collections: pages, settings, blog posts
├── components/
│ ├── common/ generic, reusable primitives
│ └── sections/ named page sections (Hero, Blog, Post, SiteHeader...)
├── layouts/main.astro shared HTML shell
├── libs/ i18n, content loaders, templating, utils
├── scripts/ client-side browser scripts
├── styles/ Tailwind config in CSS, plus partials
└── icons/ hand-authored SVGs
middleware.ts locale negotiation, at the edge
vercel.json security headers
scripts/ the Docker scripts below
You have two ways to run this project: with Docker, or directly with bun installed on your system.
-
Install Docker (or OrbStack as a macOS alternative) and make sure it's running.
-
Clone the repository:
git clone git@github.com:LucaPipolo/lcp-web.git && cd lcp-web
-
Make
.testdomains resolve to your machine (I suggest using dnsmasq). -
Run the setup script and open the site:
./scripts/setup.sh
-
Visit https://lcp-web.test.
The dev server is already running with hot reload with Vite, so any change you make is reflected straight away; there's nothing extra to start.
Caution
The Docker scripts in this repo (scripts/*.sh) currently only support macOS.
Note
On the first run, macOS asks for your password once, to trust the SSL certificate.
| Command | What it does |
|---|---|
./scripts/up.sh |
Start this checkout |
./scripts/down.sh |
Stop it, and the router if nothing else uses it |
./scripts/setup.sh |
Rewrite .env, then start. Safe to run any time |
All three accept --verbose (or -v) for full output instead of one line per step.
To run project scripts, use docker compose exec against the app container, from this checkout's own root:
docker compose exec app bun run dev # dev server
docker compose exec app bun run build # production build
docker compose exec app bun run preview # preview the buildThe Docker setup is designed around git worktrees: each worktree gets its own containers, port, and domain, so they never collide.
git worktree add ../my-feature
cd ../my-feature
./scripts/setup.shThat checkout is now served at https://my-feature.lcp-web.test, alongside lcp-web.test and any other worktree,
each running at the same time without conflicts. A single shared router handles HTTPS for all of them; down.sh only
stops that router once nothing else is using it.
This makes the project a good fit for working with multiple AI agents or an ADE like Orca side by side. Each agent can work in its own worktree, with its own running instance, without stepping on the others.
I use Orca as my ADE and create a worktree there for each feature. Pointing its setup and archive scripts at this repo's own gives every new worktree a running Docker environment automatically, with no manual step in between:
| Orca setting | Value |
|---|---|
| Setup script | $ORCA_WORKTREE_PATH/scripts/setup.sh |
| When to run | Run by default |
| Wait for setup to complete before starting agent | On |
| Archive script | $ORCA_WORKTREE_PATH/scripts/down.sh |
Setup starts that worktree's own containers before the agent gets to work in it; archive stops them once the worktree is gone.
Day to day I work mostly inside Orca itself, including its per-worktree browser: its Design Mode turns the cursor into an element picker, hovering highlights the element under it, useful for pointing an agent at something on the page. For manual edits I switch to Zed: fast to jump between worktrees, and a solid editor on its own.
-
Install bun.
-
Clone the repository:
git clone git@github.com:LucaPipolo/lcp-web.git && cd lcp-web
-
Install dependencies and start the dev server:
bun install && bun run dev
This serves the site at localhost:4321 with no HTTPS, but it is otherwise identical to Option A.
Caution
The git hooks run inside the Docker container, so
without it running you'll need git commit --no-verify to commit.
This repo is set up to work with Claude Code. This section covers the parts meant to be reached for by hand, not the ones Claude uses on its own.
I run this repo on Sonnet as the base model, and set /advisor, a
second opinion consulted before committing to an approach, to Opus rather than have Sonnet review itself. Anthropic's own
guide to choosing a model covers that
trade-off.
Commits made with AI assistance carry a Co-Authored-By: Claude Code <noreply@anthropic.com> trailer, plus a
Model: <name> (<id>) line naming what actually did the work (see git log). I want that visible rather than
folded into ordinary authorship: recording which model helped is how I track and improve how I use these tools
over time. The next thing I want there is a token count per commit, so the cost side is visible too, once the
tooling reliably exposes that.
| Skill | What it does |
|---|---|
/open-pr |
Opens a GitHub PR for the current branch, writing the title and body to match this repo's template. |
/address-pr-comments [PR] |
Works through a PR's unresolved review comments: fixes what's valid, replies to what isn't. Defaults to the current branch's PR, or targets the given PR number. |
/update-dependencies |
Updates this repo's Bun dependencies one at a time, each in its own commit. |
Note
I review PRs with ChatGPT Codex, not a human teammate, since I work alone on this
project. /address-pr-comments only handles Codex's own bot account for that reason; extending it to other
reviewers would be straightforward.
Note
/update-dependencies is deliberately not left runnable on its own (disable-model-invocation: true in its
frontmatter). Wiring it into a scheduled cloud agent, a weekly cron run rather than a live /loop (which only
polls while a session stays open), would be straightforward. I just haven't set it up yet.
Configured in .mcp.json, committed so every checkout gets them:
| Server | What it's for |
|---|---|
| Vercel | Deployments, project and domain info, logs, for this project's own account |
| Astro docs | Up to date Astro documentation lookup |
| Sentry | This project's error reports, issues, and traces |
| Context7 | Up to date documentation lookup for any library, including Tailwind CSS and Alpine.js, which have no official server of their own |
Note
Vercel and Sentry authenticate through OAuth on first connection.