pmx-canvas 0.1.19 → 0.1.21
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 +159 -0
- package/Readme.md +19 -6
- package/dist/canvas/global.css +123 -2
- package/dist/canvas/index.js +103 -68
- package/dist/json-render/index.js +109 -109
- package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
- package/dist/types/client/icons.d.ts +2 -0
- package/dist/types/client/nodes/HtmlNode.d.ts +12 -1
- package/dist/types/client/state/canvas-store.d.ts +2 -0
- package/dist/types/client/types.d.ts +3 -2
- package/dist/types/json-render/charts/components.d.ts +5 -1
- package/dist/types/json-render/renderer/index.d.ts +1 -0
- package/dist/types/json-render/server.d.ts +1 -0
- package/dist/types/mcp/canvas-access.d.ts +3 -0
- package/dist/types/server/canvas-operations.d.ts +4 -0
- package/dist/types/server/canvas-schema.d.ts +19 -3
- package/dist/types/server/canvas-serialization.d.ts +1 -0
- package/dist/types/server/canvas-state.d.ts +6 -2
- package/dist/types/server/html-node-summary.d.ts +2 -0
- package/dist/types/server/html-primitives.d.ts +42 -0
- package/dist/types/server/index.d.ts +26 -0
- package/docs/cli.md +4 -1
- package/docs/http-api.md +11 -1
- package/docs/mcp.md +10 -4
- package/docs/node-types.md +54 -4
- package/docs/screenshot.png +0 -0
- package/docs/sdk.md +12 -0
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +17 -3
- package/skills/pmx-canvas/references/html-primitives.md +132 -0
- package/src/cli/agent.ts +159 -5
- package/src/cli/index.ts +1 -1
- package/src/client/App.tsx +21 -2
- package/src/client/canvas/AnnotationLayer.tsx +33 -12
- package/src/client/canvas/CanvasViewport.tsx +88 -7
- package/src/client/canvas/CommandPalette.tsx +2 -2
- package/src/client/canvas/ContextMenu.tsx +2 -2
- package/src/client/canvas/ExpandedNodeOverlay.tsx +112 -3
- package/src/client/canvas/auto-fit.ts +5 -1
- package/src/client/icons.tsx +13 -0
- package/src/client/nodes/HtmlNode.tsx +125 -13
- package/src/client/nodes/McpAppNode.tsx +12 -4
- package/src/client/state/canvas-store.ts +15 -5
- package/src/client/state/sse-bridge.ts +5 -4
- package/src/client/theme/global.css +123 -2
- package/src/client/types.ts +2 -1
- package/src/json-render/charts/components.tsx +41 -7
- package/src/json-render/charts/extra-components.tsx +13 -12
- package/src/json-render/renderer/index.tsx +1 -0
- package/src/json-render/server.ts +3 -1
- package/src/mcp/canvas-access.ts +54 -1
- package/src/mcp/server.ts +98 -28
- package/src/server/agent-context.ts +39 -0
- package/src/server/canvas-operations.ts +99 -38
- package/src/server/canvas-provenance.ts +8 -6
- package/src/server/canvas-schema.ts +94 -3
- package/src/server/canvas-serialization.ts +16 -4
- package/src/server/canvas-state.ts +9 -4
- package/src/server/demo-state.json +1143 -0
- package/src/server/demo.ts +25 -777
- package/src/server/html-node-summary.ts +141 -0
- package/src/server/html-primitives.ts +1300 -0
- package/src/server/index.ts +63 -3
- package/src/server/server.ts +154 -17
- package/src/server/spatial-analysis.ts +5 -3
|
@@ -27,6 +27,7 @@ export interface CanvasAnnotationSummary {
|
|
|
27
27
|
color: string;
|
|
28
28
|
width: number;
|
|
29
29
|
pointCount: number;
|
|
30
|
+
text: string | null;
|
|
30
31
|
label: string | null;
|
|
31
32
|
createdAt: string;
|
|
32
33
|
}
|
|
@@ -75,6 +76,15 @@ export function getCanvasNodeTitle(node: CanvasNodeState): string | null {
|
|
|
75
76
|
}
|
|
76
77
|
|
|
77
78
|
export function getCanvasNodeContent(node: CanvasNodeState): string | null {
|
|
79
|
+
if (node.type === 'html') {
|
|
80
|
+
const primitive = typeof node.data.htmlPrimitive === 'string' ? node.data.htmlPrimitive : null;
|
|
81
|
+
const description = pickString(node.data.description);
|
|
82
|
+
return pickString(node.data.agentSummary)
|
|
83
|
+
?? pickString(node.data.contentSummary)
|
|
84
|
+
?? (primitive
|
|
85
|
+
? (description ? `${primitive}: ${description}` : primitive)
|
|
86
|
+
: null);
|
|
87
|
+
}
|
|
78
88
|
return pickString(node.data.content)
|
|
79
89
|
?? pickString(node.data.fileContent)
|
|
80
90
|
?? pickString(node.data.text)
|
|
@@ -86,12 +96,13 @@ export function getCanvasNodeContent(node: CanvasNodeState): string | null {
|
|
|
86
96
|
|
|
87
97
|
export function serializeCanvasNode(node: CanvasNodeState): SerializedCanvasNode {
|
|
88
98
|
const data = normalizeCanvasNodeData(node.type, node.data);
|
|
99
|
+
const normalizedNode = { ...node, data };
|
|
89
100
|
return {
|
|
90
101
|
...node,
|
|
91
102
|
data,
|
|
92
103
|
kind: getCanvasNodeKind(node, data),
|
|
93
|
-
title: getCanvasNodeTitle(
|
|
94
|
-
content: getCanvasNodeContent(
|
|
104
|
+
title: getCanvasNodeTitle(normalizedNode),
|
|
105
|
+
content: getCanvasNodeContent(normalizedNode),
|
|
95
106
|
path: pickString(data.path),
|
|
96
107
|
url: pickString(data.url),
|
|
97
108
|
provenance: pickProvenance(data.provenance),
|
|
@@ -180,7 +191,8 @@ export function summarizeCanvasAnnotation(annotation: CanvasAnnotation): CanvasA
|
|
|
180
191
|
color: annotation.color,
|
|
181
192
|
width: annotation.width,
|
|
182
193
|
pointCount: annotation.points.length,
|
|
183
|
-
|
|
194
|
+
text: annotation.text ?? null,
|
|
195
|
+
label: annotation.label ?? annotation.text ?? null,
|
|
184
196
|
createdAt: annotation.createdAt,
|
|
185
197
|
};
|
|
186
198
|
}
|
|
@@ -208,7 +220,7 @@ export function summarizeCanvasAnnotationForContext(
|
|
|
208
220
|
const targetNodeTitles = targetNodes.map((node) => getCanvasNodeTitle(node) ?? node.id);
|
|
209
221
|
return {
|
|
210
222
|
id: annotation.id,
|
|
211
|
-
label: annotation.label ?? null,
|
|
223
|
+
label: annotation.label ?? annotation.text ?? null,
|
|
212
224
|
bounds: annotation.bounds,
|
|
213
225
|
targetNodeIds: targetNodes.map((node) => node.id),
|
|
214
226
|
targetNodeTitles,
|
|
@@ -162,11 +162,12 @@ export interface CanvasAnnotationPoint {
|
|
|
162
162
|
|
|
163
163
|
export interface CanvasAnnotation {
|
|
164
164
|
id: string;
|
|
165
|
-
type: 'freehand';
|
|
165
|
+
type: 'freehand' | 'text';
|
|
166
166
|
points: CanvasAnnotationPoint[];
|
|
167
167
|
bounds: { x: number; y: number; width: number; height: number };
|
|
168
168
|
color: string;
|
|
169
169
|
width: number;
|
|
170
|
+
text?: string;
|
|
170
171
|
label?: string;
|
|
171
172
|
createdAt: string;
|
|
172
173
|
}
|
|
@@ -201,6 +202,10 @@ interface GroupNodesOptions {
|
|
|
201
202
|
keepGroupFrame?: boolean;
|
|
202
203
|
}
|
|
203
204
|
|
|
205
|
+
interface ApplyUpdatesOptions {
|
|
206
|
+
skipGroupChildTranslation?: boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
204
209
|
function formatBatchUpdateDescription(updates: CanvasNodeUpdate[]): string {
|
|
205
210
|
let moved = 0;
|
|
206
211
|
let resized = 0;
|
|
@@ -1216,7 +1221,7 @@ class CanvasStateManager {
|
|
|
1216
1221
|
};
|
|
1217
1222
|
}
|
|
1218
1223
|
|
|
1219
|
-
applyUpdates(updates: CanvasNodeUpdate[]): { applied: number; skipped: number } {
|
|
1224
|
+
applyUpdates(updates: CanvasNodeUpdate[], options: ApplyUpdatesOptions = {}): { applied: number; skipped: number } {
|
|
1220
1225
|
let applied = 0;
|
|
1221
1226
|
let skipped = 0;
|
|
1222
1227
|
const touchedParentGroups = new Map<string, { compact: boolean }>();
|
|
@@ -1259,7 +1264,7 @@ class CanvasStateManager {
|
|
|
1259
1264
|
}
|
|
1260
1265
|
oldSnapshots.set(update.id, structuredClone(existing));
|
|
1261
1266
|
appliedUpdates.push({ id: update.id, ...structuredClone(nextPatch) });
|
|
1262
|
-
if (existing.type === 'group' && nextPatch.position) {
|
|
1267
|
+
if (existing.type === 'group' && nextPatch.position && options.skipGroupChildTranslation !== true) {
|
|
1263
1268
|
this.translateGroupChildren(
|
|
1264
1269
|
update.id,
|
|
1265
1270
|
nextPatch.position.x - existing.position.x,
|
|
@@ -1297,7 +1302,7 @@ class CanvasStateManager {
|
|
|
1297
1302
|
operationType: 'batch',
|
|
1298
1303
|
description: formatBatchUpdateDescription(appliedUpdates),
|
|
1299
1304
|
forward: this.suppressed(() => {
|
|
1300
|
-
this.applyUpdates(appliedUpdates.map((update) => structuredClone(update)));
|
|
1305
|
+
this.applyUpdates(appliedUpdates.map((update) => structuredClone(update)), options);
|
|
1301
1306
|
}),
|
|
1302
1307
|
inverse: this.suppressed(() => {
|
|
1303
1308
|
for (const snapshot of inverseSnapshots) {
|