Scripting and CI
Run DCode from a script or a CI job: one prompt in, an answer or JSON out.
On this page
dcode -p runs one prompt without the workspace and exits. It reads the folder it runs in, does the task and prints the answer, so a script or a CI job can use it.
Run one prompt
dcode -p "Explain the failing tests in this repository"--model "Raven Max"picks the model; without it, your saved choice, else Raven Flash.--fallback-model "Raven Flash"is used when the chosen one is busy.--attach <path>adds a file, an image or a PDF; repeat it for more.--max-turns <n>stops the run after that many turns.--cwd <path>runs in another folder, and--add-dir <folders...>lets the agent work in more folders.--worktree [name]runs in a new git worktree on the branchdcode/<name>, so the run's changes stay apart from your working tree.
A run never stops to ask about updates. Every flag is on CLI reference.
Permissions in a run
Nobody can answer a question during a -p run, so a step that would ask is refused. That is why -p runs in yolo (Full access) unless you pass another mode. Choose what the run may do:
# read and plan onlydcode -p "Plan the migration to the new API" --mode plan# ask-before-changes, with the tools the job needs allowed up frontdcode -p "Run the tests and fix what fails" --mode build --allowed-tools "Bash(npm test:*) Edit"# no shell for this rundcode -p "Summarise the open TODOs" --disallowed-tools "Bash"--allowed-tools takes tool names such as Edit, rules such as Bash(npm test:*), and MCP tools such as mcp__github__*, separated by spaces. A rule that is not a tool rule stops the run before it starts. What each mode allows is on Permission modes.
Output formats
--output-format | What is printed |
|---|---|
text | The answer, and nothing else. The default. |
json | One JSON object when the run ends. --json does the same. |
stream-json | One JSON object per line for each event as it happens, then a closing line whose type is "result", with the fields of json. |
Any other value stops the run with a message, so a typo never turns into plain text a parser cannot read. The JSON object has these fields:
| Field | What it holds |
|---|---|
sessionId | The session, to pick it up again with --resume. |
traceId, turnId | Ids of the run and its turn, for support. |
response | The answer. |
structuredOutput | With --json-schema: the answer as a JSON value. |
turnResponses | When the run took more than one turn: each turn's answer. |
usage | The run's tokens, when they are known. |
eventCount | How many events the run had. |
projection | status, turnCount, totalTokenCount, contextUsed and contextWindow of the session. |
Answers that match a JSON Schema
dcode -p "List the packages in this repository" --json-schema schema.json--json-schema takes JSON text or a file. The answer must be JSON that matches the schema: if the first answer does not, DCode asks once more in the same session; if that one does not match either, the run prints Error: the answer did not match --json-schema with the reason and exits with 1. With text output the JSON value is printed on one line; with json it is in structuredOutput.
Several messages on standard input
printf '%s\n' '{"type":"user","message":{"role":"user","content":"Find the slowest test"}}' \ '{"type":"user","message":{"role":"user","content":"Now make it faster"}}' \ | dcode --input-format stream-json --output-format stream-jsonEach line with "type":"user" runs one turn, all in the same session, and each ends with its own result line. content is a string, or a list whose text parts are joined. Lines of other types are skipped. A line that is not JSON is skipped with a message on standard error, and the run then exits with 1.
Sign in on a CI machine
Set DCODE_API_KEY to an API key from your dashboard (Create a key). It signs in for that run without a browser:
export DCODE_API_KEY="<your key, from your CI secrets>"dcode -p "Review the changes on this branch and list the risks" --mode plan --output-format json > review.json- The key is held in memory for the run only. It is not saved, printed or logged, and it is taken out of the environment before anything runs, so the agent's own commands never see it.
- If the key is refused, the run prints
DCODE_API_KEY was refused. Check the key in your Dipole ML Inc. account dashboard.and exits with 1. - Requests made with an API key are paid from your API credits (API credits).
Without DCODE_API_KEY, a run uses the sign-in saved on the machine by dcode login. With neither, it prints Not signed in. Run `dcode login` to sign in with your Dipole ML Inc. account, then try again. and exits with 2.
Sessions in scripts
# give the session an id you choose, and a namedcode -p "Read the codebase and summarise it" --session-id 6f1c3c1e-3a0b-4c2e-9d7a-2b9f7c1d0e11 --name nightly-summary# carry on in the same sessiondcode -p "Now list the riskiest modules" --resume sess_6f1c3c1e-3a0b-4c2e-9d7a-2b9f7c1d0e11# carry on in a copy, leaving the original as it wasdcode -p "Try another approach" --continue --fork-session--session-id takes a UUID, with or without sess_ in front, and refuses one that already exists. --continue picks up the latest session in the folder.
Work towards a goal
dcode --target "All tests pass on Node.js 22"--target sets the session's goal and works on it without the workspace. --target-replace replaces a goal the session already has. It cannot be used with -p. Unlike -p, it does not switch to yolo; pass --mode to choose the mode.
A browser in a run
--browser-use headless lets a run use a browser without a window, and --browser-executable <path> names the Chrome or Chromium to use.
Exit codes
| Code | Meaning |
|---|---|
| 0 | Done. |
| 1 | Something failed: a wrong flag or value, an empty prompt, a refused API key, an answer that did not match --json-schema, a stdin line that was not JSON, or an error during the run. |
| 2 | No sign-in. |
| 3 | Node.js is too old (22.13 or newer is needed). |
An error is one plain line on standard error, with the run's traceId. --verbose, or DCODE_LOG_CONSOLE=1, prints the full error output.