The desk is where vfrey keeps its state. It lives on your machine.

The database

Each project has its own database: <project>/.vfrey/pipeline.sqlite. Outside a project, commands use the machine desk: ~/.vfrey/pipeline.sqlite. VFREY_HOME or DATA_DIR choose another folder and win over a project. See Projects for the order. A job in progress shows up in the dashboard of the desk it belongs to. Videos land in the project’s videos/ folder under readable names. On the machine desk, renders go to $VFREY_HOME/renders/, which is ~/.vfrey/renders/ by default. With no accounts.json, the first npx vfrey tick --now imports the first-run series. There is no copy step. An older folder with ./data/pipeline.sqlite merges in with:
To move a machine desk into a project, with readable video names, use npx @vfrey/vfrey@beta init --from ~/.vfrey instead. See Projects.

The dashboard

This is the command to use. It opens this project’s dashboard in your browser and prints its URL. If the dashboard is already running, open reuses it. If not, it starts one in the background, so it keeps running after your agent session ends, and writes its log to .vfrey/dashboard.log. Pass a run id, or a video’s path or title from npx vfrey videos, to open that run’s page. --no-browser prints the URL only. There is one dashboard per project. Two projects run two dashboards on two ports, and every page shows its project’s name: in the sidebar under the vfrey wordmark, and in the top bar when the window is narrow (the machine desk shows “Machine desk”). open only reuses a dashboard that says it serves this project, so it never lands on another project’s. A tick starts the dashboard too and leaves it running. To stop this project’s dashboard:
It stops the process the project recorded in .vfrey/dashboard.json, only while that port answers as this project, and prints No dashboard is running for project NAME. when none is. --stop does the same. To run it in the foreground instead:
It prints vfrey dashboard http://127.0.0.1:PORT as its first line. When this project’s dashboard is already running, it prints that address and exits 0 rather than starting a second one. The port is the one it recorded last, if free, else 4317 (or VFREY_DASHBOARD_PORT), else the first free port above it, trying up to 50 ports. With 4317 to 4319 in use, the dashboard lands on 4320. --port PORT forces one. npx vfrey dev and npx vfrey desk serve are the same command. The sidebar groups the screens: Board on its own, then Create (Series, Sources, Topics, Creators), Publish (Review, Runs, Publications), Grow (Metrics, Comments, Mail), and Setup (Warnings, Connections, Settings). Topics, Creators, and Mail carry a “Credits” tag. The dashboard shows:
  • the board of waiting, running, finished, and failed jobs
  • the runs, and a stage timeline for each run with its video
  • the series editor, with Go live and the switches, see Autopilot
  • Connections, Publications, Sources, Comments, Review, and the Trends tab of Metrics, see Autopilot
  • Topics, Creators, and Mail, which need an account, see Plans and credits
  • metrics and warnings, see Metrics
  • a Checks list on each run page, see Quality checks
  • settings
Loading it uploads nothing.

Metrics

The Metrics page shows the latest reading for every published post, and it never invents a number.
  • A dash (—) means the platform did not return a value. It is never a zero.
  • Under a dash, a small label says why. not exposed by the TikTok API means that platform’s official API never returns the field (watch time and retention on TikTok and Instagram, retention on Facebook, revenue anywhere but YouTube). YouTube returned no value means the read gave nothing back this time.
  • Totals and averages run over the known values only, and say how many that is: 12.4K views across 3 of 5 posts, or Mean of 2 of 5 posts that report it. With nothing known, the page says so instead of showing 0.
  • Each row says when it was read and from where: as of 2 hours ago, from YouTube. The page also shows the time of the newest reading.
  • A post published in a dry run is listed with the reason it has no metrics: nothing was published, so there is nothing to measure. A post that is live but not measured yet says to run npx vfrey analytics.
  • Revenue shows a dash with the status forbidden or a note that the official API does not provide it. Strikes and demonetization are not exposed by any official API.
Retention is a percent from 0 to 100, exactly as the platform returns it. To see a video, run npx vfrey open. The run page is /runs/JOB_ID. The tick summary ends each job with See it: and a live link to the run page. An agent with no browser can use two routes instead: An agent with no browser can also read the file straight from videos/: npx vfrey videos lists the paths.

The desk verbs

An agent reads the desk with npx vfrey desk snapshot --json and changes it with npx vfrey desk ... verbs.

Retry or cancel a job

Find the job id in the dashboard or in the snapshot.
cancel stops a stuck or running job. retry runs a failed job again. If a run is interrupted, the next tick reclaims the job when its process is gone. If it does not, cancel the job, then retry it.

What the agent cannot change

Publications, metrics, and the comment ledger cannot be deleted. Secrets are sealed with CREDENTIALS_KEY, a 32-byte base64 value, and are read back only as present or missing.