@dxos/plugin-illustrator 0.10.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 (172) hide show
  1. package/LICENSE +105 -0
  2. package/PLUGIN.mdl +55 -0
  3. package/dist/lib/IllustratorPlugin.mjs +18 -0
  4. package/dist/lib/IllustratorPlugin.mjs.map +1 -0
  5. package/dist/lib/IllustratorPlugin.node.mjs +18 -0
  6. package/dist/lib/IllustratorPlugin.node.mjs.map +1 -0
  7. package/dist/lib/IllustratorPlugin.workerd.mjs +10 -0
  8. package/dist/lib/IllustratorPlugin.workerd.mjs.map +1 -0
  9. package/dist/lib/capabilities.mjs +11 -0
  10. package/dist/lib/capabilities.mjs.map +1 -0
  11. package/dist/lib/chunk-IllustratorCapabilities.mjs +16 -0
  12. package/dist/lib/chunk-IllustratorCapabilities.mjs.map +1 -0
  13. package/dist/lib/chunk-comment-config.mjs +16 -0
  14. package/dist/lib/chunk-comment-config.mjs.map +1 -0
  15. package/dist/lib/chunk-create-object.mjs +46 -0
  16. package/dist/lib/chunk-create-object.mjs.map +1 -0
  17. package/dist/lib/chunk-create.mjs +20 -0
  18. package/dist/lib/chunk-create.mjs.map +1 -0
  19. package/dist/lib/chunk-edit.mjs +20 -0
  20. package/dist/lib/chunk-edit.mjs.map +1 -0
  21. package/dist/lib/chunk-load-sketch.mjs +64 -0
  22. package/dist/lib/chunk-load-sketch.mjs.map +1 -0
  23. package/dist/lib/chunk-meta.mjs +40 -0
  24. package/dist/lib/chunk-meta.mjs.map +1 -0
  25. package/dist/lib/chunk-model.mjs +202 -0
  26. package/dist/lib/chunk-model.mjs.map +1 -0
  27. package/dist/lib/chunk-operation-handler.mjs +11 -0
  28. package/dist/lib/chunk-operation-handler.mjs.map +1 -0
  29. package/dist/lib/chunk-react-surface.mjs +31 -0
  30. package/dist/lib/chunk-react-surface.mjs.map +1 -0
  31. package/dist/lib/chunk-read.mjs +13 -0
  32. package/dist/lib/chunk-read.mjs.map +1 -0
  33. package/dist/lib/chunk-rolldown-runtime.mjs +13 -0
  34. package/dist/lib/chunk-skill-definition.mjs +10 -0
  35. package/dist/lib/chunk-skill-definition.mjs.map +1 -0
  36. package/dist/lib/chunk-skills.mjs +65 -0
  37. package/dist/lib/chunk-skills.mjs.map +1 -0
  38. package/dist/lib/chunk-types.mjs +108 -0
  39. package/dist/lib/chunk-types.mjs.map +1 -0
  40. package/dist/lib/components.mjs +45 -0
  41. package/dist/lib/components.mjs.map +1 -0
  42. package/dist/lib/containers.mjs +58 -0
  43. package/dist/lib/containers.mjs.map +1 -0
  44. package/dist/lib/index.mjs +9 -0
  45. package/dist/lib/meta.mjs +2 -0
  46. package/dist/lib/model.mjs +2 -0
  47. package/dist/lib/operations.mjs +7 -0
  48. package/dist/lib/operations.mjs.map +1 -0
  49. package/dist/lib/plugin.mjs +9 -0
  50. package/dist/lib/plugin.mjs.map +1 -0
  51. package/dist/lib/skills.mjs +2 -0
  52. package/dist/lib/translations.mjs +27 -0
  53. package/dist/lib/translations.mjs.map +1 -0
  54. package/dist/lib/types.mjs +3 -0
  55. package/dist/lib/util.mjs +2 -0
  56. package/dist/types/dx.config.d.ts +28 -0
  57. package/dist/types/dx.config.d.ts.map +1 -0
  58. package/dist/types/src/IllustratorPlugin.d.ts +4 -0
  59. package/dist/types/src/IllustratorPlugin.d.ts.map +1 -0
  60. package/dist/types/src/IllustratorPlugin.node.d.ts +10 -0
  61. package/dist/types/src/IllustratorPlugin.node.d.ts.map +1 -0
  62. package/dist/types/src/IllustratorPlugin.workerd.d.ts +4 -0
  63. package/dist/types/src/IllustratorPlugin.workerd.d.ts.map +1 -0
  64. package/dist/types/src/capabilities/comment-config.d.ts +5 -0
  65. package/dist/types/src/capabilities/comment-config.d.ts.map +1 -0
  66. package/dist/types/src/capabilities/create-object.d.ts +5 -0
  67. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  68. package/dist/types/src/capabilities/index.d.ts +8 -0
  69. package/dist/types/src/capabilities/index.d.ts.map +1 -0
  70. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  71. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  72. package/dist/types/src/capabilities/react-surface.d.ts +5 -0
  73. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -0
  74. package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
  75. package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
  76. package/dist/types/src/components/CreateSketchPanel.d.ts +15 -0
  77. package/dist/types/src/components/CreateSketchPanel.d.ts.map +1 -0
  78. package/dist/types/src/components/index.d.ts +2 -0
  79. package/dist/types/src/components/index.d.ts.map +1 -0
  80. package/dist/types/src/containers/SketchArticle/SketchArticle.d.ts +11 -0
  81. package/dist/types/src/containers/SketchArticle/SketchArticle.d.ts.map +1 -0
  82. package/dist/types/src/containers/SketchArticle/index.d.ts +2 -0
  83. package/dist/types/src/containers/SketchArticle/index.d.ts.map +1 -0
  84. package/dist/types/src/containers/SketchCard/SketchCard.d.ts +10 -0
  85. package/dist/types/src/containers/SketchCard/SketchCard.d.ts.map +1 -0
  86. package/dist/types/src/containers/SketchCard/index.d.ts +2 -0
  87. package/dist/types/src/containers/SketchCard/index.d.ts.map +1 -0
  88. package/dist/types/src/containers/index.d.ts +3 -0
  89. package/dist/types/src/containers/index.d.ts.map +1 -0
  90. package/dist/types/src/index.d.ts +7 -0
  91. package/dist/types/src/index.d.ts.map +1 -0
  92. package/dist/types/src/meta.d.ts +33 -0
  93. package/dist/types/src/meta.d.ts.map +1 -0
  94. package/dist/types/src/model/builder.d.ts +32 -0
  95. package/dist/types/src/model/builder.d.ts.map +1 -0
  96. package/dist/types/src/model/dialect.d.ts +19 -0
  97. package/dist/types/src/model/dialect.d.ts.map +1 -0
  98. package/dist/types/src/model/index.d.ts +4 -0
  99. package/dist/types/src/model/index.d.ts.map +1 -0
  100. package/dist/types/src/model/scene.d.ts +843 -0
  101. package/dist/types/src/model/scene.d.ts.map +1 -0
  102. package/dist/types/src/operations/create.d.ts +5 -0
  103. package/dist/types/src/operations/create.d.ts.map +1 -0
  104. package/dist/types/src/operations/edit.d.ts +5 -0
  105. package/dist/types/src/operations/edit.d.ts.map +1 -0
  106. package/dist/types/src/operations/index.d.ts +3 -0
  107. package/dist/types/src/operations/index.d.ts.map +1 -0
  108. package/dist/types/src/operations/read.d.ts +5 -0
  109. package/dist/types/src/operations/read.d.ts.map +1 -0
  110. package/dist/types/src/plugin.d.ts +4 -0
  111. package/dist/types/src/plugin.d.ts.map +1 -0
  112. package/dist/types/src/skills/index.d.ts +2 -0
  113. package/dist/types/src/skills/index.d.ts.map +1 -0
  114. package/dist/types/src/skills/sketch-skill.d.ts +4 -0
  115. package/dist/types/src/skills/sketch-skill.d.ts.map +1 -0
  116. package/dist/types/src/translations.d.ts +34 -0
  117. package/dist/types/src/translations.d.ts.map +1 -0
  118. package/dist/types/src/types/IllustratorCapabilities.d.ts +10 -0
  119. package/dist/types/src/types/IllustratorCapabilities.d.ts.map +1 -0
  120. package/dist/types/src/types/Sketch.d.ts +50 -0
  121. package/dist/types/src/types/Sketch.d.ts.map +1 -0
  122. package/dist/types/src/types/SketchOperation.d.ts +427 -0
  123. package/dist/types/src/types/SketchOperation.d.ts.map +1 -0
  124. package/dist/types/src/types/index.d.ts +5 -0
  125. package/dist/types/src/types/index.d.ts.map +1 -0
  126. package/dist/types/src/types/types.d.ts +45 -0
  127. package/dist/types/src/types/types.d.ts.map +1 -0
  128. package/dist/types/src/util/index.d.ts +2 -0
  129. package/dist/types/src/util/index.d.ts.map +1 -0
  130. package/dist/types/src/util/load-sketch.d.ts +37 -0
  131. package/dist/types/src/util/load-sketch.d.ts.map +1 -0
  132. package/dist/types/tsconfig.tsbuildinfo +1 -0
  133. package/dx.config.ts +35 -0
  134. package/package.json +144 -0
  135. package/src/IllustratorPlugin.node.tsx +27 -0
  136. package/src/IllustratorPlugin.tsx +30 -0
  137. package/src/IllustratorPlugin.workerd.tsx +16 -0
  138. package/src/capabilities/comment-config.ts +20 -0
  139. package/src/capabilities/create-object.ts +66 -0
  140. package/src/capabilities/index.ts +15 -0
  141. package/src/capabilities/operation-handler.ts +16 -0
  142. package/src/capabilities/react-surface.tsx +37 -0
  143. package/src/capabilities/skill-definition.ts +14 -0
  144. package/src/components/CreateSketchPanel.tsx +68 -0
  145. package/src/components/index.ts +5 -0
  146. package/src/containers/SketchArticle/SketchArticle.tsx +48 -0
  147. package/src/containers/SketchArticle/index.ts +5 -0
  148. package/src/containers/SketchCard/SketchCard.tsx +41 -0
  149. package/src/containers/SketchCard/index.ts +5 -0
  150. package/src/containers/index.ts +6 -0
  151. package/src/index.ts +10 -0
  152. package/src/meta.ts +9 -0
  153. package/src/model/builder.ts +41 -0
  154. package/src/model/dialect.ts +53 -0
  155. package/src/model/index.ts +7 -0
  156. package/src/model/scene.ts +208 -0
  157. package/src/operations/create.ts +27 -0
  158. package/src/operations/edit.ts +23 -0
  159. package/src/operations/index.ts +11 -0
  160. package/src/operations/read.ts +21 -0
  161. package/src/plugin.ts +11 -0
  162. package/src/skills/index.ts +5 -0
  163. package/src/skills/sketch-skill.ts +70 -0
  164. package/src/translations.ts +33 -0
  165. package/src/types/IllustratorCapabilities.ts +19 -0
  166. package/src/types/Sketch.ts +69 -0
  167. package/src/types/SketchOperation.ts +76 -0
  168. package/src/types/index.ts +9 -0
  169. package/src/types/types.ts +53 -0
  170. package/src/util/index.ts +5 -0
  171. package/src/util/load-sketch.ts +74 -0
  172. package/src/vite-env.d.ts +10 -0
package/dx.config.ts ADDED
@@ -0,0 +1,35 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Config2 } from '@dxos/app-framework/config';
6
+ import { trim } from '@dxos/util';
7
+
8
+ export default Config2.make({
9
+ plugin: {
10
+ key: 'org.dxos.plugin.illustrator',
11
+ name: 'Illustrator',
12
+ author: 'DXOS',
13
+ description: trim`
14
+ Headless diagramming host plugin that provides shared infrastructure for local-first
15
+ drawing and diagramming inside DXOS Composer. The plugin owns the base \`Sketch\` ECHO
16
+ type — a named handle referencing a renderer-specific canvas object — together with the
17
+ renderer-neutral scene DSL, the diagram dialect registry, and the agent-facing sketch
18
+ skill and operations (create, read, edit).
19
+
20
+ Canvas renderers (tldraw, excalidraw, and others) are contributed by separate plugins
21
+ via the \`IllustratorCapabilities.VariantProvider\` capability. Each variant supplies its
22
+ own canvas schema, a builder that maps the scene DSL onto its records, and surface
23
+ components (Article and Card). Plugin-illustrator resolves the correct variant at
24
+ runtime and delegates rendering and DSL compilation, keeping the host layer fully
25
+ decoupled from renderer internals.
26
+
27
+ Canvas objects are stored as hidden ECHO objects alongside the top-level \`Sketch\`,
28
+ ensuring they replicate to all peers but do not appear as independent items in the
29
+ user's space graph.
30
+ `,
31
+ source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-illustrator',
32
+ icon: { key: 'ph--compass-tool--regular', hue: 'indigo' },
33
+ spec: 'PLUGIN.mdl',
34
+ },
35
+ });
package/package.json ADDED
@@ -0,0 +1,144 @@
1
+ {
2
+ "name": "@dxos/plugin-illustrator",
3
+ "version": "0.10.0",
4
+ "description": "Headless diagramming plugin for DXOS Composer (unifies canvas renderers like tldraw and excalidraw).",
5
+ "homepage": "https://dxos.org",
6
+ "bugs": "https://github.com/dxos/dxos/issues",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/dxos/dxos"
10
+ },
11
+ "license": "FSL-1.1-Apache-2.0",
12
+ "author": "DXOS.org",
13
+ "sideEffects": true,
14
+ "type": "module",
15
+ "imports": {
16
+ "#capabilities": {
17
+ "source": "./src/capabilities/index.ts",
18
+ "types": "./dist/types/src/capabilities/index.d.ts",
19
+ "default": "./dist/lib/capabilities.mjs"
20
+ },
21
+ "#components": {
22
+ "source": "./src/components/index.ts",
23
+ "types": "./dist/types/src/components/index.d.ts",
24
+ "default": "./dist/lib/components.mjs"
25
+ },
26
+ "#containers": {
27
+ "source": "./src/containers/index.ts",
28
+ "types": "./dist/types/src/containers/index.d.ts",
29
+ "default": "./dist/lib/containers.mjs"
30
+ },
31
+ "#meta": {
32
+ "source": "./src/meta.ts",
33
+ "types": "./dist/types/src/meta.d.ts",
34
+ "default": "./dist/lib/meta.mjs"
35
+ },
36
+ "#model": {
37
+ "source": "./src/model/index.ts",
38
+ "types": "./dist/types/src/model/index.d.ts",
39
+ "default": "./dist/lib/model.mjs"
40
+ },
41
+ "#operations": {
42
+ "source": "./src/operations/index.ts",
43
+ "types": "./dist/types/src/operations/index.d.ts",
44
+ "default": "./dist/lib/operations.mjs"
45
+ },
46
+ "#plugin": {
47
+ "source": {
48
+ "workerd": "./src/IllustratorPlugin.workerd.tsx",
49
+ "node": "./src/IllustratorPlugin.node.tsx",
50
+ "default": "./src/IllustratorPlugin.tsx"
51
+ },
52
+ "types": "./dist/types/src/IllustratorPlugin.d.ts",
53
+ "workerd": "./dist/lib/IllustratorPlugin.workerd.mjs",
54
+ "node": "./dist/lib/IllustratorPlugin.node.mjs",
55
+ "default": "./dist/lib/IllustratorPlugin.mjs"
56
+ },
57
+ "#skills": {
58
+ "source": "./src/skills/index.ts",
59
+ "types": "./dist/types/src/skills/index.d.ts",
60
+ "default": "./dist/lib/skills.mjs"
61
+ },
62
+ "#translations": {
63
+ "source": "./src/translations.ts",
64
+ "types": "./dist/types/src/translations.d.ts",
65
+ "default": "./dist/lib/translations.mjs"
66
+ },
67
+ "#types": {
68
+ "source": "./src/types/index.ts",
69
+ "types": "./dist/types/src/types/index.d.ts",
70
+ "default": "./dist/lib/types.mjs"
71
+ },
72
+ "#util": "./src/util/index.ts"
73
+ },
74
+ "exports": {
75
+ ".": {
76
+ "source": "./src/index.ts",
77
+ "types": "./dist/types/src/index.d.ts",
78
+ "import": "./dist/lib/index.mjs"
79
+ },
80
+ "./assets/PLUGIN.mdl": "./PLUGIN.mdl",
81
+ "./model": {
82
+ "source": "./src/model/index.ts",
83
+ "types": "./dist/types/src/model/index.d.ts",
84
+ "import": "./dist/lib/model.mjs"
85
+ },
86
+ "./plugin": {
87
+ "source": "./src/plugin.ts",
88
+ "types": "./dist/types/src/plugin.d.ts",
89
+ "import": "./dist/lib/plugin.mjs"
90
+ },
91
+ "./translations": {
92
+ "source": "./src/translations.ts",
93
+ "types": "./dist/types/src/translations.d.ts",
94
+ "import": "./dist/lib/translations.mjs"
95
+ },
96
+ "./types": {
97
+ "source": "./src/types/index.ts",
98
+ "types": "./dist/types/src/types/index.d.ts",
99
+ "import": "./dist/lib/types.mjs"
100
+ }
101
+ },
102
+ "types": "dist/types/src/index.d.ts",
103
+ "files": [
104
+ "dist",
105
+ "dx.config.ts",
106
+ "src",
107
+ "PLUGIN.mdl"
108
+ ],
109
+ "dependencies": {
110
+ "effect": "3.21.4",
111
+ "@dxos/app-framework": "0.10.0",
112
+ "@dxos/app-toolkit": "0.10.0",
113
+ "@dxos/compute": "0.10.0",
114
+ "@dxos/echo": "0.10.0",
115
+ "@dxos/echo-react": "0.10.0",
116
+ "@dxos/invariant": "0.10.0",
117
+ "@dxos/log": "0.10.0",
118
+ "@dxos/keys": "0.10.0",
119
+ "@dxos/plugin-space": "0.10.0",
120
+ "@dxos/react-ui": "0.10.0",
121
+ "@dxos/react-ui-search": "0.10.0",
122
+ "@dxos/util": "0.10.0",
123
+ "@dxos/schema": "0.10.0",
124
+ "@dxos/react-ui-form": "0.10.0"
125
+ },
126
+ "devDependencies": {
127
+ "@types/react": "~19.2.17",
128
+ "@types/react-dom": "~19.2.3",
129
+ "react": "~19.2.7",
130
+ "react-dom": "~19.2.7",
131
+ "vite": "^8.1.4",
132
+ "@dxos/ui-theme": "0.10.0",
133
+ "@dxos/plugin-testing": "0.10.0"
134
+ },
135
+ "peerDependencies": {
136
+ "react": "~19.2.7",
137
+ "react-dom": "~19.2.7",
138
+ "@dxos/react-ui": "^0.10.0",
139
+ "@dxos/ui-theme": "^0.10.0"
140
+ },
141
+ "publishConfig": {
142
+ "access": "public"
143
+ }
144
+ }
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+ import { AppPlugin } from '@dxos/app-toolkit';
7
+
8
+ import { OperationHandler, SkillDefinition } from '#capabilities';
9
+ import { meta } from '#meta';
10
+ import { translations } from '#translations';
11
+ import { Sketch } from '#types';
12
+
13
+ /**
14
+ * Headless variant of IllustratorPlugin (no React surfaces / CreateObject panel).
15
+ * Used in node contexts (CLI, agents, tests) where rendering is unavailable —
16
+ * the full variant lazy-loads `CreateSketchPanel` from `react-ui-search` which
17
+ * downstream bundlers don't resolve cleanly under nested pnpm symlinks.
18
+ */
19
+ export const IllustratorPlugin = Plugin.define(meta).pipe(
20
+ AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
21
+ AppPlugin.addSchemaModule({ schema: [Sketch.Sketch] }),
22
+ AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
23
+ AppPlugin.addTranslationsModule({ translations }),
24
+ Plugin.make,
25
+ );
26
+
27
+ export default IllustratorPlugin;
@@ -0,0 +1,30 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+ import { AppPlugin } from '@dxos/app-toolkit';
7
+
8
+ import { CommentConfig, CreateObject, OperationHandler, ReactSurface, SkillDefinition } from '#capabilities';
9
+ import { meta } from '#meta';
10
+ import { translations } from '#translations';
11
+ import { Sketch } from '#types';
12
+
13
+ // eslint-disable-next-line import/no-relative-packages
14
+ import pluginSpec from '../PLUGIN.mdl?raw';
15
+
16
+ export const IllustratorPlugin = Plugin.define(meta).pipe(
17
+ AppPlugin.addCommentConfigModule({ activate: CommentConfig }),
18
+ AppPlugin.addCreateObjectModule({ activate: CreateObject }),
19
+ AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
20
+ AppPlugin.addSchemaModule({ schema: [Sketch.Sketch] }),
21
+ AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
22
+ AppPlugin.addSurfaceModule({ activate: ReactSurface }),
23
+ AppPlugin.addTranslationsModule({ translations }),
24
+ AppPlugin.addPluginAssetModule({
25
+ asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
26
+ }),
27
+ Plugin.make,
28
+ );
29
+
30
+ export default IllustratorPlugin;
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+ import { AppPlugin } from '@dxos/app-toolkit';
7
+
8
+ import { meta } from '#meta';
9
+ import { Sketch } from '#types';
10
+
11
+ export const IllustratorPlugin = Plugin.define(meta).pipe(
12
+ AppPlugin.addSchemaModule({ schema: [Sketch.Sketch] }),
13
+ Plugin.make,
14
+ );
15
+
16
+ export default IllustratorPlugin;
@@ -0,0 +1,20 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+ import { Type } from '@dxos/echo';
10
+
11
+ import { Sketch } from '#types';
12
+
13
+ const activate = Effect.fnUntraced(function* () {
14
+ return Capability.contributes(AppCapabilities.CommentConfig, {
15
+ id: Type.getTypename(Sketch.Sketch),
16
+ comments: 'unanchored',
17
+ });
18
+ });
19
+
20
+ export default activate;
@@ -0,0 +1,66 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { Operation } from '@dxos/compute';
9
+ import { Database, Type } from '@dxos/echo';
10
+ import { invariant } from '@dxos/invariant';
11
+ import { SpaceCapabilities, SpaceOperation } from '@dxos/plugin-space';
12
+
13
+ import { CreateSketchPanel } from '#components';
14
+
15
+ import { IllustratorCapabilities, Sketch } from '../types';
16
+
17
+ type CreateOptions = Parameters<SpaceCapabilities.CreateObjectEntry['createObject']>[1];
18
+
19
+ export default Capability.makeModule(
20
+ Effect.fnUntraced(function* () {
21
+ return Capability.contributes(SpaceCapabilities.CreateObjectEntry, {
22
+ id: Type.getTypename(Sketch.Sketch),
23
+ customPanel: CreateSketchPanel,
24
+ createObject: (
25
+ { variantId, input }: { variantId: string; input?: Record<string, any> },
26
+ options: CreateOptions,
27
+ ) =>
28
+ Effect.gen(function* () {
29
+ const variants = yield* Capability.getAll(IllustratorCapabilities.VariantProvider);
30
+ const variant = variants.find((entry) => entry.id === variantId);
31
+ invariant(variant, `Unknown sketch variant: ${variantId}`);
32
+
33
+ // Build the canvas object via the variant's factory.
34
+ const canvas = yield* variant
35
+ .createCanvas(input ?? {})
36
+ .pipe(Effect.provideService(Database.Service, Database.makeService(options.db)));
37
+
38
+ // Add the canvas to the database. Stays hidden — it's referenced by the Sketch and
39
+ // shouldn't appear as a top-level item in the user's space.
40
+ yield* Operation.invoke(SpaceOperation.AddObject, {
41
+ object: canvas,
42
+ target: options.target,
43
+ targetNodeId: options.targetNodeId,
44
+ });
45
+
46
+ const sketch = Sketch.make({
47
+ name: typeof input?.name === 'string' ? input.name : undefined,
48
+ canvas,
49
+ });
50
+
51
+ // Add the user-facing Sketch wrapper. Not hidden — this is the object the user sees
52
+ // and navigates to. If this second write fails, roll back the canvas so we don't
53
+ // leak an orphaned object into the space.
54
+ return yield* Operation.invoke(SpaceOperation.AddObject, {
55
+ object: sketch,
56
+ target: options.target,
57
+ targetNodeId: options.targetNodeId,
58
+ }).pipe(
59
+ Effect.tapError(() =>
60
+ Operation.invoke(SpaceOperation.RemoveObjects, { objects: [canvas] }).pipe(Effect.ignore),
61
+ ),
62
+ );
63
+ }),
64
+ });
65
+ }),
66
+ );
@@ -0,0 +1,15 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Capability } from '@dxos/app-framework';
6
+ import { OperationHandlerSet } from '@dxos/compute';
7
+
8
+ export const CommentConfig = Capability.lazy('CommentConfig', () => import('./comment-config'));
9
+ export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
10
+ export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
11
+ 'OperationHandler',
12
+ () => import('./operation-handler'),
13
+ );
14
+ export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
15
+ export const SkillDefinition = Capability.lazy('SkillDefinition', () => import('./skill-definition'));
@@ -0,0 +1,16 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capabilities, Capability } from '@dxos/app-framework';
8
+ import type { OperationHandlerSet } from '@dxos/compute';
9
+
10
+ import { IllustratorOperationHandlerSet } from '#operations';
11
+
12
+ export default Capability.makeModule<OperationHandlerSet.OperationHandlerSet>(
13
+ Effect.fnUntraced(function* () {
14
+ return Capability.contributes(Capabilities.OperationHandler, IllustratorOperationHandlerSet);
15
+ }),
16
+ );
@@ -0,0 +1,37 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+ import React from 'react';
7
+
8
+ import { Capabilities, Capability } from '@dxos/app-framework';
9
+ import { Surface } from '@dxos/app-framework/ui';
10
+ import { AppSurface } from '@dxos/app-toolkit/ui';
11
+
12
+ import { SketchArticle, SketchCard } from '#containers';
13
+
14
+ import { Sketch } from '../types';
15
+
16
+ export default Capability.makeModule(() =>
17
+ Effect.succeed(
18
+ Capability.contributes(Capabilities.ReactSurface, [
19
+ Surface.create({
20
+ id: 'sketch',
21
+ filter: AppSurface.oneOf(
22
+ AppSurface.object(AppSurface.Article, Sketch.Sketch),
23
+ AppSurface.object(AppSurface.Section, Sketch.Sketch),
24
+ AppSurface.object(AppSurface.Slide, Sketch.Sketch),
25
+ ),
26
+ component: ({ data: { subject, attendableId, extrinsic }, role }) => (
27
+ <SketchArticle role={role} subject={subject} attendableId={attendableId} extrinsic={extrinsic} />
28
+ ),
29
+ }),
30
+ Surface.create({
31
+ id: 'sketchCard',
32
+ filter: AppSurface.object(AppSurface.CardContent, Sketch.Sketch),
33
+ component: ({ data, role }) => <SketchCard role={role} subject={data.subject} editable={data.editable} />,
34
+ }),
35
+ ]),
36
+ ),
37
+ );
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import * as Effect from 'effect/Effect';
6
+
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+
10
+ import { SketchSkill } from '#skills';
11
+
12
+ const skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition, SketchSkill)]);
13
+
14
+ export default skillDefinition;
@@ -0,0 +1,68 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React, { useCallback, useMemo } from 'react';
6
+
7
+ import { useCapabilities } from '@dxos/app-framework/ui';
8
+ import { type SpaceCapabilities } from '@dxos/plugin-space';
9
+ import { useTranslation } from '@dxos/react-ui';
10
+ import { SearchList, useSearchListResults } from '@dxos/react-ui-search';
11
+
12
+ import { meta } from '#meta';
13
+ import { IllustratorCapabilities, type SketchVariant } from '#types';
14
+
15
+ export type CreateSketchPanelProps = SpaceCapabilities.CreateObjectCustomPanelProps & {
16
+ /** Optional override (primarily for stories/tests). Defaults to IllustratorCapabilities.VariantProvider. */
17
+ variants?: SketchVariant[];
18
+ };
19
+
20
+ /**
21
+ * Variant picker for sketches (SearchList over contributed `SketchVariant[]`).
22
+ * On select, calls `onCreateObject({ variantId })`; plugin-illustrator's
23
+ * CreateObjectEntry.createObject resolves the variantId, builds the canvas via
24
+ * variant.createCanvas, then wraps it in a Sketch.
25
+ */
26
+ export const CreateSketchPanel = ({ onCreateObject, variants: variantsProp }: CreateSketchPanelProps) => {
27
+ const { t } = useTranslation(meta.profile.key);
28
+ const capabilityVariants = useCapabilities(IllustratorCapabilities.VariantProvider);
29
+ const variants = variantsProp ?? capabilityVariants;
30
+ const sorted = useMemo(() => [...variants].sort((a, b) => a.label.localeCompare(b.label)), [variants]);
31
+ const { results, handleSearch } = useSearchListResults({
32
+ items: sorted,
33
+ extract: (variant) => variant.label,
34
+ });
35
+
36
+ const handleSelect = useCallback(
37
+ (id: string) => {
38
+ const variant = variants.find((entry) => entry.id === id);
39
+ if (!variant) {
40
+ return;
41
+ }
42
+ void onCreateObject({ variantId: id });
43
+ },
44
+ [variants, onCreateObject],
45
+ );
46
+
47
+ return (
48
+ <SearchList.Root onSearch={handleSearch}>
49
+ <SearchList.Input
50
+ classNames='mb-form-gap'
51
+ autoFocus
52
+ data-testid='create-sketch-panel.variant-input'
53
+ placeholder={t('create-panel.variant.placeholder')}
54
+ />
55
+ <SearchList.Viewport>
56
+ {results.map((variant) => (
57
+ <SearchList.Item
58
+ key={variant.id}
59
+ value={variant.id}
60
+ label={variant.label}
61
+ icon={variant.icon ?? 'ph--compass-tool--regular'}
62
+ onSelect={() => handleSelect(variant.id)}
63
+ />
64
+ ))}
65
+ </SearchList.Viewport>
66
+ </SearchList.Root>
67
+ );
68
+ };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './CreateSketchPanel';
@@ -0,0 +1,48 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useCapabilities } from '@dxos/app-framework/ui';
8
+ import { type AppSurface } from '@dxos/app-toolkit/ui';
9
+ import { Obj, type Ref } from '@dxos/echo';
10
+ import { useObject } from '@dxos/echo-react';
11
+ import { useTranslation } from '@dxos/react-ui';
12
+
13
+ import { meta } from '#meta';
14
+ import { IllustratorCapabilities, type Sketch } from '#types';
15
+
16
+ export type SketchArticleProps = AppSurface.ObjectArticleProps<Sketch.Sketch> & {
17
+ extrinsic?: boolean;
18
+ };
19
+
20
+ /** Resolves the sketch's canvas and delegates rendering to the matching variant's article. */
21
+ export const SketchArticle = ({ role, attendableId, subject: sketch, extrinsic }: SketchArticleProps) => {
22
+ const { t } = useTranslation(meta.profile.key);
23
+ const variants = useCapabilities(IllustratorCapabilities.VariantProvider);
24
+ const ref = sketch.canvas as Ref.Ref<Obj.Unknown>;
25
+ // Subscribe via the snapshot for load/re-render, but hand variants the LIVE object —
26
+ // their store adapters need `Doc.createAccessor`, which rejects snapshots.
27
+ const [snapshot] = useObject(ref);
28
+ const canvas = snapshot ? ref.target : undefined;
29
+
30
+ if (!canvas) {
31
+ return null;
32
+ }
33
+
34
+ const typename = Obj.getTypename(canvas);
35
+ const match = variants.find((variant) => variant.id === typename);
36
+ if (!match?.article) {
37
+ return (
38
+ <div className='p-4 text-sm'>
39
+ {t('unsupported-variant.label', { defaultValue: 'Unsupported sketch variant' })}
40
+ </div>
41
+ );
42
+ }
43
+
44
+ const Component = match.article;
45
+ return <Component sketch={sketch} canvas={canvas} role={role} attendableId={attendableId} extrinsic={extrinsic} />;
46
+ };
47
+
48
+ SketchArticle.displayName = 'SketchArticle';
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './SketchArticle';
@@ -0,0 +1,41 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import React from 'react';
6
+
7
+ import { useCapabilities } from '@dxos/app-framework/ui';
8
+ import { type AppSurface } from '@dxos/app-toolkit/ui';
9
+ import { Obj, type Ref } from '@dxos/echo';
10
+ import { useObject } from '@dxos/echo-react';
11
+
12
+ import { IllustratorCapabilities, type Sketch } from '#types';
13
+
14
+ export type SketchCardProps = AppSurface.ObjectCardProps<Sketch.Sketch>;
15
+
16
+ /** Resolves the sketch's canvas and delegates rendering to the matching variant's card. */
17
+ export const SketchCard = ({ role, subject: sketch, editable }: SketchCardProps) => {
18
+ const variants = useCapabilities(IllustratorCapabilities.VariantProvider);
19
+ const ref = sketch.canvas as Ref.Ref<Obj.Unknown>;
20
+ // Subscribe via the snapshot for load/re-render, but hand variants the LIVE object —
21
+ // their store adapters need `Doc.createAccessor`, which rejects snapshots.
22
+ const [snapshot] = useObject(ref);
23
+ const canvas = snapshot ? ref.target : undefined;
24
+
25
+ if (!canvas) {
26
+ return null;
27
+ }
28
+
29
+ const typename = Obj.getTypename(canvas);
30
+ const match = variants.find((variant) => variant.id === typename);
31
+ if (!match?.card) {
32
+ return null;
33
+ }
34
+
35
+ const Component = match.card;
36
+ return <Component sketch={sketch} canvas={canvas} role={role} editable={editable} />;
37
+ };
38
+
39
+ SketchCard.displayName = 'SketchCard';
40
+
41
+ export default SketchCard;
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './SketchCard';
@@ -0,0 +1,6 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './SketchArticle';
6
+ export * from './SketchCard';
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export * from './meta';
6
+ export * as IllustratorModel from './model';
7
+ export * from './operations';
8
+ export * from './skills';
9
+ export * from './types';
10
+ export * from './util';
package/src/meta.ts ADDED
@@ -0,0 +1,9 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ import { Plugin } from '@dxos/app-framework';
6
+
7
+ import config from '../dx.config';
8
+
9
+ export const meta = Plugin.getMetaFromConfig(config);