$npx -y skills add affaan-m/ECC --skill plan-canvasOpen plans and HTML artifacts in a local browser canvas where the human annotates elements, chats, and approves or requests changes without leaving the page. Use when presenting a plan for review, or when feedback like "move this, change that" is easier pointed at than typed.
| 1 | # Plan Canvas |
| 2 | |
| 3 | Review loop for plans and visual artifacts: you write the artifact, the human |
| 4 | reviews it in the browser — annotating the exact element they mean, chatting, |
| 5 | and delivering an **Approve plan / Request changes** verdict — while you block |
| 6 | on a single CLI call that returns their feedback as JSON. |
| 7 | |
| 8 | Inspired by [lavish-axi](https://github.com/kunchenguid/lavish-axi); rebuilt |
| 9 | ECC-native around the `/plan` confirmation gate, with zero dependencies. |
| 10 | |
| 11 | ## When to Use |
| 12 | |
| 13 | - You just wrote a plan artifact (`.claude/plans/*.plan.md` from `/plan`) and |
| 14 | need the CONFIRM/approve decision — the canvas verdict replaces a typed |
| 15 | "yes/proceed". |
| 16 | - The user should *point at* what to change: reviewing designs, comparisons, |
| 17 | reports, or any local `.md` / `.html` artifact. |
| 18 | - The user asks for `/plan-canvas`, a visual review, or "open it in the browser". |
| 19 | |
| 20 | Do NOT use for: code review of diffs (`/code-review`), running web apps, or |
| 21 | remote URLs. The canvas serves local artifact files only. |
| 22 | |
| 23 | ## How It Works |
| 24 | |
| 25 | Invoke the CLI as `ecc-plan-canvas` — the bin shipped by the `ecc-universal` |
| 26 | package (on PATH after a global/plugin install; `node "$CLAUDE_PLUGIN_ROOT/scripts/plan-canvas.js"` |
| 27 | also works for plugin installs). Run it from the project you are reviewing in; |
| 28 | it works from any working directory. It manages a detached loopback server |
| 29 | (`127.0.0.1:4517`) shared by all sessions, keyed by artifact path — no session |
| 30 | ids to track. |
| 31 | |
| 32 | The workflow is a plain CLI-plus-JSON loop, so it is model- and harness-agnostic: |
| 33 | any agent that can run a shell command and read stdout drives it the same way |
| 34 | (Claude Code, Codex, Cursor, Gemini, OpenCode, Copilot). Trigger it however your |
| 35 | harness surfaces skills — e.g. `/plan-canvas` in Claude Code, `$plan-canvas` in |
| 36 | Codex — or just run the `ecc-plan-canvas` commands directly. |
| 37 | |
| 38 | ```bash |
| 39 | # 1. Open the artifact in the user's browser (returns immediately) |
| 40 | ecc-plan-canvas open .claude/plans/feature.plan.md |
| 41 | |
| 42 | # 2. Block until the human responds. Leave running; re-run if interrupted — |
| 43 | # queued feedback is never lost. Run in the background if your harness |
| 44 | # time-limits foreground commands. |
| 45 | ecc-plan-canvas await .claude/plans/feature.plan.md |
| 46 | ``` |
| 47 | |
| 48 | `await` prints JSON when the human acts: |
| 49 | |
| 50 | ```json |
| 51 | { |
| 52 | "status": "feedback", |
| 53 | "items": [ |
| 54 | { "kind": "annotation", "text": "Split this into two phases", |
| 55 | "anchor": { "selector": "h2:nth-of-type(3)", "tag": "h2", "snippet": "Phase 2: Migration" } }, |
| 56 | { "kind": "verdict", "verdict": "request-changes" } |
| 57 | ] |
| 58 | } |
| 59 | ``` |
| 60 | |
| 61 | - `kind: "chat"` — freeform message; answer in the canvas, not the terminal. |
| 62 | - `kind: "annotation"` — feedback anchored to an element (`anchor.selector`, |
| 63 | `anchor.snippet` show what they pointed at; `anchor.textRange.text` when |
| 64 | they highlighted a passage). |
| 65 | - `kind: "verdict"` — `approve` means the plan is CONFIRMED: stop polling, |
| 66 | end the session, and start implementing. `request-changes` means revise the |
| 67 | artifact (the canvas live-reloads it) and keep the loop going. |
| 68 | |
| 69 | **3. Respond in the canvas**, then keep listening — one command does both: |
| 70 | |
| 71 | ```bash |
| 72 | ecc-plan-canvas await <file> --reply "Split Phase 2 as requested — take a look." |
| 73 | ``` |
| 74 | |
| 75 | **4. End** when review concludes: `ecc-plan-canvas end <file>`. |
| 76 | |
| 77 | ## Diagrams (Mermaid) |
| 78 | |
| 79 | When part of the plan is a flow, architecture, sequence, state machine, ER |
| 80 | model, or dependency graph, author it as a fenced ` ```mermaid ` block instead |
| 81 | of ASCII art or a wall of prose — the canvas renders it as a themed diagram the |
| 82 | human can point at. Reach for it when a picture reads faster than a paragraph; |
| 83 | skip it for simple lists or tables. |
| 84 | |
| 85 | ````markdown |
| 86 | ```mermaid |
| 87 | flowchart LR |
| 88 | A[Market resolves] --> B{Watchers?} |
| 89 | B -->|yes| C[Enqueue jobs] --> D[Fan-out worker] |
| 90 | ``` |
| 91 | ```` |
| 92 | |
| 93 | Diagrams render in the ECC dark theme with the accent palette. Mermaid loads in |
| 94 | the browser from a pinned CDN; if that is unavailable (offline), the block |
| 95 | degrades to showing its source, so the review is never blocked. Point a local |
| 96 | mirror at `ECC_PLAN_CANVAS_MERMAID_URL` for air-gapped use. |
| 97 | |
| 98 | ## Rules |
| 99 | |
| 100 | - Markdown artifacts render in ECC's plan template (including Mermaid blocks); |
| 101 | `.html` artifacts render as-is with the annotation layer injected. For HTML |
| 102 | authoring guidance use the `frontend-design-direction` and `artifact-design` |
| 103 | skills. |
| 104 | - Edit the artifact file to revise — the canvas live-reloads on save. Never |
| 105 | re-run `open` to refresh. |
| 106 | - `{"status": "ended", "endedBy": "user"}` (or `sessionEnded: true` on a |
| 107 | feedback batch) means the user closed the review: stop polling, deliver |
| 108 | remaining updates in chat, and do not reopen. A plain `open` on that |
| 109 | session is refused; pass `--reopen` only when the us |