Writing and publishing these docs
This site is a public repository, filmopen-ai/filmopen-docs, and anyone can add to it: FilmOpen’s own developers, and the authors of plug-ins who want their guides next to FilmOpen’s. This page is the whole route, from a clone to a live page. CONTRIBUTING.md holds the same rules in short.
Everything in the repository is public, and for ever: every page, every picture, every commit and the address on every commit. Never put a key, a token, an e-mail address or a person’s name where you don’t mean it to be read.
Two branches, two sites
Section titled “Two branches, two sites”| Branch | Site | Who it is for |
|---|---|---|
dev |
docs.dev.filmopen.ai, hidden from search engines | Everyone writing, and every development build of FilmOpen |
main |
docs.filmopen.ai | Everyone using a released FilmOpen |
- Every change goes to
dev. Nobody commits tomain. A pull request is opened againstdev, and a change merged intodevis live on docs.dev.filmopen.ai within about a minute. mainchanges only with a formal release. The maintainers mergedevintomainwhen FilmOpen is released, or when the guides have changed enough to be worth it. Until then docs.filmopen.ai stays as it was, however muchdevhas moved.- A pushed commit is never rewritten. No force-push, and no deleted branch. If your push is refused because
devhas moved on, pull and push again.
Which site the app opens
Section titled “Which site the app opens”FilmOpen opens its guides at ‹website›/docs/…, for example How to get a key on a Provider keys card, and the website sends every /docs/… address here with the path kept:
- A released FilmOpen opens
filmopen.ai/docs/…, which leads to docs.filmopen.ai. - A development build of FilmOpen (a debug or profile build, the ones with development mode) opens
dev.filmopen.ai/docs/…, which leads to docs.dev.filmopen.ai, the livedevbranch.
On 18 September 2026 the development website already sent /docs/… here; filmopen.ai will do the same once its new website is live, and until then docs.filmopen.ai can be opened directly. So a page merged into dev is what every development build shows at once. A release shows it after the next merge into main. An address that exists is never moved or removed: builds of the app are in people’s hands, and a link inside one can’t be changed.
Two kinds of page
Section titled “Two kinds of page”- Written here: the guides, under
src/content/docs/docs/guides/. A page’s place there is its address, letter for letter:src/content/docs/docs/guides/publishing.mdis/docs/guides/publishing/. Anyone can add or correct one. One file in that folder is not written here:plugins.md, Writing a plug-in, is a copy made at every build, which git ignores, so an edit to it is lost. - Copied here: the specifications, the AI platform guides and the plug-in author’s guide, under
snapshot/. They are written in FilmOpen’s own repository, which is private, and copied here byte for byte by the maintainers. Nothing undersnapshot/is ever edited by hand: the build checks every copy against a manifest and fails. If one is wrong, open an issue saying what and where.
A plug-in’s own pages
Section titled “A plug-in’s own pages”Put them in a folder of their own under src/content/docs/docs/guides/, named after your plug-in in lowercase with hyphens, for example src/content/docs/docs/guides/storyboard-sketcher/. The folder becomes a group in the sidebar under Guides, labelled with the folder’s name as you wrote it, and its pages live at /docs/guides/storyboard-sketcher/…. Choose the name once: like every address here, it is not moved afterwards. account, plugins and publishing are already taken.
Set up once
Section titled “Set up once”-
Get a clone. A FilmOpen maintainer clones
filmopen-ai/filmopen-docsitself and works ondev:Terminal window git switch devgit pullPull again every time you start: on another machine, or after a while, your clone is behind, and a push from it is refused.
Everyone else forks it on GitHub, clones the fork, and adds FilmOpen’s repository as
upstream, so that the fork can keep up with it:Terminal window git remote add upstream https://github.com/filmopen-ai/filmopen-docs.gitgit fetch upstreamgit switch -c my-page upstream/devStart every change on a branch of its own, made from
upstream/devas it is that day, and push it to your fork, not to FilmOpen’s repository:Terminal window git push -u origin my-pageThen open the pull request from that branch. If
devmoves on while you work,git fetch upstreamandgit merge upstream/devbring your branch up to date, without rewriting what you have already pushed to your fork. -
Install Node 24 (the version in
.node-version, which is what the site is built with), then the site’s packages:Terminal window npm install -
Install the hooks, and commit with your GitHub noreply address. Hooks and a local address belong to a clone, so do this in every clone:
Terminal window scripts/install-hooks.shgit config --local user.email "<id>+<login>@users.noreply.github.com"GitHub → Settings → Emails shows your noreply address. With Keep my email addresses private and Block command line pushes that expose my email turned on there, GitHub also refuses a push that carries your own address. The commit hook refuses a change that carries anything shaped like a key, or an author address that isn’t a noreply one. The push hook asks about the addresses again, because a merge, a cherry-pick and a rebase make commits without the first hook. It doesn’t scan for keys, so the commit hook is the one that must have run. Both print a file’s name, never what they found.
Write a page
Section titled “Write a page”-
See the site as you write:
Terminal window npm run dev # http://localhost:4321 -
Start from a page that exists. Copy the top of
account.md: atitle, a one-sentencedescription, aneditUrlpointing at the file ondev, and a sidebarlabelandorder. -
Write what a person does, in the order they do it, with the words the app shows on screen: Settings → Provider keys, not “the keys page”. A message the app shows is quoted letter for letter. Say what isn’t built yet rather than leaving it out.
-
Pictures go in a folder named after the page, beside it:
publishing.mdwould usepublishing/step-1.png, written in the page as. The text in brackets describes the picture for someone who can’t see it: say what is on it and what is outlined.
Screenshots
Section titled “Screenshots”The platform guides show how every picture here is made, and a plug-in’s guide can follow the same rules:
- One step, one picture, cropped to the part of the page the step is about, and the thing to press outlined in red.
- Nothing private on it. Black out a key before you take the picture, not afterwards, because a key in the original file is still a key. Leave out e-mail addresses, names, account and invoice numbers, and card details. Take the picture before you type any of those, or cover them.
- In FilmOpen, a stand-in value, never a real key. A development build can be driven through its own MCP server and pictured from its own render tree, with a stand-in that its built-in key check accepts.
- Look at every picture before it is committed, at full size. Something shaped like a key is caught by a check. A key drawn in a picture’s pixels is not.
- Say when it was taken. Sites change, so a guide says the date its pictures were taken, and which steps it describes without having tried them.
Check it, then open a pull request
Section titled “Check it, then open a pull request”-
Run what the pull request’s check will run:
Terminal window npm run check # the configuration, the copies, the types, the lintnpm test # builds the site, then tests the built pages -
Commit with a message that says what changed:
Docs: <what>for a page written here. -
Open a pull request against
dev, nevermain. Thecheckworkflow runs on it, and a maintainer reads it, looks at its commits and its pictures, and merges it. Within about a minute of the merge, your page is on docs.dev.filmopen.ai. -
Your page reaches docs.filmopen.ai with the next release, when the maintainers merge
devintomain.
FilmOpen’s own changes
Section titled “FilmOpen’s own changes”A maintainer’s change follows the same route with one difference: it can be pushed to dev directly, once npm run check and npm test pass and a review by someone other than its author has passed it.
Updating a copied document
Section titled “Updating a copied document”This is the maintainers’ part: a copy can only come from FilmOpen’s repository, which is private.
-
Change the document where it is kept, in FilmOpen’s repository: a platform guide is
docs/platforms/‹platform›.md, with its pictures indocs/platforms/‹platform›/. Commit it there. What is public is decided there too, bydocs/publish.json, and nothing it doesn’t name can be copied. -
Import it here, from a checkout of FilmOpen whose
HEADis what it publishes today and holdsdocs/publish.json. The maintainers keep one beside this repository as../filmopen-publish:Terminal window npm run import -- --source ../filmopen-publishThe import reads that commit through git, never the working files, so nothing uncommitted can get out. It is always whole, and refuses anything
publish.jsondoesn’t name, a file that isn’t Markdown or a picture, a file over 5 MB, and anything shaped like a credential. Commit what it wrote asSnapshot: ‹commit›. -
Hold the copies to their commit, then look at every picture the import added:
Terminal window npm run snapshot:verify -- --source ../filmopen-publish -
Check, review and push to
devas above.
An example: the xAI guide
Section titled “An example: the xAI guide”The xAI (Grok) guide was added on 18 September 2026 this way:
- An account, step by step. A new xAI account was opened in a browser, and each page was pictured as it came: sign-up, the team, buying credit (with auto top-up, which is on by default), and creating the key. Each picture was cropped to its step, and the button outlined in red. The key was blacked out on the page before its picture was taken, and the full-screen captures were deleted once cropped. The owner signed in, paid and copied the key; nothing private went through the person taking the pictures.
- FilmOpen’s side. A development build was started without a screen, through its MCP server. Its Provider keys card was pictured with a stand-in value, and so was Key was accepted. The owner then saved the real key in their own FilmOpen, and xAI accepted it, to be sure the steps worked.
- Facts, from their sources. What $5 and $50 buy, whether they are subscriptions (they aren’t) and what auto top-up does were checked against xAI’s billing pages, and each claim in the guide links to the page it came from.
- Written where it is kept. The guide went into FilmOpen’s repository as
docs/platforms/xai.mdwith 14 pictures, beside its technical notes, and the overview of platforms was updated with it. Naming the guide in FilmOpen’s own file for xAI is what gives the xAI card its How to get a key button. - Imported, checked, reviewed, pushed. The import copied them here at that commit,
npm run checkandnpm testpassed, a separate review read every page and looked at every picture, and what it found was fixed before the push todev.