jun eval, and push them back.
You don’t have to choose one or the other. People who prefer forms keep using the Agent pages; developers work in git; both edit the same config, and the desk keeps every save as a version.
The files
A config is a folder with these files. Only these paths count; anything else in the folder is ignored by the CLI and refused by the desk.jun pull also writes AGENTS.md, CLAUDE.md and README.md: a generated guide to these files for coding AIs and people, never pushed (see Edit with your own AI).
Every key of every file is in the file format reference. For what each part does from the desk’s side, see Instructions, Tasks, Actions, Widgets and Tests.
The whole config is checked every time it’s saved or pushed. A file with an error is refused with a message that names the file and the problem, so a broken config never goes live. Limits: 200 files, 256 KB in total, 20 actions and 20 widgets.
See the files on the desk
Each Agent page has a Form / Code switch (an item’s page has AI and Code tabs). Code shows the same item as its file, in the exact text thatjun pull downloads. The forms change single fields in place, so comments, key order and keys a form doesn’t show survive an edit. A file that doesn’t parse is left for you to fix in Code.
Versions and history
Every save is a new version: a save on the Agent pages, and everyjun push. Press History at the top of the Agent page to see the most recent 50, with:
- the version number, and Live on the one the AI uses now,
- the note it was saved with (
jun push -m "…", or the note in the save bar), - Pushed from git or Saved, who did it and when,
- the files it changed.
desk.yaml (notes like “Chat widget settings”).
Restore on an older version copies it into your draft. Nothing changes for customers until you save that draft, which makes a new version. Nothing is ever overwritten, so restoring can always be undone the same way.
Until the first save, the AI uses the built-in default instructions, and History says so.
Keep it in git
Settings → AI has a Keep it in git card with the commands for your desk. Thejun CLI lives in the Jun repository, so you run it from your checkout of that repo (the copy the Deploy button made in your GitHub account works).
1
Create an API token
Go to MCP → API tokens, give the token a name (for example
laptop) and press Create token. Copy it: it’s shown only once. A token acts as you, for this workspace’s agent config only.2
Log in from your checkout
~/.jun/desk.json.3
Pull the live config
support-agent/ and records the version in support-agent/.jun-version. Commit both.Starting from nothing? npm run jun -- init support-agent writes a starter set instead (instructions, two tasks, example actions and a widget, and tests).The workflow
Once the folder is in git, a change looks like any other code change.1
Edit
Change files in a branch. For example, add a rule to
instructions.md or a step to tasks/refund.md.2
Test
3
Review
Open a pull request. Run the same command in CI so reviewers see the results (see Run evals in CI).
4
Push
When someone edited on the desk
jun push refuses to overwrite edits made on the Agent pages since your last pull:
jun pull, look at the diff with git diff, keep what you want, commit, and push again. Pushes from git never conflict with each other: git is where those changes are merged. Only saves made on the desk since your .jun-version count.
One exception: changes made only on the settings pages (in desk.yaml) don’t stop a push. If your folder didn’t change desk.yaml since your pull, the push keeps the desk’s desk.yaml and goes through; if it did, it stops as above.
Going the other way, a desk save starts from the version the page loaded. If someone saved in between and the two saves changed different files (for example, you edited the instructions while someone changed the widget’s colour), your files are saved on top of theirs. If both changed the same file, the save bar says the config changed and offers Load theirs (drops your edits) or Keep mine. Whatever they save shows up in your next jun pull.
Edit with your own AI
A pulled folder is ready for a coding AI such as Claude Code, Codex or Cursor. Besides the config,jun pull writes AGENTS.md: a guide that tells the coding AI what the folder is, every file and key, the rules (never put a key in a file), and the loop of eval, fix and push. Claude Code reads CLAUDE.md, which imports the same guide. The support AI’s own instructions are in instructions.md, so the coding AI never mistakes them for its own.
1
Create a token and pull
Create an API token in MCP → API tokens, then from your checkout:
2
Open the folder in your coding AI
Open
support-agent/ in Claude Code, Codex or Cursor and ask for the change in your words: “add a task for refund requests over $100 that hands off to billing”, “add an action that looks up the customer’s plan”.3
Test
Have it run
npm run jun -- eval support-agent --mock-tools and fix what fails. Add a test case for the new behaviour.4
Push
Review the diff, then
npm run jun -- push support-agent -m "…". A push goes live at once.instructions.md or a task.
What stays out of the files
Some things are deliberately not in the config, so they can’t end up in git:- Keys for actions. An action’s file names a key as
{secrets.NAME}; the value is a Worker secretJUN_SECRET_NAMEor a key pasted on the action’s page. See Secrets and settings. - The provider and its credentials. Choose the provider, paste keys and sign in to ChatGPT in Settings → AI. Whether the AI is on, the model, the per-job models and the monthly cap are in
desk.yaml. See Models. - Logos, people and notifications. Logos are uploaded on the Chat widget page; team members, invites and each person’s notification settings stay on the desk.
- Knowledge. Your docs, files and snippets live on the Knowledge page. See Knowledge.
jun CLI
Every command, flag and environment variable.
File format
Every key the desk accepts, file by file.
Evals in CI
Test every pull request and push on merge.
Tests
Writing test cases on the desk.