@1agh/maude 0.22.2 → 0.24.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/README.md +34 -1
- package/cli/bin/maude.mjs +3 -0
- package/cli/commands/cache.mjs +181 -0
- package/cli/commands/cache.test.mjs +166 -0
- package/cli/commands/design-link.test.mjs +84 -2
- package/cli/commands/design.mjs +95 -4
- package/cli/commands/design.test.mjs +56 -0
- package/cli/commands/help.mjs +34 -0
- package/cli/commands/hub.mjs +255 -30
- package/cli/commands/hub.test.mjs +135 -10
- package/cli/commands/init.mjs +3 -0
- package/cli/commands/preflight.mjs +11 -0
- package/cli/commands/preflight.test.mjs +46 -0
- package/cli/commands/scenario-report.mjs +45 -0
- package/cli/lib/cache.mjs +407 -0
- package/cli/lib/cache.test.mjs +303 -0
- package/cli/lib/design-link.mjs +222 -11
- package/cli/lib/flow-design-integration.test.mjs +165 -0
- package/cli/lib/gitignore-block.mjs +90 -0
- package/cli/lib/gitignore-block.test.mjs +123 -0
- package/cli/lib/hubs-config.mjs +42 -4
- package/cli/lib/plugin-cli-reachability.test.mjs +56 -0
- package/cli/lib/preflight.mjs +41 -10
- package/package.json +8 -8
- package/plugins/design/dev-server/ai-banner.tsx +2 -2
- package/plugins/design/dev-server/annotations-context-toolbar.tsx +349 -112
- package/plugins/design/dev-server/annotations-layer.tsx +906 -137
- package/plugins/design/dev-server/api.ts +109 -4
- package/plugins/design/dev-server/bin/preflight.sh +21 -10
- package/plugins/design/dev-server/bin/prep.sh +211 -0
- package/plugins/design/dev-server/bin/scenario-report.mjs +209 -0
- package/plugins/design/dev-server/bin/screenshot.sh +18 -1
- package/plugins/design/dev-server/bin/smoke.sh +94 -11
- package/plugins/design/dev-server/build.ts +69 -3
- package/plugins/design/dev-server/canvas-comment-mount.tsx +384 -0
- package/plugins/design/dev-server/canvas-cursors.ts +125 -0
- package/plugins/design/dev-server/canvas-icons.tsx +130 -0
- package/plugins/design/dev-server/canvas-lib.tsx +47 -27
- package/plugins/design/dev-server/canvas-meta.schema.json +20 -0
- package/plugins/design/dev-server/canvas-shell.tsx +358 -245
- package/plugins/design/dev-server/client/app.jsx +191 -21
- package/plugins/design/dev-server/client/styles/3-shell.css +10 -0
- package/plugins/design/dev-server/collab/awareness-bridge.ts +77 -0
- package/plugins/design/dev-server/collab/index.ts +87 -9
- package/plugins/design/dev-server/collab/persistence.ts +34 -3
- package/plugins/design/dev-server/collab/registry.ts +131 -2
- package/plugins/design/dev-server/collab/room.ts +21 -8
- package/plugins/design/dev-server/config.schema.json +20 -0
- package/plugins/design/dev-server/context-menu.tsx +167 -23
- package/plugins/design/dev-server/context.ts +31 -0
- package/plugins/design/dev-server/contextual-toolbar.tsx +7 -7
- package/plugins/design/dev-server/dist/client.bundle.js +144 -22
- package/plugins/design/dev-server/dist/comment-mount.js +1868 -0
- package/plugins/design/dev-server/dist/styles.css +16 -0
- package/plugins/design/dev-server/dom-selection.ts +156 -0
- package/plugins/design/dev-server/equal-spacing-handles.tsx +1 -1
- package/plugins/design/dev-server/export-dialog.tsx +19 -17
- package/plugins/design/dev-server/fs-watch.ts +1 -0
- package/plugins/design/dev-server/hmr-broadcast.ts +51 -20
- package/plugins/design/dev-server/http.ts +260 -20
- package/plugins/design/dev-server/input-router.tsx +125 -64
- package/plugins/design/dev-server/participants-chrome.tsx +10 -10
- package/plugins/design/dev-server/server.ts +141 -1
- package/plugins/design/dev-server/sync/agent.ts +418 -0
- package/plugins/design/dev-server/sync/atomic-write.ts +103 -0
- package/plugins/design/dev-server/sync/codec.ts +324 -0
- package/plugins/design/dev-server/sync/connection-state.ts +203 -0
- package/plugins/design/dev-server/sync/echo-guard.ts +108 -0
- package/plugins/design/dev-server/sync/fs-mirror.ts +160 -0
- package/plugins/design/dev-server/sync/hubs-config.ts +87 -0
- package/plugins/design/dev-server/sync/index.ts +918 -0
- package/plugins/design/dev-server/sync/materialize.ts +62 -0
- package/plugins/design/dev-server/sync/migrate-seed.ts +163 -0
- package/plugins/design/dev-server/sync/origins.ts +57 -0
- package/plugins/design/dev-server/sync/projection.ts +368 -0
- package/plugins/design/dev-server/sync/status.ts +115 -0
- package/plugins/design/dev-server/sync/untrusted.ts +153 -0
- package/plugins/design/dev-server/test/_helpers.ts +6 -2
- package/plugins/design/dev-server/test/annotations-layer.test.ts +231 -0
- package/plugins/design/dev-server/test/annotations-roundtrip.test.ts +276 -0
- package/plugins/design/dev-server/test/canvas-cursors.test.ts +73 -0
- package/plugins/design/dev-server/test/canvas-origin-gate.test.ts +76 -0
- package/plugins/design/dev-server/test/collab-awareness-bridge.test.ts +223 -0
- package/plugins/design/dev-server/test/collab-reseed-guard.test.ts +78 -0
- package/plugins/design/dev-server/test/collab-room.test.ts +21 -10
- package/plugins/design/dev-server/test/comment-mount.test.ts +87 -0
- package/plugins/design/dev-server/test/csp-canvas-shell.test.ts +46 -0
- package/plugins/design/dev-server/test/fixtures/phase-20-annotations.svg +1 -0
- package/plugins/design/dev-server/test/hmr-classify.test.ts +70 -0
- package/plugins/design/dev-server/test/input-router.test.ts +21 -0
- package/plugins/design/dev-server/test/sanitize-annotation-svg.test.ts +100 -0
- package/plugins/design/dev-server/test/shared-doc-convergence.test.ts +265 -0
- package/plugins/design/dev-server/test/shared-doc-foundation.test.ts +63 -0
- package/plugins/design/dev-server/test/shared-doc-migrate.test.ts +160 -0
- package/plugins/design/dev-server/test/shared-doc-projection.test.ts +238 -0
- package/plugins/design/dev-server/test/sync-agent.test.ts +278 -0
- package/plugins/design/dev-server/test/sync-atomic-write.test.ts +63 -0
- package/plugins/design/dev-server/test/sync-codec.test.ts +165 -0
- package/plugins/design/dev-server/test/sync-connection-state.test.ts +146 -0
- package/plugins/design/dev-server/test/sync-echo-guard.test.ts +96 -0
- package/plugins/design/dev-server/test/sync-fs-mirror.test.ts +182 -0
- package/plugins/design/dev-server/test/sync-hardening.test.ts +520 -0
- package/plugins/design/dev-server/test/sync-hubs-config.test.ts +130 -0
- package/plugins/design/dev-server/test/sync-meta-codec.test.ts +123 -0
- package/plugins/design/dev-server/test/sync-runtime.test.ts +812 -0
- package/plugins/design/dev-server/test/sync-status.test.ts +80 -0
- package/plugins/design/dev-server/test/sync-untrusted.test.ts +104 -0
- package/plugins/design/dev-server/test/use-collab.test.ts +0 -0
- package/plugins/design/dev-server/test/use-tool-mode.test.tsx +38 -10
- package/plugins/design/dev-server/tool-palette.tsx +18 -16
- package/plugins/design/dev-server/undo-hud.tsx +4 -4
- package/plugins/design/dev-server/undo-stack.ts +20 -4
- package/plugins/design/dev-server/use-annotation-resize.tsx +16 -5
- package/plugins/design/dev-server/use-collab.tsx +157 -13
- package/plugins/design/dev-server/use-selection-set.tsx +12 -0
- package/plugins/design/dev-server/use-tool-mode.tsx +27 -12
- package/plugins/design/dev-server/ws.ts +40 -1
- package/plugins/design/templates/_shell.html +63 -5
- package/plugins/design/templates/canvas.tsx.template +13 -0
- package/plugins/design/templates/design-system-inspiration/SUB-AGENT-PROMPTS.md +15 -7
- package/plugins/flow/.claude-plugin/config.schema.json +5 -0
- package/plugins/flow/templates/ai-skeleton/README.md +1 -1
- package/plugins/flow/templates/ai-skeleton/gitignore +10 -0
- package/plugins/flow/templates/ai-skeleton/scenarios/README.md +3 -1
- package/plugins/flow/templates/ai-skeleton/workflows.config.json +2 -1
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
// Gap 2 — .meta.json shared-layout sync codec.
|
|
2
|
+
//
|
|
3
|
+
// Artboard layout must propagate as a file diff (one machine moves an artboard →
|
|
4
|
+
// the other's .meta.json layout converges), while each user's pan/zoom
|
|
5
|
+
// (`viewport`) and the security opt-in (`syncable`) stay strictly local. These
|
|
6
|
+
// tests pin that split: applyMetaToDoc stores only the shared subset, and
|
|
7
|
+
// mergeSharedMetaIntoLocal layers it back without trampling local-only keys.
|
|
8
|
+
|
|
9
|
+
import { describe, expect, test } from 'bun:test';
|
|
10
|
+
import * as Y from 'yjs';
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
META_LOCAL_KEYS,
|
|
14
|
+
applyCssToDoc,
|
|
15
|
+
applyMetaToDoc,
|
|
16
|
+
cssFromDoc,
|
|
17
|
+
mergeSharedMetaIntoLocal,
|
|
18
|
+
metaFromDoc,
|
|
19
|
+
} from '../sync/codec.ts';
|
|
20
|
+
|
|
21
|
+
describe('Gap 2 — meta codec: shared layout syncs, per-user keys stay local', () => {
|
|
22
|
+
test('applyMetaToDoc stores ONLY the shared subset (viewport/last_modified/syncable stripped)', () => {
|
|
23
|
+
const doc = new Y.Doc();
|
|
24
|
+
const full = JSON.stringify({
|
|
25
|
+
title: 'Kanban',
|
|
26
|
+
layout: { 'ab-1': { x: 10, y: 20 } },
|
|
27
|
+
viewport: { x: 999, y: 888, zoom: 0.5 },
|
|
28
|
+
last_modified: '2026-01-01T00:00:00Z',
|
|
29
|
+
syncable: true,
|
|
30
|
+
});
|
|
31
|
+
expect(applyMetaToDoc(doc, full)).toBe(true);
|
|
32
|
+
|
|
33
|
+
const shared = JSON.parse(metaFromDoc(doc) as string);
|
|
34
|
+
expect(shared.title).toBe('Kanban');
|
|
35
|
+
expect(shared.layout).toEqual({ 'ab-1': { x: 10, y: 20 } });
|
|
36
|
+
// The three per-machine keys never enter the synced doc.
|
|
37
|
+
expect(shared.viewport).toBeUndefined();
|
|
38
|
+
expect(shared.last_modified).toBeUndefined();
|
|
39
|
+
expect(shared.syncable).toBeUndefined();
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('applyMetaToDoc is a NO-OP when only per-user keys differ (no churn from panning)', () => {
|
|
43
|
+
const doc = new Y.Doc();
|
|
44
|
+
applyMetaToDoc(doc, JSON.stringify({ title: 'X', viewport: { x: 1 } }));
|
|
45
|
+
// Same shared content, different viewport → must not register a change,
|
|
46
|
+
// otherwise every pan would emit a sync op.
|
|
47
|
+
expect(applyMetaToDoc(doc, JSON.stringify({ title: 'X', viewport: { x: 2 } }))).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('mergeSharedMetaIntoLocal takes shared layout, PRESERVES local viewport + syncable', () => {
|
|
51
|
+
const shared = JSON.stringify({ title: 'Kanban', layout: { 'ab-1': { x: 10, y: 20 } } });
|
|
52
|
+
const local = JSON.stringify({
|
|
53
|
+
title: 'Kanban (stale)',
|
|
54
|
+
layout: { 'ab-1': { x: 0, y: 0 } },
|
|
55
|
+
viewport: { x: 42, y: 7, zoom: 1.5 },
|
|
56
|
+
syncable: false,
|
|
57
|
+
last_modified: 'local-ts',
|
|
58
|
+
});
|
|
59
|
+
const merged = JSON.parse(mergeSharedMetaIntoLocal(local, shared) as string);
|
|
60
|
+
expect(merged.layout).toEqual({ 'ab-1': { x: 10, y: 20 } }); // shared layout won
|
|
61
|
+
expect(merged.title).toBe('Kanban'); // shared title won
|
|
62
|
+
expect(merged.viewport).toEqual({ x: 42, y: 7, zoom: 1.5 }); // LOCAL viewport kept
|
|
63
|
+
expect(merged.syncable).toBe(false); // LOCAL opt-in kept (security invariant)
|
|
64
|
+
expect(merged.last_modified).toBe('local-ts'); // local timestamp kept
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
test('round-trip: artboard move on A reaches B without touching B viewport / syncable', () => {
|
|
68
|
+
const aDoc = new Y.Doc();
|
|
69
|
+
applyMetaToDoc(
|
|
70
|
+
aDoc,
|
|
71
|
+
JSON.stringify({
|
|
72
|
+
title: 'K',
|
|
73
|
+
layout: { 'ab-1': { x: 100, y: 200 } },
|
|
74
|
+
viewport: { zoom: 0.5 },
|
|
75
|
+
syncable: true,
|
|
76
|
+
})
|
|
77
|
+
);
|
|
78
|
+
const shared = metaFromDoc(aDoc) as string;
|
|
79
|
+
|
|
80
|
+
const bLocal = JSON.stringify({
|
|
81
|
+
title: 'K',
|
|
82
|
+
layout: { 'ab-1': { x: 0, y: 0 } },
|
|
83
|
+
viewport: { zoom: 2.0 },
|
|
84
|
+
syncable: false,
|
|
85
|
+
});
|
|
86
|
+
const bMerged = JSON.parse(mergeSharedMetaIntoLocal(bLocal, shared) as string);
|
|
87
|
+
expect(bMerged.layout['ab-1']).toEqual({ x: 100, y: 200 }); // A's move landed on B
|
|
88
|
+
expect(bMerged.viewport).toEqual({ zoom: 2.0 }); // B's camera untouched
|
|
89
|
+
expect(bMerged.syncable).toBe(false); // B's opt-in untouched
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test('a freshly-cloned peer with no local viewport just takes the shared subset', () => {
|
|
93
|
+
const merged = JSON.parse(
|
|
94
|
+
mergeSharedMetaIntoLocal('{}', JSON.stringify({ title: 'K', layout: { a: 1 } })) as string
|
|
95
|
+
);
|
|
96
|
+
expect(merged).toEqual({ title: 'K', layout: { a: 1 } });
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test('META_LOCAL_KEYS pins the never-synced set', () => {
|
|
100
|
+
expect([...META_LOCAL_KEYS].sort()).toEqual(['last_modified', 'syncable', 'viewport']);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('mergeSharedMetaIntoLocal returns null on an unparseable shared payload', () => {
|
|
104
|
+
expect(mergeSharedMetaIntoLocal('{}', 'not json')).toBeNull();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('Gap 3 — css codec (opaque wholesale text)', () => {
|
|
109
|
+
test('applyCssToDoc round-trips the css string', () => {
|
|
110
|
+
const doc = new Y.Doc();
|
|
111
|
+
expect(cssFromDoc(doc)).toBeNull();
|
|
112
|
+
const css = '.ka-card { color: red; }\n';
|
|
113
|
+
expect(applyCssToDoc(doc, css)).toBe(true);
|
|
114
|
+
expect(cssFromDoc(doc)).toBe(css);
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
test('applyCssToDoc is a no-op when unchanged (loop-safe)', () => {
|
|
118
|
+
const doc = new Y.Doc();
|
|
119
|
+
applyCssToDoc(doc, '.x{}');
|
|
120
|
+
expect(applyCssToDoc(doc, '.x{}')).toBe(false);
|
|
121
|
+
expect(applyCssToDoc(doc, '.x{ color: blue }')).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
});
|