npm create vfrey@beta my-channel, open it in your coding agent, and ask for videos. The folder tells the agent what to do, holds the videos under readable names, and has its own dashboard.
A project is explicit: it is the folder that holds a vfrey.json file. A command run in some other folder does not quietly make a database there.
What is in it
vfrey.json looks like { "version": 1, "name": "my-channel", "id": "<uuid>" }. The id lets a dashboard prove which project it serves. Commit vfrey.json. The .gitignore leaves out node_modules/, .vfrey/, and videos/.
The skill copies in the project match the version of the package the project installed, so they are never older than it. Because the instruction files and skills are already there, an agent started in the folder needs nothing else. See Your agent.
npx @vfrey/vfrey@beta init does the same scaffold in the folder you are in. Run it again to repair a project: it writes what is missing and keeps what exists. create-vfrey is a thin wrapper around it that also runs npm install and vfrey doctor.
Found like git finds .git
Every command starts in the folder you run it from and walks up to the first folder that holds vfrey.json. That folder is the project root, and its data folder is <root>/.vfrey/. So you can run npx vfrey from my-channel/scenes/octopus/ and it works on my-channel.
Which engine renders
Each run picks an engine in this order:--engine, then the series, then the project’s vfrey.json (npx vfrey init --engine ENGINE_ID records it), then the machine default. See Engines.
Where the data goes
The data folder is chosen in this order:DATA_DIR, if set.VFREY_HOME, if set.- The nearest project’s
.vfrey/folder. - The machine desk,
~/.vfrey.
tick, worker, render, videos) prints one line on stderr:
DATA_DIR or VFREY_HOME set, the line is not printed, because the data is not on ~/.vfrey. In --json output, tick, videos, and open report project as { name, root }, or null when no project decided the folder.
Readable videos
In a project, a finished video isvideos/YYYY-MM-DD <title>.mp4, with the transcript beside it as .txt. The title is made safe for a file name: no / : \ * ? " < > |, at most 80 characters. If the name is taken, it becomes ... (2).mp4. The run id stays in the database and the dashboard, not in the file name.
Do not rename or move a video by hand, because vfrey tracks its path. Outside a project, the machine desk keeps renders/JOB_ID.mp4 as before. npx vfrey videos lists them either way.
One dashboard per project
npx vfrey open reuses this project’s dashboard when it is running. If not, it starts one in the background, waits until it answers, opens your browser, and prints the URL. Run it again and you get the same dashboard, not a second server. The dashboard outlives the agent session. Its log is .vfrey/dashboard.log.
Two projects run two dashboards on two ports, and each page header shows its project’s name (the machine desk shows “Machine desk”). A dashboard counts as this project’s only when it answers GET /api/state with this project’s id, so open never lands you on another project’s dashboard. See Local desk.
The machine index and vfrey projects
~/.vfrey/projects.json lists every project on the machine: id, name, root, and when it was last used. init and create-vfrey add to it, and any command that resolves a project refreshes its entry. It is a convenience only. A project’s data never depends on it.
missing. npx vfrey projects --prune drops those, and --json prints it for a machine.
Outside a project, npx vfrey open does not guess. If the machine desk has no videos and projects exist, it lists them and tells you to cd into one.
Bring your ~/.vfrey along
If you made videos before projects, import them:
npx @vfrey/vfrey@beta init --from ~/.vfrey. It copies the database (run ids kept), the renders as readable files in videos/ with their transcripts, and the scene copies. Stored paths are rewritten. The source is not changed, and a source that another vfrey process is writing to is refused. Run it again and it adds nothing.
Symlinked folders
vfrey compares folders by their real path, with symlinks resolved. A project reached through a symlink is the same project: discovery, the data folder, the machine index (projects.json lists it once, by its real root), and the dashboard check all agree. So cd into a symlink to a project and run npx vfrey as usual.
Move or rename the folder
Moving or renaming a project folder is fine. A project’s video paths are stored relative to the project root, and discovery finds the marker wherever the folder now is. The machine index updates the next time you run a command inside it. Until thennpx vfrey projects shows the old path as missing.