Skip to main content

pmx-canvas

Spatial canvas workbench for visual thinking — nodes, edges, groups on an infinite 2D canvas with pan/zoom, minimap, and real-time sync. Use this skill whenever you need to lay out information spatially: investigation boards, architecture diagrams, dependency maps, task plans, status dashboards, file relationship views, or any scenario where a flat list or text wall isn't enough. Also use when the user mentions "canvas", "board", "diagram", "spatial layout", "visual map", "node graph", or wants to see how things connect. The canvas is your extended working memory — pin nodes to curate context, read spatial arrangement to understand intent.

インストールへ移動

ソース情報

リポジトリ
pskoett/pmx-canvas
ソースの最終更新活動
2026年9月9日 07:49
検出された SKILL.md の言語
英語
スター
19
フォーク
3

インストール方法

デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。

ソースファイルを確認

インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。

ファイルエクスプローラー
14 ファイル

SKILL.md を表示中

SKILL.md
ソースの指示 · 読み取り専用プレビュー
name
pmx-canvas
description
Spatial canvas workbench for visual thinking — nodes, edges, groups on an infinite 2D canvas with pan/zoom, minimap, and real-time sync. Use this skill whenever you need to lay out information spatially: investigation boards, architecture diagrams, dependency maps, task plans, status dashboards, file relationship views, or any scenario where a flat list or text wall isn't enough. Also use when the user mentions "canvas", "board", "diagram", "spatial layout", "visual map", "node graph", or wants to see how things connect. The canvas is your extended working memory — pin nodes to curate context, read spatial arrangement to understand intent.
# PMX Canvas PMX Canvas is a server-authoritative spatial workbench controlled through MCP, HTTP, or the CLI. Humans curate agent context by pinning nodes; agents read that curation through `canvas://pinned-context`. State survives browser refresh. ## Runtime prerequisites PMX Canvas 0.6.1 requires **Bun >=1.4.2**, including when installed through npm. Check `bun --version` and ensure Bun is on the MCP host's PATH, not just your shell's; use an absolute executable path if needed. Install/configure only when requested. For pinned installation, MCP configuration, managed services, and disposable verification, read [Installing PMX Canvas](references/installing-pmx-canvas.md). ## Required Operating Sequence 0. **After a `pmx-canvas` upgrade, refresh this skill first.** Run `pmx-canvas skills sync --yes` (`--check` to detect drift; exit 1 when stale) — it finds the skill copies already installed in the workspace (whatever layout your agent uses) and replaces the complete trees from the package, references/evals/fixtures included. Sync ONLY from the installed package, never from a source checkout: this skill documents the runtime it ships with, and a newer repo skill paired with an older installed runtime advertises commands and themes the binary does not have (0.4.3 report skew finding). Also restart the HTTP daemon and any `--mcp` processes; Bun does not hot-reload a running process. 1. **Open or focus the workbench before mutating.** Reuse one visible canvas surface for the session. 2. **Verify workspace identity at the actual target.** Read `GET /health` at the URL your CLI/MCP/browser is using; its `workspace` must equal the intended canonical absolute root. `pmx-canvas serve status --port=<port>` checks the local listener on that port, not an arbitrary `PMX_CANVAS_URL`. A healthy listener may belong to another project. 3. **Read before write.** Search with `canvas_query { action: "search", query }` before creating nodes. Read the full layout only when necessary. The MCP parameter is `query` — passing the HTTP API's `q` is silently ignored and returns zero results. 4. **Snapshot before destructive changes.** Use `canvas_snapshot { action: "save", name }` before clear, restore, or a major reorganization. 5. **Show intent with the Ghost Cursor — by default.** Signal with `canvas_intent { action: "signal", ... }` before every meaningful create, move, connect, remove, or edit, then pass the returned `intent.id` as `intentId` on the mutation so the ghost settles into the result. Use it as much as possible to make your next move and your work visible: the human watches intent form and can veto mid-thought. Skip it only for trivial in-place tweaks or high-frequency batch churn. The default TTL (~8s) expires between agent turns: signal with `ttlMs: 30000` and settle by passing `intentId` on the mutation in the same or next call. Since 0.4.5, an agent mutation WITHOUT a signal still shows a server-synthesized **auto-ghost** (rendered lighter — dimmer, dotted, no veto — and settled instantly). That is a visibility floor, not a replacement: only an explicit signal gives the human a real pre-mutation veto window, your reasoning (`reason`), and staged multi-step previews. Batch and browser-human actions never auto-ghost. 6. **Attach a session so the human can see you (0.4.8+).** Start board work with `canvas_ax_state { action: "set-presence", attached: true, label: "<who you are>" }` and end it with `{ attached: false }` — detaching hands the human a receipt. Everything the session gives you and asks of you (cursor + phase chip, the session panel, steering, the scope fence's 403s, the human edit lock's 409s, unattended approvals) is in **Sessions & the human** below. 7. **Mutate through current composites.** Prefer the 16 composite MCP tools below. 7. **Arrange and validate.** After batch changes, use `canvas_view { action: "arrange" }` when appropriate and always finish with `canvas_query { action: "validate" }`. 7b. **Show the human.** After creating user-facing output, bring the camera to it: a single node gets `canvas_view { action: "focus", id }` (pans by default), a small cluster gets `canvas_view { action: "fit", nodeIds: [...] }` with exactly the new ids. See **In-View Placement & Sizing** below — auto-placement is board-relative, not camera-relative. 8. **Verify context pins.** Pin with `canvas_pin_nodes` or the browser's **Pin as context**, then read `canvas://pinned-context`. 9. **Clean up temporary nodes.** Remove retry/test fixtures and restore the baseline snapshot when the task requires leaving the board unchanged. ## Workspace Safety Before any create, update, remove, clear, restore, arrange, or smoke test, choose an absolute project root and a dedicated free port. For a local target: ```bash export PMX_CANVAS_WORKSPACE_ROOT=/absolute/path/to/project export PMX_CANVAS_PORT=14313 # Example only: choose a free port for this workspace. unset PMX_CANVAS_URL # Remove a stale URL before selecting a different local target. curl --fail --silent --show-error "http://localhost:${PMX_CANVAS_PORT}/health" pmx-canvas serve status --port="$PMX_CANVAS_PORT" ``` Compare the health field **`workspace`** (not `workspaceRoot`) to the intended root, resolving symlinks before comparison. Stop on mismatch or failed health; do not write. If deliberately using `PMX_CANVAS_URL` or `--server-url`, check `/health` at that exact URL instead. Confirm the browser and MCP use the same verified target, especially after fallback to another port. Do not print URLs containing credentials. `pmx-canvas smoke` reports health/workspace/version information, checks MCP initialize, creates/searches/removes a temporary node, and validates the board. **It mutates state** and does not enforce your intended workspace identity; version skew is reported, not necessarily a failing check. Use a disposable workspace, verify health first, and inspect both the JSON details and exit status (1 when a check fails). It is not a read-only probe or a guarantee of unchanged history. - If `responsive: true` but `pidRunning: false`, treat the listener as potentially stale. - On mismatch, leave the other workspace's server alone. Start the intended workspace on a different free port, target it explicitly, and re-check `/health` before writing. - On an ordinary local machine, `pmx-canvas serve --daemon --no-open --port=<free-port>` refuses a different-workspace occupant. In a managed environment, supervise foreground `pmx-canvas serve --no-open --port=<free-port>` with the host's service manager instead. - `PMX_CANVAS_PORT` selects the CLI/MCP port. CLI target flags override environment values (`--server-url` wins over `--port`); otherwise `PMX_CANVAS_URL` wins over `PMX_CANVAS_PORT`. For server startup, explicit `--port` wins, then `PMX_WEB_CANVAS_PORT`, then `PMX_CANVAS_PORT`; in Amp orbs `PORT` is a later fallback. URL targeting does not select the server's bind port. - **MCP transport workspace resolution.** Set **`PMX_CANVAS_WORKSPACE_ROOT` plus a dedicated `PMX_CANVAS_PORT`** in the host configuration. Without an explicit root, MCP may inherit a different workspace from the preferred-port daemon; `PMX_CANVAS_ALLOW_WORKSPACE_SPLIT=1` opts out of that heuristic. Current source honors an explicit root, but may bind a fallback port if the preferred port is occupied. Root alone therefore does not guarantee CLI, MCP, and browser target alignment; older installed runtimes can also differ. Inspect startup output and the actual health endpoint, never assume the preferred port was bound. Clear stale inherited `PMX_CANVAS_URL` values in the host configuration as well as the shell. - CLI query/mutation commands are HTTP clients and do not start a server. `serve` or `--mcp` starts or attaches to one. Use the host's authenticated preview mechanism for remote viewing; a loopback URL is only reachable inside the machine/orb running the service. ## Choose the Smallest Useful Node Type | Need | Node/tool | |------|-----------| | Narrative, note, explanation | `markdown` via `canvas_node` | | Progress or current state | `status` via `canvas_node` | | Persistent context cards | `context` via `canvas_node` | | Event/check stream | `ledger` or `trace` via `canvas_node` | | Local source with live updates | `file` via `canvas_node` | | Tabular data (`.csv`/`.tsv`), a PDF, or any other file on disk (0.4.6+) | `file` via `canvas_node` — CSV/TSV render as tables, PDFs render inline, other binaries show a size placeholder. Never paste a CSV into a markdown fence. | | Code review / unified diff (0.4.6+) | `diff` via `canvas_node` (content = diff text; link to its file node with a `references` edge) | | Flowchart / sequence / state diagram (0.4.6+) | `mermaid` via `canvas_node` (content = mermaid source; renders client-side, no hosted app) | | Image | `image` via `canvas_node` | | Cached URL content | `webpage` via `canvas_node` | | Structured UI | `json-render` via `canvas_render` | | Chart | `graph` via `canvas_render` | | Live work-item board (0.4.6+) | `canvas_render { action: "workboard" }` — one board node, auto-refreshes on work-item changes | | Generated communication surface | HTML primitive via `canvas_node` | | Give the agent tasks + watch progress + loop (0.4.7+) | `ax-board` HTML primitive — a live AX control surface, created AX-enabled | | The same, drawn as a task flow, and materializable to real nodes+edges (0.4.7+) | `ax-flow` HTML primitive — **Materialize to board** lays the steps out as nodes joined by `flow` edges with a loop-back edge, each linked to a work item | | Drive a flow WITHOUT the panel (0.4.7+) | Materialized step nodes carry native Start/Done/Blocked controls, and the anchor adds Run loop/Stop + steer. The native loop runs server-side, so it survives a browser reload and keeps advancing while the tab is closed. | | Self-contained HTML/JS | `html` via `canvas_node` | | Hosted interactive MCP app | `canvas_app { action: "open-mcp-app" }` | | Excalidraw diagram (interactive/human drawing) | `canvas_app { action: "diagram" }` — prefer `mermaid` for agent-authored diagrams | | Bundled React artifact | `canvas_app { action: "build-artifact" }` | Use the lightest tier that communicates the result. Do not build a web artifact when markdown, json-render, a graph, or an HTML primitive is sufficient. ## Current MCP Composites The live MCP surface is **22 tools**: the 16 composites below plus 6 standalones. This table is kept in sync with the server's composite registry; `tools/list` on a fresh `pmx-canvas --mcp` is always authoritative, independent of the installed release version. | Composite | Actions | |-----------|---------| | `canvas_node` | `add`, `get`, `update`, `remove` | | `canvas_render` | `describe-schema`, `validate`, `add-json-render`, `stream-json-render`, `add-graph` | | `canvas_edge` | `add`, `update`, `remove` | | `canvas_group` | `create`, `add`, `ungroup` | | `canvas_history` | `undo`, `redo` | | `canvas_view` | `arrange`, `focus`, `fit`, `clear`, `remove-annotation` | | `canvas_query` | `search`, `layout`, `validate` | | `canvas_webview` | `status`, `start`, `stop`, `resize`, `evaluate` | | `canvas_app` | `open-mcp-app`, `diagram`, `build-artifact` | | `canvas_ax_state` | `get`, `set-focus`, `set-policy`, `report-capability`, `presence`, `set-presence` | | `canvas_ax_work` | `add`, `update`, `annotate` | | `canvas_ax_gate` | `request`, `resolve`, `await` with `approval`, `elicitation`, or `mode` | | `canvas_ax_timeline` | `read`, `record-event`, `add-evidence`, `send-steering` | | `canvas_ax_delivery` | `claim`, `mark` | | `canvas_snapshot` | `save`, `list`, `restore`, `delete`, `gc`, `diff` | | `canvas_intent` | `signal`, `update`, `clear` | Important routing: - Basic nodes: `canvas_node { action: "add", type, ... }` - HTML: `canvas_node { action: "add", type: "html", html }` - HTML primitive: `canvas_node { action: "add", type: "html", primitive, data }` - Graph: `canvas_render { action: "add-graph", ... }` - JSON render: `canvas_render { action: "add-json-render", ... }` - MCP app: `canvas_app { action: "open-mcp-app", ... }` - Excalidraw: `canvas_app { action: "diagram", ... }` - Web artifact: `canvas_app { action: "build-artifact", ... }` As of v0.3.0, the 57 legacy single-purpose tools from the v0.2 compatibility window are removed. The composites above plus the retained standalones are now the whole MCP surface: `canvas_batch`, `canvas_pin_nodes`, `canvas_screenshot`, `canvas_ax_interaction`, `canvas_ingest_activity`, and `canvas_invoke_command`. Snapshots are the `canvas_snapshot` composite (actions `save | list | restore | delete | gc | diff`); the 6 legacy snapshot standalones were removed in v0.4.0 after their deprecated 0.3.x window. ## Spatial Rules - Treat proximity as relatedness and top-left to bottom-right as reading order. - Search before adding to avoid duplicate nodes. - Extend the current board in place; do not evict prior nodes to add new material. - Use groups only when the frame communicates meaningful containment. - Keep related nodes 40–80 px apart and separate unrelated clusters by roughly 150–250 px. - Use directed edges for actual relationships, not decoration. - Edge types: `flow`, `depends-on`, `relation`, `references`. - After manual or batch layout changes, run `canvas_query { action: "validate" }`. ## In-View Placement & Sizing (required for user-facing nodes) Auto-placement (omitting `x`/`y`) is **board-relative, not camera-relative**: it places right of the last node or scans rows from the origin, ignoring where the human is looking. On a board with distant nodes, an auto-placed node lands off-camera. 1. Omit `x`/`y` only on an empty or locally dense board. Otherwise place near the human's attention: the pinned/focused neighborhood, or explicit coordinates beside the last user-facing output (gap ≥ 24–48 px). 2. After creating nodes the human should see, pan the camera (operating-sequence step 7b): `focus` for one node, `fit` with exactly the new `nodeIds` for a cluster. Use `noPan` (`focus --no-pan`) only when you must not steal the camera. 3. Never fit the whole board to "show" new work — on a board with outliers that miniaturizes everything. Always pass explicit `nodeIds` to `fit`. 4. Never leave user-facing output at far coordinates without a focus/fit. 5. **Do not hand-compute a whole board's coordinates.** Create the nodes (omitting x/y), then `canvas_view { action: "arrange", layout: "grid" | "column" | "flow" }` and finish with a `fit` over the new ids. Manual pixel math is what produces long-line, unbalanced boards. 6. `fit` sizes itself to the connected browser window (0.4.6+) — you do not need to guess `width`/`height`. Pass them only to fit for a window other than the human's. 7. **Every node is a canvas card.** Nodes render on the canvas where you put them — there is no docked/HUD placement and no `dockPosition` (removed in the rail-chrome redesign); `status` and `context` nodes are ordinary cards like the rest. **Size for content.** Omitting `width`/`height` gives readable per-type defaults — prefer them: markdown 640×420, status 360×200, file 520×360, diff 640×420, mermaid 640×460, html 720×640, graph 760×520, mcp-app 960×600, web-artifact 960×720. A *hosted* app opened with `canvas_app { action: "open-mcp-app" | "diagram" }` — including the Excalidraw diagram preset — is the exception: request `width: 720, height: 500` for its standard landscape preset instead of relying on the 960×600 default for a directly created `mcp-app` node. After the app mounts, read the node back with `canvas_query { action: "layout" }` and use its persisted width and height for subsequent placement or layout; the mounted app may have changed the requested dimensions. Since 0.4.6 the server clamps explicit creation sizes UP to per-type
GitHubで見る
この SKILL.md は非常に大きいため、SkillsMP では最初のセクションだけを表示しています。 GitHubで見る