pmx-canvas 0.1.18 → 0.1.20
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 +128 -0
- package/Readme.md +19 -6
- package/dist/canvas/global.css +35 -2
- package/dist/canvas/index.js +70 -69
- 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/state/canvas-store.d.ts +2 -0
- package/dist/types/client/types.d.ts +2 -1
- 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 +8 -2
- package/dist/types/server/html-primitives.d.ts +34 -0
- package/dist/types/server/index.d.ts +19 -0
- package/docs/RELEASE.md +153 -0
- package/docs/bun-webview-integration.md +296 -0
- package/docs/cli.md +143 -0
- package/docs/evals/e2e-cli-coverage.md +61 -0
- package/docs/http-api.md +201 -0
- package/docs/mcp.md +137 -0
- package/docs/node-types.md +272 -0
- package/docs/plans/.gitkeep +0 -0
- package/docs/plans/plan-001-semantic-watch-mvp.md +335 -0
- package/docs/plans/plan-002-human-attention-layer-design-spec.md +679 -0
- package/docs/plans/plan-003-human-attention-layer-implementation-plan.md +572 -0
- package/docs/reactive-canvas-proposal.md +578 -0
- package/docs/release-review-0.1.0.md +38 -0
- package/docs/screenshot.png +0 -0
- package/docs/screenshots/demo-workbench-dark.png +0 -0
- package/docs/screenshots/demo-workbench-light.png +0 -0
- package/docs/screenshots/welcome-dark.png +0 -0
- package/docs/screenshots/welcome-light.png +0 -0
- package/docs/sdk.md +103 -0
- package/package.json +2 -1
- package/skills/pmx-canvas/SKILL.md +8 -0
- package/src/cli/agent.ts +167 -5
- package/src/client/App.tsx +20 -1
- package/src/client/canvas/AnnotationLayer.tsx +33 -12
- package/src/client/canvas/CanvasViewport.tsx +88 -7
- package/src/client/canvas/CommandPalette.tsx +1 -1
- package/src/client/canvas/ContextMenu.tsx +2 -2
- package/src/client/canvas/ExpandedNodeOverlay.tsx +7 -1
- package/src/client/icons.tsx +13 -0
- package/src/client/nodes/McpAppNode.tsx +12 -4
- package/src/client/state/canvas-store.ts +15 -5
- package/src/client/state/sse-bridge.ts +4 -3
- package/src/client/theme/global.css +35 -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 +25 -0
- package/src/mcp/server.ts +85 -27
- package/src/server/agent-context.ts +17 -0
- package/src/server/canvas-operations.ts +91 -38
- package/src/server/canvas-schema.ts +83 -3
- package/src/server/canvas-serialization.ts +9 -2
- package/src/server/canvas-state.ts +27 -9
- package/src/server/demo-state.json +1143 -0
- package/src/server/demo.ts +25 -777
- package/src/server/html-primitives.ts +990 -0
- package/src/server/index.ts +43 -2
- package/src/server/server.ts +140 -14
- package/src/server/spatial-analysis.ts +3 -3
|
@@ -32,6 +32,12 @@ function normalizePositiveInteger(value: number | undefined): number | undefined
|
|
|
32
32
|
return Math.floor(value);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function normalizeSnapshotTimestamp(value: string | undefined): string | undefined {
|
|
36
|
+
if (!value) return undefined;
|
|
37
|
+
const parsed = Date.parse(value);
|
|
38
|
+
return Number.isFinite(parsed) ? new Date(parsed).toISOString() : undefined;
|
|
39
|
+
}
|
|
40
|
+
|
|
35
41
|
export const PMX_CANVAS_DIR = '.pmx-canvas';
|
|
36
42
|
const STATE_FILENAME = 'state.json';
|
|
37
43
|
const SNAPSHOTS_SUBDIR = 'snapshots';
|
|
@@ -89,6 +95,8 @@ export interface CanvasSnapshot {
|
|
|
89
95
|
export interface CanvasSnapshotListOptions {
|
|
90
96
|
limit?: number;
|
|
91
97
|
query?: string;
|
|
98
|
+
before?: string;
|
|
99
|
+
after?: string;
|
|
92
100
|
all?: boolean;
|
|
93
101
|
}
|
|
94
102
|
|
|
@@ -154,11 +162,12 @@ export interface CanvasAnnotationPoint {
|
|
|
154
162
|
|
|
155
163
|
export interface CanvasAnnotation {
|
|
156
164
|
id: string;
|
|
157
|
-
type: 'freehand';
|
|
165
|
+
type: 'freehand' | 'text';
|
|
158
166
|
points: CanvasAnnotationPoint[];
|
|
159
167
|
bounds: { x: number; y: number; width: number; height: number };
|
|
160
168
|
color: string;
|
|
161
169
|
width: number;
|
|
170
|
+
text?: string;
|
|
162
171
|
label?: string;
|
|
163
172
|
createdAt: string;
|
|
164
173
|
}
|
|
@@ -193,6 +202,10 @@ interface GroupNodesOptions {
|
|
|
193
202
|
keepGroupFrame?: boolean;
|
|
194
203
|
}
|
|
195
204
|
|
|
205
|
+
interface ApplyUpdatesOptions {
|
|
206
|
+
skipGroupChildTranslation?: boolean;
|
|
207
|
+
}
|
|
208
|
+
|
|
196
209
|
function formatBatchUpdateDescription(updates: CanvasNodeUpdate[]): string {
|
|
197
210
|
let moved = 0;
|
|
198
211
|
let resized = 0;
|
|
@@ -856,11 +869,16 @@ class CanvasStateManager {
|
|
|
856
869
|
}
|
|
857
870
|
}
|
|
858
871
|
const query = options.query?.trim().toLowerCase();
|
|
859
|
-
const
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
)
|
|
863
|
-
|
|
872
|
+
const before = normalizeSnapshotTimestamp(options.before);
|
|
873
|
+
const after = normalizeSnapshotTimestamp(options.after);
|
|
874
|
+
const filtered = snapshots.filter((snapshot) => {
|
|
875
|
+
if (query && !snapshot.id.toLowerCase().includes(query) && !snapshot.name.toLowerCase().includes(query)) {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
if (before && snapshot.createdAt > before) return false;
|
|
879
|
+
if (after && snapshot.createdAt < after) return false;
|
|
880
|
+
return true;
|
|
881
|
+
});
|
|
864
882
|
const sorted = filtered.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
|
865
883
|
const limit = options.all ? undefined : (normalizePositiveInteger(options.limit) ?? 20);
|
|
866
884
|
return limit === undefined ? sorted : sorted.slice(0, limit);
|
|
@@ -1203,7 +1221,7 @@ class CanvasStateManager {
|
|
|
1203
1221
|
};
|
|
1204
1222
|
}
|
|
1205
1223
|
|
|
1206
|
-
applyUpdates(updates: CanvasNodeUpdate[]): { applied: number; skipped: number } {
|
|
1224
|
+
applyUpdates(updates: CanvasNodeUpdate[], options: ApplyUpdatesOptions = {}): { applied: number; skipped: number } {
|
|
1207
1225
|
let applied = 0;
|
|
1208
1226
|
let skipped = 0;
|
|
1209
1227
|
const touchedParentGroups = new Map<string, { compact: boolean }>();
|
|
@@ -1246,7 +1264,7 @@ class CanvasStateManager {
|
|
|
1246
1264
|
}
|
|
1247
1265
|
oldSnapshots.set(update.id, structuredClone(existing));
|
|
1248
1266
|
appliedUpdates.push({ id: update.id, ...structuredClone(nextPatch) });
|
|
1249
|
-
if (existing.type === 'group' && nextPatch.position) {
|
|
1267
|
+
if (existing.type === 'group' && nextPatch.position && options.skipGroupChildTranslation !== true) {
|
|
1250
1268
|
this.translateGroupChildren(
|
|
1251
1269
|
update.id,
|
|
1252
1270
|
nextPatch.position.x - existing.position.x,
|
|
@@ -1284,7 +1302,7 @@ class CanvasStateManager {
|
|
|
1284
1302
|
operationType: 'batch',
|
|
1285
1303
|
description: formatBatchUpdateDescription(appliedUpdates),
|
|
1286
1304
|
forward: this.suppressed(() => {
|
|
1287
|
-
this.applyUpdates(appliedUpdates.map((update) => structuredClone(update)));
|
|
1305
|
+
this.applyUpdates(appliedUpdates.map((update) => structuredClone(update)), options);
|
|
1288
1306
|
}),
|
|
1289
1307
|
inverse: this.suppressed(() => {
|
|
1290
1308
|
for (const snapshot of inverseSnapshots) {
|