Files
designcraft/docs/agents.md
T
noah1400andClaude Opus 5.5 8547a9fca4 CLI: --export writes the file type its extension names (#432)
--export knew .pdf, .epub, .idml and .designcraft and saved a PNG of
the page under every other name: out.html, out.txt, OUT.PDF, and
out.designcraft from `script`. The exit status was 0.

.html and .htm now run file.exportHtml, .rtf and .txt run
file.exportText (the story being edited or of the selected frame), and
extensions match in any case. A name with another extension is an
error before anything runs; one with no extension is still a PNG.
`run` and `script` share one list, and `script` saves a copy for
.designcraft.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 11:55:05 +02:00

4.2 KiB

Driving DesignCraft from agents and scripts

Every user-visible action in DesignCraft is a command (crates/engine/src/cmd), and every command is reachable three ways — pick whichever fits the agent:

Surface Use it when Entry point
CLI One-shot jobs, shell pipelines, CI: build or edit a document and export it designcraft-cli run, script, app, describe, commands
MCP Claude and other MCP clients; images of pages and the window come back as content designcraft-cli mcp (mcp.md)
Control channel Your own client driving the running app (JSON lines over TCP) designcraft --control 7979 (control-protocol.md)

Discover commands

designcraft-cli commands footnote        # every command whose id/label/menu mentions "footnote"
designcraft-cli describe xref.insert     # label, menu path, shortcut and parameters of one command

Parameters are documented on each command (params), e.g. {anchor? | paragraph?: text to find | story? + para?, format?}.

Scripts: several commands, later ones using earlier results

A script is one command per line (command.id {json params}; # comments), JSON lines, or a JSON array of {command, params}. A parameter string "$N.path" becomes that value of step N's result (0-based, $last for the previous step); "${N.path}" interpolates inside longer strings.

cat > page.dcs <<'DCS'
frame.create {"rect": [72, 72, 540, 300], "content": "text", "text": "Results of the survey"}
text.select  {"story": "$0.story", "anchor": 0, "focus": 0}
footnote.insert {"text": "Survey run in 2026."}
frame.create {"rect": [72, 320, 540, 500], "content": "text", "text": "See ."}
text.select  {"story": "$3.story", "anchor": 4, "focus": 4}
xref.insert  {"paragraph": "Results", "format": "Paragraph Text & Page Number"}
DCS
designcraft-cli script page.dcs --save page.designcraft --export page.pdf --export page.png
designcraft-cli script page.dcs --connect 7979      # the same steps, live in the running app

The result is JSON: {"completed": n, "results": [...]}, plus failedIndex / failedCommand / error when a step fails (the exit status is non-zero; --keep-going records errors and continues). run --cmd ID=JSON accepts the same references, and MCP's batch tool takes commands or script text with them.

run works through its arguments in order. --page, --scale and --pdf-options apply to the --export / --all-pages that follow them, so one run can write several sizes (run --sample --scale 0.5 --export small.png --scale 2 --export large.png); one with no export after it is an error.

--export writes the file type its extension names: .png or .jpg (a page), .pdf, .designcraft, .idml, .epub, .html, and .rtf or .txt (the story being edited or of the selected frame). A name with no extension is a PNG of the page; another extension is an error, and nothing runs.

Data merge

data.source.select {path, sheet?} links a CSV/TSV/.xlsx file to the document (data.source.update re-reads it, data.source.remove drops it); data.fields lists its fields. data.placeholder.add {field, role?, story?, at?, end?, item?} marks text or a frame as a field (role: text, image, qr, hyperlink); data.options sets records, tiling and image fitting; data.preview {record} / data.preview.stop show one record without saving it.

data.merge now creates a new document and leaves the template unchanged (the old spread parameter, which appended pages to the template, is an error). It uses the linked source, or inline csv / rows / path / bytes:

echo 'data.merge {"path": "people.csv", "records": "range", "range": "1-20"}' | designcraft-cli script - --in template.designcraft --save merged.designcraft

The running app

designcraft --sample --control 7979 &
designcraft-cli app type.changeCase '{"case": "title"}'            # any command
designcraft-cli app --method ui.screenshot '{"path": "/tmp/w.png"}' # any control-channel method

ui.menu.invoke {command} without params acts like choosing the menu item: a command labelled "…" opens its dialog, which ui.dialog.set / ui.dialog.confirm fill in and close like a user would.