Skip to content

Latest commit

 

History

History
330 lines (254 loc) · 13.4 KB

File metadata and controls

330 lines (254 loc) · 13.4 KB

CLI reference

The CLI is the shell-native way to run and control PMX Canvas. It targets http://localhost:4313 by default — override with PMX_CANVAS_URL or PMX_CANVAS_PORT when the server runs elsewhere, or per invocation with the global --port <n> / --server-url <url> flags (any position; --server-url wins over --port, and both win over the environment variables). An invalid value for either flag is a hard error — the CLI never falls back silently to the default port.

pmx-canvas node list --port 4750                      # target a non-default daemon
pmx-canvas --server-url http://127.0.0.1:4750 status  # same, by URL

pump — reactive steering for CLI agents

pmx-canvas pump turns any CLI agent (Codex, Amp, a script) into a steerable board citizen: it long-polls the per-consumer delivery claim and runs your command once per steer, marking per-consumer on success.

On Windows the exec runs through cmd.exe and receives the steer message on stdin. The {message} and {id} placeholders are refused there: cmd.exe expands %VAR% and re-parses the result, so a steer containing shell metacharacters could inject commands. Read stdin, or reference PMX_STEER_MESSAGE / PMX_STEER_ID inside your own script.

pmx-canvas pump --consumer codex-cli --exec 'codex exec --full-auto {message}'
pmx-canvas pump --consumer amp --exec 'amp -x {message}' --parent claude-code

The Codex example starts a non-interactive CLI task. It does not steer an open Codex desktop task: desktop owns that thread's writer and requires a host adapter that uses the app's native follow-up channel.

  • The steer text reaches the command as $PMX_STEER_MESSAGE (env) and stdin; {message} in the template expands to the quoted env reference — steer content is never spliced into the shell line.
  • The delivery envelope rides along as env: $PMX_STEER_ID, $PMX_STEER_SOURCE (who sent it), $PMX_STEER_TARGET (your consumer key, or ALL for a broadcast), and $PMX_STEER_CREATED_AT — so the host turn can say who steered, whether it was addressed, and how old it is.
  • Startup backlog is marked silently (pass --backlog deliver to process it).
  • A failing command is retried twice, then the pump exits non-zero and leaves the steer pending so a failed host injection cannot look delivered.
  • --parent <key> rolls the pumped agent up under an orchestrator's chip; --once processes a single steer (useful in scripts and tests).
  • Survives daemon restarts; backs off against pre-0.4.9 servers that ignore waitMs.

Server lifecycle

pmx-canvas                            # Start canvas, open browser
pmx-canvas --demo                     # Start with the showcase demo board
pmx-canvas --port=8080                # Custom port
pmx-canvas --no-open                  # Headless (for agents/CI)
pmx-canvas --theme=light              # dark | light | high-contrast | midnight | sepia | arctic | ember | forest | volt
pmx-canvas --mcp                      # Run as MCP server (stdio)
pmx-canvas --webview-automation       # Start headless Bun.WebView session
pmx-canvas open                       # Open the current workbench in a browser

Daemon mode

Run detached with pid/log tracking instead of holding a terminal:

pmx-canvas serve --daemon --no-open --wait-ms=20000   # Start detached, wait for health
pmx-canvas serve status                               # Inspect daemon health + pid
pmx-canvas serve stop                                 # Stop the daemon for this port

Nodes and edges

pmx-canvas node add --type webpage --url https://example.com/docs
pmx-canvas node add --type web-artifact --title "Dashboard" --app-file ./App.tsx
pmx-canvas node add --type graph --graph-type bar --data-file ./metrics.json --x-key label --y-key value
pmx-canvas node add --type graph --graph-type bar --data '[{"x":"a","y":1}]' --x-key x --y-key y
pmx-canvas graph add --graph-type bar --data '[{"x":"a","y":1}]' --x-key x --y-key y   # Alias
pmx-canvas html primitive add --kind choice-grid --data-file ./options.json --title "Options"
pmx-canvas html primitive schema --summary
pmx-canvas node add --help --type webpage --json                                        # Schema for one type

pmx-canvas external-app add --kind excalidraw --title "Diagram"

pmx-canvas edge add --from-search "DVT O3 — GitOps" --to-search "deep work trend" --type relation

# Updates return a compact { ok, id, position, size, updatedFields } envelope;
# pass --full for the complete node payload (ext-app payloads can be huge).
pmx-canvas node update <node-id> --width 840 --height 620
pmx-canvas node update <node-id> --title "Renamed" --full

--from-search / --to-search must each resolve to exactly one node — broad queries fail rather than guess. Use the full visible title.

CLI create commands return the created node shape with normalized title, content, and geometry, which makes scripting stacked layouts and batch follow-ups easier.

Graph height flags

Graph height flags split by target:

  • --node-height / --nodeHeight — the canvas node frame
  • --chart-height — the chart content inside the node
  • --height — accepted as a frame-height compatibility alias

For MCP/HTTP payloads, use nodeHeight for the frame and height for chart content.

Discovery and validation

pmx-canvas node schema --type json-render --component Table --summary
pmx-canvas validate                                                      # Layout validation
pmx-canvas validate spec --type json-render --spec-file ./dashboard.json --summary
pmx-canvas validate spec --type html-primitive --kind choice-grid --data-json '{"items":[{"title":"A"}]}' --summary

The schema commands surface the running server's data, which is strictly better than guessing flags or payloads.

Batch and arrange

pmx-canvas batch --file ./canvas-ops.json

See HTTP API → batch for the operation schema; the same JSON works for the CLI batch file.

Web artifacts

pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --deps recharts --include-logs

Failed or empty CLI bundles print ok: false, exit non-zero, and do not create a canvas node.

Watch (semantic deltas)

pmx-canvas watch consumes the SSE stream and emits compact semantic deltas for agents that need low-token updates instead of full layout snapshots. It filters noise from harmless moves and reports meaningful events such as pins, node additions/removals, group changes, edge connections, and moves that change spatial clustering.

pmx-canvas watch --events context-pin,move-end
pmx-canvas watch --json --events context-pin --max-events 1

Focus and fit

pmx-canvas focus <node-id>            # Pan viewport to a node
pmx-canvas focus <node-id> --no-pan   # Select/raise without panning
pmx-canvas fit                        # Fit the viewport to every node
pmx-canvas fit <id-a> <id-b>          # Fit to just these nodes

fit sizes itself to the connected browser window, so you rarely need to pass --width / --height. After creating output a human should see, focus a single node or fit the new ids — auto-placement is board-relative, not camera-relative.

Snapshots

pmx-canvas snapshot save --name "before-refactor"
pmx-canvas snapshot list
pmx-canvas snapshot restore <snapshot-id>
pmx-canvas snapshot delete <snapshot-id>
pmx-canvas snapshot gc --keep 20      # Delete all but the newest N
pmx-canvas diff <snapshot-id>         # Compare the canvas against a snapshot

AX context

AX commands expose the host-agnostic context contract used by adapters. Pins remain the explicit human-curated context set; AX focus is the current attention target and persists with canvas state and snapshots.

pmx-canvas ax status                  # Persisted AX state
pmx-canvas ax context                 # Pinned + focused agent context
pmx-canvas ax focus node-1 node-2      # Set AX focus
pmx-canvas ax focus --clear           # Clear AX focus

AX primitives

Host-agnostic agent-experience primitives. Timeline commands persist for diagnostics (retention-bounded, not snapshotted); work items, approval gates, and review annotations are canvas-bound and ride snapshots/restore.

# Timeline
pmx-canvas ax event add --kind tool-start --summary "ran tests"
pmx-canvas ax steer "focus on the failing test first"
pmx-canvas ax evidence add --kind test-output --title "unit pass"
pmx-canvas ax timeline --limit 50

# Work items (canvas-bound)
pmx-canvas ax work add --title "Wire up auth" --status in-progress node-1
pmx-canvas ax work update <id> --status done
pmx-canvas ax work list

# Approval gates (canvas-bound; pending → approved/rejected)
pmx-canvas ax approval request --title "Deploy to prod" --action deploy.prod
pmx-canvas ax approval resolve <id> --decision approved
pmx-canvas ax approval list

# Review annotations (canvas-bound)
pmx-canvas ax review add --body "off-by-one" --kind finding --severity error --file src/x.ts
pmx-canvas ax review list

# Host capability (own partition; survives clear)
pmx-canvas ax host report --host copilot --canvas --session-messaging
pmx-canvas ax host status

AX interactions, delivery, elicitation, mode, commands & policy

# Node interaction — one capability-gated envelope (server re-validates + scopes)
pmx-canvas ax interaction --type ax.work.create --node node-1 --payload '{"title":"Wire auth"}'

# Delivery — claim pending steering for a consumer (loop-safe), then acknowledge
pmx-canvas ax delivery list --consumer copilot --limit 20
pmx-canvas ax delivery mark <steering-id>

# Elicitation — request structured human input, then answer
pmx-canvas ax elicitation request --prompt "Who owns this migration?" --fields owner
pmx-canvas ax elicitation respond <id> --response '{"owner":"alice"}'
pmx-canvas ax elicitation list

# Mode — request a plan/execute/autonomous transition, then resolve
pmx-canvas ax mode request --mode execute --reason "plan approved"
pmx-canvas ax mode resolve <id> --decision approved
pmx-canvas ax mode list

# Commands — list the registry, invoke a registry-gated command
pmx-canvas ax command list
pmx-canvas ax command invoke pmx.plan
pmx-canvas ax command invoke pmx.promote-context --args '{"nodeIds":["n1"]}'

# Policy — read / patch the tool/prompt policy (stored by PMX, enforced by adapters)
pmx-canvas ax policy get
pmx-canvas ax policy set --excluded-tools shell,write --mode concise

Environment smoke check

pmx-canvas smoke                 # one-command check of a running canvas
pmx-canvas smoke --port 4750     # target a specific daemon

Verifies server health + workspace, CLI/server version skew, the MCP initialize handshake, a temporary node create/search/remove round-trip (the temp node is always removed, including on failure), and board validation. Prints a JSON report and exits 1 if any check fails.

Copilot adapter

Install the bundled GitHub Copilot extension adapter into a repo. The adapter maps onto the same neutral AX surfaces (it never makes the core GitHub-specific).

pmx-canvas copilot install-extension --dry-run   # Preview target, writes nothing
pmx-canvas copilot install-extension --yes        # Install/overwrite into .github/extensions/pmx-canvas/

Skill sync

Refresh the pmx-canvas skill copies already installed in this workspace. The command discovers them (any <agent-dir>/skills/pmx-canvas[-testing], whichever agent layout the workspace uses) and compares/replaces whole trees — references, evals, and fixtures included — so a copy can no longer drift while its SKILL.md hash matches. It never creates a copy where none is installed and makes no assumptions about which agents you use.

pmx-canvas skills sync --yes     # Refresh every installed copy from the package
pmx-canvas skills sync --check   # Report drift only (exit 1 when stale), change nothing

Replacing a tree is destructive, so the sync requires --yes; without it the command only reports drift (like --check) and hints at the flag. A directory whose SKILL.md identity doesn't match the bundled skill is skipped, never replaced.

Run skills sync --yes (and copilot install-extension --yes if the repo uses the Copilot adapter) after every pmx-canvas upgrade so agents operate on the released guidance.

WebView automation

Drive a headless Bun.WebView (Chromium or WebKit) pointed at the workbench:

pmx-canvas webview status
pmx-canvas webview start --backend chrome --width 1440 --height 900
pmx-canvas webview evaluate --expression "document.title"
pmx-canvas webview resize --width 1280 --height 800
pmx-canvas webview screenshot --output ./canvas.png
pmx-canvas webview stop

Use WebView for visual annotation inspection. Agent-readable canvas context only reports annotation targets and bounds; it does not describe whether the human drew an arrow, line, circle, or other shape. Inspect .annotation-layer path or take a screenshot when the drawn form matters.

Humans draw with the rail's Annotate popover (pen / text) and remove marks with its eraser. If an agent already knows the annotation ID from context, it can remove it through MCP with canvas_view { action: "remove-annotation", id }.

When to reach for the CLI

  • Direct terminal control without MCP wiring
  • Shell scripts and CI-friendly automation
  • Schema-driven discovery from the running server
  • Local debugging of canvas, webview, and screenshot flows
  • A control surface that covers normal canvas work without MCP wiring