op - OpenPencil CLI (drives the editor over the HTTP MCP transport)

USAGE:
  op [--port N] tools                     list every MCP tool + input schema
  op [--port N] <tool> [key=value ...]    call one MCP tool with string args
  op [--port N] <command> [options]       TS-style command aliases
  op help                                 show this message

COMMON COMMANDS:
  op start [--file path.op] [--port N]     launch the live editor (live canvas);
                                           op <tool> then drives the on-screen canvas
  op start --web [--host H] [--file path.op]
                                           serve the browser editor (wasm bundle +
                                           MCP) and open http://127.0.0.1:PORT;
                                           --host 0.0.0.0 binds for LAN/Docker
  op start --headless [--file path.op]     run the windowless file-backed MCP server
                                           (CI / display-less agents)
  op stop                                  stop the running editor / MCP server
  op install [--target T]                  install openpencil-skill for AI agents
  op uninstall [--target T]                uninstall openpencil-skill
  op skill:export <skill> [--out DIR]       export embedded skill as DIR/<skill>/SKILL.md
  op status                               check whether MCP HTTP is reachable
  op export [--item ID|--selection] --output PATH [--format png] [--scale N]
                                          export a page, arbitrary node, or the
                                          current Live Canvas selection; omitting
                                          --item is equivalent to --selection
  op export-deck --output PATH [--format pptx|html|pdf]
                                          export the active page's boards as a
                                          presentation deck: PowerPoint, self-
                                          contained HTML, or slide-per-page PDF
  op export-frames --output-dir DIR [--format png|jpeg|webp]
                                          export every top-level frame on the
                                          active page, one image per frame
  op templates [--scene S] [--tag T]        list scene templates: the shipped
                                          catalogue plus the templates you
                                          saved, saved first (user: ids)
  op use-template <id>                      start from a scene template: takes
                                          over a blank starter page, otherwise
                                          appends its boards
  op styles [<id>] [--tag T] [--platform P] list style guides: the shipped
                                          corpus plus your imported DESIGN.md
                                          files; a bare id prints its markdown
  op get [--type T] [--name N] [--id ID] [--depth N] [--parent P]
  op selection                            get current selection
  op insert <json|@file|-> [--parent P] [--page PAGE] [--post-process]
                                          insert a PenNode JSON tree
  op update <id> <json|@file|-> [--page PAGE] [--post-process]
                                          patch node data
  op delete <id> [--page PAGE]            delete a node
  op read-nodes [ids] [--depth N] [--vars] [--page P] [--file F]
  op move <id> [--parent P] [--index N] [--page PAGE]
                                          reparent a node (empty parent = page root)
  op copy <id> [--parent P] [--page PAGE] deep-copy a node
  op replace <id> <json|@file|-> [--page PAGE] [--post-process]
                                          replace with PenNode JSON
  op design <dsl|json-array|@file|->      call batch_design(operations/nodes_json)
      --script            treat the payload as a sandboxed JS program (I(parent, obj) + loops); implied for @file.js / @file.mjs
  op design:skeleton <json-array|@file|->
  op design:content [section] <json-array|@file|->
  op design:refine --root-id <id>
  op design:upsert-vars --key K --file vars.json [--source P] [--hash H]
  op design:upsert-component --key K --name N --file node.json [--source P] [--hash H]
  op design:upsert-screen --key K --file node.json [--source P] [--hash H]
  op design:status [--kind token|component|screen]
  op design:lint [--node ID]
  op page list|add [--name N]|remove|rename|reorder|duplicate ...
  op vars                                 get variables + theme axes
  op vars:set <json|@file|-> [--replace] set variables
  op themes                               get theme axes
  op themes:set <json|@file|-> [--replace]
  op layout [--parent P] [--depth N]      snapshot layout tree
  op find-space [--direction D] [--width W] [--height H]
  op import:svg <file.svg> [--x N] [--y N] [--parent P] [--page PAGE]
  op import:html <file.html|url> [--x N] [--y N] [--parent P] [--page PAGE] [--viewport-height N] [--out out.op]
  op import:snapshot <snapshot.json> [--x N] [--y N] [--parent P] [--page PAGE] [--out out.op]
  op import:figma <file.fig> [--out output.op]
  op codegen:plan <plan-json|@file|->
  op codegen:submit <planId> <chunk-result|@file|->
  op codegen:assemble <planId> [--framework react]
  op codegen:clean <planId>

GLOBAL FLAGS:
  --port <n>      MCP HTTP port (default: 3100). When omitted, server-bound
                  commands auto-discover the live editor via
                  ~/.openpencil/.op-mcp-port (verified with a JSON-RPC ping)
  --pretty        pretty-print JSON replies
  --file <path>   `op start` document path; otherwise target .op file for
                  tools that accept filePath (omit for the live canvas)
  --page <id>     target page ID for tools that support pageId

The server must be running at:
  http://127.0.0.1:3100/mcp

Low-level examples:
  op tools
  op insert_node kind=rect name=Box x=10 y=20 width=100 height=60
  op set_node_fill_hex node_id=n3 hex=#ff0000
