Step 6: Let people make their own board
The same picker vvd run shows in the terminal, built from inside the app itself.
Step 5 proved two boards can be independent. It didn't show you how anyone gets a second
one. Right now that's a terminal question — vvd run asks "open which project?" before it
ever shows you a browser. Here's that exact prompt, for real, in a real project:
$ vvd run
? Open Toy in which project? › (Use arrow keys)
❯ The Salt Road
Winterhold
+ New — a fresh ToyPick one (or make one) and the dev tab opens already scoped to it — that's the mechanism behind Step 5's independence, driven from a terminal instead of two browser panes.
Your app can offer the same choice inside its own UI, with the capability that prompt is built on:
const projects = useHostCapability("projects")
const boards = await projects.list("toy") // every board this world has
const fresh = await projects.create("toy", "A new board")Add a small header above the canvas that lists existing boards and makes new ones:
Edit and the example re-runs. Tab indents; press Escape to leave the editor.
You should see: a thin bar above the board, naming your scope ("world canon" — a docs
page mounts no project) and a + New board button. Click it a few times; the pill row
fills up. Nothing is wired to actually switch boards here — that's the tab's job, covered
next — but the list and the creation are real calls against the fake host, the same shape
vvd run's prompt makes against the real one.
needs: ['projects'] — new here
Every capability your tool touches gets declared. useCollabState didn't need one
(collaboration is granted by default); projects does — it's how the install screen
tells a user "this app can create instances of itself" before they say yes.
Switching, for real
Inside a real world, your app is mounted as a tab, and the tab knows which board it's bound to:
const tab = useHost().tab
tab?.setProject(chosen) // re-bind THIS tab — the host persists it and re-scopes you
tab?.setProject(null) // back to world canonRead tab off the host rather than through useHostCapability — it only exists where
there are tabs, and a docs page, an embed, and a published link all honestly have none.
Projects covers tab and the
projects capability end to end.