@dxos/plugin-tldraw 0.12.0-next-73daef452f1464b62efdbca75fb0067c1066f264 → 0.13.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/PLUGIN.mdl +144 -25
- package/dist/lib/TldrawCapabilities.mjs.map +1 -1
- package/dist/lib/assets/{plugin-tldraw-BDrn_mrV.css → plugin-tldraw-D5Xn3em_.css} +11 -0
- package/dist/lib/capabilities.browser.mjs +30 -0
- package/dist/lib/capabilities.browser.mjs.map +1 -0
- package/dist/lib/capabilities.mjs +2 -4
- package/dist/lib/capabilities.mjs.map +1 -1
- package/dist/lib/capabilities.node.mjs.map +1 -1
- package/dist/lib/capabilities.tauri.mjs +30 -0
- package/dist/lib/capabilities.tauri.mjs.map +1 -0
- package/dist/lib/capabilities.workerd.mjs.map +1 -1
- package/dist/lib/chunk-PLUGIN.mjs +6 -0
- package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
- package/dist/lib/chunk-TldrawArticle.mjs +21 -14
- package/dist/lib/chunk-TldrawArticle.mjs.map +1 -1
- package/dist/lib/chunk-TldrawCard.mjs +7 -10
- package/dist/lib/chunk-TldrawCard.mjs.map +1 -1
- package/dist/lib/chunk-settings.mjs +2 -2
- package/dist/lib/chunk-settings.mjs.map +1 -1
- package/dist/lib/components.mjs +45 -9
- package/dist/lib/components.mjs.map +1 -1
- package/dist/lib/containers.mjs.map +1 -1
- package/dist/lib/hooks.mjs +2 -2
- package/dist/lib/hooks.mjs.map +1 -1
- package/dist/lib/index.mjs +0 -1
- package/dist/lib/meta.mjs.map +1 -1
- package/dist/lib/model.mjs +26 -12
- package/dist/lib/model.mjs.map +1 -1
- package/dist/lib/translations.mjs.map +1 -1
- package/dist/types/src/capabilities/gen/browser.d.ts +6 -0
- package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
- package/dist/types/src/capabilities/gen/tauri.d.ts +6 -0
- package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/components/Canvas/Canvas.d.ts +7 -0
- package/dist/types/src/components/Canvas/Canvas.d.ts.map +1 -1
- package/dist/types/src/components/Canvas/Canvas.stories.d.ts.map +1 -1
- package/dist/types/src/components/Canvas/UiSchematic.stories.d.ts +15 -0
- package/dist/types/src/components/Canvas/UiSchematic.stories.d.ts.map +1 -0
- package/dist/types/src/components/Canvas/index.d.ts +2 -2
- package/dist/types/src/components/Canvas/index.d.ts.map +1 -1
- package/dist/types/src/components/custom/index.d.ts +5 -5
- package/dist/types/src/components/custom/index.d.ts.map +1 -1
- package/dist/types/src/components/index.d.ts +1 -1
- package/dist/types/src/components/index.d.ts.map +1 -1
- package/dist/types/src/containers/TldrawArticle/TldrawArticle.d.ts +1 -1
- package/dist/types/src/containers/TldrawArticle/TldrawArticle.d.ts.map +1 -1
- package/dist/types/src/containers/TldrawArticle/index.d.ts +1 -1
- package/dist/types/src/containers/TldrawArticle/index.d.ts.map +1 -1
- package/dist/types/src/containers/TldrawCard/index.d.ts +1 -1
- package/dist/types/src/containers/TldrawCard/index.d.ts.map +1 -1
- package/dist/types/src/containers/index.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +2 -2
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useStoreAdapter.d.ts +1 -1
- package/dist/types/src/hooks/useStoreAdapter.d.ts.map +1 -1
- package/dist/types/src/index.d.ts +1 -2
- package/dist/types/src/index.d.ts.map +1 -1
- package/dist/types/src/migrations/index.d.ts +2 -2
- package/dist/types/src/migrations/index.d.ts.map +1 -1
- package/dist/types/src/model/RecordBuilder.d.ts +10 -0
- package/dist/types/src/model/RecordBuilder.d.ts.map +1 -1
- package/dist/types/src/model/builder.d.ts +4 -3
- package/dist/types/src/model/builder.d.ts.map +1 -1
- package/dist/types/src/model/index.d.ts +4 -4
- package/dist/types/src/model/index.d.ts.map +1 -1
- package/dist/types/src/model/read.d.ts +3 -3
- package/dist/types/src/model/read.d.ts.map +1 -1
- package/dist/types/src/model/render.d.ts +2 -2
- package/dist/types/src/model/render.d.ts.map +1 -1
- package/dist/types/src/testing/index.d.ts +1 -1
- package/dist/types/src/testing/index.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/TldrawCapabilities.d.ts +2 -2
- package/dist/types/src/types/TldrawCapabilities.d.ts.map +1 -1
- package/dist/types/src/types/index.d.ts +4 -4
- package/dist/types/src/types/index.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +41 -32
- package/src/capabilities/gen/browser.ts +42 -0
- package/src/capabilities/gen/node.ts +1 -1
- package/src/capabilities/gen/tauri.ts +42 -0
- package/src/capabilities/gen/workerd.ts +1 -1
- package/src/capabilities/index.ts +7 -3
- package/src/capabilities/settings.ts +2 -2
- package/src/components/Canvas/Canvas.stories.tsx +17 -15
- package/src/components/Canvas/Canvas.tsx +71 -10
- package/src/components/Canvas/Mermaid.stories.tsx +5 -5
- package/src/components/Canvas/UiSchematic.stories.tsx +74 -0
- package/src/components/Canvas/index.ts +2 -2
- package/src/components/Canvas/theme.css +11 -0
- package/src/components/custom/index.ts +5 -5
- package/src/components/index.ts +1 -1
- package/src/containers/TldrawArticle/TldrawArticle.tsx +31 -16
- package/src/containers/TldrawArticle/index.ts +1 -1
- package/src/containers/TldrawCard/TldrawCard.stories.tsx +1 -1
- package/src/containers/TldrawCard/TldrawCard.tsx +2 -2
- package/src/containers/TldrawCard/index.ts +1 -1
- package/src/containers/index.ts +2 -2
- package/src/hooks/index.ts +2 -2
- package/src/hooks/useStoreAdapter.ts +3 -3
- package/src/index.ts +1 -2
- package/src/meta.ts +1 -1
- package/src/migrations/index.ts +2 -2
- package/src/migrations/migrate.ts +1 -1
- package/src/model/RecordBuilder.test.ts +1 -1
- package/src/model/RecordBuilder.ts +19 -2
- package/src/model/builder.ts +6 -6
- package/src/model/index.ts +4 -4
- package/src/model/read.ts +3 -3
- package/src/model/render.ts +8 -4
- package/src/model/scene.test.ts +31 -3
- package/src/testing/index.ts +1 -1
- package/src/translations.ts +2 -2
- package/src/types/TldrawCapabilities.ts +2 -2
- package/src/types/index.ts +4 -4
- package/src/variant.test.ts +3 -4
package/PLUGIN.mdl
CHANGED
|
@@ -15,9 +15,10 @@ Each extension is defined in the Appendix or resolved via its URI.
|
|
|
15
15
|
|-------------|--------------------------------|
|
|
16
16
|
| `type` | `org.dxos.mdl.type@1.0` |
|
|
17
17
|
| `feat` | `org.dxos.mdl.feat@1.0` |
|
|
18
|
-
| `
|
|
18
|
+
| `scenario` | `org.dxos.mdl.scenario@1.0` |
|
|
19
19
|
| `component` | `org.dxos.mdl.component@1.0` |
|
|
20
|
-
| `op` | `org.dxos.mdl.op@1.
|
|
20
|
+
| `op` | `org.dxos.mdl.op@1.1` |
|
|
21
|
+
| `test` | `org.dxos.mdl.test@1.0` |
|
|
21
22
|
|
|
22
23
|
## Types
|
|
23
24
|
|
|
@@ -116,38 +117,55 @@ component SketchSettings
|
|
|
116
117
|
|
|
117
118
|
## Operations
|
|
118
119
|
|
|
120
|
+
> **Architecture has moved since this section was written.** `plugin-tldraw` no longer owns a
|
|
121
|
+
> `Sketch`/`Canvas` type or a `createSketch`/`readSketch`/`editSketch` operation — there is no
|
|
122
|
+
> `operations/` directory and no `Sketch` class in `src/` at all. Tldraw is now a **render/create
|
|
123
|
+
> variant** contributed to `plugin-illustrator`'s `Drawing` type
|
|
124
|
+
> (`src/capabilities/drawing-variant.ts`, `IllustratorCapabilities.VariantProvider`, id
|
|
125
|
+
> `tldraw.com/2`) — `TldrawArticle`/`TldrawCard` render a `Drawing.Canvas` whose `schema` is
|
|
126
|
+
> `tldraw.com/2`, and the Scene DSL create/read/edit operations documented below actually live in
|
|
127
|
+
> `@dxos/plugin-illustrator` (`org.dxos.operation.illustrator.{create,read,edit}`), invoked with
|
|
128
|
+
> `variant: 'tldraw.com/2'` to select this plugin's renderer. The type/component sections above
|
|
129
|
+
> (`Canvas`, `Sketch`, `Scene`, `WorldObject`, `Command`) and F-7/F-8 below describe the DSL
|
|
130
|
+
> correctly in spirit but attribute it to the wrong plugin; QA-1/QA-2 below invoke the real keys.
|
|
131
|
+
|
|
119
132
|
```mdl
|
|
120
133
|
op createSketch
|
|
121
|
-
|
|
134
|
+
key: org.dxos.operation.illustrator.create
|
|
135
|
+
desc: |
|
|
136
|
+
Owned by plugin-illustrator, not this plugin (see note above). Creates a Drawing with an
|
|
137
|
+
associated Canvas and adds it to the target space or collection; `variant: 'tldraw.com/2'`
|
|
138
|
+
selects the tldraw renderer instead of another registered DrawingVariant.
|
|
122
139
|
input:
|
|
123
140
|
name?: string
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
output: Sketch
|
|
141
|
+
variant?: string # canvas typename; here 'tldraw.com/2' — defaults to the first registered variant
|
|
142
|
+
output: { object: Drawing }
|
|
127
143
|
effects: [echo:write]
|
|
128
144
|
```
|
|
129
145
|
|
|
130
146
|
```mdl
|
|
131
147
|
op readSketch
|
|
148
|
+
key: org.dxos.operation.illustrator.read
|
|
132
149
|
desc: |
|
|
133
|
-
Returns the derived Scene (world objects with
|
|
134
|
-
from the live canvas records, plus a count of unmanaged
|
|
135
|
-
Origins derive from bounding boxes, so the scene stays coherent after
|
|
136
|
-
drag shapes. The agent calls this before editing an existing sketch.
|
|
150
|
+
Owned by plugin-illustrator (see note above). Returns the derived Scene (world objects with
|
|
151
|
+
object-local coordinates) read from the live canvas records, plus a count of unmanaged
|
|
152
|
+
(hand-drawn) shapes. Origins derive from bounding boxes, so the scene stays coherent after
|
|
153
|
+
users drag shapes. The agent calls this before editing an existing sketch.
|
|
137
154
|
input:
|
|
138
|
-
|
|
155
|
+
drawing: Ref<Drawing>
|
|
139
156
|
output: { scene: Scene, unmanaged: number }
|
|
140
157
|
requires: [Database]
|
|
141
158
|
```
|
|
142
159
|
|
|
143
160
|
```mdl
|
|
144
161
|
op editSketch
|
|
162
|
+
key: org.dxos.operation.illustrator.edit
|
|
145
163
|
desc: |
|
|
146
|
-
Applies scene commands atomically (one
|
|
147
|
-
objects or individual elements by id. Returns the
|
|
148
|
-
agent can maintain its mental model across turns.
|
|
164
|
+
Owned by plugin-illustrator (see note above). Applies scene commands atomically (one
|
|
165
|
+
Obj.update): upsert/move/remove world objects or individual elements by id. Returns the
|
|
166
|
+
resulting scene so the agent can maintain its mental model across turns.
|
|
149
167
|
input:
|
|
150
|
-
|
|
168
|
+
drawing: Ref<Drawing>
|
|
151
169
|
commands: Command[]
|
|
152
170
|
output: { scene: Scene, unmanaged: number, upserted: string[], removed: number }
|
|
153
171
|
effects: [echo:write]
|
|
@@ -266,7 +284,7 @@ feat F-8: Scene DSL and Agent Skill
|
|
|
266
284
|
## Acceptance
|
|
267
285
|
|
|
268
286
|
```mdl
|
|
269
|
-
|
|
287
|
+
scenario T-1: Create and open sketch
|
|
270
288
|
given: a Composer space is active
|
|
271
289
|
when: op:createSketch runs with name "My Diagram"
|
|
272
290
|
then:
|
|
@@ -276,7 +294,7 @@ test T-1: Create and open sketch
|
|
|
276
294
|
```
|
|
277
295
|
|
|
278
296
|
```mdl
|
|
279
|
-
|
|
297
|
+
scenario T-2: Drawing persists across reload
|
|
280
298
|
given: a Sketch is open and the user draws a freehand stroke
|
|
281
299
|
when: the page is reloaded and the Sketch is reopened
|
|
282
300
|
then:
|
|
@@ -285,7 +303,7 @@ test T-2: Drawing persists across reload
|
|
|
285
303
|
```
|
|
286
304
|
|
|
287
305
|
```mdl
|
|
288
|
-
|
|
306
|
+
scenario T-3: Collaborative edit
|
|
289
307
|
given: two peers have the same Sketch open
|
|
290
308
|
when: peer A draws a rectangle
|
|
291
309
|
then:
|
|
@@ -294,7 +312,7 @@ test T-3: Collaborative edit
|
|
|
294
312
|
```
|
|
295
313
|
|
|
296
314
|
```mdl
|
|
297
|
-
|
|
315
|
+
scenario T-4: Read-only slide role
|
|
298
316
|
given: a Sketch is rendered in role slide
|
|
299
317
|
then:
|
|
300
318
|
- tldraw toolbar is not shown
|
|
@@ -303,7 +321,7 @@ test T-4: Read-only slide role
|
|
|
303
321
|
```
|
|
304
322
|
|
|
305
323
|
```mdl
|
|
306
|
-
|
|
324
|
+
scenario T-5: Grid toggle
|
|
307
325
|
given: SketchSettings panel is open
|
|
308
326
|
when: user enables the grid and selects "dotted"
|
|
309
327
|
then:
|
|
@@ -313,7 +331,7 @@ test T-5: Grid toggle
|
|
|
313
331
|
```
|
|
314
332
|
|
|
315
333
|
```mdl
|
|
316
|
-
|
|
334
|
+
scenario T-6: Attention-aware toolbar
|
|
317
335
|
given: a Sketch is open in article role alongside other articles
|
|
318
336
|
when: user clicks on the sketch to give it attention
|
|
319
337
|
then: tldraw toolbar becomes visible
|
|
@@ -322,7 +340,7 @@ test T-6: Attention-aware toolbar
|
|
|
322
340
|
```
|
|
323
341
|
|
|
324
342
|
```mdl
|
|
325
|
-
|
|
343
|
+
scenario T-7: Scene DSL round-trip
|
|
326
344
|
given: an empty Sketch
|
|
327
345
|
when: editSketch upserts a "face" object (head/eyes/smile), then upserts a "hat" object and
|
|
328
346
|
replaces only the "smile" element, then removes the "hat"
|
|
@@ -334,7 +352,7 @@ test T-7: Scene DSL round-trip
|
|
|
334
352
|
```
|
|
335
353
|
|
|
336
354
|
```mdl
|
|
337
|
-
|
|
355
|
+
scenario T-8: Conversational drawing (live AI)
|
|
338
356
|
given: the stories-assistant Sketch storybook (config.remote) with the sketch skill bound
|
|
339
357
|
when: the user prompts "Draw a smiley face", then "Add a hat"
|
|
340
358
|
then:
|
|
@@ -347,6 +365,107 @@ test T-8: Conversational drawing (live AI)
|
|
|
347
365
|
|
|
348
366
|
---
|
|
349
367
|
|
|
368
|
+
## QA
|
|
369
|
+
|
|
370
|
+
Executable tests. Each step carries a human instruction (`do`) and, where the step maps to an
|
|
371
|
+
invocable operation, an agent binding (`invoke`). Report failures by test and step number.
|
|
372
|
+
Tldraw is enabled by default in every environment (`plugin-defs.tsx` `getDefaults`).
|
|
373
|
+
|
|
374
|
+
```mdl
|
|
375
|
+
test QA-1: Create a tldraw sketch and draw on it
|
|
376
|
+
desc: The core whiteboard round-trip — create a Drawing bound to the tldraw variant, draw, reload.
|
|
377
|
+
actors: both
|
|
378
|
+
covers: [F-1.1, F-1.2, F-2.1, F-2.2, T-1, T-2]
|
|
379
|
+
status: unverified
|
|
380
|
+
given:
|
|
381
|
+
- an identity exists
|
|
382
|
+
- space: a space is open
|
|
383
|
+
- collection: a collection in that space, to create into
|
|
384
|
+
- no Drawing named "QA Sketch" exists — ABORT rather than deleting one this test did not create
|
|
385
|
+
steps:
|
|
386
|
+
- name: Create the sketch
|
|
387
|
+
do: In the navtree, click + on a collection and choose Sketch (tldraw). Name it "QA Sketch".
|
|
388
|
+
invoke: [op:createSketch] { name: "QA Sketch", variant: "tldraw.com/2" }
|
|
389
|
+
capture: created
|
|
390
|
+
expect: a Drawing named "QA Sketch" opens in TldrawArticle with an empty canvas
|
|
391
|
+
assert: return !!$created.object
|
|
392
|
+
- name: Place it in the collection
|
|
393
|
+
do: (no separate gesture — the navtree create action places it)
|
|
394
|
+
invoke: org.dxos.operation.space.addObject { object: $created.object, target: $given.collection }
|
|
395
|
+
expect: "QA Sketch" appears as a row under the collection
|
|
396
|
+
- name: Draw a shape
|
|
397
|
+
do: With the sketch open and focused (attention), select the rectangle tool and draw a rectangle on the canvas.
|
|
398
|
+
expect: the rectangle appears on the canvas
|
|
399
|
+
note: |
|
|
400
|
+
NO `invoke` — freehand drawing is a pointer gesture inside the tldraw canvas, with no
|
|
401
|
+
operation behind it; the DSL ops (`op:editSketch`) address semantic world objects, not
|
|
402
|
+
raw hand-drawn shapes. This step is human-only.
|
|
403
|
+
after:
|
|
404
|
+
- name: Delete the sketch
|
|
405
|
+
do: Right-click "QA Sketch" in the navtree and choose Delete.
|
|
406
|
+
invoke: org.dxos.operation.space.removeObjects { objects: [$created.object], target: $given.collection }
|
|
407
|
+
expect: the row leaves the navtree and its plank closes if it was open
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
```mdl
|
|
411
|
+
test QA-2: Scene DSL round-trip — draw a face, then add a hat without redrawing it
|
|
412
|
+
desc: |
|
|
413
|
+
The agent-facing DSL path (F-8 / T-7): create, read, and edit a scene addressed by semantic
|
|
414
|
+
object ids, verifying an edit to one world object leaves siblings untouched.
|
|
415
|
+
actors: agent
|
|
416
|
+
covers: [F-7.1, F-7.2, F-8.2, F-8.3, T-7]
|
|
417
|
+
status: unverified
|
|
418
|
+
given:
|
|
419
|
+
- an identity exists
|
|
420
|
+
- space: a space is open
|
|
421
|
+
- collection: a collection in that space, to create into
|
|
422
|
+
- no Drawing named "QA Face" exists — ABORT rather than deleting one this test did not create
|
|
423
|
+
steps:
|
|
424
|
+
- name: Create the sketch
|
|
425
|
+
do: (agent-only step — DSL editing has no human equivalent gesture; a human would draw freehand instead)
|
|
426
|
+
invoke: [op:createSketch] { name: "QA Face", variant: "tldraw.com/2" }
|
|
427
|
+
capture: created
|
|
428
|
+
expect: an empty Drawing named "QA Face" is created
|
|
429
|
+
assert: return !!$created.object
|
|
430
|
+
- name: Place it in the collection
|
|
431
|
+
do: (no separate gesture)
|
|
432
|
+
invoke: org.dxos.operation.space.addObject { object: $created.object, target: $given.collection }
|
|
433
|
+
expect: "QA Face" appears as a row under the collection
|
|
434
|
+
- name: Draw a face
|
|
435
|
+
do: (no human gesture — this is the DSL path)
|
|
436
|
+
invoke: |
|
|
437
|
+
org.dxos.operation.illustrator.edit {
|
|
438
|
+
drawing: $created.object,
|
|
439
|
+
commands: [{ kind: "upsert-object", id: "face", elements: [
|
|
440
|
+
{ id: "head", type: "circle" },
|
|
441
|
+
{ id: "smile", type: "arc" }
|
|
442
|
+
] }]
|
|
443
|
+
}
|
|
444
|
+
capture: withFace
|
|
445
|
+
expect: the canvas renders a circle ("head") and an arc ("smile"); reading the scene returns
|
|
446
|
+
a "face" object with both element ids
|
|
447
|
+
assert: return $result.upserted.includes('face')
|
|
448
|
+
- name: Add a hat without touching the face
|
|
449
|
+
do: (no human gesture — this is the DSL path)
|
|
450
|
+
invoke: |
|
|
451
|
+
org.dxos.operation.illustrator.edit {
|
|
452
|
+
drawing: $created.object,
|
|
453
|
+
commands: [{ kind: "upsert-object", id: "hat", elements: [{ id: "brim", type: "triangle" }] }]
|
|
454
|
+
}
|
|
455
|
+
expect: the canvas now also renders the hat; the face's "head" and "smile" records are
|
|
456
|
+
byte-identical to the previous step's — the edit touched only the "hat" object
|
|
457
|
+
assert: return $result.upserted.includes('hat') && !$result.upserted.includes('face')
|
|
458
|
+
note: |
|
|
459
|
+
This is the mental-model regression T-8 describes for live AI conversation — asserting on
|
|
460
|
+
`upserted` (which object ids the edit actually touched) is the falsifiable form of "the
|
|
461
|
+
face was not redrawn," per Rule 5.
|
|
462
|
+
after:
|
|
463
|
+
- name: Delete the sketch
|
|
464
|
+
do: Right-click "QA Face" in the navtree and choose Delete.
|
|
465
|
+
invoke: org.dxos.operation.space.removeObjects { objects: [$created.object], target: $given.collection }
|
|
466
|
+
expect: the row leaves the navtree and its plank closes if it was open
|
|
467
|
+
```
|
|
468
|
+
|
|
350
469
|
## Appendix: Extension Definitions
|
|
351
470
|
|
|
352
471
|
```mdl
|
|
@@ -371,8 +490,8 @@ ext feat
|
|
|
371
490
|
```
|
|
372
491
|
|
|
373
492
|
```mdl
|
|
374
|
-
ext
|
|
375
|
-
uri: org.dxos.mdl.
|
|
493
|
+
ext scenario
|
|
494
|
+
uri: org.dxos.mdl.scenario@1.0
|
|
376
495
|
desc: An acceptance scenario expressed as given / when / then steps.
|
|
377
496
|
fields:
|
|
378
497
|
given?: Step | Step[]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TldrawCapabilities.mjs","names":[],"sources":["../../src/types/TldrawCapabilities.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Atom from 'effect/
|
|
1
|
+
{"version":3,"file":"TldrawCapabilities.mjs","names":[],"sources":["../../src/types/TldrawCapabilities.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as Atom from 'effect/reactivity/Atom';\n\nimport * as Capability from '@dxos/app-framework/Capability';\n\nimport { meta } from '#meta';\n\n// Inline import to avoid `Settings` namespace alias colliding with the\n// `Settings` capability export below.\nexport const Settings = Capability.makeSingleton<Atom.Writable<import('./Settings.ts').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\n"],"mappings":";;;;;AAcA,IAAa,WAAW,WAAW,cAA+D,CAAC,CACjG,GAAG,KAAK,QAAQ,IAAI,qBACtB"}
|
|
@@ -21,4 +21,15 @@
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
+
|
|
25
|
+
/* Maps the app's surfaces onto tldraw's own variables. */
|
|
26
|
+
.tl-background {
|
|
27
|
+
--color-background: var(--color-base-surface);
|
|
28
|
+
}
|
|
29
|
+
.tl-container.tl-theme__light,
|
|
30
|
+
.tl-container.tl-theme__dark {
|
|
31
|
+
--color-selected: var(--color-accent-bg);
|
|
32
|
+
--color-panel: var(--color-modal-surface);
|
|
33
|
+
--color-panel-contrast: var(--color-separator);
|
|
34
|
+
}
|
|
24
35
|
/*$vite$:1*/
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
|
|
2
|
+
import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
|
|
3
|
+
import * as AppCapability from "@dxos/app-toolkit/AppCapability";
|
|
4
|
+
import { translations } from "#translations";
|
|
5
|
+
import { TldrawCapabilities } from "#types";
|
|
6
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
7
|
+
import * as IllustratorCapabilities from "@dxos/plugin-illustrator/IllustratorCapabilities";
|
|
8
|
+
import * as IllustratorEvents from "@dxos/plugin-illustrator/IllustratorEvents";
|
|
9
|
+
import { meta } from "#meta";
|
|
10
|
+
//#region src/capabilities/gen/browser.ts
|
|
11
|
+
var DrawingVariant = Capability.lazyModule("drawing-variant", {
|
|
12
|
+
provides: [IllustratorCapabilities.VariantProvider],
|
|
13
|
+
activatesOn: IllustratorEvents.Start,
|
|
14
|
+
environments: ["browser", "tauri"]
|
|
15
|
+
}, () => import("./chunk-drawing-variant.mjs"));
|
|
16
|
+
var PluginAsset = AppCapability.pluginAsset({
|
|
17
|
+
pluginId: meta.profile.key,
|
|
18
|
+
path: "PLUGIN.mdl",
|
|
19
|
+
content: PLUGIN_default,
|
|
20
|
+
mimeType: "application/x-mdl"
|
|
21
|
+
});
|
|
22
|
+
var TldrawSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
|
|
23
|
+
activatesOn: ActivationEvents.Idle,
|
|
24
|
+
provides: [TldrawCapabilities.Settings]
|
|
25
|
+
});
|
|
26
|
+
var Translations = AppCapability.translations(translations);
|
|
27
|
+
//#endregion
|
|
28
|
+
export { DrawingVariant, PluginAsset, TldrawSettings, Translations };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=capabilities.browser.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.browser.mjs","names":[],"sources":["../../src/capabilities/gen/browser.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'browser' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as IllustratorCapabilities from '@dxos/plugin-illustrator/IllustratorCapabilities';\nimport * as IllustratorEvents from '@dxos/plugin-illustrator/IllustratorEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\n// Browser-only: the variant supplies the React article/card components that render a drawing.\nexport const DrawingVariant = Capability.lazyModule(\n 'drawing-variant',\n {\n provides: [IllustratorCapabilities.VariantProvider],\n activatesOn: IllustratorEvents.Start,\n environments: ['browser', 'tauri'],\n },\n () => import('../drawing-variant.ts'),\n);\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nexport const TldrawSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,iBAAiB,WAAW,WACvC,mBACA;CACE,UAAU,CAAC,wBAAwB,eAAe;CAClD,aAAa,kBAAkB;CAC/B,cAAc,CAAC,WAAW,OAAO;AACnC,SACM,OAAO,8BACf;AAEA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAmB;CACnF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
|
|
1
2
|
import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
|
|
2
3
|
import * as AppCapability from "@dxos/app-toolkit/AppCapability";
|
|
3
4
|
import { translations } from "#translations";
|
|
@@ -6,14 +7,11 @@ import * as Capability from "@dxos/app-framework/Capability";
|
|
|
6
7
|
import * as IllustratorCapabilities from "@dxos/plugin-illustrator/IllustratorCapabilities";
|
|
7
8
|
import * as IllustratorEvents from "@dxos/plugin-illustrator/IllustratorEvents";
|
|
8
9
|
import { meta } from "#meta";
|
|
9
|
-
//#region PLUGIN.mdl?raw
|
|
10
|
-
var PLUGIN_default = "---\nid: org.dxos.plugin.tldraw\nname: TldrawPlugin\nversion: 0.1.0\n---\n\nA collaborative whiteboard plugin for `DXOS` Composer — powered by tldraw, persisted in ECHO, and available as a first-class workspace object.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|-------------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `test` | `org.dxos.mdl.test@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.0` |\n\n## Types\n\n```mdl\ntype Canvas\n desc: Low-level drawing document backed by a tldraw store.\n fields:\n schema?: string # external schema reference (default: tldraw.com/2)\n content: Map<string, any> # tldraw store snapshot — shapes, bindings, assets\n```\n\n```mdl\ntype Sketch\n desc: User-facing whiteboard object that wraps a Canvas.\n fields:\n name?: string\n canvas: Ref<Canvas> # reference to the tldraw content store\n```\n\n```mdl\ntype SketchGrid\n literals: mesh | dotted\n```\n\n```mdl\ntype Settings\n fields:\n showGrid?: boolean # display a background grid on the canvas\n gridType?: SketchGrid # mesh or dotted pattern\n```\n\n```mdl\ntype Scene\n desc: |\n Backend-neutral scene DSL (src/model). A diagram is a set of world objects\n (\"face\", \"hat\") composed of elements in object-local units; a compiler maps\n the scene to tldraw records with identity stamped in record meta\n ({ object, element, kind, scale, dialect }) so edits address shapes by id.\n fields:\n objects: WorldObject[]\n```\n\n```mdl\ntype WorldObject\n fields:\n id: string # semantic id (\"face\"); addressing key for edits\n origin?: Point # canvas px; derived from bbox top-left on read\n scale?: number # canvas px per local unit (default 1)\n elements: Element[] # rect | ellipse | circle | diamond | triangle |\n # line | curve | arc | text | arrow\n```\n\n```mdl\ntype Command\n desc: Scene edit commands (D2-Oracle-style, addressed by id).\n literals: upsert-object | upsert-elements | remove-elements | remove-object | move-object\n```\n\n## Components\n\n```mdl\ncomponent SketchArticle\n desc: Full-screen whiteboard surface for a Sketch object. Renders inside article, section, and slide roles.\n props:\n subject: Sketch\n settings: Settings\n attendableId: string\n role: article | section | slide\n state:\n editor?: Editor # tldraw Editor instance\n hasAttention: boolean\n slots:\n toolbar?: ReactNode # injected tldraw toolbar actions\n actions:\n createThread() # opens a comment thread anchored to a selection\n layout: |\n ┌─────────────────────────────────┐\n │ tldraw toolbar (when attended) │\n ├─────────────────────────────────┤\n │ │\n │ infinite canvas (tldraw) │\n │ shapes / freehand / text │\n │ │\n │ [comment thread anchors] │\n │ │\n └─────────────────────────────────┘\n```\n\n```mdl\ncomponent SketchSettings\n desc: Settings panel for the Sketch plugin — controls grid visibility and type.\n props:\n settings: Settings\n onSettingsChange?: (updater: (s: Settings) => Settings) => void\n```\n\n## Operations\n\n```mdl\nop createSketch\n desc: Creates a new Sketch with an associated Canvas and adds it to the target space or collection.\n input:\n name?: string\n schema?: string # tldraw schema version (default: tldraw.com/2)\n content?: Map<string, any> # optional initial tldraw store snapshot\n output: Sketch\n effects: [echo:write]\n```\n\n```mdl\nop readSketch\n desc: |\n Returns the derived Scene (world objects with object-local coordinates) read\n from the live canvas records, plus a count of unmanaged (hand-drawn) shapes.\n Origins derive from bounding boxes, so the scene stays coherent after users\n drag shapes. The agent calls this before editing an existing sketch.\n input:\n sketch: Ref<Sketch>\n output: { scene: Scene, unmanaged: number }\n requires: [Database]\n```\n\n```mdl\nop editSketch\n desc: |\n Applies scene commands atomically (one Obj.update): upsert/move/remove world\n objects or individual elements by id. Returns the resulting scene so the\n agent can maintain its mental model across turns.\n input:\n sketch: Ref<Sketch>\n commands: Command[]\n output: { scene: Scene, unmanaged: number, upserted: string[], removed: number }\n effects: [echo:write]\n requires: [Database]\n```\n\n## Features\n\n```mdl\nfeat F-1: Whiteboard Canvas\n\n req F-1.1: Each Sketch owns exactly one Canvas; the Canvas holds the full tldraw store snapshot.\n req F-1.2: Canvas content is stored as a plain record in ECHO — no binary blobs.\n req F-1.3: All tldraw shape types (freehand, geometric, text, arrow, image) are supported.\n```\n\n```mdl\nfeat F-2: ECHO Persistence\n\n req F-2.1:\n when: user makes any edit in the whiteboard\n then: Canvas.content is updated in ECHO within the debounce window\n\n req F-2.2:\n when: Sketch is opened after a page reload\n then: tldraw store is hydrated from Canvas.content; no drawing is lost\n\n req F-2.3: Canvas is a separate ECHO object from Sketch so it can be replicated independently.\n```\n\n```mdl\nfeat F-3: Real-time Collaboration\n\n req F-3.1:\n when: two or more peers open the same Sketch\n then: edits by each peer appear on the other's canvas via ECHO replication\n\n req F-3.2:\n when: a peer is offline and makes edits\n then: changes merge with remote state on reconnection using ECHO CRDT semantics\n```\n\n```mdl\nfeat F-4: Roles and Presentation\n\n req F-4.1:\n when: role is article\n then: full tldraw toolbar shown when the sketch has attention; hidden otherwise\n\n req F-4.2:\n when: role is slide\n then: canvas is read-only; zoom capped at 1.5×\n\n req F-4.3:\n when: role is section\n then: canvas auto-zooms to fit content; no toolbar shown\n```\n\n```mdl\nfeat F-5: Comment Threads\n\n req F-5.1:\n when: user activates the thread tool in the toolbar\n then: a new comment thread is created anchored to the current selection\n\n req F-5.2: Thread anchor positions are stored alongside the drawing so they survive reloads.\n```\n\n```mdl\nfeat F-6: Grid Settings\n\n req F-6.1:\n when: Settings.showGrid is true\n then: a background grid rendered beneath drawing content\n\n req F-6.2:\n when: Settings.gridType is mesh\n then: a square-mesh grid is shown\n\n req F-6.3:\n when: Settings.gridType is dotted\n then: a dotted grid is shown\n```\n\n```mdl\nfeat F-7: Create Sketch Operation\n\n req F-7.1: Plugin contributes op:createSketch to the operation registry.\n req F-7.2:\n when: op:createSketch is invoked\n then: a Sketch + Canvas pair is created and returned; the Sketch is added to the target collection\n```\n\n```mdl\nfeat F-8: Scene DSL and Agent Skill\n\n req F-8.1: The scene model (src/model) is backend-neutral — no tldraw imports in scene.ts;\n the tldraw compiler (render.ts/read.ts) is one backend, Excalidraw can be added later.\n req F-8.2: Every DSL-generated tldraw record carries meta { object, element, kind, scale, dialect };\n record ids are deterministic (shape:<object>/<element>) so re-rendering an element reuses its id.\n req F-8.3:\n when: op:editSketch upserts elements of an existing object\n then: only records with matching element ids are replaced; sibling elements are untouched\n req F-8.4:\n when: a shape bound by an arrow is removed\n then: its bindings are removed too; no dangling binding records remain\n req F-8.5:\n when: op:readSketch runs after a user drags shapes in the UI\n then: the derived scene reflects the moved geometry (origin = bbox top-left)\n req F-8.6: Plugin contributes the org.dxos.skill.sketch skill (create/read/edit tools +\n DSL instructions: object-local units, semantic ids, read-before-edit workflow).\n req F-8.7: A dialect registry (scene only for now) reserves the extension point for\n mermaid / d2 / sequence / uml-class compilers that emit scene commands.\n```\n\n## Acceptance\n\n```mdl\ntest T-1: Create and open sketch\n given: a Composer space is active\n when: op:createSketch runs with name \"My Diagram\"\n then:\n - a Sketch object is created with name \"My Diagram\"\n - Sketch.canvas references a new Canvas with empty content\n - Sketch appears in the space object list\n```\n\n```mdl\ntest T-2: Drawing persists across reload\n given: a Sketch is open and the user draws a freehand stroke\n when: the page is reloaded and the Sketch is reopened\n then:\n - the stroke is visible on the canvas\n - Canvas.content is non-empty\n```\n\n```mdl\ntest T-3: Collaborative edit\n given: two peers have the same Sketch open\n when: peer A draws a rectangle\n then:\n - peer B sees the rectangle appear within the ECHO sync window\n - no data loss if both peers edit simultaneously\n```\n\n```mdl\ntest T-4: Read-only slide role\n given: a Sketch is rendered in role slide\n then:\n - tldraw toolbar is not shown\n - all drawing tools are disabled\n - zoom is capped at 1.5×\n```\n\n```mdl\ntest T-5: Grid toggle\n given: SketchSettings panel is open\n when: user enables the grid and selects \"dotted\"\n then:\n - Settings.showGrid === true\n - Settings.gridType === dotted\n - dotted grid appears on the canvas immediately\n```\n\n```mdl\ntest T-6: Attention-aware toolbar\n given: a Sketch is open in article role alongside other articles\n when: user clicks on the sketch to give it attention\n then: tldraw toolbar becomes visible\n when: user clicks away, removing attention\n then: tldraw toolbar is hidden\n```\n\n```mdl\ntest T-7: Scene DSL round-trip\n given: an empty Sketch\n when: editSketch upserts a \"face\" object (head/eyes/smile), then upserts a \"hat\" object and\n replaces only the \"smile\" element, then removes the \"hat\"\n then:\n - readSketch returns the face with derived origin and all element ids\n - the untouched face elements are byte-identical across the hat edit\n - removing the hat removes exactly its records and no bindings dangle\n # Covered by src/operations/operations.test.ts and src/model/scene.test.ts.\n```\n\n```mdl\ntest T-8: Conversational drawing (live AI)\n given: the stories-assistant Sketch storybook (config.remote) with the sketch skill bound\n when: the user prompts \"Draw a smiley face\", then \"Add a hat\"\n then:\n - the agent creates a \"face\" world object via editSketch\n - the follow-up adds a \"hat\" object WITHOUT redrawing the face (mental-model test)\n # Manual: stories/stories-assistant/Sketch → DrawAndUpdateTest / Reflection (tags: ['!test']).\n # Verified live 2026-07-23 (remote EDGE, claude-opus-4-8): face drawn, hat composed on top,\n # face records untouched.\n```\n\n---\n\n## Appendix: Extension Definitions\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap\n literals?: UnionList\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next test\n uri: org.dxos.mdl.test@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n";
|
|
11
|
-
//#endregion
|
|
12
10
|
//#region src/capabilities/index.ts
|
|
13
11
|
var DrawingVariant = Capability.lazyModule("drawing-variant", {
|
|
14
12
|
provides: [IllustratorCapabilities.VariantProvider],
|
|
15
13
|
activatesOn: IllustratorEvents.Start,
|
|
16
|
-
environments: []
|
|
14
|
+
environments: ["browser", "tauri"]
|
|
17
15
|
}, () => import("./chunk-drawing-variant.mjs"));
|
|
18
16
|
var PluginAsset = AppCapability.pluginAsset({
|
|
19
17
|
pluginId: meta.profile.key,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as IllustratorCapabilities from '@dxos/plugin-illustrator/IllustratorCapabilities';\nimport * as IllustratorEvents from '@dxos/plugin-illustrator/IllustratorEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\n// Browser-only: the variant supplies the React article/card components that render a drawing.\nexport const DrawingVariant = Capability.lazyModule(\n 'drawing-variant',\n {
|
|
1
|
+
{"version":3,"file":"capabilities.mjs","names":[],"sources":["../../src/capabilities/index.ts"],"sourcesContent":["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as IllustratorCapabilities from '@dxos/plugin-illustrator/IllustratorCapabilities';\nimport * as IllustratorEvents from '@dxos/plugin-illustrator/IllustratorEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\n// eslint-disable-next-line import/no-relative-packages\nimport pluginSpec from '../../PLUGIN.mdl?raw';\n\n// Browser-only: the variant supplies the React article/card components that render a drawing.\nexport const DrawingVariant = Capability.lazyModule(\n 'drawing-variant',\n {\n provides: [IllustratorCapabilities.VariantProvider],\n activatesOn: IllustratorEvents.Start,\n environments: ['browser', 'tauri'],\n },\n () => import('./drawing-variant.ts'),\n);\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\nexport const TldrawSettings = AppCapability.settings(() => import('./settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;;AAkBA,IAAa,iBAAiB,WAAW,WACvC,mBACA;CACE,UAAU,CAAC,wBAAwB,eAAe;CAClD,aAAa,kBAAkB;CAC/B,cAAc,CAAC,WAAW,OAAO;AACnC,SACM,OAAO,8BACf;AAEA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AACD,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAkB;CAClF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AACD,IAAa,eAAe,cAAc,aAAa,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.node.mjs","names":[],"sources":["../../src/capabilities/gen/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'node' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\nexport const TldrawSettings = AppCapability.settings(() => import('../settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const DrawingVariant = undefined;\nexport const PluginAsset = undefined;\n"],"mappings":";;;;;AAYA,IAAa,iBAAiB,cAAc,eAAe,OAAO,
|
|
1
|
+
{"version":3,"file":"capabilities.node.mjs","names":[],"sources":["../../src/capabilities/gen/node.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'node' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\nexport const TldrawSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const DrawingVariant = undefined;\nexport const PluginAsset = undefined;\n"],"mappings":";;;;;AAYA,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAmB;CACnF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,iBAAiB,KAAA;AAC9B,IAAa,cAAc,KAAA"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { t as PLUGIN_default } from "./chunk-PLUGIN.mjs";
|
|
2
|
+
import * as ActivationEvents from "@dxos/app-framework/ActivationEvents";
|
|
3
|
+
import * as AppCapability from "@dxos/app-toolkit/AppCapability";
|
|
4
|
+
import { translations } from "#translations";
|
|
5
|
+
import { TldrawCapabilities } from "#types";
|
|
6
|
+
import * as Capability from "@dxos/app-framework/Capability";
|
|
7
|
+
import * as IllustratorCapabilities from "@dxos/plugin-illustrator/IllustratorCapabilities";
|
|
8
|
+
import * as IllustratorEvents from "@dxos/plugin-illustrator/IllustratorEvents";
|
|
9
|
+
import { meta } from "#meta";
|
|
10
|
+
//#region src/capabilities/gen/tauri.ts
|
|
11
|
+
var DrawingVariant = Capability.lazyModule("drawing-variant", {
|
|
12
|
+
provides: [IllustratorCapabilities.VariantProvider],
|
|
13
|
+
activatesOn: IllustratorEvents.Start,
|
|
14
|
+
environments: ["browser", "tauri"]
|
|
15
|
+
}, () => import("./chunk-drawing-variant.mjs"));
|
|
16
|
+
var PluginAsset = AppCapability.pluginAsset({
|
|
17
|
+
pluginId: meta.profile.key,
|
|
18
|
+
path: "PLUGIN.mdl",
|
|
19
|
+
content: PLUGIN_default,
|
|
20
|
+
mimeType: "application/x-mdl"
|
|
21
|
+
});
|
|
22
|
+
var TldrawSettings = AppCapability.settings(() => import("./chunk-settings.mjs"), {
|
|
23
|
+
activatesOn: ActivationEvents.Idle,
|
|
24
|
+
provides: [TldrawCapabilities.Settings]
|
|
25
|
+
});
|
|
26
|
+
var Translations = AppCapability.translations(translations);
|
|
27
|
+
//#endregion
|
|
28
|
+
export { DrawingVariant, PluginAsset, TldrawSettings, Translations };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=capabilities.tauri.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.tauri.mjs","names":[],"sources":["../../src/capabilities/gen/tauri.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'tauri' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as Capability from '@dxos/app-framework/Capability';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\nimport * as IllustratorCapabilities from '@dxos/plugin-illustrator/IllustratorCapabilities';\nimport * as IllustratorEvents from '@dxos/plugin-illustrator/IllustratorEvents';\n\nimport { meta } from '#meta';\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\nimport pluginSpec from '../../../PLUGIN.mdl?raw';\n\n// Browser-only: the variant supplies the React article/card components that render a drawing.\nexport const DrawingVariant = Capability.lazyModule(\n 'drawing-variant',\n {\n provides: [IllustratorCapabilities.VariantProvider],\n activatesOn: IllustratorEvents.Start,\n environments: ['browser', 'tauri'],\n },\n () => import('../drawing-variant.ts'),\n);\n\nexport const PluginAsset = AppCapability.pluginAsset({\n pluginId: meta.profile.key,\n path: 'PLUGIN.mdl',\n content: pluginSpec,\n mimeType: 'application/x-mdl',\n});\n\nexport const TldrawSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;;AAmBA,IAAa,iBAAiB,WAAW,WACvC,mBACA;CACE,UAAU,CAAC,wBAAwB,eAAe;CAClD,aAAa,kBAAkB;CAC/B,cAAc,CAAC,WAAW,OAAO;AACnC,SACM,OAAO,8BACf;AAEA,IAAa,cAAc,cAAc,YAAY;CACnD,UAAU,KAAK,QAAQ;CACvB,MAAM;CACN,SAAS;CACT,UAAU;AACZ,CAAC;AAED,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAmB;CACnF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capabilities.workerd.mjs","names":[],"sources":["../../src/capabilities/gen/workerd.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'workerd' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\nexport const TldrawSettings = AppCapability.settings(() => import('../settings'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const DrawingVariant = undefined;\nexport const PluginAsset = undefined;\n"],"mappings":";;;;;AAYA,IAAa,iBAAiB,cAAc,eAAe,OAAO,
|
|
1
|
+
{"version":3,"file":"capabilities.workerd.mjs","names":[],"sources":["../../src/capabilities/gen/workerd.ts"],"sourcesContent":["//\n// Copyright 2026 DXOS.org\n//\n\n// GENERATED by dx-plugin — do not edit. Sliced from ../index.ts for the 'workerd' condition.\n\nimport * as ActivationEvents from '@dxos/app-framework/ActivationEvents';\nimport * as AppCapability from '@dxos/app-toolkit/AppCapability';\n\nimport { translations } from '#translations';\nimport { TldrawCapabilities } from '#types';\n\nexport const TldrawSettings = AppCapability.settings(() => import('../settings.ts'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\n\nexport const Translations = AppCapability.translations(translations);\n\nexport const DrawingVariant = undefined;\nexport const PluginAsset = undefined;\n"],"mappings":";;;;;AAYA,IAAa,iBAAiB,cAAc,eAAe,OAAO,yBAAmB;CACnF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,iBAAiB,KAAA;AAC9B,IAAa,cAAc,KAAA"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
//#region PLUGIN.mdl?raw
|
|
2
|
+
var PLUGIN_default = "---\nid: org.dxos.plugin.tldraw\nname: TldrawPlugin\nversion: 0.1.0\n---\n\nA collaborative whiteboard plugin for `DXOS` Composer — powered by tldraw, persisted in ECHO, and available as a first-class workspace object.\n\n## Extensions\n\nThe following extension dialects are used in this document.\nEach extension is defined in the Appendix or resolved via its URI.\n\n| Term | URI |\n|-------------|--------------------------------|\n| `type` | `org.dxos.mdl.type@1.0` |\n| `feat` | `org.dxos.mdl.feat@1.0` |\n| `scenario` | `org.dxos.mdl.scenario@1.0` |\n| `component` | `org.dxos.mdl.component@1.0` |\n| `op` | `org.dxos.mdl.op@1.1` |\n| `test` | `org.dxos.mdl.test@1.0` |\n\n## Types\n\n```mdl\ntype Canvas\n desc: Low-level drawing document backed by a tldraw store.\n fields:\n schema?: string # external schema reference (default: tldraw.com/2)\n content: Map<string, any> # tldraw store snapshot — shapes, bindings, assets\n```\n\n```mdl\ntype Sketch\n desc: User-facing whiteboard object that wraps a Canvas.\n fields:\n name?: string\n canvas: Ref<Canvas> # reference to the tldraw content store\n```\n\n```mdl\ntype SketchGrid\n literals: mesh | dotted\n```\n\n```mdl\ntype Settings\n fields:\n showGrid?: boolean # display a background grid on the canvas\n gridType?: SketchGrid # mesh or dotted pattern\n```\n\n```mdl\ntype Scene\n desc: |\n Backend-neutral scene DSL (src/model). A diagram is a set of world objects\n (\"face\", \"hat\") composed of elements in object-local units; a compiler maps\n the scene to tldraw records with identity stamped in record meta\n ({ object, element, kind, scale, dialect }) so edits address shapes by id.\n fields:\n objects: WorldObject[]\n```\n\n```mdl\ntype WorldObject\n fields:\n id: string # semantic id (\"face\"); addressing key for edits\n origin?: Point # canvas px; derived from bbox top-left on read\n scale?: number # canvas px per local unit (default 1)\n elements: Element[] # rect | ellipse | circle | diamond | triangle |\n # line | curve | arc | text | arrow\n```\n\n```mdl\ntype Command\n desc: Scene edit commands (D2-Oracle-style, addressed by id).\n literals: upsert-object | upsert-elements | remove-elements | remove-object | move-object\n```\n\n## Components\n\n```mdl\ncomponent SketchArticle\n desc: Full-screen whiteboard surface for a Sketch object. Renders inside article, section, and slide roles.\n props:\n subject: Sketch\n settings: Settings\n attendableId: string\n role: article | section | slide\n state:\n editor?: Editor # tldraw Editor instance\n hasAttention: boolean\n slots:\n toolbar?: ReactNode # injected tldraw toolbar actions\n actions:\n createThread() # opens a comment thread anchored to a selection\n layout: |\n ┌─────────────────────────────────┐\n │ tldraw toolbar (when attended) │\n ├─────────────────────────────────┤\n │ │\n │ infinite canvas (tldraw) │\n │ shapes / freehand / text │\n │ │\n │ [comment thread anchors] │\n │ │\n └─────────────────────────────────┘\n```\n\n```mdl\ncomponent SketchSettings\n desc: Settings panel for the Sketch plugin — controls grid visibility and type.\n props:\n settings: Settings\n onSettingsChange?: (updater: (s: Settings) => Settings) => void\n```\n\n## Operations\n\n> **Architecture has moved since this section was written.** `plugin-tldraw` no longer owns a\n> `Sketch`/`Canvas` type or a `createSketch`/`readSketch`/`editSketch` operation — there is no\n> `operations/` directory and no `Sketch` class in `src/` at all. Tldraw is now a **render/create\n> variant** contributed to `plugin-illustrator`'s `Drawing` type\n> (`src/capabilities/drawing-variant.ts`, `IllustratorCapabilities.VariantProvider`, id\n> `tldraw.com/2`) — `TldrawArticle`/`TldrawCard` render a `Drawing.Canvas` whose `schema` is\n> `tldraw.com/2`, and the Scene DSL create/read/edit operations documented below actually live in\n> `@dxos/plugin-illustrator` (`org.dxos.operation.illustrator.{create,read,edit}`), invoked with\n> `variant: 'tldraw.com/2'` to select this plugin's renderer. The type/component sections above\n> (`Canvas`, `Sketch`, `Scene`, `WorldObject`, `Command`) and F-7/F-8 below describe the DSL\n> correctly in spirit but attribute it to the wrong plugin; QA-1/QA-2 below invoke the real keys.\n\n```mdl\nop createSketch\n key: org.dxos.operation.illustrator.create\n desc: |\n Owned by plugin-illustrator, not this plugin (see note above). Creates a Drawing with an\n associated Canvas and adds it to the target space or collection; `variant: 'tldraw.com/2'`\n selects the tldraw renderer instead of another registered DrawingVariant.\n input:\n name?: string\n variant?: string # canvas typename; here 'tldraw.com/2' — defaults to the first registered variant\n output: { object: Drawing }\n effects: [echo:write]\n```\n\n```mdl\nop readSketch\n key: org.dxos.operation.illustrator.read\n desc: |\n Owned by plugin-illustrator (see note above). Returns the derived Scene (world objects with\n object-local coordinates) read from the live canvas records, plus a count of unmanaged\n (hand-drawn) shapes. Origins derive from bounding boxes, so the scene stays coherent after\n users drag shapes. The agent calls this before editing an existing sketch.\n input:\n drawing: Ref<Drawing>\n output: { scene: Scene, unmanaged: number }\n requires: [Database]\n```\n\n```mdl\nop editSketch\n key: org.dxos.operation.illustrator.edit\n desc: |\n Owned by plugin-illustrator (see note above). Applies scene commands atomically (one\n Obj.update): upsert/move/remove world objects or individual elements by id. Returns the\n resulting scene so the agent can maintain its mental model across turns.\n input:\n drawing: Ref<Drawing>\n commands: Command[]\n output: { scene: Scene, unmanaged: number, upserted: string[], removed: number }\n effects: [echo:write]\n requires: [Database]\n```\n\n## Features\n\n```mdl\nfeat F-1: Whiteboard Canvas\n\n req F-1.1: Each Sketch owns exactly one Canvas; the Canvas holds the full tldraw store snapshot.\n req F-1.2: Canvas content is stored as a plain record in ECHO — no binary blobs.\n req F-1.3: All tldraw shape types (freehand, geometric, text, arrow, image) are supported.\n```\n\n```mdl\nfeat F-2: ECHO Persistence\n\n req F-2.1:\n when: user makes any edit in the whiteboard\n then: Canvas.content is updated in ECHO within the debounce window\n\n req F-2.2:\n when: Sketch is opened after a page reload\n then: tldraw store is hydrated from Canvas.content; no drawing is lost\n\n req F-2.3: Canvas is a separate ECHO object from Sketch so it can be replicated independently.\n```\n\n```mdl\nfeat F-3: Real-time Collaboration\n\n req F-3.1:\n when: two or more peers open the same Sketch\n then: edits by each peer appear on the other's canvas via ECHO replication\n\n req F-3.2:\n when: a peer is offline and makes edits\n then: changes merge with remote state on reconnection using ECHO CRDT semantics\n```\n\n```mdl\nfeat F-4: Roles and Presentation\n\n req F-4.1:\n when: role is article\n then: full tldraw toolbar shown when the sketch has attention; hidden otherwise\n\n req F-4.2:\n when: role is slide\n then: canvas is read-only; zoom capped at 1.5×\n\n req F-4.3:\n when: role is section\n then: canvas auto-zooms to fit content; no toolbar shown\n```\n\n```mdl\nfeat F-5: Comment Threads\n\n req F-5.1:\n when: user activates the thread tool in the toolbar\n then: a new comment thread is created anchored to the current selection\n\n req F-5.2: Thread anchor positions are stored alongside the drawing so they survive reloads.\n```\n\n```mdl\nfeat F-6: Grid Settings\n\n req F-6.1:\n when: Settings.showGrid is true\n then: a background grid rendered beneath drawing content\n\n req F-6.2:\n when: Settings.gridType is mesh\n then: a square-mesh grid is shown\n\n req F-6.3:\n when: Settings.gridType is dotted\n then: a dotted grid is shown\n```\n\n```mdl\nfeat F-7: Create Sketch Operation\n\n req F-7.1: Plugin contributes op:createSketch to the operation registry.\n req F-7.2:\n when: op:createSketch is invoked\n then: a Sketch + Canvas pair is created and returned; the Sketch is added to the target collection\n```\n\n```mdl\nfeat F-8: Scene DSL and Agent Skill\n\n req F-8.1: The scene model (src/model) is backend-neutral — no tldraw imports in scene.ts;\n the tldraw compiler (render.ts/read.ts) is one backend, Excalidraw can be added later.\n req F-8.2: Every DSL-generated tldraw record carries meta { object, element, kind, scale, dialect };\n record ids are deterministic (shape:<object>/<element>) so re-rendering an element reuses its id.\n req F-8.3:\n when: op:editSketch upserts elements of an existing object\n then: only records with matching element ids are replaced; sibling elements are untouched\n req F-8.4:\n when: a shape bound by an arrow is removed\n then: its bindings are removed too; no dangling binding records remain\n req F-8.5:\n when: op:readSketch runs after a user drags shapes in the UI\n then: the derived scene reflects the moved geometry (origin = bbox top-left)\n req F-8.6: Plugin contributes the org.dxos.skill.sketch skill (create/read/edit tools +\n DSL instructions: object-local units, semantic ids, read-before-edit workflow).\n req F-8.7: A dialect registry (scene only for now) reserves the extension point for\n mermaid / d2 / sequence / uml-class compilers that emit scene commands.\n```\n\n## Acceptance\n\n```mdl\nscenario T-1: Create and open sketch\n given: a Composer space is active\n when: op:createSketch runs with name \"My Diagram\"\n then:\n - a Sketch object is created with name \"My Diagram\"\n - Sketch.canvas references a new Canvas with empty content\n - Sketch appears in the space object list\n```\n\n```mdl\nscenario T-2: Drawing persists across reload\n given: a Sketch is open and the user draws a freehand stroke\n when: the page is reloaded and the Sketch is reopened\n then:\n - the stroke is visible on the canvas\n - Canvas.content is non-empty\n```\n\n```mdl\nscenario T-3: Collaborative edit\n given: two peers have the same Sketch open\n when: peer A draws a rectangle\n then:\n - peer B sees the rectangle appear within the ECHO sync window\n - no data loss if both peers edit simultaneously\n```\n\n```mdl\nscenario T-4: Read-only slide role\n given: a Sketch is rendered in role slide\n then:\n - tldraw toolbar is not shown\n - all drawing tools are disabled\n - zoom is capped at 1.5×\n```\n\n```mdl\nscenario T-5: Grid toggle\n given: SketchSettings panel is open\n when: user enables the grid and selects \"dotted\"\n then:\n - Settings.showGrid === true\n - Settings.gridType === dotted\n - dotted grid appears on the canvas immediately\n```\n\n```mdl\nscenario T-6: Attention-aware toolbar\n given: a Sketch is open in article role alongside other articles\n when: user clicks on the sketch to give it attention\n then: tldraw toolbar becomes visible\n when: user clicks away, removing attention\n then: tldraw toolbar is hidden\n```\n\n```mdl\nscenario T-7: Scene DSL round-trip\n given: an empty Sketch\n when: editSketch upserts a \"face\" object (head/eyes/smile), then upserts a \"hat\" object and\n replaces only the \"smile\" element, then removes the \"hat\"\n then:\n - readSketch returns the face with derived origin and all element ids\n - the untouched face elements are byte-identical across the hat edit\n - removing the hat removes exactly its records and no bindings dangle\n # Covered by src/operations/operations.test.ts and src/model/scene.test.ts.\n```\n\n```mdl\nscenario T-8: Conversational drawing (live AI)\n given: the stories-assistant Sketch storybook (config.remote) with the sketch skill bound\n when: the user prompts \"Draw a smiley face\", then \"Add a hat\"\n then:\n - the agent creates a \"face\" world object via editSketch\n - the follow-up adds a \"hat\" object WITHOUT redrawing the face (mental-model test)\n # Manual: stories/stories-assistant/Sketch → DrawAndUpdateTest / Reflection (tags: ['!test']).\n # Verified live 2026-07-23 (remote EDGE, claude-opus-4-8): face drawn, hat composed on top,\n # face records untouched.\n```\n\n---\n\n## QA\n\nExecutable tests. Each step carries a human instruction (`do`) and, where the step maps to an\ninvocable operation, an agent binding (`invoke`). Report failures by test and step number.\nTldraw is enabled by default in every environment (`plugin-defs.tsx` `getDefaults`).\n\n```mdl\ntest QA-1: Create a tldraw sketch and draw on it\n desc: The core whiteboard round-trip — create a Drawing bound to the tldraw variant, draw, reload.\n actors: both\n covers: [F-1.1, F-1.2, F-2.1, F-2.2, T-1, T-2]\n status: unverified\n given:\n - an identity exists\n - space: a space is open\n - collection: a collection in that space, to create into\n - no Drawing named \"QA Sketch\" exists — ABORT rather than deleting one this test did not create\n steps:\n - name: Create the sketch\n do: In the navtree, click + on a collection and choose Sketch (tldraw). Name it \"QA Sketch\".\n invoke: [op:createSketch] { name: \"QA Sketch\", variant: \"tldraw.com/2\" }\n capture: created\n expect: a Drawing named \"QA Sketch\" opens in TldrawArticle with an empty canvas\n assert: return !!$created.object\n - name: Place it in the collection\n do: (no separate gesture — the navtree create action places it)\n invoke: org.dxos.operation.space.addObject { object: $created.object, target: $given.collection }\n expect: \"QA Sketch\" appears as a row under the collection\n - name: Draw a shape\n do: With the sketch open and focused (attention), select the rectangle tool and draw a rectangle on the canvas.\n expect: the rectangle appears on the canvas\n note: |\n NO `invoke` — freehand drawing is a pointer gesture inside the tldraw canvas, with no\n operation behind it; the DSL ops (`op:editSketch`) address semantic world objects, not\n raw hand-drawn shapes. This step is human-only.\n after:\n - name: Delete the sketch\n do: Right-click \"QA Sketch\" in the navtree and choose Delete.\n invoke: org.dxos.operation.space.removeObjects { objects: [$created.object], target: $given.collection }\n expect: the row leaves the navtree and its plank closes if it was open\n```\n\n```mdl\ntest QA-2: Scene DSL round-trip — draw a face, then add a hat without redrawing it\n desc: |\n The agent-facing DSL path (F-8 / T-7): create, read, and edit a scene addressed by semantic\n object ids, verifying an edit to one world object leaves siblings untouched.\n actors: agent\n covers: [F-7.1, F-7.2, F-8.2, F-8.3, T-7]\n status: unverified\n given:\n - an identity exists\n - space: a space is open\n - collection: a collection in that space, to create into\n - no Drawing named \"QA Face\" exists — ABORT rather than deleting one this test did not create\n steps:\n - name: Create the sketch\n do: (agent-only step — DSL editing has no human equivalent gesture; a human would draw freehand instead)\n invoke: [op:createSketch] { name: \"QA Face\", variant: \"tldraw.com/2\" }\n capture: created\n expect: an empty Drawing named \"QA Face\" is created\n assert: return !!$created.object\n - name: Place it in the collection\n do: (no separate gesture)\n invoke: org.dxos.operation.space.addObject { object: $created.object, target: $given.collection }\n expect: \"QA Face\" appears as a row under the collection\n - name: Draw a face\n do: (no human gesture — this is the DSL path)\n invoke: |\n org.dxos.operation.illustrator.edit {\n drawing: $created.object,\n commands: [{ kind: \"upsert-object\", id: \"face\", elements: [\n { id: \"head\", type: \"circle\" },\n { id: \"smile\", type: \"arc\" }\n ] }]\n }\n capture: withFace\n expect: the canvas renders a circle (\"head\") and an arc (\"smile\"); reading the scene returns\n a \"face\" object with both element ids\n assert: return $result.upserted.includes('face')\n - name: Add a hat without touching the face\n do: (no human gesture — this is the DSL path)\n invoke: |\n org.dxos.operation.illustrator.edit {\n drawing: $created.object,\n commands: [{ kind: \"upsert-object\", id: \"hat\", elements: [{ id: \"brim\", type: \"triangle\" }] }]\n }\n expect: the canvas now also renders the hat; the face's \"head\" and \"smile\" records are\n byte-identical to the previous step's — the edit touched only the \"hat\" object\n assert: return $result.upserted.includes('hat') && !$result.upserted.includes('face')\n note: |\n This is the mental-model regression T-8 describes for live AI conversation — asserting on\n `upserted` (which object ids the edit actually touched) is the falsifiable form of \"the\n face was not redrawn,\" per Rule 5.\n after:\n - name: Delete the sketch\n do: Right-click \"QA Face\" in the navtree and choose Delete.\n invoke: org.dxos.operation.space.removeObjects { objects: [$created.object], target: $given.collection }\n expect: the row leaves the navtree and its plank closes if it was open\n```\n\n## Appendix: Extension Definitions\n\n```mdl\next type\n uri: org.dxos.mdl.type@1.0\n desc: A named data structure with typed fields and optional literals.\n fields:\n desc?: Prose\n fields?: FieldMap\n literals?: UnionList\n extends?: TypeRef[]\n```\n\n```mdl\next feat\n uri: org.dxos.mdl.feat@1.0\n desc: A named feature grouping one or more requirements.\n fields:\n desc?: Prose\n req: RequirementList\n nesting: self\n```\n\n```mdl\next scenario\n uri: org.dxos.mdl.scenario@1.0\n desc: An acceptance scenario expressed as given / when / then steps.\n fields:\n given?: Step | Step[]\n when?: Step | Step[]\n then: Step | Step[]\n tags?: TagList\n```\n\n```mdl\next component\n uri: org.dxos.mdl.component@1.0\n desc: A UI component with props, internal state, slots, actions, and events.\n fields:\n desc?: Prose\n props?: FieldMap\n state?: FieldMap\n slots?: FieldMap\n actions?: ActionMap\n emits?: EventMap\n layout?: CodeBlock\n```\n\n```mdl\next op\n uri: org.dxos.mdl.op@1.0\n desc: |\n A named operation with typed inputs, outputs, and declared errors.\n Pure ops have no effects or requires. Effectful ops declare both.\n fields:\n desc?: Prose\n input?: FieldMap\n output?: TypeExpr\n errors?: ErrorMap\n effects?: EffectList\n requires?: ServiceList\n note?: Prose\n```\n";
|
|
3
|
+
//#endregion
|
|
4
|
+
export { PLUGIN_default as t };
|
|
5
|
+
|
|
6
|
+
//# sourceMappingURL=chunk-PLUGIN.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chunk-PLUGIN.mjs","names":[],"sources":[],"mappings":""}
|
|
@@ -1,27 +1,30 @@
|
|
|
1
1
|
import { TldrawCapabilities } from "#types";
|
|
2
2
|
import "react";
|
|
3
3
|
import { Obj } from "@dxos/echo";
|
|
4
|
-
import
|
|
4
|
+
import * as Util from "@dxos/react-ui/Util";
|
|
5
5
|
import { isTauri } from "@dxos/util";
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { invariant } from "@dxos/invariant";
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
8
|
+
import * as Hooks from "@dxos/app-framework/Hooks";
|
|
9
|
+
import * as AppSurface from "@dxos/app-toolkit/AppSurface";
|
|
10
|
+
import * as ToolkitHooks from "@dxos/app-toolkit/Hooks";
|
|
11
|
+
import * as GraphHooks from "@dxos/plugin-graph/Hooks";
|
|
11
12
|
import * as Drawing from "@dxos/plugin-illustrator/Drawing";
|
|
12
13
|
import { useAttention } from "@dxos/react-ui-attention";
|
|
14
|
+
import * as Layout from "@dxos/react-ui/Layout";
|
|
15
|
+
import * as Panel from "@dxos/react-ui/Panel";
|
|
13
16
|
import { CanvasComponent } from "#components";
|
|
14
17
|
//#region src/containers/TldrawArticle/TldrawArticle.tsx
|
|
15
18
|
var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-tldraw/src/containers/TldrawArticle/TldrawArticle.tsx";
|
|
16
|
-
var TldrawArticle = ({ role, attendableId, drawing, canvas, extrinsic }) => {
|
|
19
|
+
var TldrawArticle = ({ role, attendableId, drawing, canvas, extrinsic, selection, onSelectionChange, onActivate }) => {
|
|
17
20
|
invariant(Obj.instanceOf(Drawing.Canvas, canvas), void 0, {
|
|
18
21
|
"~LogMeta": "~LogMeta",
|
|
19
22
|
F: __dxlog_file,
|
|
20
|
-
L:
|
|
23
|
+
L: 36,
|
|
21
24
|
S: void 0,
|
|
22
25
|
A: ["Obj.instanceOf(Drawing.Canvas, canvas)", ""]
|
|
23
26
|
});
|
|
24
|
-
const settings =
|
|
27
|
+
const [settings, updateSettings] = Hooks.useAtomCapabilityState(TldrawCapabilities.Settings);
|
|
25
28
|
const id = Obj.getURI(drawing);
|
|
26
29
|
const { hasAttention } = useAttention(attendableId);
|
|
27
30
|
const section = role === AppSurface.Section.role;
|
|
@@ -29,14 +32,18 @@ var TldrawArticle = ({ role, attendableId, drawing, canvas, extrinsic }) => {
|
|
|
29
32
|
readonly: role === AppSurface.Slide.role,
|
|
30
33
|
autoCenter: section ? true : void 0
|
|
31
34
|
};
|
|
32
|
-
const { graph } = useAppGraph();
|
|
33
|
-
const handleThreadCreate = useActions(graph, id).find((action) => action.id === `${id}/comment`)?.data;
|
|
35
|
+
const { graph } = ToolkitHooks.useAppGraph();
|
|
36
|
+
const handleThreadCreate = GraphHooks.useActions(graph, id).find((action) => action.id === `${id}/comment`)?.data;
|
|
34
37
|
const content = /* @__PURE__ */ jsx(CanvasComponent, {
|
|
35
38
|
classNames: "dx-attention-surface",
|
|
36
39
|
canvas,
|
|
37
40
|
settings,
|
|
41
|
+
onSettingsChange: updateSettings,
|
|
38
42
|
hideUi: section ? !hasAttention : !hasAttention && !isTauri(),
|
|
39
43
|
onThreadCreate: handleThreadCreate,
|
|
44
|
+
selection,
|
|
45
|
+
onSelectionChange,
|
|
46
|
+
onActivate,
|
|
40
47
|
...props
|
|
41
48
|
}, id);
|
|
42
49
|
return section ? /* @__PURE__ */ jsx(Container, {
|
|
@@ -44,13 +51,13 @@ var TldrawArticle = ({ role, attendableId, drawing, canvas, extrinsic }) => {
|
|
|
44
51
|
children: content
|
|
45
52
|
}) : /* @__PURE__ */ jsx(Article, { children: content });
|
|
46
53
|
};
|
|
47
|
-
var Article = composable((props, forwardedRef) => /* @__PURE__ */ jsx(Panel.Root, {
|
|
48
|
-
...composableProps(props, { classNames: "aspect-square" }),
|
|
54
|
+
var Article = Util.composable((props, forwardedRef) => /* @__PURE__ */ jsx(Panel.Root, {
|
|
55
|
+
...Util.composableProps(props, { classNames: "aspect-square" }),
|
|
49
56
|
ref: forwardedRef,
|
|
50
|
-
children: /* @__PURE__ */ jsx(Panel.
|
|
57
|
+
children: /* @__PURE__ */ jsx(Panel.Body, { children: props.children })
|
|
51
58
|
}));
|
|
52
|
-
var Container = composable(({ fill, ...props }, forwardedRef) => /* @__PURE__ */ jsx(Flex, {
|
|
53
|
-
...composableProps(props, { classNames: [fill ? "
|
|
59
|
+
var Container = Util.composable(({ fill, ...props }, forwardedRef) => /* @__PURE__ */ jsx(Layout.Flex, {
|
|
60
|
+
...Util.composableProps(props, { classNames: [fill ? "dx-fill" : "aspect-square", "overflow-hidden"] }),
|
|
54
61
|
ref: forwardedRef,
|
|
55
62
|
children: props.children
|
|
56
63
|
}));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-TldrawArticle.mjs","names":[],"sources":["../../src/containers/TldrawArticle/TldrawArticle.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren } from 'react';\n\nimport
|
|
1
|
+
{"version":3,"file":"chunk-TldrawArticle.mjs","names":[],"sources":["../../src/containers/TldrawArticle/TldrawArticle.tsx"],"sourcesContent":["//\n// Copyright 2024 DXOS.org\n//\n\nimport React, { type PropsWithChildren } from 'react';\n\nimport * as Hooks from '@dxos/app-framework/Hooks';\nimport * as AppSurface from '@dxos/app-toolkit/AppSurface';\nimport * as ToolkitHooks from '@dxos/app-toolkit/Hooks';\nimport { Obj } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\nimport * as GraphHooks from '@dxos/plugin-graph/Hooks';\nimport * as Drawing from '@dxos/plugin-illustrator/Drawing';\nimport * as IllustratorCapabilities from '@dxos/plugin-illustrator/IllustratorCapabilities';\nimport { useAttention } from '@dxos/react-ui-attention';\nimport * as Layout from '@dxos/react-ui/Layout';\nimport * as Panel from '@dxos/react-ui/Panel';\nimport * as Util from '@dxos/react-ui/Util';\nimport { isTauri } from '@dxos/util';\n\nimport { CanvasComponent } from '#components';\nimport { TldrawCapabilities } from '#types';\n\nexport type TldrawArticleProps = IllustratorCapabilities.DrawingVariantSurfaceProps;\n\nexport const TldrawArticle = ({\n role,\n attendableId,\n drawing,\n canvas,\n extrinsic,\n selection,\n onSelectionChange,\n onActivate,\n}: TldrawArticleProps) => {\n invariant(Obj.instanceOf(Drawing.Canvas, canvas));\n const [settings, updateSettings] = Hooks.useAtomCapabilityState(TldrawCapabilities.Settings);\n const id = Obj.getURI(drawing as Obj.Any);\n const { hasAttention } = useAttention(attendableId);\n const section = role === AppSurface.Section.role;\n\n const props = {\n readonly: role === AppSurface.Slide.role,\n autoCenter: section ? true : undefined,\n };\n\n // TODO(wittjosiah): Genericize tldraw toolbar actions w/ graph.\n const { graph } = ToolkitHooks.useAppGraph();\n const actions = GraphHooks.useActions(graph, id);\n const handleThreadCreate = actions.find((action) => action.id === `${id}/comment`)?.data;\n\n const content = (\n <CanvasComponent\n // Force instance per canvas object. Otherwise, sketches share the same instance.\n key={id}\n classNames='dx-attention-surface'\n canvas={canvas}\n settings={settings}\n onSettingsChange={updateSettings}\n // Section embeds render read-only (no controls/grid) until focused, on every platform; the\n // isTauri allowance (always-on UI) applies only to the full article/slide roles.\n // TODO(wittjosiah): Ensure attention works as expected on the mobile app.\n hideUi={section ? !hasAttention : !hasAttention && !isTauri()}\n onThreadCreate={handleThreadCreate}\n selection={selection}\n onSelectionChange={onSelectionChange}\n onActivate={onActivate}\n {...props}\n />\n );\n\n // An extrinsically-sized embed fills its (possibly non-square) box; otherwise it falls back to a\n // square so the intrinsic embed has a sensible height.\n return section ? <Container fill={extrinsic}>{content}</Container> : <Article>{content}</Article>;\n};\n\nconst Article = Util.composable<HTMLDivElement, PropsWithChildren>((props, forwardedRef) => (\n <Panel.Root {...Util.composableProps(props, { classNames: 'aspect-square' })} ref={forwardedRef}>\n <Panel.Body>{props.children}</Panel.Body>\n </Panel.Root>\n));\n\nconst Container = Util.composable<HTMLDivElement, PropsWithChildren<{ fill?: boolean }>>(\n ({ fill, ...props }, forwardedRef) => (\n <Layout.Flex\n {...Util.composableProps(props, { classNames: [fill ? 'dx-fill' : 'aspect-square', 'overflow-hidden'] })}\n ref={forwardedRef}\n >\n {props.children}\n </Layout.Flex>\n ),\n);\n\nTldrawArticle.displayName = 'TldrawArticle';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAyBA,IAAa,iBAAiB,EAC5B,MACA,cACA,SACA,QACA,WACA,WACA,mBACA,iBACwB;CACxB,UAAU,IAAI,WAAW,QAAQ,QAAQ,MAAM,GAAA,KAAA,GAAA;EAAA,YAAA;EAAA,GAAA;EAAA,GAAA;EAAA,GAAA,KAAA;EAAA,GAAA,CAAA,0CAAA,EAAA;CAAA,CAAC;CAChD,MAAM,CAAC,UAAU,kBAAkB,MAAM,uBAAuB,mBAAmB,QAAQ;CAC3F,MAAM,KAAK,IAAI,OAAO,OAAkB;CACxC,MAAM,EAAE,iBAAiB,aAAa,YAAY;CAClD,MAAM,UAAU,SAAS,WAAW,QAAQ;CAE5C,MAAM,QAAQ;EACZ,UAAU,SAAS,WAAW,MAAM;EACpC,YAAY,UAAU,OAAO,KAAA;CAC/B;CAGA,MAAM,EAAE,UAAU,aAAa,YAAY;CAE3C,MAAM,qBADU,WAAW,WAAW,OAAO,EAClB,CAAA,CAAQ,MAAM,WAAW,OAAO,OAAO,GAAG,GAAG,SAAS,CAAC,EAAE;CAEpF,MAAM,UACJ,oBAAC,iBAAD;EAGE,YAAW;EACH;EACE;EACV,kBAAkB;EAIlB,QAAQ,UAAU,CAAC,eAAe,CAAC,gBAAgB,CAAC,QAAQ;EAC5D,gBAAgB;EACL;EACQ;EACP;EACZ,GAAI;CACL,GAdM,EAcN;CAKH,OAAO,UAAU,oBAAC,WAAD;EAAW,MAAM;EAAY,UAAA;CAAmB,CAAA,IAAI,oBAAC,SAAD,EAAA,UAAU,QAAiB,CAAA;AAClG;AAEA,IAAM,UAAU,KAAK,YAA+C,OAAO,iBACzE,oBAAC,MAAM,MAAP;CAAY,GAAI,KAAK,gBAAgB,OAAO,EAAE,YAAY,gBAAgB,CAAC;CAAG,KAAK;CACjF,UAAA,oBAAC,MAAM,MAAP,EAAA,UAAa,MAAM,SAAqB,CAAA;AAC9B,CAAA,CACb;AAED,IAAM,YAAY,KAAK,YACpB,EAAE,MAAM,GAAG,SAAS,iBACnB,oBAAC,OAAO,MAAR;CACE,GAAI,KAAK,gBAAgB,OAAO,EAAE,YAAY,CAAC,OAAO,YAAY,iBAAiB,iBAAiB,EAAE,CAAC;CACvG,KAAK;CAEJ,UAAA,MAAM;AACI,CAAA,CAEjB;AAEA,cAAc,cAAc"}
|