@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.
Files changed (117) hide show
  1. package/PLUGIN.mdl +144 -25
  2. package/dist/lib/TldrawCapabilities.mjs.map +1 -1
  3. package/dist/lib/assets/{plugin-tldraw-BDrn_mrV.css → plugin-tldraw-D5Xn3em_.css} +11 -0
  4. package/dist/lib/capabilities.browser.mjs +30 -0
  5. package/dist/lib/capabilities.browser.mjs.map +1 -0
  6. package/dist/lib/capabilities.mjs +2 -4
  7. package/dist/lib/capabilities.mjs.map +1 -1
  8. package/dist/lib/capabilities.node.mjs.map +1 -1
  9. package/dist/lib/capabilities.tauri.mjs +30 -0
  10. package/dist/lib/capabilities.tauri.mjs.map +1 -0
  11. package/dist/lib/capabilities.workerd.mjs.map +1 -1
  12. package/dist/lib/chunk-PLUGIN.mjs +6 -0
  13. package/dist/lib/chunk-PLUGIN.mjs.map +1 -0
  14. package/dist/lib/chunk-TldrawArticle.mjs +21 -14
  15. package/dist/lib/chunk-TldrawArticle.mjs.map +1 -1
  16. package/dist/lib/chunk-TldrawCard.mjs +7 -10
  17. package/dist/lib/chunk-TldrawCard.mjs.map +1 -1
  18. package/dist/lib/chunk-settings.mjs +2 -2
  19. package/dist/lib/chunk-settings.mjs.map +1 -1
  20. package/dist/lib/components.mjs +45 -9
  21. package/dist/lib/components.mjs.map +1 -1
  22. package/dist/lib/containers.mjs.map +1 -1
  23. package/dist/lib/hooks.mjs +2 -2
  24. package/dist/lib/hooks.mjs.map +1 -1
  25. package/dist/lib/index.mjs +0 -1
  26. package/dist/lib/meta.mjs.map +1 -1
  27. package/dist/lib/model.mjs +26 -12
  28. package/dist/lib/model.mjs.map +1 -1
  29. package/dist/lib/translations.mjs.map +1 -1
  30. package/dist/types/src/capabilities/gen/browser.d.ts +6 -0
  31. package/dist/types/src/capabilities/gen/browser.d.ts.map +1 -0
  32. package/dist/types/src/capabilities/gen/tauri.d.ts +6 -0
  33. package/dist/types/src/capabilities/gen/tauri.d.ts.map +1 -0
  34. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  35. package/dist/types/src/components/Canvas/Canvas.d.ts +7 -0
  36. package/dist/types/src/components/Canvas/Canvas.d.ts.map +1 -1
  37. package/dist/types/src/components/Canvas/Canvas.stories.d.ts.map +1 -1
  38. package/dist/types/src/components/Canvas/UiSchematic.stories.d.ts +15 -0
  39. package/dist/types/src/components/Canvas/UiSchematic.stories.d.ts.map +1 -0
  40. package/dist/types/src/components/Canvas/index.d.ts +2 -2
  41. package/dist/types/src/components/Canvas/index.d.ts.map +1 -1
  42. package/dist/types/src/components/custom/index.d.ts +5 -5
  43. package/dist/types/src/components/custom/index.d.ts.map +1 -1
  44. package/dist/types/src/components/index.d.ts +1 -1
  45. package/dist/types/src/components/index.d.ts.map +1 -1
  46. package/dist/types/src/containers/TldrawArticle/TldrawArticle.d.ts +1 -1
  47. package/dist/types/src/containers/TldrawArticle/TldrawArticle.d.ts.map +1 -1
  48. package/dist/types/src/containers/TldrawArticle/index.d.ts +1 -1
  49. package/dist/types/src/containers/TldrawArticle/index.d.ts.map +1 -1
  50. package/dist/types/src/containers/TldrawCard/index.d.ts +1 -1
  51. package/dist/types/src/containers/TldrawCard/index.d.ts.map +1 -1
  52. package/dist/types/src/containers/index.d.ts.map +1 -1
  53. package/dist/types/src/hooks/index.d.ts +2 -2
  54. package/dist/types/src/hooks/index.d.ts.map +1 -1
  55. package/dist/types/src/hooks/useStoreAdapter.d.ts +1 -1
  56. package/dist/types/src/hooks/useStoreAdapter.d.ts.map +1 -1
  57. package/dist/types/src/index.d.ts +1 -2
  58. package/dist/types/src/index.d.ts.map +1 -1
  59. package/dist/types/src/migrations/index.d.ts +2 -2
  60. package/dist/types/src/migrations/index.d.ts.map +1 -1
  61. package/dist/types/src/model/RecordBuilder.d.ts +10 -0
  62. package/dist/types/src/model/RecordBuilder.d.ts.map +1 -1
  63. package/dist/types/src/model/builder.d.ts +4 -3
  64. package/dist/types/src/model/builder.d.ts.map +1 -1
  65. package/dist/types/src/model/index.d.ts +4 -4
  66. package/dist/types/src/model/index.d.ts.map +1 -1
  67. package/dist/types/src/model/read.d.ts +3 -3
  68. package/dist/types/src/model/read.d.ts.map +1 -1
  69. package/dist/types/src/model/render.d.ts +2 -2
  70. package/dist/types/src/model/render.d.ts.map +1 -1
  71. package/dist/types/src/testing/index.d.ts +1 -1
  72. package/dist/types/src/testing/index.d.ts.map +1 -1
  73. package/dist/types/src/translations.d.ts.map +1 -1
  74. package/dist/types/src/types/TldrawCapabilities.d.ts +2 -2
  75. package/dist/types/src/types/TldrawCapabilities.d.ts.map +1 -1
  76. package/dist/types/src/types/index.d.ts +4 -4
  77. package/dist/types/src/types/index.d.ts.map +1 -1
  78. package/dist/types/tsconfig.tsbuildinfo +1 -1
  79. package/package.json +41 -32
  80. package/src/capabilities/gen/browser.ts +42 -0
  81. package/src/capabilities/gen/node.ts +1 -1
  82. package/src/capabilities/gen/tauri.ts +42 -0
  83. package/src/capabilities/gen/workerd.ts +1 -1
  84. package/src/capabilities/index.ts +7 -3
  85. package/src/capabilities/settings.ts +2 -2
  86. package/src/components/Canvas/Canvas.stories.tsx +17 -15
  87. package/src/components/Canvas/Canvas.tsx +71 -10
  88. package/src/components/Canvas/Mermaid.stories.tsx +5 -5
  89. package/src/components/Canvas/UiSchematic.stories.tsx +74 -0
  90. package/src/components/Canvas/index.ts +2 -2
  91. package/src/components/Canvas/theme.css +11 -0
  92. package/src/components/custom/index.ts +5 -5
  93. package/src/components/index.ts +1 -1
  94. package/src/containers/TldrawArticle/TldrawArticle.tsx +31 -16
  95. package/src/containers/TldrawArticle/index.ts +1 -1
  96. package/src/containers/TldrawCard/TldrawCard.stories.tsx +1 -1
  97. package/src/containers/TldrawCard/TldrawCard.tsx +2 -2
  98. package/src/containers/TldrawCard/index.ts +1 -1
  99. package/src/containers/index.ts +2 -2
  100. package/src/hooks/index.ts +2 -2
  101. package/src/hooks/useStoreAdapter.ts +3 -3
  102. package/src/index.ts +1 -2
  103. package/src/meta.ts +1 -1
  104. package/src/migrations/index.ts +2 -2
  105. package/src/migrations/migrate.ts +1 -1
  106. package/src/model/RecordBuilder.test.ts +1 -1
  107. package/src/model/RecordBuilder.ts +19 -2
  108. package/src/model/builder.ts +6 -6
  109. package/src/model/index.ts +4 -4
  110. package/src/model/read.ts +3 -3
  111. package/src/model/render.ts +8 -4
  112. package/src/model/scene.test.ts +31 -3
  113. package/src/testing/index.ts +1 -1
  114. package/src/translations.ts +2 -2
  115. package/src/types/TldrawCapabilities.ts +2 -2
  116. package/src/types/index.ts +4 -4
  117. 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
- | `test` | `org.dxos.mdl.test@1.0` |
18
+ | `scenario` | `org.dxos.mdl.scenario@1.0` |
19
19
  | `component` | `org.dxos.mdl.component@1.0` |
20
- | `op` | `org.dxos.mdl.op@1.0` |
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
- desc: Creates a new Sketch with an associated Canvas and adds it to the target space or collection.
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
- schema?: string # tldraw schema version (default: tldraw.com/2)
125
- content?: Map<string, any> # optional initial tldraw store snapshot
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 object-local coordinates) read
134
- from the live canvas records, plus a count of unmanaged (hand-drawn) shapes.
135
- Origins derive from bounding boxes, so the scene stays coherent after users
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
- sketch: Ref<Sketch>
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 Obj.update): upsert/move/remove world
147
- objects or individual elements by id. Returns the resulting scene so 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
- sketch: Ref<Sketch>
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
- test T-1: Create and open sketch
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
- test T-2: Drawing persists across reload
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
- test T-3: Collaborative edit
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
- test T-4: Read-only slide role
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
- test T-5: Grid toggle
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
- test T-6: Attention-aware toolbar
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
- test T-7: Scene DSL round-trip
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
- test T-8: Conversational drawing (live AI)
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 test
375
- uri: org.dxos.mdl.test@1.0
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/unstable/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').Settings>>()(\n `${meta.profile.key}.capability.settings`,\n);\n"],"mappings":";;;;;AAcA,IAAa,WAAW,WAAW,cAA4D,CAAC,CAC9F,GAAG,KAAK,QAAQ,IAAI,qBACtB"}
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 { provides: [IllustratorCapabilities.VariantProvider], activatesOn: IllustratorEvents.Start, environments: [] },\n () => import('./drawing-variant'),\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'), {\n activatesOn: ActivationEvents.Idle,\n provides: [TldrawCapabilities.Settings],\n});\nexport const Translations = AppCapability.translations(translations);\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAa,iBAAiB,WAAW,WACvC,mBACA;CAAE,UAAU,CAAC,wBAAwB,eAAe;CAAG,aAAa,kBAAkB;CAAO,cAAc,CAAC;AAAE,SACxG,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,yBAAe;CAC/E,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AACD,IAAa,eAAe,cAAc,aAAa,YAAY"}
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,yBAAgB;CAChF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,iBAAiB,KAAA;AAC9B,IAAa,cAAc,KAAA"}
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,yBAAgB;CAChF,aAAa,iBAAiB;CAC9B,UAAU,CAAC,mBAAmB,QAAQ;AACxC,CAAC;AAED,IAAa,eAAe,cAAc,aAAa,YAAY;AAEnE,IAAa,iBAAiB,KAAA;AAC9B,IAAa,cAAc,KAAA"}
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 { Flex, Panel, composable, composableProps } from "@dxos/react-ui";
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 { useAtomCapability } from "@dxos/app-framework/ui";
9
- import { AppSurface, useAppGraph } from "@dxos/app-toolkit/ui";
10
- import { useActions } from "@dxos/plugin-graph/hooks";
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: 25,
23
+ L: 36,
21
24
  S: void 0,
22
25
  A: ["Obj.instanceOf(Drawing.Canvas, canvas)", ""]
23
26
  });
24
- const settings = useAtomCapability(TldrawCapabilities.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.Content, { children: props.children })
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 ? "h-full w-full" : "aspect-square", "overflow-hidden"] }),
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 { useAtomCapability } from '@dxos/app-framework/ui';\nimport { AppSurface, useAppGraph } from '@dxos/app-toolkit/ui';\nimport { Obj } from '@dxos/echo';\nimport { invariant } from '@dxos/invariant';\nimport { useActions } from '@dxos/plugin-graph/hooks';\nimport * as Drawing from '@dxos/plugin-illustrator/Drawing';\nimport * as IllustratorCapabilities from '@dxos/plugin-illustrator/IllustratorCapabilities';\nimport { Flex, Panel } from '@dxos/react-ui';\nimport { composable, composableProps } from '@dxos/react-ui';\nimport { useAttention } from '@dxos/react-ui-attention';\nimport { isTauri } from '@dxos/util';\n\nimport { CanvasComponent } from '#components';\nimport { TldrawCapabilities } from '#types';\n\nexport type TldrawArticleProps = IllustratorCapabilities.DrawingVariantSurfaceProps;\n\nexport const TldrawArticle = ({ role, attendableId, drawing, canvas, extrinsic }: TldrawArticleProps) => {\n invariant(Obj.instanceOf(Drawing.Canvas, canvas));\n const settings = useAtomCapability(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 } = useAppGraph();\n const actions = 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 // 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 {...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 = composable<HTMLDivElement, PropsWithChildren>((props, forwardedRef) => (\n <Panel.Root {...composableProps(props, { classNames: 'aspect-square' })} ref={forwardedRef}>\n <Panel.Content>{props.children}</Panel.Content>\n </Panel.Root>\n));\n\nconst Container = composable<HTMLDivElement, PropsWithChildren<{ fill?: boolean }>>(\n ({ fill, ...props }, forwardedRef) => (\n <Flex\n {...composableProps(props, { classNames: [fill ? 'h-full w-full' : 'aspect-square', 'overflow-hidden'] })}\n ref={forwardedRef}\n >\n {props.children}\n </Flex>\n ),\n);\n\nTldrawArticle.displayName = 'TldrawArticle';\n"],"mappings":";;;;;;;;;;;;;;;AAuBA,IAAa,iBAAiB,EAAE,MAAM,cAAc,SAAS,QAAQ,gBAAoC;CACvG,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,WAAW,kBAAkB,mBAAmB,QAAQ;CAC9D,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,YAAY;CAE9B,MAAM,qBADU,WAAW,OAAO,EACP,CAAA,CAAQ,MAAM,WAAW,OAAO,OAAO,GAAG,GAAG,SAAS,CAAC,EAAE;CAEpF,MAAM,UACJ,oBAAC,iBAAD;EAGE,YAAW;EACH;EACE;EAIV,QAAQ,UAAU,CAAC,eAAe,CAAC,gBAAgB,CAAC,QAAQ;EAC5D,gBAAgB;EAChB,GAAI;CACL,GAVM,EAUN;CAKH,OAAO,UAAU,oBAAC,WAAD;EAAW,MAAM;EAAY,UAAA;CAAmB,CAAA,IAAI,oBAAC,SAAD,EAAA,UAAU,QAAiB,CAAA;AAClG;AAEA,IAAM,UAAU,YAA+C,OAAO,iBACpE,oBAAC,MAAM,MAAP;CAAY,GAAI,gBAAgB,OAAO,EAAE,YAAY,gBAAgB,CAAC;CAAG,KAAK;CAC5E,UAAA,oBAAC,MAAM,SAAP,EAAA,UAAgB,MAAM,SAAwB,CAAA;AACpC,CAAA,CACb;AAED,IAAM,YAAY,YACf,EAAE,MAAM,GAAG,SAAS,iBACnB,oBAAC,MAAD;CACE,GAAI,gBAAgB,OAAO,EAAE,YAAY,CAAC,OAAO,kBAAkB,iBAAiB,iBAAiB,EAAE,CAAC;CACxG,KAAK;CAEJ,UAAA,MAAM;AACH,CAAA,CAEV;AAEA,cAAc,cAAc"}
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"}