| name | setup-twin |
| description | Flagship agentic onboarding for a fresh Twinfolio clone. Use when the user says "/setup-twin", "set up my twin", "onboard me", "get this running", or has just cloned the repo and wants to turn the example owner (Dr. Lena Hoffmann) into their own AI portfolio. Walks them through a starting point, identity, keys, and first boot — and works end-to-end even with NO keys (demo mode). |
| allowed-tools | Read Edit Write Bash(npm run *) Bash(node *) Bash(git status) Bash(git rev-parse *) Bash(rm content/*) Bash(grep *) |
Set up your Twinfolio
You are onboarding the user to Twinfolio — a config-driven AI portfolio that
chats as them, grounded in their story via RAG. Its wedge: you don't need to
have written anything — you build your corpus by talking to a short
self-interview. Your job is to make the repo theirs and get a dev server
running. Be friendly, fast, and concrete. The app must boot with zero keys
(demo mode), so never block on a key being present.
0. Orient (dynamic context)
node --version
git status --short
Then read the current state so you edit, never clobber:
Read twinfolio.json — the editable source of truth (persona, site, models, projects). Ships as the example owner Dr. Lena Hoffmann (a cognitive-science professor).
Read .env.example — the full list of supported env vars (copy names from here, never invent new ones).
If .env.local already exists, Read it and treat it as the base — merge, don't overwrite.
1. (Optional) Pick a starting point
The repo ships a small gallery of example owners in examples/, so the user can
start from the persona closest to them instead of the professor:
examples/product-manager — Jordan Mensah, Senior PM
examples/fractional-cto — Maya Okonkwo, Fractional CTO
examples/indie-founder — Theo Lindqvist, Indie SaaS founder
examples/author — Sofia Marchetti, Author (a "companion to my book")
examples/designer — Diego Salas, Brand & motion designer
Offer it: "Want to start from an example closest to you, or from the default
professor?" If they pick one, copy it into place (use Read then Write, since
these become their files):
examples/<slug>/twinfolio.json → twinfolio.json
examples/<slug>/content/profile.md → content/profile.md
- remove the professor-specific
content/project-predictive-mind.md if present.
If they keep the default, leave the Hoffmann files in place. Either way, what's
in content/ is just a placeholder — the real corpus comes next, from them.
2. Ask the user (one short round)
Collect in a single friendly message (all optional — they can skip any):
- Persona name (e.g. "Sam Lee") and role (e.g. "Staff Engineer"). Default: keep the example owner.
- OpenRouter API key — the chat brain and the local-RAG embeddings (one key = chat + grounded answers). https://openrouter.ai/keys. Without it, chat runs in demo mode (still streams).
- Gemini API key (optional) — powers the Gemini File Search backend and the voice self-interview. Not needed for the default local backend. https://aistudio.google.com/apikey.
- Site name and public URL (optional).
Make clear: nothing is required. They can hit enter through all of it and still get a working site.
3. Write .env.local
Create .env.local (gitignored — secrets never go in git). Start from
.env.example's key names exactly; fill only what they gave you:
OPENROUTER_API_KEY=<their key or blank>
GEMINI_API_KEY=<their key or blank>
GEMINI_FILE_SEARCH_STORE_NAME=
NEXT_PUBLIC_SITE_NAME=<site name or their name>
NEXT_PUBLIC_SITE_URL=http://localhost:3000
USAGE_SALT=twinfolio-dev-salt-change-me
# ADMIN_TOKEN only matters for a DEPLOYED site (gates /admin). Local dev is open.
# ADMIN_TOKEN=<long random value, set later when deploying>
Do not add env var names that aren't in .env.example.
4. Update twinfolio.json
Edit twinfolio.json to replace the example identity with theirs (only fields
they supplied): persona.name, persona.role, persona.shortBio,
persona.greeting, and site.name / site.url / site.social.*. Keep the JSON
valid. Don't touch models, usage, or rag unless asked. Clear projects to
[] (the example's projects aren't theirs) unless they want to keep examples.
Then remove the sample corpus (mirror what the GUI wizard does on its first
real save). Once the user has supplied their own name, find and delete every
file in content/ tagged with the sample sentinel:
grep -rl "twinfolio:sample" content/
rm content/<each-listed-file>
The retrieval index already filters these out, but leaving them on disk means
the example owner's bio ships in the user's published repo. If they kept the
example identity (no name given), leave the files alone.
5. The real onboarding: build the corpus by talking
This is the point of Twinfolio. Tell them the example content/ is a placeholder
and the best way to fill it with their story is the self-interview:
- Open
/admin and start the interview (voice needs a Gemini key; text needs OpenRouter), or run /setup-twin later.
- They talk; the twin asks about their work and distills the answers into
content/profile.md.
Then build the retrieval index for their backend:
- Local vectors (default backend) — fast, no database, embeds via the
OpenRouter key (the same one as chat). Run it whenever that key is set:
npm run embed
- Gemini File Search (optional) — needs a Gemini key. Set
rag.backend
to filesearch first, then:
npm run provision-store
The store name is saved into twinfolio.json (rag.storeName), so nothing to
paste; the GEMINI_FILE_SEARCH_STORE_NAME env var only overrides it.
If the backend's key is missing (no OpenRouter key on local; no Gemini key on
File Search): skip indexing and explain RAG is off for now (the twin answers
from persona only) — they can index later once they add the key.
6. Boot it
npm run dev
Open http://localhost:3000. What they'll see:
- No keys → working site, chat replies in demo mode (canned but streamed).
- OpenRouter key → real chat in their persona's voice — and, once indexed,
grounded answers with citations (local RAG runs on the same key).
-
- Gemini key → the voice interview, and the File Search backend if chosen.
7. Hand off
- Build your corpus: the self-interview in
/admin (talk to it) — the primary path. Or drop markdown/PDF into content/ and /add-to-corpus.
- Make it yours visually:
/retheme, or edit app/theme.css.
- Tune everything in a GUI:
/admin (the Studio — open locally with no auth).
- Go live:
/deploy for the Vercel walkthrough.
Keep the final summary tight: what you changed (.env.local, twinfolio.json,
which starting example if any), whether an index was built, and the one URL to open.