pmx-canvas 0.1.0
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.
- package/CHANGELOG.md +38 -0
- package/LICENSE +21 -0
- package/Readme.md +865 -0
- package/dist/canvas/global.css +3173 -0
- package/dist/canvas/index.js +183 -0
- package/dist/json-render/index.css +2 -0
- package/dist/json-render/index.js +389 -0
- package/dist/types/cli/agent.d.ts +13 -0
- package/dist/types/cli/index.d.ts +2 -0
- package/dist/types/cli/watch.d.ts +5 -0
- package/dist/types/client/App.d.ts +1 -0
- package/dist/types/client/canvas/AttentionHistory.d.ts +1 -0
- package/dist/types/client/canvas/AttentionToast.d.ts +1 -0
- package/dist/types/client/canvas/CanvasNode.d.ts +8 -0
- package/dist/types/client/canvas/CanvasViewport.d.ts +8 -0
- package/dist/types/client/canvas/CommandPalette.d.ts +4 -0
- package/dist/types/client/canvas/ContextMenu.d.ts +24 -0
- package/dist/types/client/canvas/ContextPinBar.d.ts +1 -0
- package/dist/types/client/canvas/ContextPinHud.d.ts +1 -0
- package/dist/types/client/canvas/DockedNode.d.ts +4 -0
- package/dist/types/client/canvas/EdgeLayer.d.ts +8 -0
- package/dist/types/client/canvas/ExpandedNodeOverlay.d.ts +1 -0
- package/dist/types/client/canvas/FocusFieldLayer.d.ts +1 -0
- package/dist/types/client/canvas/Minimap.d.ts +23 -0
- package/dist/types/client/canvas/SelectionBar.d.ts +1 -0
- package/dist/types/client/canvas/ShortcutOverlay.d.ts +3 -0
- package/dist/types/client/canvas/SnapshotPanel.d.ts +7 -0
- package/dist/types/client/canvas/snap-guides.d.ts +23 -0
- package/dist/types/client/canvas/use-node-drag.d.ts +15 -0
- package/dist/types/client/canvas/use-node-resize.d.ts +15 -0
- package/dist/types/client/canvas/use-pan-zoom.d.ts +16 -0
- package/dist/types/client/ext-app/bridge.d.ts +161 -0
- package/dist/types/client/icons.d.ts +70 -0
- package/dist/types/client/index.d.ts +1 -0
- package/dist/types/client/nodes/ContextNode.d.ts +34 -0
- package/dist/types/client/nodes/ExtAppFrame.d.ts +18 -0
- package/dist/types/client/nodes/FileNode.d.ts +5 -0
- package/dist/types/client/nodes/GroupNode.d.ts +6 -0
- package/dist/types/client/nodes/ImageNode.d.ts +10 -0
- package/dist/types/client/nodes/InlineFormatBar.d.ts +7 -0
- package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +14 -0
- package/dist/types/client/nodes/LedgerNode.d.ts +4 -0
- package/dist/types/client/nodes/MarkdownNode.d.ts +6 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +4 -0
- package/dist/types/client/nodes/MdFormatBar.d.ts +8 -0
- package/dist/types/client/nodes/PromptNode.d.ts +5 -0
- package/dist/types/client/nodes/ResponseNode.d.ts +5 -0
- package/dist/types/client/nodes/StatusNode.d.ts +4 -0
- package/dist/types/client/nodes/StatusSummary.d.ts +4 -0
- package/dist/types/client/nodes/TraceNode.d.ts +4 -0
- package/dist/types/client/nodes/WebpageNode.d.ts +5 -0
- package/dist/types/client/nodes/image-warnings.d.ts +6 -0
- package/dist/types/client/nodes/inline-editor-commands.d.ts +11 -0
- package/dist/types/client/nodes/md-format.d.ts +25 -0
- package/dist/types/client/state/attention-bridge.d.ts +3 -0
- package/dist/types/client/state/attention-store.d.ts +25 -0
- package/dist/types/client/state/canvas-store.d.ts +74 -0
- package/dist/types/client/state/intent-bridge.d.ts +158 -0
- package/dist/types/client/state/sse-bridge.d.ts +5 -0
- package/dist/types/client/theme/tokens.d.ts +27 -0
- package/dist/types/client/types.d.ts +40 -0
- package/dist/types/client/utils/ext-app-tool-result.d.ts +1 -0
- package/dist/types/client/utils/placement.d.ts +1 -0
- package/dist/types/client/utils/platform.d.ts +2 -0
- package/dist/types/json-render/catalog.d.ts +815 -0
- package/dist/types/json-render/charts/components.d.ts +54 -0
- package/dist/types/json-render/charts/definitions.d.ts +103 -0
- package/dist/types/json-render/charts/extra-components.d.ts +58 -0
- package/dist/types/json-render/charts/extra-definitions.d.ts +181 -0
- package/dist/types/json-render/renderer/index.d.ts +16 -0
- package/dist/types/json-render/schema.d.ts +46 -0
- package/dist/types/json-render/server.d.ts +55 -0
- package/dist/types/mcp/server.d.ts +22 -0
- package/dist/types/server/agent-context.d.ts +21 -0
- package/dist/types/server/artifact-paths.d.ts +3 -0
- package/dist/types/server/canvas-operations.d.ts +154 -0
- package/dist/types/server/canvas-provenance.d.ts +13 -0
- package/dist/types/server/canvas-schema.d.ts +49 -0
- package/dist/types/server/canvas-serialization.d.ts +25 -0
- package/dist/types/server/canvas-state.d.ts +174 -0
- package/dist/types/server/canvas-validation.d.ts +33 -0
- package/dist/types/server/chart-template.d.ts +29 -0
- package/dist/types/server/code-graph.d.ts +67 -0
- package/dist/types/server/context-cards.d.ts +24 -0
- package/dist/types/server/diagram-presets.d.ts +28 -0
- package/dist/types/server/ext-app-call-registry.d.ts +16 -0
- package/dist/types/server/ext-app-tool-result.d.ts +1 -0
- package/dist/types/server/file-watcher.d.ts +16 -0
- package/dist/types/server/index.d.ts +243 -0
- package/dist/types/server/mcp-app-candidate.d.ts +25 -0
- package/dist/types/server/mcp-app-host.d.ts +65 -0
- package/dist/types/server/mcp-app-runtime.d.ts +47 -0
- package/dist/types/server/mutation-history.d.ts +105 -0
- package/dist/types/server/placement.d.ts +37 -0
- package/dist/types/server/server.d.ts +103 -0
- package/dist/types/server/spatial-analysis.d.ts +87 -0
- package/dist/types/server/trace-manager.d.ts +48 -0
- package/dist/types/server/web-artifacts.d.ts +50 -0
- package/dist/types/server/webpage-node.d.ts +25 -0
- package/dist/types/shared/auto-arrange.d.ts +29 -0
- package/dist/types/shared/ext-app-tool-result.d.ts +9 -0
- package/dist/types/shared/placement.d.ts +26 -0
- package/dist/types/shared/semantic-attention.d.ts +97 -0
- package/package.json +109 -0
- package/skills/data-analysis/SKILL.md +324 -0
- package/skills/doc-coauthoring/SKILL.md +375 -0
- package/skills/frontend-design/SKILL.md +45 -0
- package/skills/json-render-codegen/SKILL.md +112 -0
- package/skills/json-render-core/SKILL.md +265 -0
- package/skills/json-render-ink/SKILL.md +273 -0
- package/skills/json-render-mcp/SKILL.md +132 -0
- package/skills/json-render-react/SKILL.md +264 -0
- package/skills/json-render-shadcn/SKILL.md +159 -0
- package/skills/playwright-cli/SKILL.md +67 -0
- package/skills/pmx-canvas/SKILL.md +668 -0
- package/skills/pmx-canvas/evals/evals.json +186 -0
- package/skills/pmx-canvas-testing/SKILL.md +78 -0
- package/skills/published-consumer-e2e/SKILL.md +43 -0
- package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +241 -0
- package/skills/web-artifacts-builder/SKILL.md +80 -0
- package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +167 -0
- package/skills/web-artifacts-builder/scripts/init-artifact.sh +425 -0
- package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/src/cli/agent.ts +2144 -0
- package/src/cli/index.ts +622 -0
- package/src/cli/watch.ts +88 -0
- package/src/client/App.tsx +507 -0
- package/src/client/canvas/AttentionHistory.tsx +81 -0
- package/src/client/canvas/AttentionToast.tsx +19 -0
- package/src/client/canvas/CanvasNode.tsx +363 -0
- package/src/client/canvas/CanvasViewport.tsx +590 -0
- package/src/client/canvas/CommandPalette.tsx +302 -0
- package/src/client/canvas/ContextMenu.tsx +601 -0
- package/src/client/canvas/ContextPinBar.tsx +25 -0
- package/src/client/canvas/ContextPinHud.tsx +22 -0
- package/src/client/canvas/DockedNode.tsx +66 -0
- package/src/client/canvas/EdgeLayer.tsx +280 -0
- package/src/client/canvas/ExpandedNodeOverlay.tsx +260 -0
- package/src/client/canvas/FocusFieldLayer.tsx +107 -0
- package/src/client/canvas/Minimap.tsx +301 -0
- package/src/client/canvas/SelectionBar.tsx +69 -0
- package/src/client/canvas/ShortcutOverlay.tsx +69 -0
- package/src/client/canvas/SnapshotPanel.tsx +236 -0
- package/src/client/canvas/snap-guides.ts +170 -0
- package/src/client/canvas/use-node-drag.ts +51 -0
- package/src/client/canvas/use-node-resize.ts +59 -0
- package/src/client/canvas/use-pan-zoom.ts +191 -0
- package/src/client/ext-app/bridge.ts +542 -0
- package/src/client/icons.tsx +424 -0
- package/src/client/index.tsx +7 -0
- package/src/client/nodes/ContextNode.tsx +412 -0
- package/src/client/nodes/ExtAppFrame.tsx +509 -0
- package/src/client/nodes/FileNode.tsx +256 -0
- package/src/client/nodes/GroupNode.tsx +39 -0
- package/src/client/nodes/ImageNode.tsx +160 -0
- package/src/client/nodes/InlineFormatBar.tsx +169 -0
- package/src/client/nodes/InlineMarkdownEditor.tsx +123 -0
- package/src/client/nodes/LedgerNode.tsx +37 -0
- package/src/client/nodes/MarkdownNode.tsx +359 -0
- package/src/client/nodes/McpAppNode.tsx +85 -0
- package/src/client/nodes/MdFormatBar.tsx +109 -0
- package/src/client/nodes/PromptNode.tsx +597 -0
- package/src/client/nodes/ResponseNode.tsx +153 -0
- package/src/client/nodes/StatusNode.tsx +84 -0
- package/src/client/nodes/StatusSummary.tsx +38 -0
- package/src/client/nodes/TraceNode.tsx +120 -0
- package/src/client/nodes/WebpageNode.tsx +288 -0
- package/src/client/nodes/image-warnings.ts +95 -0
- package/src/client/nodes/inline-editor-commands.ts +37 -0
- package/src/client/nodes/md-format.ts +206 -0
- package/src/client/state/attention-bridge.ts +328 -0
- package/src/client/state/attention-store.ts +73 -0
- package/src/client/state/canvas-store.ts +631 -0
- package/src/client/state/intent-bridge.ts +315 -0
- package/src/client/state/sse-bridge.ts +965 -0
- package/src/client/theme/global.css +3173 -0
- package/src/client/theme/tokens.ts +72 -0
- package/src/client/types-shims.d.ts +5 -0
- package/src/client/types.ts +81 -0
- package/src/client/utils/ext-app-tool-result.ts +4 -0
- package/src/client/utils/placement.ts +4 -0
- package/src/client/utils/platform.ts +2 -0
- package/src/json-render/catalog.ts +256 -0
- package/src/json-render/charts/components.tsx +198 -0
- package/src/json-render/charts/definitions.ts +81 -0
- package/src/json-render/charts/extra-components.tsx +267 -0
- package/src/json-render/charts/extra-definitions.ts +145 -0
- package/src/json-render/renderer/index.css +174 -0
- package/src/json-render/renderer/index.tsx +86 -0
- package/src/json-render/schema.ts +62 -0
- package/src/json-render/server.ts +597 -0
- package/src/mcp/server.ts +1377 -0
- package/src/server/agent-context.ts +242 -0
- package/src/server/artifact-paths.ts +17 -0
- package/src/server/canvas-operations.ts +1279 -0
- package/src/server/canvas-provenance.ts +243 -0
- package/src/server/canvas-schema.ts +432 -0
- package/src/server/canvas-serialization.ts +95 -0
- package/src/server/canvas-state.ts +1134 -0
- package/src/server/canvas-validation.ts +114 -0
- package/src/server/chart-template.ts +449 -0
- package/src/server/code-graph.ts +370 -0
- package/src/server/context-cards.ts +31 -0
- package/src/server/diagram-presets.ts +71 -0
- package/src/server/ext-app-call-registry.ts +77 -0
- package/src/server/ext-app-tool-result.ts +4 -0
- package/src/server/file-watcher.ts +121 -0
- package/src/server/index.ts +647 -0
- package/src/server/mcp-app-candidate.ts +174 -0
- package/src/server/mcp-app-host.ts +814 -0
- package/src/server/mcp-app-runtime.ts +459 -0
- package/src/server/mutation-history.ts +350 -0
- package/src/server/placement.ts +125 -0
- package/src/server/server.ts +3846 -0
- package/src/server/spatial-analysis.ts +356 -0
- package/src/server/trace-manager.ts +333 -0
- package/src/server/web-artifacts/scripts/bundle-artifact.sh +167 -0
- package/src/server/web-artifacts/scripts/init-artifact.sh +426 -0
- package/src/server/web-artifacts/scripts/shadcn-components.tar.gz +0 -0
- package/src/server/web-artifacts.ts +442 -0
- package/src/server/webpage-node.ts +328 -0
- package/src/shared/auto-arrange.ts +439 -0
- package/src/shared/ext-app-tool-result.ts +76 -0
- package/src/shared/placement.ts +81 -0
- package/src/shared/semantic-attention.ts +598 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "pmx-canvas",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"name": "investigation-board",
|
|
7
|
+
"prompt": "I'm debugging a memory leak in our Node.js API. The /api/users endpoint is leaking memory on every request. I found a suspicious closure in src/handlers/users.ts that captures the entire request object, and the heap snapshot shows growing EventEmitter listeners. Can you set up an investigation board on the canvas so I can see the full picture?",
|
|
8
|
+
"expected_output": "Creates multiple nodes (bug description, code file, heap findings, hypothesis) connected with edges, arranged in a tree layout. Uses appropriate node types (markdown for findings, file for source, status for investigation progress).",
|
|
9
|
+
"assertions": [
|
|
10
|
+
{
|
|
11
|
+
"name": "creates-multiple-nodes",
|
|
12
|
+
"description": "Creates at least 3 nodes representing different aspects of the investigation",
|
|
13
|
+
"type": "output_check"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"name": "uses-edges",
|
|
17
|
+
"description": "Connects nodes with labeled edges showing relationships between evidence",
|
|
18
|
+
"type": "output_check"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "uses-tree-or-arrange",
|
|
22
|
+
"description": "Arranges the nodes using tree layout or explicit positioning for readability",
|
|
23
|
+
"type": "output_check"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "uses-appropriate-types",
|
|
27
|
+
"description": "Uses file nodes for source code and markdown/status for findings rather than all markdown",
|
|
28
|
+
"type": "output_check"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": 2,
|
|
34
|
+
"name": "architecture-diagram",
|
|
35
|
+
"prompt": "We're building a microservices backend with these services: API Gateway (Express, port 3000), Auth Service (JWT + OAuth2, port 3001), User Service (CRUD, port 3002), PostgreSQL (port 5432), and Redis (caching, port 6379). The API Gateway routes to Auth and User services, both Auth and User read/write to PostgreSQL, and User Service uses Redis for caching. Can you visualize this architecture on the canvas?",
|
|
36
|
+
"expected_output": "Creates nodes for each service with relevant details, connects them with flow/depends-on edges with descriptive labels, groups related services, and arranges in a readable layout.",
|
|
37
|
+
"assertions": [
|
|
38
|
+
{
|
|
39
|
+
"name": "all-services-present",
|
|
40
|
+
"description": "Creates nodes for all 5 services/datastores mentioned",
|
|
41
|
+
"type": "output_check"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"name": "correct-connections",
|
|
45
|
+
"description": "Creates edges matching the described relationships (Gateway->Auth, Gateway->User, Auth->PG, User->PG, User->Redis)",
|
|
46
|
+
"type": "output_check"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "edge-labels",
|
|
50
|
+
"description": "Uses descriptive edge labels (not bare unlabeled edges)",
|
|
51
|
+
"type": "output_check"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"name": "layout-applied",
|
|
55
|
+
"description": "Applies auto-arrange or uses explicit positioning for readable layout",
|
|
56
|
+
"type": "output_check"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": 3,
|
|
62
|
+
"name": "task-plan-tracking",
|
|
63
|
+
"prompt": "I need to implement a new payment feature. Here's the plan: 1) Define payment schema (done), 2) Build Stripe integration (in progress), 3) Create payment API routes (blocked by #2), 4) Add webhook handlers (blocked by #3), 5) Write integration tests (blocked by #4), 6) Update API docs (can start anytime). Show this on the canvas as a task board with dependencies.",
|
|
64
|
+
"expected_output": "Creates status nodes for each task with appropriate colors (green=done, yellow=in-progress, red=blocked, blue=ready), connects with depends-on edges, and arranges to show dependency flow.",
|
|
65
|
+
"assertions": [
|
|
66
|
+
{
|
|
67
|
+
"name": "six-task-nodes",
|
|
68
|
+
"description": "Creates exactly 6 task nodes, one for each task",
|
|
69
|
+
"type": "output_check"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"name": "semantic-colors",
|
|
73
|
+
"description": "Uses green for done, yellow for in-progress, red for blocked tasks",
|
|
74
|
+
"type": "output_check"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"name": "dependency-edges",
|
|
78
|
+
"description": "Creates depends-on edges matching the described blocking relationships",
|
|
79
|
+
"type": "output_check"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"name": "status-node-type",
|
|
83
|
+
"description": "Uses status node type (not markdown) for task items",
|
|
84
|
+
"type": "output_check"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"id": 4,
|
|
90
|
+
"name": "read-pinned-context",
|
|
91
|
+
"prompt": "I've pinned some nodes on the canvas that I want you to look at. Can you read what I've pinned and summarize what you think I'm focusing on?",
|
|
92
|
+
"expected_output": "Reads canvas://pinned-context resource, summarizes the pinned nodes' content, identifies spatial neighborhoods, and explains what the human appears to be focusing on based on the pinned context and nearby nodes.",
|
|
93
|
+
"assertions": [
|
|
94
|
+
{
|
|
95
|
+
"name": "reads-pinned-context",
|
|
96
|
+
"description": "Reads the canvas://pinned-context MCP resource (not just canvas_get_layout)",
|
|
97
|
+
"type": "output_check"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"name": "summarizes-content",
|
|
101
|
+
"description": "Provides a meaningful summary of what the pinned nodes contain",
|
|
102
|
+
"type": "output_check"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"name": "interprets-intent",
|
|
106
|
+
"description": "Makes an interpretation of what the human is focusing on based on pinned context",
|
|
107
|
+
"type": "output_check"
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": 5,
|
|
113
|
+
"name": "code-exploration-files",
|
|
114
|
+
"prompt": "I'm trying to understand how the authentication flow works in this project. Can you put the relevant auth files on the canvas so I can see how they connect? The main files are src/auth/login.ts, src/auth/middleware.ts, src/auth/jwt.ts, and src/routes/auth.ts.",
|
|
115
|
+
"expected_output": "Creates file nodes for each mentioned file (content auto-loads), relies on code graph to auto-detect import dependencies, groups auth files together, and reads canvas://code-graph for dependency analysis.",
|
|
116
|
+
"assertions": [
|
|
117
|
+
{
|
|
118
|
+
"name": "uses-file-nodes",
|
|
119
|
+
"description": "Creates file type nodes (not markdown with pasted code) for source files",
|
|
120
|
+
"type": "output_check"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "all-files-added",
|
|
124
|
+
"description": "Adds all 4 mentioned files to the canvas",
|
|
125
|
+
"type": "output_check"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"name": "groups-files",
|
|
129
|
+
"description": "Groups the auth files together in a canvas group",
|
|
130
|
+
"type": "output_check"
|
|
131
|
+
}
|
|
132
|
+
]
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"id": 6,
|
|
136
|
+
"name": "status-dashboard-updates",
|
|
137
|
+
"prompt": "I'm running a deployment pipeline. Create a dashboard on the canvas showing: Build (passing), Unit Tests (running), Integration Tests (queued), Deploy to Staging (queued). Then update it - unit tests just passed and integration tests are now running.",
|
|
138
|
+
"expected_output": "Creates status nodes with semantic colors, arranges as grid dashboard, then updates nodes in place using canvas_update_node (not delete+recreate) to reflect new state.",
|
|
139
|
+
"assertions": [
|
|
140
|
+
{
|
|
141
|
+
"name": "initial-dashboard",
|
|
142
|
+
"description": "Creates 4 status nodes with appropriate initial colors",
|
|
143
|
+
"type": "output_check"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"name": "updates-in-place",
|
|
147
|
+
"description": "Uses canvas_update_node to change status (not remove+add)",
|
|
148
|
+
"type": "output_check"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"name": "grid-layout",
|
|
152
|
+
"description": "Arranges nodes in grid layout for dashboard view",
|
|
153
|
+
"type": "output_check"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "color-transitions",
|
|
157
|
+
"description": "Updates colors to reflect new state (unit tests -> green, integration -> yellow)",
|
|
158
|
+
"type": "output_check"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"id": 7,
|
|
164
|
+
"name": "snapshot-before-changes",
|
|
165
|
+
"prompt": "I want to reorganize the canvas to explore a different approach, but I don't want to lose what's there now. Can you save the current state, clear it, and set up a fresh workspace for the new approach? If it doesn't work out I want to go back.",
|
|
166
|
+
"expected_output": "Takes a named snapshot of current state, then clears the canvas. Mentions that canvas_restore can bring back the old state. Does NOT just clear without snapshotting.",
|
|
167
|
+
"assertions": [
|
|
168
|
+
{
|
|
169
|
+
"name": "takes-snapshot",
|
|
170
|
+
"description": "Saves a snapshot with canvas_snapshot before clearing",
|
|
171
|
+
"type": "output_check"
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
"name": "clears-after-snapshot",
|
|
175
|
+
"description": "Clears the canvas after (not before) saving the snapshot",
|
|
176
|
+
"type": "output_check"
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"name": "mentions-restore",
|
|
180
|
+
"description": "Tells the user how to restore (canvas_restore) if they want to go back",
|
|
181
|
+
"type": "output_check"
|
|
182
|
+
}
|
|
183
|
+
]
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pmx-canvas-testing
|
|
3
|
+
description: >
|
|
4
|
+
Repo-standard test and verification workflow for PMX Canvas. Use when you change code, add
|
|
5
|
+
tests, debug regressions, prepare handoff, or need to decide which local verification commands
|
|
6
|
+
to run. This skill defines the default test ladder, when to run Bun tests vs. browser tests,
|
|
7
|
+
how to handle pre-existing failures, and what evidence to report back.
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# PMX Canvas Testing
|
|
11
|
+
|
|
12
|
+
Use this skill whenever you touch code in this repo and need a consistent verification path.
|
|
13
|
+
|
|
14
|
+
## When To Use
|
|
15
|
+
|
|
16
|
+
- Any code change that should be validated before handoff
|
|
17
|
+
- Adding or updating tests
|
|
18
|
+
- Debugging a regression or flaky behavior
|
|
19
|
+
- Updating CI or coverage commands
|
|
20
|
+
- Deciding the minimum acceptable verification for a task
|
|
21
|
+
|
|
22
|
+
## Default Verification Ladder
|
|
23
|
+
|
|
24
|
+
Pick the narrowest command that proves the change, then escalate if the change crosses layers.
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
bun run test # Fast Bun suite for server/state/API coverage
|
|
28
|
+
bun run test:coverage # Same Bun suite with coverage output
|
|
29
|
+
bun run test:web-canvas # Browser smoke against a real running app
|
|
30
|
+
bun run test:all # Bun suite + browser smoke
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Which Command To Run
|
|
34
|
+
|
|
35
|
+
- Server/state/API-only changes: run `bun run test`
|
|
36
|
+
- Test-only changes: run `bun run test` and `bun run test:coverage` if coverage matters
|
|
37
|
+
- Client/UI/browser interaction changes: run `bun run test:web-canvas`
|
|
38
|
+
- Cross-stack or non-trivial changes: run `bun run test:all`
|
|
39
|
+
- Before changing browser-visible behavior under `src/client/`: rebuild with `bun run build`
|
|
40
|
+
Manual browser validation also requires a fresh client bundle. `bun run test:web-canvas`
|
|
41
|
+
already does this for you.
|
|
42
|
+
|
|
43
|
+
## Current Project Test Surface
|
|
44
|
+
|
|
45
|
+
- Bun tests live under `tests/unit/`
|
|
46
|
+
- Playwright browser smoke lives under `tests/e2e/`
|
|
47
|
+
- CI runs coverage plus the browser smoke flow
|
|
48
|
+
|
|
49
|
+
Prefer extending the existing suites before inventing a one-off script.
|
|
50
|
+
|
|
51
|
+
## Test Authoring Rules
|
|
52
|
+
|
|
53
|
+
- Keep unit tests isolated. Reset singleton server state between tests.
|
|
54
|
+
- Test public behavior first: HTTP endpoints, persisted state, visible UI outcomes
|
|
55
|
+
- Use browser tests for interactions the user actually performs: node creation, pins, snapshots,
|
|
56
|
+
loading the workbench, and other sync-sensitive flows
|
|
57
|
+
- Avoid brittle selectors. Prefer stable text, roles, titles, or deliberate component hooks
|
|
58
|
+
- If a change spans server and client, add at least one server-side assertion and one browser or
|
|
59
|
+
API-level proof
|
|
60
|
+
|
|
61
|
+
## Failure Handling
|
|
62
|
+
|
|
63
|
+
- Never wave away a failure without checking whether your change caused it
|
|
64
|
+
- If the failure is truly pre-existing, say that explicitly and include the failing command
|
|
65
|
+
- If a command cannot run in the environment, say what blocked it
|
|
66
|
+
- If browser tests fail after a client change, confirm the bundle was rebuilt and the server
|
|
67
|
+
started from the updated code
|
|
68
|
+
|
|
69
|
+
## Handoff Standard
|
|
70
|
+
|
|
71
|
+
Before marking work done, report:
|
|
72
|
+
|
|
73
|
+
- Which verification command(s) you ran
|
|
74
|
+
- Whether they passed
|
|
75
|
+
- Any meaningful gaps, skipped checks, or known pre-existing failures
|
|
76
|
+
|
|
77
|
+
For non-trivial changes, the default expectation is `bun run test:all` unless there is a clear
|
|
78
|
+
reason to scope verification more narrowly.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: published-consumer-e2e
|
|
3
|
+
description: Re-run PMX Canvas like an external user by packing the repo, installing the tarball into a clean temp workspace, seeding the SDLC demo, and validating it in a browser. Use when asked to verify the published-package workflow, artifact/json-render coverage, or the full outside-in demo.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Published Consumer E2E
|
|
7
|
+
|
|
8
|
+
Use this skill when the goal is to test PMX Canvas from the outside instead of the repo dev path.
|
|
9
|
+
|
|
10
|
+
## Default Path
|
|
11
|
+
|
|
12
|
+
Run:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
bash skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
That script will:
|
|
19
|
+
|
|
20
|
+
1. pack the current repo as a tarball,
|
|
21
|
+
2. create a clean temp consumer workspace,
|
|
22
|
+
3. install the tarball with Bun,
|
|
23
|
+
4. copy `examples/published-consumer-sdlc/` into that workspace,
|
|
24
|
+
5. start the seeded demo through the package's public SDK,
|
|
25
|
+
6. run a headed `playwright-cli` browser pass that snapshots the live workbench and asserts the article, artifact, json-render, graph, trace, and context surfaces are present.
|
|
26
|
+
|
|
27
|
+
## Flags
|
|
28
|
+
|
|
29
|
+
- `--port=4600` to change the server port
|
|
30
|
+
- `--skip-playwright` to stop after pack/install + HTTP smoke
|
|
31
|
+
- `--headless` if a visible browser is impossible
|
|
32
|
+
- `--keep-running` to leave the temp consumer server alive after the script exits
|
|
33
|
+
- `--workdir=/tmp/custom-dir` to reuse a known temp location
|
|
34
|
+
|
|
35
|
+
## Notes
|
|
36
|
+
|
|
37
|
+
- Install the browser tool once with `bun add -g @playwright/cli@latest`.
|
|
38
|
+
- Default to headed browser validation so the human can watch the run.
|
|
39
|
+
- Prefer the script over manually rebuilding the temp consumer.
|
|
40
|
+
- If you change the example assets or this browser test, rerun the full script instead of repo-only tests.
|
|
41
|
+
- The script assembles the tarball manually instead of relying on `npm pack` or `bun pm pack`, because pack/build commands can hang in this workspace.
|
|
42
|
+
- The skill uses `playwright-cli` instead of the repo-local `playwright test` path because the local Playwright CLI is currently incompatible with the Bun/Node mix in this environment.
|
|
43
|
+
- On failure, inspect the temp workspace log path printed by the script before changing code.
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
5
|
+
SKILL_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
|
6
|
+
REPO_ROOT="$(cd "${SKILL_DIR}/../.." && pwd)"
|
|
7
|
+
|
|
8
|
+
BUN_BIN="${BUN_BIN:-$HOME/.bun/bin/bun}"
|
|
9
|
+
PORT="4513"
|
|
10
|
+
WORKDIR=""
|
|
11
|
+
KEEP_RUNNING=0
|
|
12
|
+
SKIP_PLAYWRIGHT=0
|
|
13
|
+
HEADED=1
|
|
14
|
+
|
|
15
|
+
for arg in "$@"; do
|
|
16
|
+
case "$arg" in
|
|
17
|
+
--port=*)
|
|
18
|
+
PORT="${arg#*=}"
|
|
19
|
+
;;
|
|
20
|
+
--workdir=*)
|
|
21
|
+
WORKDIR="${arg#*=}"
|
|
22
|
+
;;
|
|
23
|
+
--keep-running)
|
|
24
|
+
KEEP_RUNNING=1
|
|
25
|
+
;;
|
|
26
|
+
--skip-playwright)
|
|
27
|
+
SKIP_PLAYWRIGHT=1
|
|
28
|
+
;;
|
|
29
|
+
--headless)
|
|
30
|
+
HEADED=0
|
|
31
|
+
;;
|
|
32
|
+
--headed)
|
|
33
|
+
HEADED=1
|
|
34
|
+
;;
|
|
35
|
+
*)
|
|
36
|
+
echo "Unknown argument: $arg" >&2
|
|
37
|
+
exit 1
|
|
38
|
+
;;
|
|
39
|
+
esac
|
|
40
|
+
done
|
|
41
|
+
|
|
42
|
+
if [[ ! -x "${BUN_BIN}" ]]; then
|
|
43
|
+
echo "Bun binary not found at ${BUN_BIN}. Set BUN_BIN or install Bun." >&2
|
|
44
|
+
exit 1
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
export PATH="/opt/homebrew/bin:/usr/local/bin:$(dirname "${BUN_BIN}"):${PATH}"
|
|
48
|
+
|
|
49
|
+
if [[ -z "${WORKDIR}" ]]; then
|
|
50
|
+
WORKDIR="$(mktemp -d "${TMPDIR:-/tmp}/pmx-canvas-published-consumer.XXXXXX")"
|
|
51
|
+
else
|
|
52
|
+
mkdir -p "${WORKDIR}"
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
PACK_DIR="${WORKDIR}/pack"
|
|
56
|
+
PACKAGE_STAGING="${WORKDIR}/package"
|
|
57
|
+
CONSUMER_DIR="${WORKDIR}/consumer"
|
|
58
|
+
LOG_FILE="${WORKDIR}/server.log"
|
|
59
|
+
rm -rf "${PACK_DIR}" "${PACKAGE_STAGING}"
|
|
60
|
+
mkdir -p "${PACK_DIR}" "${PACKAGE_STAGING}/package" "${CONSUMER_DIR}/demo"
|
|
61
|
+
|
|
62
|
+
cleanup() {
|
|
63
|
+
if [[ -n "${SERVER_PID:-}" ]] && kill -0 "${SERVER_PID}" 2>/dev/null; then
|
|
64
|
+
kill "${SERVER_PID}" 2>/dev/null || true
|
|
65
|
+
wait "${SERVER_PID}" 2>/dev/null || true
|
|
66
|
+
fi
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
trap cleanup EXIT
|
|
70
|
+
|
|
71
|
+
echo "[published-consumer] assembling install tarball from ${REPO_ROOT}"
|
|
72
|
+
cp "${REPO_ROOT}/package.json" "${PACKAGE_STAGING}/package/package.json"
|
|
73
|
+
cp "${REPO_ROOT}/Readme.md" "${PACKAGE_STAGING}/package/Readme.md"
|
|
74
|
+
if [[ -f "${REPO_ROOT}/LICENSE" ]]; then
|
|
75
|
+
cp "${REPO_ROOT}/LICENSE" "${PACKAGE_STAGING}/package/LICENSE"
|
|
76
|
+
fi
|
|
77
|
+
cp -R "${REPO_ROOT}/src" "${PACKAGE_STAGING}/package/src"
|
|
78
|
+
mkdir -p "${PACKAGE_STAGING}/package/dist/canvas" "${PACKAGE_STAGING}/package/dist/json-render"
|
|
79
|
+
cp "${REPO_ROOT}/dist/canvas/index.js" "${PACKAGE_STAGING}/package/dist/canvas/index.js"
|
|
80
|
+
cp "${REPO_ROOT}/dist/canvas/global.css" "${PACKAGE_STAGING}/package/dist/canvas/global.css"
|
|
81
|
+
cp "${REPO_ROOT}/dist/json-render/index.js" "${PACKAGE_STAGING}/package/dist/json-render/index.js"
|
|
82
|
+
cp "${REPO_ROOT}/dist/json-render/index.css" "${PACKAGE_STAGING}/package/dist/json-render/index.css"
|
|
83
|
+
TARBALL="pmx-canvas-published-consumer.tgz"
|
|
84
|
+
tar -czf "${PACK_DIR}/${TARBALL}" -C "${PACKAGE_STAGING}" package
|
|
85
|
+
|
|
86
|
+
echo "[published-consumer] staging temp consumer at ${CONSUMER_DIR}"
|
|
87
|
+
rm -rf "${CONSUMER_DIR}"
|
|
88
|
+
mkdir -p "${CONSUMER_DIR}/demo"
|
|
89
|
+
cp -R "${REPO_ROOT}/examples/published-consumer-sdlc/." "${CONSUMER_DIR}/demo/"
|
|
90
|
+
cat > "${CONSUMER_DIR}/package.json" <<'JSON'
|
|
91
|
+
{
|
|
92
|
+
"name": "pmx-canvas-published-consumer",
|
|
93
|
+
"private": true,
|
|
94
|
+
"type": "module"
|
|
95
|
+
}
|
|
96
|
+
JSON
|
|
97
|
+
|
|
98
|
+
(cd "${CONSUMER_DIR}" && "${BUN_BIN}" add "${PACK_DIR}/${TARBALL}")
|
|
99
|
+
|
|
100
|
+
echo "[published-consumer] starting seeded demo on port ${PORT}"
|
|
101
|
+
SERVER_PID="$(
|
|
102
|
+
python3 - "${CONSUMER_DIR}" "${BUN_BIN}" "${PORT}" "${LOG_FILE}" <<'PY'
|
|
103
|
+
import subprocess
|
|
104
|
+
import sys
|
|
105
|
+
|
|
106
|
+
consumer_dir, bun_bin, port, log_file = sys.argv[1:5]
|
|
107
|
+
|
|
108
|
+
with open(log_file, "ab", buffering=0) as log:
|
|
109
|
+
proc = subprocess.Popen(
|
|
110
|
+
[bun_bin, "run", "demo/seed-demo.ts", f"--port={port}", "--hold"],
|
|
111
|
+
cwd=consumer_dir,
|
|
112
|
+
stdin=subprocess.DEVNULL,
|
|
113
|
+
stdout=log,
|
|
114
|
+
stderr=subprocess.STDOUT,
|
|
115
|
+
start_new_session=True,
|
|
116
|
+
)
|
|
117
|
+
print(proc.pid)
|
|
118
|
+
PY
|
|
119
|
+
)"
|
|
120
|
+
|
|
121
|
+
READY=0
|
|
122
|
+
for _ in $(seq 1 90); do
|
|
123
|
+
if curl -fsS "http://127.0.0.1:${PORT}/api/canvas/state" >/dev/null 2>&1; then
|
|
124
|
+
READY=1
|
|
125
|
+
break
|
|
126
|
+
fi
|
|
127
|
+
sleep 1
|
|
128
|
+
done
|
|
129
|
+
|
|
130
|
+
if [[ "${READY}" -ne 1 ]]; then
|
|
131
|
+
echo "[published-consumer] server did not become ready. Log follows:" >&2
|
|
132
|
+
cat "${LOG_FILE}" >&2 || true
|
|
133
|
+
exit 1
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
SEEDED=0
|
|
137
|
+
NODE_COUNT="0"
|
|
138
|
+
for _ in $(seq 1 120); do
|
|
139
|
+
if ! kill -0 "${SERVER_PID}" 2>/dev/null; then
|
|
140
|
+
echo "[published-consumer] seeded demo process exited early. Log follows:" >&2
|
|
141
|
+
cat "${LOG_FILE}" >&2 || true
|
|
142
|
+
exit 1
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
NODE_COUNT="$(
|
|
146
|
+
curl -fsS "http://127.0.0.1:${PORT}/api/canvas/state" \
|
|
147
|
+
| "${BUN_BIN}" -e 'let raw="";for await (const chunk of Bun.stdin.stream()){raw+=chunk instanceof Uint8Array ? Buffer.from(chunk).toString() : String(chunk);} const state=JSON.parse(raw); console.log(state.nodes.length);'
|
|
148
|
+
)"
|
|
149
|
+
|
|
150
|
+
if [[ "${NODE_COUNT}" -ge 18 ]]; then
|
|
151
|
+
SEEDED=1
|
|
152
|
+
break
|
|
153
|
+
fi
|
|
154
|
+
|
|
155
|
+
sleep 1
|
|
156
|
+
done
|
|
157
|
+
|
|
158
|
+
if [[ "${SEEDED}" -ne 1 ]]; then
|
|
159
|
+
echo "[published-consumer] demo did not finish seeding. Last node count: ${NODE_COUNT}" >&2
|
|
160
|
+
cat "${LOG_FILE}" >&2 || true
|
|
161
|
+
exit 1
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
echo "[published-consumer] workspace ready"
|
|
165
|
+
echo " url: http://127.0.0.1:${PORT}/workbench"
|
|
166
|
+
echo " node-count: ${NODE_COUNT}"
|
|
167
|
+
echo " temp-workdir: ${WORKDIR}"
|
|
168
|
+
echo " server-log: ${LOG_FILE}"
|
|
169
|
+
|
|
170
|
+
if [[ "${SKIP_PLAYWRIGHT}" -ne 1 ]]; then
|
|
171
|
+
echo "[published-consumer] running browser validation"
|
|
172
|
+
if ! command -v playwright-cli >/dev/null 2>&1; then
|
|
173
|
+
echo "[published-consumer] playwright-cli is required for browser validation." >&2
|
|
174
|
+
echo "Install it with: bun add -g @playwright/cli@latest" >&2
|
|
175
|
+
exit 1
|
|
176
|
+
fi
|
|
177
|
+
|
|
178
|
+
PLAYWRIGHT_SESSION="pc${PORT}"
|
|
179
|
+
PLAYWRIGHT_OPEN_CMD=(playwright-cli "-s=${PLAYWRIGHT_SESSION}" open "http://127.0.0.1:${PORT}/workbench" --browser chrome)
|
|
180
|
+
if [[ "${HEADED}" -eq 1 ]]; then
|
|
181
|
+
PLAYWRIGHT_OPEN_CMD+=(--headed)
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
(
|
|
185
|
+
cd "${REPO_ROOT}"
|
|
186
|
+
rm -f .playwright-cli/page-*.yml .playwright-cli/page-*.png .playwright-cli/console-*.log 2>/dev/null || true
|
|
187
|
+
"${PLAYWRIGHT_OPEN_CMD[@]}"
|
|
188
|
+
sleep 3
|
|
189
|
+
playwright-cli "-s=${PLAYWRIGHT_SESSION}" snapshot >/dev/null
|
|
190
|
+
|
|
191
|
+
SNAPSHOT_FILE="$(ls -t .playwright-cli/page-*.yml | head -n 1)"
|
|
192
|
+
if [[ -z "${SNAPSHOT_FILE}" ]]; then
|
|
193
|
+
echo "[published-consumer] playwright-cli did not produce a snapshot." >&2
|
|
194
|
+
exit 1
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
for expected in \
|
|
198
|
+
"Synthetic SDLC Report" \
|
|
199
|
+
"Pipeline Atlas" \
|
|
200
|
+
"SDLC Control Room Artifact" \
|
|
201
|
+
"Control Tower Widgets" \
|
|
202
|
+
"Release Gate Intake" \
|
|
203
|
+
"Service Readiness Matrix" \
|
|
204
|
+
"Lead Time Trend" \
|
|
205
|
+
"Defects by Stage" \
|
|
206
|
+
"Operational Load" \
|
|
207
|
+
"Context (3)" \
|
|
208
|
+
"npm pack" \
|
|
209
|
+
"canvas.buildWebArtifact" \
|
|
210
|
+
"playwright"
|
|
211
|
+
do
|
|
212
|
+
if ! rg -Fq "${expected}" "${SNAPSHOT_FILE}"; then
|
|
213
|
+
echo "[published-consumer] expected browser snapshot to include: ${expected}" >&2
|
|
214
|
+
echo "Snapshot: ${SNAPSHOT_FILE}" >&2
|
|
215
|
+
exit 1
|
|
216
|
+
fi
|
|
217
|
+
done
|
|
218
|
+
|
|
219
|
+
playwright-cli "-s=${PLAYWRIGHT_SESSION}" screenshot >/dev/null
|
|
220
|
+
SCREENSHOT_FILE="$(ls -t .playwright-cli/page-*.png | head -n 1)"
|
|
221
|
+
echo "[published-consumer] browser snapshot: ${SNAPSHOT_FILE}"
|
|
222
|
+
echo "[published-consumer] browser screenshot: ${SCREENSHOT_FILE}"
|
|
223
|
+
|
|
224
|
+
if [[ "${KEEP_RUNNING}" -ne 1 ]]; then
|
|
225
|
+
playwright-cli "-s=${PLAYWRIGHT_SESSION}" close >/dev/null || true
|
|
226
|
+
fi
|
|
227
|
+
)
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
if [[ "${KEEP_RUNNING}" -eq 1 ]]; then
|
|
231
|
+
trap - EXIT
|
|
232
|
+
echo "[published-consumer] leaving server running"
|
|
233
|
+
echo " PMX_CANVAS_URL=http://127.0.0.1:${PORT}"
|
|
234
|
+
echo " PMX_CONSUMER_DIR=${CONSUMER_DIR}"
|
|
235
|
+
echo " PMX_SERVER_PID=${SERVER_PID}"
|
|
236
|
+
exit 0
|
|
237
|
+
fi
|
|
238
|
+
|
|
239
|
+
cleanup
|
|
240
|
+
trap - EXIT
|
|
241
|
+
echo "[published-consumer] completed"
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: web-artifacts-builder
|
|
3
|
+
description: Suite of tools for creating elaborate, multi-component single-file HTML web artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.
|
|
4
|
+
license: Complete terms in LICENSE.txt
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Web Artifacts Builder
|
|
8
|
+
|
|
9
|
+
To build powerful single-file frontend web artifacts, follow these steps:
|
|
10
|
+
1. Initialize the frontend repo using `scripts/init-artifact.sh`
|
|
11
|
+
2. Develop your artifact by editing the generated code
|
|
12
|
+
3. Bundle all code into a single HTML file using `scripts/bundle-artifact.sh`
|
|
13
|
+
4. Display artifact to user
|
|
14
|
+
5. (Optional) Test the artifact
|
|
15
|
+
|
|
16
|
+
**Stack**: React 18 + TypeScript + Vite + Parcel (bundling) + Tailwind CSS + shadcn/ui
|
|
17
|
+
|
|
18
|
+
## Design & Style Guidelines
|
|
19
|
+
|
|
20
|
+
VERY IMPORTANT: To avoid what is often referred to as "AI slop", avoid using excessive centered layouts, purple gradients, uniform rounded corners, and Inter font.
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
In `pmx-canvas`, prefer the `canvas_build_web_artifact` MCP tool when available. It uses the same
|
|
25
|
+
bundled runtime scripts, writes reusable source under `.pmx-canvas/artifacts/.web-artifacts/`,
|
|
26
|
+
emits a bundled HTML file under `.pmx-canvas/artifacts/`, and can open the result directly on the
|
|
27
|
+
canvas as an embedded node.
|
|
28
|
+
For browser verification after the build, pair this skill with the local `playwright-cli` skill.
|
|
29
|
+
|
|
30
|
+
### Step 1: Initialize Project
|
|
31
|
+
|
|
32
|
+
Run the initialization script to create a new React project:
|
|
33
|
+
```bash
|
|
34
|
+
bash scripts/init-artifact.sh <project-name>
|
|
35
|
+
cd <project-name>
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
This creates a fully configured project with:
|
|
39
|
+
- ✅ React + TypeScript (via Vite)
|
|
40
|
+
- ✅ Tailwind CSS 3.4.1 with shadcn/ui theming system
|
|
41
|
+
- ✅ Path aliases (`@/`) configured
|
|
42
|
+
- ✅ 40+ shadcn/ui components pre-installed
|
|
43
|
+
- ✅ All Radix UI dependencies included
|
|
44
|
+
- ✅ Parcel configured for bundling (via .parcelrc)
|
|
45
|
+
- ✅ Node 18+ compatibility (auto-detects and pins Vite version)
|
|
46
|
+
|
|
47
|
+
### Step 2: Develop Your Artifact
|
|
48
|
+
|
|
49
|
+
To build the artifact, edit the generated files. See **Common Development Tasks** below for guidance.
|
|
50
|
+
|
|
51
|
+
### Step 3: Bundle to Single HTML File
|
|
52
|
+
|
|
53
|
+
To bundle the React app into a single HTML artifact:
|
|
54
|
+
```bash
|
|
55
|
+
bash scripts/bundle-artifact.sh
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
This creates `bundle.html` - a self-contained artifact with all JavaScript, CSS, and dependencies inlined. This file can be opened directly in a browser or shared in artifact-capable clients.
|
|
59
|
+
|
|
60
|
+
**Requirements**: Your project must have an `index.html` in the root directory.
|
|
61
|
+
|
|
62
|
+
**What the script does**:
|
|
63
|
+
- Reuses existing bundling dependencies when present; otherwise installs them once
|
|
64
|
+
- Creates `.parcelrc` config with path alias support
|
|
65
|
+
- Builds with Parcel (no source maps) using a quieter log profile
|
|
66
|
+
- Inlines all assets into single HTML using html-inline
|
|
67
|
+
|
|
68
|
+
### Step 4: Share Artifact with User
|
|
69
|
+
|
|
70
|
+
Finally, share the bundled HTML file with the user or open it in the browser so they can view it.
|
|
71
|
+
|
|
72
|
+
### Step 5: Testing/Visualizing the Artifact (Optional)
|
|
73
|
+
|
|
74
|
+
Note: This is a completely optional step. Only perform if necessary or requested.
|
|
75
|
+
|
|
76
|
+
To test/visualize the artifact, use available tools (including other Skills or built-in tools like Playwright or Puppeteer). In general, avoid testing the artifact upfront as it adds latency between the request and when the finished artifact can be seen. Test later, after presenting the artifact, if requested or if issues arise.
|
|
77
|
+
|
|
78
|
+
## Reference
|
|
79
|
+
|
|
80
|
+
- **shadcn/ui components**: https://ui.shadcn.com/docs/components
|