pmx-canvas 0.1.29 → 0.1.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/CHANGELOG.md +219 -0
  2. package/Readme.md +20 -10
  3. package/dist/canvas/global.css +51 -56
  4. package/dist/canvas/index.js +80 -163
  5. package/dist/canvas/surface-theme.css +142 -0
  6. package/dist/json-render/index.js +103 -103
  7. package/dist/types/client/nodes/HtmlNode.d.ts +0 -7
  8. package/dist/types/client/nodes/ax-node-actions.d.ts +18 -0
  9. package/dist/types/client/nodes/surface-url.d.ts +22 -0
  10. package/dist/types/client/state/attention-bridge.d.ts +3 -0
  11. package/dist/types/client/state/intent-bridge.d.ts +17 -0
  12. package/dist/types/json-render/renderer/index.d.ts +2 -0
  13. package/dist/types/json-render/schema.d.ts +2 -0
  14. package/dist/types/json-render/server.d.ts +2 -0
  15. package/dist/types/mcp/canvas-access.d.ts +47 -0
  16. package/dist/types/server/ax-interaction.d.ts +210 -0
  17. package/dist/types/server/ax-state.d.ts +67 -1
  18. package/dist/types/server/canvas-db.d.ts +4 -0
  19. package/dist/types/server/canvas-serialization.d.ts +2 -0
  20. package/dist/types/server/canvas-state.d.ts +54 -2
  21. package/dist/types/server/html-surface.d.ts +46 -0
  22. package/dist/types/server/index.d.ts +63 -5
  23. package/dist/types/server/mutation-history.d.ts +1 -1
  24. package/dist/types/server/placement.d.ts +1 -1
  25. package/dist/types/server/server.d.ts +12 -0
  26. package/dist/types/shared/surface.d.ts +19 -0
  27. package/docs/cli.md +30 -0
  28. package/docs/http-api.md +55 -0
  29. package/docs/mcp.md +40 -2
  30. package/docs/node-types.md +26 -0
  31. package/docs/plans/plan-004-pmx-ax-primitives.md +623 -394
  32. package/docs/sdk.md +23 -1
  33. package/package.json +2 -2
  34. package/skills/pmx-canvas/SKILL.md +107 -9
  35. package/src/cli/agent.ts +177 -0
  36. package/src/cli/index.ts +8 -1
  37. package/src/client/canvas/CanvasNode.tsx +8 -4
  38. package/src/client/canvas/DockedNode.tsx +38 -38
  39. package/src/client/canvas/ExpandedNodeOverlay.tsx +12 -0
  40. package/src/client/nodes/ContextNode.tsx +17 -0
  41. package/src/client/nodes/ExtAppFrame.tsx +40 -3
  42. package/src/client/nodes/FileNode.tsx +26 -0
  43. package/src/client/nodes/HtmlNode.tsx +60 -188
  44. package/src/client/nodes/McpAppNode.tsx +47 -2
  45. package/src/client/nodes/StatusNode.tsx +20 -0
  46. package/src/client/nodes/ax-node-actions.ts +39 -0
  47. package/src/client/nodes/surface-url.ts +48 -0
  48. package/src/client/state/attention-bridge.ts +5 -0
  49. package/src/client/state/intent-bridge.ts +33 -0
  50. package/src/client/theme/global.css +51 -56
  51. package/src/client/theme/surface-theme.css +142 -0
  52. package/src/json-render/renderer/index.tsx +31 -0
  53. package/src/json-render/schema.ts +4 -0
  54. package/src/json-render/server.ts +13 -0
  55. package/src/mcp/canvas-access.ts +198 -1
  56. package/src/mcp/server.ts +232 -2
  57. package/src/server/ax-context.ts +3 -0
  58. package/src/server/ax-interaction.ts +549 -0
  59. package/src/server/ax-state.ts +188 -2
  60. package/src/server/canvas-db.ts +20 -0
  61. package/src/server/canvas-operations.ts +11 -0
  62. package/src/server/canvas-serialization.ts +9 -0
  63. package/src/server/canvas-state.ts +201 -26
  64. package/src/server/html-surface.ts +190 -0
  65. package/src/server/index.ts +122 -7
  66. package/src/server/mutation-history.ts +5 -0
  67. package/src/server/placement.ts +5 -1
  68. package/src/server/server.ts +360 -0
  69. package/src/shared/surface.ts +38 -0
@@ -1,463 +1,692 @@
1
1
  ---
2
- title: PMX AX Primitives and Copilot Adapter Plan
2
+ title: PMX-AX Core Primitives and Host Adapter Plan
3
3
  status: draft
4
- date: 2026-06-02
4
+ date: 2026-06-07
5
5
  ---
6
6
 
7
- # PMX AX Primitives and Copilot Adapter Plan
7
+ # PMX-AX Core Primitives and Host Adapter Plan
8
8
 
9
9
  ## Summary
10
10
 
11
- PMX Canvas should own the agent-experience primitives as core PMX concepts, not
12
- as GitHub Copilot concepts. GitHub Copilot becomes the first native host
13
- adapter: it renders the existing PMX workbench in a Copilot canvas and maps
14
- Copilot SDK features onto the neutral PMX AX contract.
15
-
16
- This plan keeps PMX Canvas agent-agnostic and backward-compatible while adding:
17
-
18
- - core AX state and serializers
19
- - HTTP, SDK, MCP, and CLI surfaces for the AX primitives
20
- - a committed `.github/extensions/pmx-canvas/` Copilot canvas adapter
21
- - CLI support to scaffold/install the same adapter in other PMX Canvas projects
22
-
23
- Codex is intentionally out of scope for this pass, but the core contract should
24
- make a later Codex adapter straightforward.
25
-
26
- Implementation should proceed in vertical slices: each primitive lands across
27
- state, persistence, HTTP, SDK, MCP, CLI, docs, and tests before moving to the
28
- next primitive group. This avoids half-wired surfaces and keeps the existing PMX
29
- "one operation, all access paths" rule intact.
30
-
31
- ## Interview Decisions
32
-
33
- - First pass surfaces: core model, HTTP, SDK, MCP, CLI, and GitHub Copilot
34
- adapter.
35
- - Out of scope: Codex adapter. Copilot should be a real adapter for the
36
- existing PMX Canvas experience, not a demo-only scaffold.
37
- - Compatibility: preserve existing APIs and state formats; add optional AX
38
- fields/endpoints/tables in a backward-compatible way.
39
- - Persistence: AX state lives inside the existing `.pmx-canvas/canvas.db`
40
- persistence model alongside nodes, edges, context pins, annotations, and
41
- snapshots.
42
- - Copilot distribution: commit a project extension under
43
- `.github/extensions/pmx-canvas/` and add CLI support to scaffold/install that
44
- adapter for other projects later.
45
-
46
- ## Core AX Primitive Contract
47
-
48
- | PMX AX primitive | Core meaning | Persistence/snapshot semantics | First adapter mapping |
49
- |---|---|---|---|
50
- | `canvas-surface` | A live PMX workbench surface with nodes, edges, viewport, annotations, pins, and snapshots. | Existing canvas state and snapshots. | Copilot `createCanvas().open()` returns the running `/workbench` URL. |
51
- | `pinned-context` | Human-curated node set plus bounded agent-readable summaries and neighborhoods. | Existing context pin state and snapshots. | Copilot hooks return it as `additionalContext`; MCP keeps `canvas://pinned-context`. |
52
- | `focus` | Current node or node set the human/agent wants attention on. | Canvas-bound state; snapshot with canvas. | Copilot canvas action/HTTP/CLI can focus without requiring app-specific state. |
53
- | `agent-action` | Normalized operation request against PMX state. | Operation request/result is timeline state; effects persist through target primitive. | Copilot canvas actions/tools proxy to PMX HTTP/SDK/MCP operations. |
54
- | `steering-message` | User instruction emitted from the PMX surface to the active agent session. | Timeline state; persisted in DB but not restored by snapshots. | Copilot adapter maps it to `session.send()` or `sendAndWait()`. |
55
- | `approval-gate` | A PMX-owned request for human approval/rejection before a high-impact AX action. | Canvas-bound state while pending/resolved; snapshot with canvas. | Copilot adapter exposes approval UI/actions and may map safe cases to SDK permission hooks. |
56
- | `work-item` | Visible task/plan/status primitive tied to nodes or agent work. | Canvas-bound state; snapshot with canvas. | Existing status/markdown nodes can render it; adapters can update it through AX APIs. |
57
- | `evidence-item` | Inspectable artifact such as logs, tool result, screenshot, file, diff, or test output. | Timeline state; persisted in DB with retention, not restored by snapshots. | Copilot session/tool events become evidence nodes/items. |
58
- | `review-annotation` | Human or agent comment/finding anchored to a node/file/region. | Canvas-bound state; snapshot with canvas. | PMX annotations/nodes remain source of truth; Copilot can render and update them. |
59
- | `agent-event` | Normalized timeline event for prompts, assistant messages, tool starts/results, failures, approvals, and steering. | Timeline state; persisted in DB with retention, not restored by snapshots. | Copilot `session.on(...)` events are normalized into PMX AX events. |
60
- | `host-capability` | What the current host can do: canvas, hooks, tools, session messaging, permissions, files, UI prompts. | Session/host state; persisted only when useful for diagnostics. | Copilot `session.capabilities` maps to neutral capability flags. |
11
+ PMX-AX is the host-agnostic agent experience layer for PMX Canvas. It belongs
12
+ in PMX core, not in any single adapter. PMX-AX defines durable primitives,
13
+ state, node interaction contracts, permissions, delivery semantics, and audit
14
+ history. Host adapters such as GitHub Copilot, Codex, Claude, MCP, or CLI map
15
+ their native capabilities into PMX-AX, but they do not define PMX-AX.
16
+
17
+ The GitHub Copilot app is the first rich native adapter. Its SDK surfaces are
18
+ useful as a parity check, but the implementation must keep a clean boundary:
19
+
20
+ - **PMX-AX core owns:** primitives, state, node capabilities, interaction
21
+ schemas, policy, approvals, timeline, delivery status, and host capability
22
+ negotiation.
23
+ - **PMX Canvas UI owns:** native node interactions, visible work surfaces,
24
+ human steering, and spatial collaboration.
25
+ - **Renderer transports own:** how a specific renderer emits interactions
26
+ safely, for example native client events, json-render actions, sandboxed HTML
27
+ `postMessage`, or MCP app bridges.
28
+ - **Host adapters own:** mapping PMX-AX to host-specific APIs such as Copilot
29
+ hooks, tools, slash commands, system messages, permission hooks, and session
30
+ messaging.
31
+
32
+ This plan remakes the earlier Copilot-focused AX work into a core PMX-AX plan.
33
+ Copilot remains important, but only as one adapter.
34
+
35
+ ## Product Thesis
36
+
37
+ Chat is where humans instruct and resolve ambiguity. PMX Canvas is where the
38
+ work becomes visible. PMX-AX is the contract that lets humans and agents operate
39
+ on that visible work together.
40
+
41
+ The core loop should be:
42
+
43
+ ```text
44
+ human or agent interacts with a node
45
+ -> node emits a validated AX interaction
46
+ -> PMX-AX records durable state and timeline
47
+ -> PMX Canvas updates visible work surfaces
48
+ -> host adapter exposes relevant context, prompts, tools, approvals, or events
49
+ -> agent can react, continue, or ask for clarification
50
+ ```
51
+
52
+ The key shift is that AX interactions are not limited to HTML nodes. HTML needs
53
+ a bridge because it is sandboxed, but PMX-AX applies to any node type that
54
+ declares or receives an allowed capability.
55
+
56
+ ## Design Principles
57
+
58
+ 1. **Core before adapter.** PMX-AX primitives must work through PMX HTTP, SDK,
59
+ MCP, CLI, and browser UI before they depend on a host adapter.
60
+ 2. **Adapters map, they do not own.** Copilot, Codex, Claude, CLI, and MCP
61
+ adapters translate host capabilities into PMX-AX concepts.
62
+ 3. **Node-bound by default.** AX interactions should know which node, actor,
63
+ and surface created them.
64
+ 4. **Capability-gated.** Not every node can do every AX action. Node type and
65
+ node metadata must define what is allowed.
66
+ 5. **Validated interaction envelope.** All node-originated interactions use one
67
+ normalized event shape and strict payload validation.
68
+ 6. **Visible, auditable, replayable.** Work state and decisions should be
69
+ inspectable through PMX Canvas and reconstructable through a bounded
70
+ timeline.
71
+ 7. **Safe transport boundaries.** Sandboxed HTML, MCP apps, native nodes, and
72
+ host adapters use different transports, but converge on the same PMX-AX
73
+ endpoint and schema.
74
+ 8. **No arbitrary execution.** Node interactions can request PMX-AX primitives,
75
+ never arbitrary shell, tool, MCP, or host execution.
76
+ 9. **Delivery has state.** Instructions and events need pending, delivered,
77
+ failed, acknowledged, and ignored outcomes.
78
+ 10. **Backwards-compatible state.** AX additions must preserve existing canvas,
79
+ snapshot, MCP, HTTP, CLI, and SDK behavior.
80
+
81
+ ## Core PMX-AX Model
61
82
 
62
83
  ### State partitions
63
84
 
64
- - **Canvas-bound AX state:** `focus`, `work-item`, `approval-gate`,
65
- `review-annotation`, and existing pins. These participate in canvas
66
- snapshots and restore.
67
- - **Timeline AX state:** `agent-event`, `evidence-item`, `agent-action`
68
- records, and `steering-message`. These persist in the PMX DB for diagnostics
69
- and continuity but are not restored by canvas snapshots.
70
- - **Host/session AX state:** `host-capability`. This is reported by adapters
71
- and exposed for diagnostics, but it should not make core depend on any host.
72
-
73
- ## Architecture
74
-
75
- ### Make the change easy first
76
-
77
- Add a small core AX module before wiring endpoints:
78
-
79
- - `src/server/ax-state.ts`
80
- - AX primitive types
81
- - normalizers and validation helpers
82
- - context/export serializers
83
- - event/action/evidence/approval/work-item helpers
84
-
85
- This avoids scattering AX-specific object shapes across `canvas-state.ts`,
86
- `server.ts`, `index.ts`, `mcp/server.ts`, and `cli/agent.ts`.
87
-
88
- ### Vertical slice sequencing
85
+ | Partition | Contents | Persistence | Snapshot behavior |
86
+ |---|---|---|---|
87
+ | Canvas-bound AX state | focus, work items, approvals, review annotations, node AX capabilities, interaction state | `.pmx-canvas/canvas.db` | included in snapshots |
88
+ | Timeline AX state | events, evidence, steering, tool/session records, delivery outcomes | `.pmx-canvas/canvas.db` with retention | not restored by snapshots |
89
+ | Host/session AX state | host capabilities, active adapter sessions, delivery cursors | persisted only where useful | not restored by snapshots |
90
+ | Policy AX state | permission rules, tool policies, command registry, mode rules | PMX project config or DB, depending on durability need | included when project-scoped |
89
91
 
90
- Use primitive groups as the unit of implementation:
92
+ ### Core primitives
91
93
 
92
- 1. AX context and focus: reuse existing pins and prove context export across
93
- HTTP, SDK, MCP, CLI, and Copilot hook injection.
94
- 2. Steering and agent events: prove adapter-to-session messaging and timeline
95
- recording without changing canvas rendering.
96
- 3. Work items and approvals: add user-visible collaboration state and approval
97
- enforcement for AX actions that explicitly opt into approval.
98
- 4. Evidence and review annotations: add richer diagnostics and review surfaces.
99
- 5. Host capabilities and adapter polish: expose what each host can support and
100
- improve native Copilot ergonomics.
94
+ | PMX-AX primitive | Core meaning | Example node use | Host adapter mapping |
95
+ |---|---|---|---|
96
+ | `canvas-surface` | A visible shared workbench surface. | Workbench, grouped board, node gallery. | Copilot `createCanvas().open()`, browser canvas, Codex browser panel. |
97
+ | `context` | Agent-readable context from pins, focus, selected nodes, and policy. | Pin a design note, focus a file node. | Copilot `additionalContext`, MCP resources, CLI `ax context`. |
98
+ | `focus` | Current node or node set requiring attention. | User focuses an incident node. | Host prompt context, adapter actions. |
99
+ | `node-capability` | What AX actions a node can emit or anchor. | Meeting board can create work; file node can create review. | Mostly core; adapters may report support. |
100
+ | `node-interaction` | Validated event emitted by an eligible node. | Drag agenda item to action lane. | Adapter may turn selected interactions into prompts or UI. |
101
+ | `work-item` | Visible task, plan step, or follow-up tied to nodes. | Status node updates a task; meeting board creates action. | Host tasks/tools if supported. |
102
+ | `approval-gate` | PMX-owned human approval before a high-impact action. | Deploy node asks for approval. | Copilot permission hooks where safe. |
103
+ | `evidence-item` | Inspectable artifact: log, file, diff, screenshot, test output, tool result. | File node marks itself as evidence. | Tool results, screenshots, host evidence surfaces. |
104
+ | `review-annotation` | Comment or finding anchored to node, file, region, or diff. | File node emits review comment. | PR review comments where adapter supports it. |
105
+ | `steering-message` | Human instruction from PMX surface to an active agent. | "Investigate this failing lane first." | Copilot `session.send()`, CLI prompt, future Codex bridge. |
106
+ | `agent-event` | Normalized prompt, response, tool, failure, approval, or state event. | Timeline node shows session activity. | Host session hooks/events. |
107
+ | `command` | Named user-invoked intent. | `/pmx-plan`, `/promote-context`. | Copilot slash commands, CLI commands, MCP tools. |
108
+ | `tool-policy` | Allowed, excluded, or approval-required tool rules. | Node requests "read-only investigation mode". | Copilot `availableTools`, `excludedTools`, permission hooks. |
109
+ | `prompt-policy` | System/context/prompt injection rules. | Context node requests concise mode. | Copilot `systemMessage`, modified prompt, additional context. |
110
+ | `mode-request` | Request or approval for mode transition. | Plan node asks to exit planning and execute. | Copilot exit plan mode, auto mode switch hooks. |
111
+ | `elicitation` | Structured request for human input. | Form node asks for missing migration owner. | Copilot `onUserInputRequest`, `onElicitationRequest`, `session.ui`. |
112
+ | `host-capability` | What the current adapter can support. | Copilot supports canvases/hooks/tools, CLI does not support UI prompts. | Host capability report. |
113
+ | `delivery` | State of adapter-bound instructions/events. | Steering pending, sent, acked, failed. | Adapter cursors, delivered markers, retry policy. |
114
+
115
+ ## Node AX Capability Model
116
+
117
+ AX should be available to most node types where useful, not all nodes and not
118
+ all actions.
119
+
120
+ ### Capability sources
121
+
122
+ Capabilities can come from two places:
123
+
124
+ 1. **Server-side node-type registry** for safe defaults.
125
+ 2. **Per-node metadata** for explicit opt-in or narrowed permission.
126
+
127
+ Example shape:
128
+
129
+ ```ts
130
+ interface NodeAxCapabilities {
131
+ enabled: boolean;
132
+ allowed: Array<
133
+ | 'ax.event.record'
134
+ | 'ax.steer'
135
+ | 'ax.work.create'
136
+ | 'ax.work.update'
137
+ | 'ax.evidence.add'
138
+ | 'ax.approval.request'
139
+ | 'ax.approval.resolve'
140
+ | 'ax.review.add'
141
+ | 'ax.focus.set'
142
+ | 'ax.command.invoke'
143
+ | 'ax.elicitation.request'
144
+ | 'ax.mode.request'
145
+ >;
146
+ requiresApproval?: string[];
147
+ delivery?: 'record-only' | 'notify-agent' | 'send-to-agent';
148
+ }
149
+ ```
150
+
151
+ ### Initial node capability matrix
152
+
153
+ | Node type | AX fit | Example allowed interactions |
154
+ |---|---|---|
155
+ | `markdown` | High | steer, evidence, work create, command invoke |
156
+ | `context` | High | focus, steer, evidence, prompt policy |
157
+ | `status` | High | work update, approval request, event record |
158
+ | `file` | High | evidence add, review add, focus |
159
+ | `json-render` | High | structured action events, work update, elicitation request |
160
+ | `graph` | Medium | evidence add, focus set, event record for selected data |
161
+ | `html` / `html-primitive` | High when opted in | work, steering, approvals, review, evidence via sandbox bridge |
162
+ | `mcp-app` / `web-artifact` | Medium to high | app bridge events where trusted and schema-validated |
163
+ | `image` | Medium | evidence add, review annotation |
164
+ | `ledger` / `trace` | High | evidence add, event record |
165
+ | `group` | Medium | focus, work grouping, command invoke |
166
+ | `prompt` / `response` | Internal | agent-event, context, delivery state |
167
+
168
+ Default rule: a node can anchor AX state, but only eligible nodes can emit AX
169
+ interactions.
170
+
171
+ ## Node Interaction Envelope
172
+
173
+ All node-originated AX interactions should converge on one normalized shape:
174
+
175
+ ```ts
176
+ interface PmxAxInteraction {
177
+ type: string;
178
+ sourceNodeId: string;
179
+ sourceSurface?: 'native-node' | 'json-render' | 'html-node' | 'mcp-app' | 'adapter';
180
+ actor?: {
181
+ kind: 'human' | 'agent' | 'system';
182
+ id?: string;
183
+ displayName?: string;
184
+ };
185
+ payload: Record<string, unknown>;
186
+ correlationId?: string;
187
+ createdAt?: string;
188
+ metadata?: Record<string, unknown>;
189
+ }
190
+ ```
191
+
192
+ The shared server endpoint should validate:
193
+
194
+ - source node exists
195
+ - node type can emit the interaction
196
+ - node metadata allows the interaction
197
+ - payload matches the schema for the requested PMX-AX primitive
198
+ - requested delivery mode is allowed
199
+ - action does not request arbitrary tool or host execution
200
+
201
+ Suggested endpoint:
202
+
203
+ ```text
204
+ POST /api/canvas/ax/interaction
205
+ ```
206
+
207
+ It should map valid interactions onto existing PMX-AX operations:
208
+
209
+ - `ax.event.record` -> timeline event
210
+ - `ax.steer` -> steering message and delivery queue
211
+ - `ax.work.create` -> work item
212
+ - `ax.work.update` -> work item patch
213
+ - `ax.evidence.add` -> evidence item
214
+ - `ax.approval.request` -> approval gate
215
+ - `ax.approval.resolve` -> approval resolution
216
+ - `ax.review.add` -> review annotation
217
+ - `ax.focus.set` -> focus state
218
+ - `ax.command.invoke` -> PMX command intent, not arbitrary host command
219
+ - `ax.elicitation.request` -> PMX input request
220
+ - `ax.mode.request` -> PMX mode transition request
221
+
222
+ ## Interaction Transports
223
+
224
+ | Transport | Used by | Mechanism | Trust boundary |
225
+ |---|---|---|---|
226
+ | Native client event | PMX-rendered nodes | direct client API call to PMX HTTP | trusted PMX client, still server-validated |
227
+ | json-render action | json-render nodes | structured action callback to PMX client | schema-driven, server-validated |
228
+ | HTML bridge | `html` and `html-primitive` nodes | sandboxed iframe `postMessage` to parent | opaque origin, token and source validation |
229
+ | MCP app bridge | `mcp-app` nodes | explicit app bridge where available | app identity and schema validation |
230
+ | MCP client surface | MCP-capable agents and clients | MCP resources, prompts, tools, and notifications over the PMX MCP server | client capability and policy validation |
231
+ | Host adapter action | Copilot, Codex, host-native apps | host adapter invokes PMX AX endpoint | host capability and policy validation |
101
232
 
102
- Each group should be complete across all applicable access paths before the
103
- next group starts.
233
+ HTML is therefore one transport, not the AX model.
104
234
 
105
- ### Server-authoritative state
235
+ ## Adapterless MCP Support
106
236
 
107
- `CanvasStateManager` remains the source of truth. AX state should be loaded,
108
- mutated, snapshotted, restored, and notified through the same server-side path
109
- as canvas nodes and context pins.
237
+ PMX-AX should work for agents and clients that do not support Copilot-style
238
+ extensions. MCP is the main agnostic integration path.
110
239
 
111
- ### Adapter boundary
240
+ The baseline should be:
112
241
 
113
- Core must not import `@github/copilot-sdk`. The Copilot adapter lives under
114
- `.github/extensions/pmx-canvas/extension.mjs` and talks to PMX Canvas through
115
- HTTP plus normal Copilot SDK APIs.
242
+ ```text
243
+ agent/client -> PMX MCP resources/tools/prompts -> PMX-AX core
244
+ ```
116
245
 
117
- The adapter should:
246
+ This means Claude Desktop, Claude Code, Codex with MCP, Cursor, Windsurf, raw
247
+ MCP clients, shell agents, and custom scripts can participate in PMX-AX without
248
+ a host-native extension when they can access the PMX MCP server.
118
249
 
119
- 1. discover a running PMX Canvas server through an explicit contract
120
- 2. open the existing `/workbench` URL in a Copilot canvas
121
- 3. expose Copilot canvas actions that proxy PMX AX and canvas operations
122
- 4. inject PMX pinned/AX context on prompt submission
123
- 5. map session events and steering messages to PMX AX events/evidence
250
+ | Capability | Adapterless MCP path | Host-native enhancement |
251
+ |---|---|---|
252
+ | Read PMX context | `canvas://ax-context`, `canvas_get_ax_context`, and an MCP prompt template such as `pmx-current-context` | Adapter injects context automatically into the host prompt. |
253
+ | Keep prompt context fresh | MCP resource notifications and explicit resource reads | Adapter hook injects on every prompt submission. |
254
+ | Send PMX steering to an active agent | Pending steering exposed through MCP resources/tools, e.g. `canvas://ax-pending-steering`, `canvas_claim_ax_delivery`, `canvas_mark_ax_delivery` | Adapter calls host session APIs such as Copilot `session.send()`. |
255
+ | Ask human for structured input | PMX elicitation state exposed through MCP resources/tools | Adapter maps to host UI elicitation APIs. |
256
+ | Gate tool use | PMX tool policy exposed through MCP resources/tools and optional MCP pre-tool hooks where supported | Adapter maps to host tool filtering and permission hooks. |
124
257
 
125
- The discovery contract should be implemented before adapter features:
258
+ Important limitation: generic MCP cannot universally force text into a host chat
259
+ thread. PMX can make pending steering visible and claimable through MCP, and
260
+ MCP-aware agents can read and act on it. Direct host-chat injection still
261
+ requires either MCP-client support for that behavior or a host-native adapter.
126
262
 
127
- 1. use adapter input or environment (`PMX_CANVAS_URL` / `PMX_CANVAS_PORT`) when
128
- provided
129
- 2. probe the repo default loopback server (`127.0.0.1:4313`) and any configured
130
- port
131
- 3. read PMX daemon metadata under `.pmx-canvas/` when available
132
- 4. fail with a visible `session.log()` diagnostic and an actionable canvas error
133
- instead of opening a blank iframe
263
+ ## Host and MCP Capability Matrix
134
264
 
135
- ## Affected Files/Areas
265
+ The Copilot SDK exposes features that should be represented as core PMX-AX
266
+ concepts where generally useful. Anything host-specific stays adapter-only.
136
267
 
137
- ### Core state and persistence
268
+ | Host/client surface | PMX-AX core concept | Adapter or MCP responsibility |
269
+ |---|---|---|
270
+ | Custom tools | `command`, `agent-action`, `tool-policy` | Expose approved PMX actions as host tools. |
271
+ | Slash commands | `command` | Register host commands that invoke PMX command intents. |
272
+ | System message control | `prompt-policy` | Apply PMX policy to host `systemMessage` or additional context. |
273
+ | Tool filtering | `tool-policy` | Map PMX allowed/excluded/approval-required tools to host controls. |
274
+ | User input / elicitation | `elicitation` | Render host UI prompts and record answers in PMX-AX. |
275
+ | Exit plan mode | `mode-request` | Map PMX mode approvals to host plan-mode hooks. |
276
+ | Auto mode switch | `mode-request` | Record and mediate host mode-change requests. |
277
+ | MCP Apps passthrough | `host-capability`, `canvas-surface` | Report support and route app surfaces where safe. |
278
+ | Pre-MCP tool hook | `tool-policy`, `agent-event` | Audit or mutate MCP calls according to PMX policy. |
279
+ | Hook mutation details | `prompt-policy`, `tool-policy`, `agent-event` | Map modified prompt/args/result/output suppression to PMX policy and timeline. |
280
+ | Canvas schema validation | `canvas-surface`, `command`, `agent-action` | Validate canvas input/action schemas and avoid reserved names. |
281
+ | Canvas identity/state model | `host-capability`, `delivery` | Treat `canvasId`, `extensionId`, and `instanceId` as host IDs, not PMX durable IDs. |
282
+ | MCP resources/prompts | `context`, `prompt-policy` | Expose PMX context through resources and prompt templates for adapterless clients. |
283
+ | MCP steering queue | `steering-message`, `delivery` | Let MCP clients claim, act on, and mark pending steering delivered. |
284
+
285
+ ## Copilot Adapter Rules
286
+
287
+ The Copilot adapter should stay thin:
288
+
289
+ - import `@github/copilot-sdk/extension` only in the extension package
290
+ - open the existing PMX `/workbench`
291
+ - expose actions that call PMX HTTP APIs
292
+ - inject PMX context through prompt hooks
293
+ - map host session/tool events into PMX timeline
294
+ - deliver explicit pending steering messages into the active Copilot session
295
+ - report host capabilities into PMX-AX
296
+ - never own durable PMX state
297
+
298
+ Durable PMX state must not be keyed by Copilot `instanceId`. Use PMX node IDs,
299
+ project IDs, adapter session IDs, and delivery cursors instead.
300
+
301
+ ## Delivery Semantics
302
+
303
+ PMX-AX needs explicit delivery state for anything that crosses from PMX into an
304
+ agent, MCP client, or host.
305
+
306
+ ```ts
307
+ type DeliveryStatus =
308
+ | 'pending'
309
+ | 'delivered'
310
+ | 'acknowledged'
311
+ | 'failed'
312
+ | 'ignored'
313
+ | 'expired';
314
+ ```
315
+
316
+ Minimum requirements:
317
+
318
+ - steering messages have delivery status and source adapter
319
+ - adapters and MCP clients can claim and mark messages delivered
320
+ - PMX prevents loops, for example Copilot-originated steering should not be sent
321
+ back into the same Copilot session
322
+ - failed delivery is visible in timeline diagnostics
323
+ - delivery cursors survive adapter or MCP client restart where useful
324
+
325
+ Likely HTTP additions:
326
+
327
+ ```text
328
+ GET /api/canvas/ax/delivery/pending?consumer=copilot
329
+ GET /api/canvas/ax/delivery/pending?consumer=mcp
330
+ POST /api/canvas/ax/delivery/:id/mark
331
+ POST /api/canvas/ax/steer/:id/delivered
332
+ ```
333
+
334
+ The exact route shape can change, but delivery must be a first-class PMX-AX
335
+ concern.
336
+
337
+ ## Permission and Policy Model
338
+
339
+ PMX approvals and host permissions overlap but are not identical.
340
+
341
+ PMX core should define:
342
+
343
+ - approval gates for PMX-owned actions
344
+ - tool policy for allowed, excluded, and approval-required tools
345
+ - prompt policy for context and system-message injection
346
+ - node capability policy for emitted interactions
347
+ - mode transition policy for plan/execute/autonomous workflows
348
+
349
+ Adapters should map these to host primitives where available:
350
+
351
+ - Copilot permission hooks
352
+ - Copilot available/excluded tools
353
+ - Copilot user input and elicitation hooks
354
+ - Copilot plan-mode and auto-mode hooks
355
+ - CLI confirmation prompts
356
+ - MCP tool gating
357
+
358
+ If a host lacks a feature, PMX should degrade to record-only, visible approval
359
+ state, or a clear unsupported capability status.
360
+
361
+ ## Affected Files and Areas
362
+
363
+ ### Core PMX-AX
138
364
 
139
- - `src/server/ax-state.ts` - new core AX primitive model and serializers
140
- - `src/server/canvas-state.ts` - own AX state, persistence integration,
141
- notifications, snapshots, restore, clear
142
- - `src/server/canvas-db.ts` - add migration-safe AX tables or JSON state row
143
- and snapshot persistence
144
- - `src/server/canvas-serialization.ts` and/or `src/server/agent-context.ts` -
145
- reuse existing pinned-context summaries in the AX context export
365
+ - `src/server/ax-state.ts`
366
+ - extend primitive types, node capabilities, interactions, delivery, policy,
367
+ commands, elicitation, and mode requests
368
+ - `src/server/canvas-state.ts`
369
+ - own PMX-AX state and persistence integration
370
+ - `src/server/canvas-db.ts`
371
+ - additive tables for interactions, delivery, policy, commands, or mode state
372
+ where needed
373
+ - `src/server/agent-context.ts`
374
+ - build bounded context from pins, focus, node capabilities, and delivery state
375
+ - `src/server/canvas-serialization.ts`
376
+ - include canvas-bound PMX-AX state in snapshots
146
377
 
147
- ### Core operations and SDK
378
+ ### HTTP and SSE
148
379
 
149
- - `src/server/canvas-operations.ts` - add shared operation helpers for AX
150
- mutations
151
- - `src/server/index.ts` - add `PmxCanvas` SDK methods for AX state, context,
152
- actions, approvals, evidence, events, work items, capabilities, and steering
153
- - `src/mcp/canvas-access.ts` - add local/remote access methods for AX APIs
380
+ - `src/server/server.ts`
381
+ - shared `/api/canvas/ax/interaction`
382
+ - delivery routes
383
+ - command/policy/mode/elicitation routes if not covered by existing AX routes
384
+ - SSE events for AX state, timeline, delivery, and node interaction outcomes
154
385
 
155
- ### HTTP and SSE
386
+ ### Client/browser
156
387
 
157
- - `src/server/server.ts` - add routes such as:
158
- - `GET /api/canvas/ax`
159
- - `PATCH /api/canvas/ax`
160
- - `GET /api/canvas/ax/context`
161
- - `POST /api/canvas/ax/action`
162
- - `POST /api/canvas/ax/event`
163
- - `POST /api/canvas/ax/evidence`
164
- - `POST /api/canvas/ax/approval`
165
- - `POST /api/canvas/ax/steer`
166
- - emit `ax-state-changed` / `ax-event-created` SSE events where useful
167
- - keep existing `/api/canvas/context-pins` and `/api/canvas/pinned-context`
168
- stable; AX context should build on them
169
-
170
- ### MCP
171
-
172
- - `src/mcp/server.ts`
173
- - add AX resource(s), likely `canvas://ax` and `canvas://ax-context`
174
- - add tools such as `canvas_get_ax`, `canvas_update_ax`,
175
- `canvas_record_ax_event`, `canvas_add_evidence`,
176
- `canvas_request_approval`, and `canvas_send_steering`
177
- - update resource notifications for AX changes
178
-
179
- ### CLI
180
-
181
- - `src/cli/index.ts` - add top-level command group routing, likely `ax`
182
- and/or `copilot`
183
- - `src/cli/agent.ts` - add agent-native JSON commands:
184
- - `pmx-canvas ax status`
185
- - `pmx-canvas ax context`
186
- - `pmx-canvas ax event add`
187
- - `pmx-canvas ax evidence add`
188
- - `pmx-canvas ax approval request|resolve`
189
- - `pmx-canvas ax work add|update|list`
190
- - `pmx-canvas copilot install-extension`
388
+ - `src/client/nodes/HtmlNode.tsx`
389
+ - sandbox bridge transport only for HTML/html-primitive
390
+ - `src/server/html-surface.ts`
391
+ - inject `window.PMX_AX.emit(...)` helper when bridge is enabled
392
+ - json-render node renderer
393
+ - emit structured PMX-AX interactions from native actions where applicable
394
+ - native node renderers
395
+ - expose selected PMX-AX actions in node menus or inline controls
396
+ - SSE bridge/client store
397
+ - update visible AX state live
398
+
399
+ ### SDK, MCP, and CLI
400
+
401
+ - `src/server/index.ts`
402
+ - PMX SDK methods for interactions, delivery, policy, commands, elicitation,
403
+ and mode requests
404
+ - `src/mcp/server.ts` and `src/mcp/canvas-access.ts`
405
+ - MCP resources/tools/prompts for PMX-AX state, interactions, delivery,
406
+ policy, command intents, and adapterless prompt context
407
+ - resources such as `canvas://ax-context`, `canvas://ax-timeline`,
408
+ `canvas://ax-pending-steering`, and `canvas://ax-delivery`
409
+ - prompt templates such as `pmx-current-context` so MCP-aware clients can
410
+ inject PMX context without a host-native adapter
411
+ - delivery tools such as `canvas_claim_ax_delivery` and
412
+ `canvas_mark_ax_delivery` so MCP clients can act on pending steering
413
+ - `src/cli/index.ts` and `src/cli/agent.ts`
414
+ - `pmx-canvas ax interaction`
415
+ - `pmx-canvas ax delivery`
416
+ - `pmx-canvas ax command`
417
+ - `pmx-canvas ax policy`
418
+ - `pmx-canvas ax mode`
191
419
 
192
420
  ### Copilot adapter
193
421
 
194
422
  - `.github/extensions/pmx-canvas/extension.mjs`
195
- - register a canvas through `joinSession({ canvases: [...] })`
196
- - use `createCanvas` from `@github/copilot-sdk/extension`
197
- - bind a loopback-safe workbench URL from the PMX server
198
- - expose action handlers for PMX operations
199
- - add `onUserPromptSubmitted` and `onSessionStart` hooks for AX context
200
- - subscribe to session events and record normalized AX events/evidence
201
- - use `session.log()`, never `console.log()`
202
- - a bundled extension template path in the published package, for example
203
- `src/cli/templates/copilot-extension/pmx-canvas/extension.mjs` or an
204
- equivalent package-included location
423
+ - map Copilot SDK hooks/actions/tools/commands to PMX-AX
424
+ - inject PMX context and prompt policy
425
+ - report host capabilities
426
+ - consume delivery queue for explicit steering
427
+ - record host events and tool evidence
428
+ - avoid `console.log`; use `session.log()`
205
429
 
206
- ### Client/browser
430
+ ### Docs and skills
207
431
 
208
- - `src/client/types.ts` - add client-side AX types if the workbench needs to
209
- render AX state directly
210
- - `src/client/state/sse-bridge.ts` - consume AX SSE events if browser UI
211
- should react live
212
- - Existing workbench UI should stay intact; Copilot embeds it rather than
213
- reimplementing the canvas renderer.
214
-
215
- ### Docs and package contents
216
-
217
- - `Readme.md`
218
432
  - `docs/http-api.md`
219
433
  - `docs/sdk.md`
220
434
  - `docs/mcp.md`
221
435
  - `docs/cli.md`
436
+ - `docs/node-types.md`
222
437
  - `skills/pmx-canvas/SKILL.md`
223
- - `package.json` - include the Copilot extension template in published package
224
- files if the current package configuration would otherwise omit it
225
-
226
- ## Implementation Checklist
227
-
228
- ### Phase 0: Adapter/API spike and scaffolding
229
-
230
- - [x] Re-check the local `create-canvas` skill and Copilot SDK docs/types before
231
- writing the extension entrypoint.
232
- - [x] Use `extensions_manage scaffold` for the project extension baseline, then
233
- edit it into `.github/extensions/pmx-canvas/extension.mjs`.
234
- - [x] Define the PMX server discovery contract for the adapter.
235
- - [x] Add or choose a package-included extension template path for CLI
236
- installation.
237
-
238
- ### Phase 1: AX context and focus vertical slice
239
-
240
- - [x] Define `src/server/ax-state.ts` with primitive types, normalizers, and
241
- context/focus serializers.
242
- - [x] Add canvas-bound AX focus state to `CanvasStateManager` without changing
243
- existing node, edge, annotation, pin, or snapshot behavior.
244
- - [x] Persist focus state in SQLite using additive schema changes only.
245
- - [x] Snapshot and restore canvas-bound AX focus state.
246
- - [x] Add HTTP endpoints and SSE events for AX context/focus.
247
- - [x] Add `PmxCanvas` SDK methods for AX context/focus.
248
- - [x] Add `CanvasAccess` local/remote methods for AX context/focus.
249
- - [x] Add MCP resources/tools and resource notifications for AX context/focus.
250
- - [x] Add CLI `ax context` and `ax focus` commands.
251
- - [x] Make the Copilot adapter open the live PMX workbench and inject AX context
252
- from prompt hooks.
253
-
254
- ### Phase 2: Steering and agent-event vertical slice
255
-
256
- - [ ] Add timeline persistence for steering messages and agent events with a
257
- retention policy.
258
- - [ ] Add HTTP/SDK/MCP/CLI operations for recording and reading AX timeline
259
- events.
260
- - [ ] Add Copilot adapter steering actions that call `session.send()` only from
261
- explicit user/action flows.
262
- - [ ] Subscribe to useful Copilot session events and record normalized
263
- `agent-event` entries.
264
-
265
- ### Phase 3: Work items and approval gates vertical slice
266
-
267
- - [ ] Add canvas-bound work-item and approval-gate state.
268
- - [ ] Persist and snapshot work items and approval gates.
269
- - [ ] Add HTTP/SDK/MCP/CLI operations for work-item and approval lifecycle.
270
- - [ ] Enforce approvals for AX actions explicitly marked as requiring approval;
271
- existing non-AX canvas endpoints remain unchanged.
272
- - [ ] Add Copilot adapter UI/actions for approval request and resolution.
273
-
274
- ### Phase 4: Evidence, review annotations, and host capabilities
275
-
276
- - [ ] Add timeline evidence-item persistence and retention.
277
- - [ ] Add review-annotation state or map the AX shape onto existing annotations
278
- where possible.
279
- - [ ] Add host-capability reporting across HTTP/SDK/MCP/CLI.
280
- - [ ] Record Copilot tool/session evidence where low-risk and useful.
281
-
282
- ### Phase 5: Docs, template install, and verification
283
-
284
- - [ ] Add `pmx-canvas copilot install-extension` or equivalent scaffold command.
285
- - [ ] Ensure the extension template is included in published package contents.
286
- - [ ] Update docs and the pmx-canvas skill to describe AX primitives and the
287
- Copilot adapter.
288
- - [ ] Add parity/static tests for state persistence, HTTP, SDK, MCP, CLI,
289
- adapter scaffold behavior, and no Copilot imports in core.
290
- - [ ] Run the repo-standard verification ladder after implementation.
438
+ - `skills/pmx-canvas/references/html-primitives.md`
439
+ - `skills/pmx-canvas/references/github-copilot-app-adapter.md`
440
+
441
+ ## Implementation Plan
442
+
443
+ ### Phase 0: Reframe and inventory
444
+
445
+ - [ ] Rename the plan and docs language from Copilot-first AX to PMX-AX core.
446
+ - [ ] Inventory existing AX implementation and mark what is already done:
447
+ focus, context, work, approvals, evidence, review, timeline, host capability.
448
+ - [ ] Inventory Copilot SDK surfaces and classify them as:
449
+ core PMX-AX concept, adapter mapping, or out of scope.
450
+ - [ ] Add static guard that PMX core imports no Copilot SDK packages.
451
+
452
+ ### Phase 1: Node AX capability and interaction core
453
+
454
+ - [ ] Add node AX capability types and normalizers.
455
+ - [ ] Add a server-side default capability registry per node type.
456
+ - [ ] Add optional per-node `data.axCapabilities` metadata.
457
+ - [ ] Add shared `PmxAxInteraction` envelope and validation.
458
+ - [ ] Add `/api/canvas/ax/interaction`.
459
+ - [ ] Map interaction types to existing AX operations.
460
+ - [ ] Emit SSE for accepted and rejected interactions.
461
+ - [ ] Add tests for capability allow/deny behavior.
462
+
463
+ ### Phase 2: Native node and json-render interactions
464
+
465
+ - [ ] Add client helpers for native node renderers to submit AX interactions.
466
+ - [ ] Add node menu or inline controls for obvious native actions:
467
+ status -> work update, file -> evidence/review, context -> focus/steer.
468
+ - [ ] Add json-render action mapping to AX interactions.
469
+ - [ ] Add visible ack/error feedback for interaction outcomes.
470
+ - [ ] Add tests for native and json-render interaction submission.
471
+
472
+ ### Phase 3: Sandboxed HTML transport
473
+
474
+ - [ ] Add opt-in HTML bridge capability.
475
+ - [ ] Inject `window.PMX_AX.emit(type, payload, options?)` from
476
+ `html-surface.ts` when enabled.
477
+ - [ ] Use iframe `postMessage` to parent with token, node ID, event type,
478
+ payload, and correlation ID.
479
+ - [ ] Validate iframe source, token, node ID, node capability, and payload in
480
+ `HtmlNode.tsx` before calling the shared PMX endpoint.
481
+ - [ ] Keep iframe sandbox as `allow-scripts` only.
482
+ - [ ] Add ack/error responses back into the iframe.
483
+ - [ ] Update at least one interactive HTML primitive, preferably Meeting
484
+ Liveboard, so moving an item to Actions creates or updates a work item
485
+ and records an event.
486
+
487
+ ### Phase 4: Delivery, steering, and agent reaction
488
+
489
+ - [ ] Add delivery status to steering and other adapter-bound events.
490
+ - [ ] Add pending delivery query and mark-delivered routes.
491
+ - [ ] Add loop prevention by source adapter/session.
492
+ - [ ] Add MCP resources/tools for pending steering and delivery state so
493
+ adapterless MCP clients can read, claim, act on, and acknowledge steering.
494
+ - [ ] Add an MCP prompt template for current PMX context so MCP-aware clients can
495
+ inject PMX context without a host-native extension.
496
+ - [ ] Update Copilot adapter to consume explicit pending steering and call
497
+ `session.send()` only for allowed delivery items.
498
+ - [ ] Record delivery success/failure in PMX timeline.
499
+ - [ ] Add CLI/MCP visibility into pending and failed delivery.
500
+
501
+ ### Phase 5: Policy, commands, mode, and elicitation
502
+
503
+ - [ ] Add PMX command primitive and registry.
504
+ - [ ] Map Copilot slash commands to PMX command intents.
505
+ - [ ] Add prompt policy for additional context, modified prompt, and system
506
+ message append/customization.
507
+ - [ ] Add tool policy for available tools, excluded tools, and
508
+ approval-required tools.
509
+ - [ ] Add mode request primitive for plan exit and auto mode changes.
510
+ - [ ] Add elicitation primitive for structured human input.
511
+ - [ ] Map Copilot hooks to these PMX concepts where available.
512
+
513
+ ### Phase 6: MCP app and web artifact bridge
514
+
515
+ - [ ] Define which MCP app and web-artifact interactions are trusted enough to
516
+ bridge into PMX-AX.
517
+ - [ ] Add app identity and schema validation.
518
+ - [ ] Route app interactions through the same `/api/canvas/ax/interaction`
519
+ endpoint.
520
+ - [ ] Keep unsafe or unknown app interactions record-only or disabled.
521
+
522
+ ### Phase 7: Documentation and verification
523
+
524
+ - [ ] Update HTTP, SDK, MCP, CLI, node type, and skill docs.
525
+ - [ ] Update Copilot adapter reference to describe it as a host mapping.
526
+ - [ ] Add examples for:
527
+ - status node updating work
528
+ - file node creating evidence
529
+ - Meeting Liveboard creating action work
530
+ - Copilot adapter delivering steering
531
+ - [ ] Run repo-standard validation.
291
532
 
292
533
  ## Success Criteria
293
534
 
294
- - PMX Canvas core can represent and persist AX primitives without any GitHub
295
- Copilot dependency.
296
- - Existing PMX Canvas behavior remains backward-compatible: current HTTP, MCP,
297
- CLI, SDK, browser, snapshots, and pinned-context flows keep working.
298
- - HTTP, SDK, MCP, and CLI expose the same AX primitives consistently.
299
- - The GitHub Copilot app can open PMX Canvas natively through a project canvas
300
- extension and render the existing workbench.
301
- - The Copilot adapter can:
302
- - inject PMX AX/pinned context on prompt submission
303
- - proxy core canvas/AX actions
304
- - update pins/basic canvas state
305
- - send steering instructions to the agent session
306
- - record useful Copilot session/tool events as AX events/evidence
307
- - Canvas-bound AX state is included in snapshots; timeline AX state persists in
308
- the PMX DB but is not restored by snapshots.
309
- - Codex is not implemented, but no core type or persistence decision prevents a
310
- later Codex adapter.
311
-
312
- ## Risk Assessment
313
-
314
- | Risk | Impact | Mitigation |
315
- |---|---|---|
316
- | AX model becomes Copilot-shaped instead of PMX-shaped. | Future Codex/MCP/HTTP reuse becomes expensive. | Keep all Copilot imports and names out of core; use neutral PMX primitives and adapter mapping only. |
317
- | Persistence changes break existing `.pmx-canvas/canvas.db` files. | Existing users lose or corrupt canvas state. | Add new tables/rows with `CREATE TABLE IF NOT EXISTS`; keep current tables and existing payload shapes stable. |
318
- | Duplicating pinned-context logic creates drift. | Different agents receive different context. | Reuse `agent-context.ts` and existing pinned-context summaries for AX context export. |
319
- | Copilot adapter tries to reimplement the workbench UI. | Large fragile UI duplicate. | Embed the existing `/workbench` URL and use adapter code only for SDK hooks/actions/session events. |
320
- | Extension process cannot run Bun/PMX server in some environments. | Copilot canvas opens without a backend. | Prefer discovering an existing PMX server; add explicit startup diagnostics and clear error states. Use loopback URLs only. |
321
- | `session.send()` from hooks causes loops. | Adapter can recursively prompt the agent. | Do not call `session.send()` synchronously from prompt hooks; steering actions should be user/action initiated. |
322
- | MCP/CLI/SDK parity drifts. | Agents see different capabilities by host. | Follow the existing repo rule: new operation lands in state manager, SDK, HTTP, MCP, and CLI together. |
323
- | SQLite schema changes assume migrations that do not exist. | Older DBs fail to load. | Use additive tables/columns only unless a real migration path is added; do not bump schema version without a tested migrator. |
324
- | AX timeline grows without bounds. | DB size and context export become noisy. | Add a retention/query limit policy for timeline primitives; context export should include bounded summaries only. |
535
+ - PMX-AX is documented and implemented as core PMX architecture, not Copilot
536
+ glue.
537
+ - Eligible node types can emit or anchor AX interactions through a shared
538
+ validated endpoint.
539
+ - HTML/html-primitive nodes use a sandbox-safe bridge, but the AX model is not
540
+ HTML-specific.
541
+ - Work items, approvals, evidence, review annotations, steering, context, focus,
542
+ commands, policy, mode requests, and delivery semantics have PMX-owned types.
543
+ - Copilot SDK primitives map clearly to PMX-AX concepts or are explicitly
544
+ adapter-only.
545
+ - PMX core imports no Copilot SDK code.
546
+ - Durable PMX state is not keyed by Copilot `instanceId`.
547
+ - Agent-readable context and timeline expose node-originated interactions.
548
+ - Adapter-bound steering has visible pending, delivered, failed, or ignored
549
+ state.
550
+ - Adapterless MCP clients can access current PMX context through resources,
551
+ tools, and prompt templates.
552
+ - Adapterless MCP clients can see and claim pending PMX steering through MCP
553
+ resources/tools even when they cannot inject directly into a host chat.
554
+ - Existing canvas behavior remains backward-compatible.
325
555
 
326
556
  ## Test Strategy
327
557
 
328
558
  ### Unit tests
329
559
 
560
+ - `tests/unit/ax-state.test.ts` or equivalent:
561
+ - interaction envelope validation
562
+ - node capability allow/deny rules
563
+ - delivery status transitions
564
+ - prompt/tool/mode policy normalization
330
565
  - `tests/unit/canvas-state.test.ts`
331
- - AX state persists and reloads
332
- - AX state is included in snapshots and restored
333
- - clearing canvas handles AX state according to the chosen semantics
566
+ - canvas-bound PMX-AX state persists and snapshots
567
+ - timeline state persists but is retention-bounded
334
568
  - `tests/unit/server-api.test.ts`
335
- - HTTP AX endpoints return stable JSON
336
- - AX context reuses pinned node summaries
337
- - SSE emits AX events when AX state changes
338
- - `tests/unit/pmx-canvas-sdk.test.ts`
339
- - `PmxCanvas` exposes AX methods and mutates core state correctly
569
+ - `/api/canvas/ax/interaction` accepts valid payloads
570
+ - rejects disabled node, disallowed action, invalid payload, unknown node
571
+ - maps valid interactions to work/evidence/review/steering/focus
572
+ - delivery routes round-trip
573
+ - `tests/unit/html-surface.test.ts`
574
+ - bridge script is injected only when enabled
575
+ - unsafe token values are sanitized
576
+ - helper API shape is present
577
+ - `tests/unit/client-*`
578
+ - iframe source/token validation
579
+ - ack/error postMessage behavior
580
+ - json-render/native interaction submission
340
581
  - `tests/unit/mcp-server.test.ts`
341
- - MCP lists AX resources/tools
342
- - MCP tools can read/update AX state
343
- - resource notifications include AX changes
344
- - `tests/unit/cli-node.test.ts` or a new CLI test file
345
- - `pmx-canvas ax ...` commands return JSON and fail loudly on invalid input
346
- - `pmx-canvas copilot install-extension --dry-run` previews the target path
347
- - Static/parity tests
348
- - no core/server/shared files import `@github/copilot-sdk`
349
- - every committed AX operation has SDK, HTTP, MCP, and CLI coverage or an
350
- explicit documented exception
351
- - the Copilot extension template is included in the package file list
582
+ - exposes PMX context as MCP resources and prompt templates
583
+ - exposes pending steering/delivery state through MCP resources/tools
584
+ - claim/mark delivery tools update PMX delivery state
585
+ - Static tests:
586
+ - no PMX core imports `@github/copilot-sdk`
587
+ - every PMX-AX operation has HTTP, SDK, MCP, and CLI coverage or an explicit
588
+ documented exception
352
589
 
353
590
  ### Adapter tests
354
591
 
355
- - Add a focused test around the generated Copilot extension file/template:
356
- - extension file exists at `.github/extensions/pmx-canvas/extension.mjs`
357
- - it imports only `@github/copilot-sdk/extension` and Node built-ins
358
- - it contains no `console.log`
359
- - declared canvas/actions avoid reserved `canvas.*` action names
360
- - server discovery failures produce visible adapter diagnostics
361
-
362
- Full runtime Copilot SDK execution may not be practical in normal Bun tests, so
363
- the minimum automated test should verify the scaffold/template and the PMX HTTP
364
- contract it relies on.
365
-
366
- ### Integration/e2e
367
-
368
- - Existing web canvas Playwright test after client changes.
369
- - HTTP smoke:
370
- - start PMX server
371
- - add nodes
372
- - pin nodes
373
- - read `/api/canvas/ax/context`
374
- - invoke an AX event/evidence/approval mutation
375
- - Snapshot smoke:
376
- - create canvas-bound AX state
377
- - save snapshot
378
- - mutate AX state
379
- - restore snapshot
380
- - confirm canvas-bound AX state restored and timeline state remains bounded
381
- - MCP smoke:
382
- - start MCP server
383
- - list AX resources/tools
384
- - read AX context
385
-
386
- ## Validation and Diagnostics
387
-
388
- - Build/typecheck must catch shared type drift:
389
- - `bun run typecheck`
390
- - `bun run build`
391
- - Unit tests should cover the changed surfaces:
392
- - `bun test tests/unit/canvas-state.test.ts tests/unit/server-api.test.ts tests/unit/pmx-canvas-sdk.test.ts tests/unit/mcp-server.test.ts tests/unit/cli-node.test.ts`
393
- - If client code changes, run the canvas bundle build and browser tests per repo
394
- guidance.
395
- - For manual Copilot adapter validation:
396
- - reload extensions
397
- - verify `pmx-canvas` appears in canvas capabilities
398
- - open the Copilot canvas
399
- - confirm the PMX workbench loads
400
- - pin a node and confirm the next prompt receives AX context
401
- - invoke a basic adapter action and confirm PMX state changes
402
-
403
- Diagnostics expectations:
404
-
405
- - Extension failures should be visible through `extensions_manage inspect`.
406
- - Adapter should use `session.log()` for user-visible errors.
407
- - HTTP/CLI/MCP failures should include actionable errors, not silent no-ops.
408
-
409
- ## Knowledge Map
410
-
411
- | Step | Knowledge Source | Confidence |
592
+ - Copilot extension declares valid canvas/action schemas.
593
+ - No reserved `canvas.*` action names.
594
+ - Adapter uses `session.log()`, not `console.log()`.
595
+ - Adapter maps host capabilities into PMX host-capability state.
596
+ - Adapter does not own durable PMX state.
597
+ - Adapter avoids delivery loops for Copilot-originated steering.
598
+
599
+ ### Integration tests
600
+
601
+ - Start PMX server.
602
+ - Add a status node with AX capability.
603
+ - Submit interaction to update/create a work item.
604
+ - Add an HTML Meeting Liveboard node.
605
+ - Move item into Actions and verify:
606
+ - work item exists
607
+ - timeline event exists
608
+ - context/timeline APIs expose the result
609
+ - browser shows ack or error
610
+ - Exercise Copilot adapter manually or through static harness:
611
+ - open PMX workbench
612
+ - pin/focus node
613
+ - verify prompt context injection
614
+ - create pending steering
615
+ - verify delivery or visible unsupported state
616
+
617
+ ## Validation Commands
618
+
619
+ Use existing repo commands only:
620
+
621
+ ```bash
622
+ bun run typecheck
623
+ bun run test
624
+ bun run build
625
+ ```
626
+
627
+ If client behavior changes significantly, also run the relevant Playwright
628
+ coverage:
629
+
630
+ ```bash
631
+ bun run test:web-canvas
632
+ ```
633
+
634
+ ## Risks and Mitigations
635
+
636
+ | Risk | Impact | Mitigation |
412
637
  |---|---|---|
413
- | Define neutral AX primitives | Prompt/context from interview plus existing PMX pinned-context architecture | High |
414
- | Persist AX state in core | Codebase: `canvas-state.ts`, `canvas-db.ts`, tests/helpers persistence patterns | High |
415
- | Expose HTTP/SDK/MCP/CLI surfaces | Codebase: existing 1:1 operation pattern in `server.ts`, `index.ts`, `mcp/server.ts`, `cli/agent.ts` | High |
416
- | Build Copilot canvas adapter | Reachable SDK docs: `create-canvas` skill, `extensions.md`, `agent-author.md`, `canvas.d.ts`, `session.d.ts`; verify again in Phase 0 | High |
417
- | Inject context in Copilot | Reachable SDK docs: `onUserPromptSubmitted` and `additionalContext` | High |
418
- | Programmatic steering in Copilot | Reachable SDK docs: `session.send()` / `sendAndWait()` and gotchas | High |
419
- | Runtime validation inside actual GitHub Copilot app | Host tooling available through extension management and canvas tools; runtime still requires manual inspection | Medium |
420
- | Codex adapter | Out of scope; future host-specific docs needed | Not planned |
638
+ | PMX-AX becomes Copilot-shaped. | Codex, MCP, CLI, and future hosts become second-class. | Keep core PMX concepts neutral and SDK mapping adapter-only. |
639
+ | AX interactions become HTML-only. | Native nodes and structured PMX surfaces cannot participate. | Build shared node interaction layer first, then add HTML as one transport. |
640
+ | Over-broad node permissions. | Arbitrary artifact code can steer agents or mutate state. | Capability registry, per-node opt-in, strict schemas, no arbitrary execution. |
641
+ | Adapter delivery loops. | Copilot sends messages back to itself repeatedly. | Source/session tracking, delivery cursors, loop-prevention tests. |
642
+ | Timeline becomes noisy. | Agent context degrades. | Retention, summaries, filters, delivery status, and context budget rules. |
643
+ | Policy overlaps host permissions badly. | Confusing approval behavior. | PMX approval is canonical; host permissions are mapped where safe. |
644
+ | Durable state tied to host instance IDs. | State breaks when panels close/reopen. | Use PMX node/project/session IDs; treat host instance IDs as transient. |
645
+ | Bridge creates security regressions. | Sandbox or origin protections weaken. | Keep `allow-scripts` only, validate parent/iframe source and token, test rejection paths. |
421
646
 
422
647
  ## Open Questions
423
648
 
424
- - [ ] Should `canvas_clear` remove timeline AX events/evidence, or only
425
- canvas-bound AX state? This can proceed with the conservative default:
426
- clear canvas-bound state and keep timeline history subject to retention.
427
- - [ ] Should `approval-gate` integrate deeply with Copilot permission hooks in
428
- this first pass or only expose PMX approvals through adapter UI/actions?
429
- This can proceed by implementing PMX approvals first and mapping
430
- permission hooks only where low-risk.
649
+ - Which node types should have AX emission enabled by default, if any?
650
+ - Should project owners be able to configure node AX capabilities globally?
651
+ - Which PMX commands should be first-class in the command registry?
652
+ - How much prompt/system-message mutation should PMX allow by default?
653
+ - Should delivery be limited to steering messages first, or generalized across
654
+ all adapter-bound AX events immediately?
655
+ - Which MCP app bridge interactions are safe enough for first-pass support?
656
+ - Should PMX expose a visible "AX inbox" for pending delivery, approvals, and
657
+ elicitation requests?
431
658
 
432
659
  ## Rejected Alternatives
433
660
 
434
- ### Put Copilot SDK concepts directly in PMX core
435
-
436
- Rejected because PMX Canvas must remain usable by any agent. Core should expose
437
- neutral AX concepts; Copilot translates them to SDK hooks, canvases, tools, and
438
- session events.
661
+ ### Build only an HTML Node AX Bridge
439
662
 
440
- ### Store AX in `.pmx-canvas/ax.json`
663
+ Rejected because it solves the sandboxed artifact problem but misses the larger
664
+ AX model. HTML is one transport. PMX-AX must support native nodes, json-render,
665
+ files, status nodes, context nodes, MCP apps, and adapters.
441
666
 
442
- Rejected by interview decision. AX should persist with existing PMX Canvas state
443
- in SQLite and snapshots, so project state remains coherent.
667
+ ### Treat GitHub Copilot SDK parity as the PMX-AX model
444
668
 
445
- ### Rebuild the PMX workbench UI inside the Copilot extension
669
+ Rejected because PMX Canvas must stay host-agnostic. Copilot SDK features are a
670
+ high-value adapter mapping and parity checklist, not the source of truth.
446
671
 
447
- Rejected because the existing PMX browser app already implements full canvas
448
- functionality. The adapter should embed and bridge it rather than fork the UI.
672
+ ### Store adapter state inside Copilot canvas instances
449
673
 
450
- ## Refinement Notes
674
+ Rejected because `instanceId` is transient host UI state. Durable PMX-AX state
675
+ must live in PMX Canvas state and be keyed by PMX domain IDs.
451
676
 
452
- ### Draft pass
677
+ ### Allow arbitrary HTML iframes to call PMX APIs directly
453
678
 
454
- Initial plan aligns the broad implementation with existing repo rules: state is
455
- server-authoritative, MCP tools map to SDK/HTTP/state operations, and the
456
- Copilot adapter is isolated from core.
679
+ Rejected for untrusted or semi-trusted sandboxed nodes. Local does not mean
680
+ trusted: HTML nodes can contain pasted code, generated artifacts, CDN scripts,
681
+ or copied examples. If arbitrary iframe code can call PMX APIs directly, it can
682
+ bypass node capabilities and access every enabled local endpoint for canvas
683
+ mutation, steering, approvals, evidence, or future privileged actions.
457
684
 
458
- ### Fresh-eyes pass 1
685
+ The parent-mediated bridge preserves the sandbox, binds each interaction to the
686
+ originating node and iframe token, and validates intent before PMX state
687
+ changes.
459
688
 
460
- Refined the plan from a breadth-first implementation into phased vertical
461
- slices, split canvas-bound AX state from timeline AX state, made server
462
- discovery and template packaging explicit, added static/parity tests, and
463
- resolved the snapshot-vs-timeline contradiction before implementation.
689
+ Trusted built-in PMX app surfaces may still call internal PMX APIs directly when
690
+ they are first-party, same-origin, and covered by normal server validation. This
691
+ rejection applies to arbitrary `html`, generated `html-primitive`, and other
692
+ semi-trusted iframe content.