@dxos/plugin-kanban 0.8.4-main.ae835ea → 0.8.4-main.bc2380dfbc

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 (282) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/KanbanArticle-NEJ3LNBO.mjs +132 -0
  4. package/dist/lib/neutral/KanbanArticle-NEJ3LNBO.mjs.map +7 -0
  5. package/dist/lib/neutral/KanbanPlugin.mjs +36 -0
  6. package/dist/lib/neutral/KanbanPlugin.mjs.map +7 -0
  7. package/dist/lib/neutral/KanbanPlugin.node.mjs +27 -0
  8. package/dist/lib/neutral/KanbanPlugin.node.mjs.map +7 -0
  9. package/dist/lib/neutral/KanbanPlugin.workerd.mjs +21 -0
  10. package/dist/lib/neutral/KanbanPlugin.workerd.mjs.map +7 -0
  11. package/dist/lib/neutral/KanbanSettings-G6M47NSK.mjs +83 -0
  12. package/dist/lib/neutral/KanbanSettings-G6M47NSK.mjs.map +7 -0
  13. package/dist/lib/neutral/blueprint-definition-FHVIEKTQ.mjs +15 -0
  14. package/dist/lib/neutral/blueprint-definition-FHVIEKTQ.mjs.map +7 -0
  15. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  16. package/dist/lib/neutral/capabilities/index.mjs +19 -0
  17. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  18. package/dist/lib/neutral/chunk-6FPBLOS3.mjs +8 -0
  19. package/dist/lib/neutral/chunk-6FPBLOS3.mjs.map +7 -0
  20. package/dist/lib/neutral/chunk-J5LGTIGS.mjs +10 -0
  21. package/dist/lib/neutral/chunk-KDPM77BD.mjs +21 -0
  22. package/dist/lib/neutral/chunk-KDPM77BD.mjs.map +7 -0
  23. package/dist/lib/neutral/chunk-OQ72EEGU.mjs +254 -0
  24. package/dist/lib/neutral/chunk-OQ72EEGU.mjs.map +7 -0
  25. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs +26 -0
  26. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs.map +7 -0
  27. package/dist/lib/neutral/components/index.mjs +243 -0
  28. package/dist/lib/neutral/components/index.mjs.map +7 -0
  29. package/dist/lib/neutral/containers/index.mjs +11 -0
  30. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  31. package/dist/lib/neutral/create-object-DKBSI46K.mjs +40 -0
  32. package/dist/lib/neutral/create-object-DKBSI46K.mjs.map +7 -0
  33. package/dist/lib/neutral/delete-card-356CBACE.mjs +24 -0
  34. package/dist/lib/neutral/delete-card-356CBACE.mjs.map +7 -0
  35. package/dist/lib/neutral/delete-card-field-IRCZL2BR.mjs +42 -0
  36. package/dist/lib/neutral/delete-card-field-IRCZL2BR.mjs.map +7 -0
  37. package/dist/lib/neutral/hooks/index.mjs +432 -0
  38. package/dist/lib/neutral/hooks/index.mjs.map +7 -0
  39. package/dist/lib/neutral/index.mjs +34 -0
  40. package/dist/lib/neutral/index.mjs.map +7 -0
  41. package/dist/lib/neutral/meta.json +1 -0
  42. package/dist/lib/neutral/meta.mjs +8 -0
  43. package/dist/lib/neutral/meta.mjs.map +7 -0
  44. package/dist/lib/neutral/migrations-IWBT35UT.mjs +31 -0
  45. package/dist/lib/neutral/migrations-IWBT35UT.mjs.map +7 -0
  46. package/dist/lib/neutral/operation-handler-B7IW6MXU.mjs +13 -0
  47. package/dist/lib/neutral/operation-handler-B7IW6MXU.mjs.map +7 -0
  48. package/dist/lib/neutral/operations/index.mjs +8 -0
  49. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  50. package/dist/lib/neutral/plugin.mjs +16 -0
  51. package/dist/lib/neutral/plugin.mjs.map +7 -0
  52. package/dist/lib/neutral/react-surface-QROEHBRW.mjs +93 -0
  53. package/dist/lib/neutral/react-surface-QROEHBRW.mjs.map +7 -0
  54. package/dist/lib/neutral/restore-card-P25Y4YSE.mjs +21 -0
  55. package/dist/lib/neutral/restore-card-P25Y4YSE.mjs.map +7 -0
  56. package/dist/lib/neutral/restore-card-field-NHR3R4XI.mjs +40 -0
  57. package/dist/lib/neutral/restore-card-field-NHR3R4XI.mjs.map +7 -0
  58. package/dist/lib/neutral/testing/index.mjs +60 -0
  59. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  60. package/dist/lib/neutral/translations.mjs +44 -0
  61. package/dist/lib/neutral/translations.mjs.map +7 -0
  62. package/dist/lib/neutral/types/index.mjs +22 -0
  63. package/dist/lib/neutral/types/index.mjs.map +7 -0
  64. package/dist/lib/neutral/undo-mappings-6CHW6BOF.mjs +42 -0
  65. package/dist/lib/neutral/undo-mappings-6CHW6BOF.mjs.map +7 -0
  66. package/dist/types/src/KanbanPlugin.d.ts +3 -1
  67. package/dist/types/src/KanbanPlugin.d.ts.map +1 -1
  68. package/dist/types/src/KanbanPlugin.node.d.ts +4 -0
  69. package/dist/types/src/KanbanPlugin.node.d.ts.map +1 -0
  70. package/dist/types/src/KanbanPlugin.test.d.ts +2 -0
  71. package/dist/types/src/KanbanPlugin.test.d.ts.map +1 -0
  72. package/dist/types/src/KanbanPlugin.workerd.d.ts +4 -0
  73. package/dist/types/src/KanbanPlugin.workerd.d.ts.map +1 -0
  74. package/dist/types/src/blueprints/index.d.ts +2 -0
  75. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  76. package/dist/types/src/blueprints/kanban-blueprint.d.ts +4 -0
  77. package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +1 -0
  78. package/dist/types/src/capabilities/artifact-definition.d.ts +3 -2
  79. package/dist/types/src/capabilities/artifact-definition.d.ts.map +1 -1
  80. package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -4
  81. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -1
  82. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  83. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  84. package/dist/types/src/capabilities/index.d.ts +13 -3
  85. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  86. package/dist/types/src/capabilities/migrations.d.ts +6 -0
  87. package/dist/types/src/capabilities/migrations.d.ts.map +1 -0
  88. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  89. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  90. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  91. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  92. package/dist/types/src/capabilities/undo-mappings.d.ts +5 -0
  93. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -0
  94. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts +37 -0
  95. package/dist/types/src/components/KanbanBoard/KanbanBoard.d.ts.map +1 -0
  96. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts +72 -0
  97. package/dist/types/src/components/KanbanBoard/KanbanBoard.stories.d.ts.map +1 -0
  98. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts +9 -0
  99. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -0
  100. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts +8 -0
  101. package/dist/types/src/components/KanbanBoard/KanbanColumn.d.ts.map +1 -0
  102. package/dist/types/src/components/KanbanBoard/context.d.ts +38 -0
  103. package/dist/types/src/components/KanbanBoard/context.d.ts.map +1 -0
  104. package/dist/types/src/components/KanbanBoard/index.d.ts +2 -0
  105. package/dist/types/src/components/KanbanBoard/index.d.ts.map +1 -0
  106. package/dist/types/src/components/index.d.ts +1 -2
  107. package/dist/types/src/components/index.d.ts.map +1 -1
  108. package/dist/types/src/containers/KanbanArticle/KanbanArticle.d.ts +6 -0
  109. package/dist/types/src/containers/KanbanArticle/KanbanArticle.d.ts.map +1 -0
  110. package/dist/types/src/containers/KanbanArticle/KanbanArticle.stories.d.ts +79 -0
  111. package/dist/types/src/containers/KanbanArticle/KanbanArticle.stories.d.ts.map +1 -0
  112. package/dist/types/src/containers/KanbanArticle/index.d.ts +2 -0
  113. package/dist/types/src/containers/KanbanArticle/index.d.ts.map +1 -0
  114. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts +13 -0
  115. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +1 -0
  116. package/dist/types/src/containers/KanbanSettings/index.d.ts +2 -0
  117. package/dist/types/src/containers/KanbanSettings/index.d.ts.map +1 -0
  118. package/dist/types/src/containers/index.d.ts +4 -0
  119. package/dist/types/src/containers/index.d.ts.map +1 -0
  120. package/dist/types/src/hooks/index.d.ts +7 -0
  121. package/dist/types/src/hooks/index.d.ts.map +1 -0
  122. package/dist/types/src/hooks/useEchoChangeCallback.d.ts +13 -0
  123. package/dist/types/src/hooks/useEchoChangeCallback.d.ts.map +1 -0
  124. package/dist/types/src/hooks/useItemsProjection.d.ts +10 -0
  125. package/dist/types/src/hooks/useItemsProjection.d.ts.map +1 -0
  126. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts +2 -0
  127. package/dist/types/src/hooks/useKanbanBoardModel.browser.test.d.ts.map +1 -0
  128. package/dist/types/src/hooks/useKanbanBoardModel.d.ts +16 -0
  129. package/dist/types/src/hooks/useKanbanBoardModel.d.ts.map +1 -0
  130. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts +22 -0
  131. package/dist/types/src/hooks/useKanbanColumnEventHandler.d.ts.map +1 -0
  132. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts +19 -0
  133. package/dist/types/src/hooks/useKanbanItemEventHandler.d.ts.map +1 -0
  134. package/dist/types/src/hooks/useProjectionModel.d.ts +15 -0
  135. package/dist/types/src/hooks/useProjectionModel.d.ts.map +1 -0
  136. package/dist/types/src/index.d.ts +3 -1
  137. package/dist/types/src/index.d.ts.map +1 -1
  138. package/dist/types/src/meta.d.ts +2 -2
  139. package/dist/types/src/meta.d.ts.map +1 -1
  140. package/dist/types/src/operations/delete-card-field.d.ts +5 -0
  141. package/dist/types/src/operations/delete-card-field.d.ts.map +1 -0
  142. package/dist/types/src/operations/delete-card.d.ts +5 -0
  143. package/dist/types/src/operations/delete-card.d.ts.map +1 -0
  144. package/dist/types/src/operations/index.d.ts +3 -0
  145. package/dist/types/src/operations/index.d.ts.map +1 -0
  146. package/dist/types/src/operations/restore-card-field.d.ts +5 -0
  147. package/dist/types/src/operations/restore-card-field.d.ts.map +1 -0
  148. package/dist/types/src/operations/restore-card.d.ts +5 -0
  149. package/dist/types/src/operations/restore-card.d.ts.map +1 -0
  150. package/dist/types/src/playwright/board-manager.d.ts +5 -0
  151. package/dist/types/src/playwright/board-manager.d.ts.map +1 -0
  152. package/dist/types/src/playwright/playwright.config.d.ts +3 -0
  153. package/dist/types/src/playwright/playwright.config.d.ts.map +1 -0
  154. package/dist/types/src/playwright/smoke.spec.d.ts +2 -0
  155. package/dist/types/src/playwright/smoke.spec.d.ts.map +1 -0
  156. package/dist/types/src/plugin.d.ts +4 -0
  157. package/dist/types/src/plugin.d.ts.map +1 -0
  158. package/dist/types/src/testing/KanbanCardTileSimple.d.ts +7 -0
  159. package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -0
  160. package/dist/types/src/testing/index.d.ts +2 -0
  161. package/dist/types/src/testing/index.d.ts.map +1 -0
  162. package/dist/types/src/translations.d.ts +50 -22
  163. package/dist/types/src/translations.d.ts.map +1 -1
  164. package/dist/types/src/types/Kanban.d.ts +108 -0
  165. package/dist/types/src/types/Kanban.d.ts.map +1 -0
  166. package/dist/types/src/types/KanbanOperation.d.ts +52 -0
  167. package/dist/types/src/types/KanbanOperation.d.ts.map +1 -0
  168. package/dist/types/src/types/constants.d.ts +6 -0
  169. package/dist/types/src/types/constants.d.ts.map +1 -0
  170. package/dist/types/src/types/index.d.ts +3 -0
  171. package/dist/types/src/types/index.d.ts.map +1 -1
  172. package/dist/types/src/types/migrations.test.d.ts +2 -0
  173. package/dist/types/src/types/migrations.test.d.ts.map +1 -0
  174. package/dist/types/src/types/schema.d.ts +17 -51
  175. package/dist/types/src/types/schema.d.ts.map +1 -1
  176. package/dist/types/src/types/types.d.ts +28 -0
  177. package/dist/types/src/types/types.d.ts.map +1 -1
  178. package/dist/types/src/util/arrangement.d.ts +72 -0
  179. package/dist/types/src/util/arrangement.d.ts.map +1 -0
  180. package/dist/types/src/util/arrangement.test.d.ts +2 -0
  181. package/dist/types/src/util/arrangement.test.d.ts.map +1 -0
  182. package/dist/types/src/util/index.d.ts +2 -0
  183. package/dist/types/src/util/index.d.ts.map +1 -0
  184. package/dist/types/tsconfig.tsbuildinfo +1 -1
  185. package/package.json +123 -57
  186. package/src/KanbanPlugin.node.ts +21 -0
  187. package/src/KanbanPlugin.test.ts +31 -0
  188. package/src/KanbanPlugin.tsx +28 -56
  189. package/src/KanbanPlugin.workerd.ts +18 -0
  190. package/src/blueprints/index.ts +5 -0
  191. package/src/blueprints/kanban-blueprint.ts +27 -0
  192. package/src/capabilities/artifact-definition.ts +116 -114
  193. package/src/capabilities/blueprint-definition.ts +13 -24
  194. package/src/capabilities/create-object.ts +40 -0
  195. package/src/capabilities/index.ts +12 -4
  196. package/src/capabilities/migrations.ts +35 -0
  197. package/src/capabilities/operation-handler.ts +14 -0
  198. package/src/capabilities/react-surface.tsx +77 -67
  199. package/src/capabilities/undo-mappings.ts +34 -0
  200. package/src/components/KanbanBoard/KanbanBoard.stories.tsx +145 -0
  201. package/src/components/KanbanBoard/KanbanBoard.tsx +164 -0
  202. package/src/components/KanbanBoard/KanbanCard.tsx +101 -0
  203. package/src/components/KanbanBoard/KanbanColumn.tsx +72 -0
  204. package/src/components/KanbanBoard/context.ts +54 -0
  205. package/src/components/KanbanBoard/index.ts +5 -0
  206. package/src/components/index.ts +1 -2
  207. package/src/containers/KanbanArticle/KanbanArticle.stories.tsx +276 -0
  208. package/src/containers/KanbanArticle/KanbanArticle.tsx +178 -0
  209. package/src/containers/KanbanArticle/index.ts +5 -0
  210. package/src/containers/KanbanSettings/KanbanSettings.tsx +94 -0
  211. package/src/containers/KanbanSettings/index.ts +5 -0
  212. package/src/containers/index.ts +8 -0
  213. package/src/hooks/index.ts +10 -0
  214. package/src/hooks/useEchoChangeCallback.ts +30 -0
  215. package/src/hooks/useItemsProjection.ts +44 -0
  216. package/src/hooks/useKanbanBoardModel.browser.test.ts +234 -0
  217. package/src/hooks/useKanbanBoardModel.ts +157 -0
  218. package/src/hooks/useKanbanColumnEventHandler.ts +106 -0
  219. package/src/hooks/useKanbanItemEventHandler.ts +133 -0
  220. package/src/hooks/useProjectionModel.ts +58 -0
  221. package/src/index.ts +3 -2
  222. package/src/meta.ts +3 -3
  223. package/src/operations/delete-card-field.ts +47 -0
  224. package/src/operations/delete-card.ts +23 -0
  225. package/src/operations/index.ts +10 -0
  226. package/src/operations/restore-card-field.ts +41 -0
  227. package/src/operations/restore-card.ts +21 -0
  228. package/src/playwright/board-manager.ts +13 -0
  229. package/src/playwright/playwright.config.ts +19 -0
  230. package/src/playwright/smoke.spec.ts +107 -0
  231. package/src/plugin.ts +11 -0
  232. package/src/testing/KanbanCardTileSimple.tsx +82 -0
  233. package/src/testing/index.ts +5 -0
  234. package/src/translations.ts +28 -20
  235. package/src/types/Kanban.ts +150 -0
  236. package/src/types/KanbanOperation.ts +67 -0
  237. package/src/types/constants.ts +9 -0
  238. package/src/types/index.ts +4 -0
  239. package/src/types/migrations.test.ts +82 -0
  240. package/src/types/schema.ts +32 -44
  241. package/src/types/types.ts +35 -0
  242. package/src/util/arrangement.test.ts +217 -0
  243. package/src/util/arrangement.ts +177 -0
  244. package/src/util/index.ts +5 -0
  245. package/dist/lib/browser/blueprint-definition-UYVX622Q.mjs +0 -28
  246. package/dist/lib/browser/blueprint-definition-UYVX622Q.mjs.map +0 -7
  247. package/dist/lib/browser/chunk-3UDST345.mjs +0 -85
  248. package/dist/lib/browser/chunk-3UDST345.mjs.map +0 -7
  249. package/dist/lib/browser/index.mjs +0 -105
  250. package/dist/lib/browser/index.mjs.map +0 -7
  251. package/dist/lib/browser/intent-resolver-VVBNS2TO.mjs +0 -111
  252. package/dist/lib/browser/intent-resolver-VVBNS2TO.mjs.map +0 -7
  253. package/dist/lib/browser/meta.json +0 -1
  254. package/dist/lib/browser/react-surface-FNXJ6VJX.mjs +0 -255
  255. package/dist/lib/browser/react-surface-FNXJ6VJX.mjs.map +0 -7
  256. package/dist/lib/browser/types/index.mjs +0 -11
  257. package/dist/lib/node-esm/blueprint-definition-42P47FUY.mjs +0 -30
  258. package/dist/lib/node-esm/blueprint-definition-42P47FUY.mjs.map +0 -7
  259. package/dist/lib/node-esm/chunk-JBOARUAT.mjs +0 -87
  260. package/dist/lib/node-esm/chunk-JBOARUAT.mjs.map +0 -7
  261. package/dist/lib/node-esm/index.mjs +0 -106
  262. package/dist/lib/node-esm/index.mjs.map +0 -7
  263. package/dist/lib/node-esm/intent-resolver-ACN7UALP.mjs +0 -112
  264. package/dist/lib/node-esm/intent-resolver-ACN7UALP.mjs.map +0 -7
  265. package/dist/lib/node-esm/meta.json +0 -1
  266. package/dist/lib/node-esm/react-surface-ZHYHCV5N.mjs +0 -256
  267. package/dist/lib/node-esm/react-surface-ZHYHCV5N.mjs.map +0 -7
  268. package/dist/lib/node-esm/types/index.mjs +0 -12
  269. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  270. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  271. package/dist/types/src/components/KanbanContainer.d.ts +0 -7
  272. package/dist/types/src/components/KanbanContainer.d.ts.map +0 -1
  273. package/dist/types/src/components/KanbanContainer.stories.d.ts +0 -41
  274. package/dist/types/src/components/KanbanContainer.stories.d.ts.map +0 -1
  275. package/dist/types/src/components/KanbanViewEditor.d.ts +0 -8
  276. package/dist/types/src/components/KanbanViewEditor.d.ts.map +0 -1
  277. package/src/capabilities/intent-resolver.ts +0 -71
  278. package/src/components/KanbanContainer.stories.tsx +0 -193
  279. package/src/components/KanbanContainer.tsx +0 -95
  280. package/src/components/KanbanViewEditor.tsx +0 -64
  281. /package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  282. /package/dist/lib/{node-esm/types/index.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
@@ -5,23 +5,22 @@
5
5
  // ISSUE(burdon): defineArtifact
6
6
  // @ts-nocheck
7
7
 
8
- import * as Function from 'effect/Function';
8
+ import * as Effect from 'effect/Effect';
9
9
  import * as Schema from 'effect/Schema';
10
10
 
11
11
  import { ToolResult, createTool } from '@dxos/ai';
12
- import { Capabilities, type PromiseIntentDispatcher, chain, contributes, createIntent } from '@dxos/app-framework';
12
+ import { Capabilities, Capability, type PromiseIntentDispatcher } from '@dxos/app-framework';
13
13
  import { createArtifactElement } from '@dxos/assistant';
14
- import { defineArtifact } from '@dxos/blueprints';
15
- import { Obj, Query } from '@dxos/echo';
14
+ import { defineArtifact } from '@dxos/compute';
15
+ import { Filter, Obj, Query, View } from '@dxos/echo';
16
16
  import { invariant } from '@dxos/invariant';
17
- import { SpaceAction } from '@dxos/plugin-space/types';
18
- import { Filter, type Space, fullyQualifiedId } from '@dxos/react-client/echo';
19
- import { KanbanView } from '@dxos/react-ui-kanban';
20
- import { DataType } from '@dxos/schema';
17
+ import { SpaceOperation } from '@dxos/plugin-space';
18
+ import { type Space } from '@dxos/react-client/echo';
19
+ import { ViewModel } from '@dxos/schema';
21
20
  import { isNonNullable } from '@dxos/util';
22
21
 
23
- import { meta } from '../meta';
24
- import { KanbanAction } from '../types';
22
+ import { meta } from '#meta';
23
+ import { Kanban } from '#types';
25
24
 
26
25
  const QualifiedId = Schema.String.annotations({
27
26
  description: 'The fully qualified ID of the kanban `spaceID:objectID`',
@@ -34,115 +33,118 @@ declare global {
34
33
  }
35
34
  }
36
35
 
37
- export default () => {
38
- const definition = defineArtifact({
39
- id: `artifact:${meta.id}`,
40
- name: meta.name,
41
- instructions: `
36
+ export default Capability.makeModule(() =>
37
+ Effect.sync(() => {
38
+ const definition = defineArtifact({
39
+ id: `artifact:${meta.id}`,
40
+ name: meta.name,
41
+ instructions: `
42
42
  - Before adding items to a kanban board, inspect the board to see its schema
43
43
  - When adding items, you must not include the 'id' field -- it is automatically generated
44
44
  - BEFORE adding items, always make sure the board has been shown to the user!
45
45
  `,
46
- schema: KanbanView,
47
- tools: [
48
- createTool(meta.id, {
49
- name: 'create',
50
- description: `
46
+ schema: Kanban.Kanban,
47
+ tools: [
48
+ createTool(meta.id, {
49
+ name: 'create',
50
+ description: `
51
51
  Create a new kanban board using an existing schema.
52
52
  Use schema_create first to create a schema, or schema_list to choose an existing one.`,
53
- caption: 'Creating kanban board...',
54
- schema: Schema.Struct({
55
- typename: Schema.String.annotations({
56
- description: 'The fully qualified name of the record type to use for the kanban cards.',
57
- }),
58
- pivotColumn: Schema.optional(Schema.String).annotations({
59
- description: 'Optional field name to use as the column pivot.',
60
- }),
61
- }),
62
- execute: async ({ typename, pivotColumn }, { extensions }) => {
63
- invariant(extensions?.space, 'No space');
64
- invariant(extensions?.dispatch, 'No intent dispatcher');
65
-
66
- // Validate schema exists first
67
- const schema = await extensions.space.db.schemaRegistry.query({ typename }).firstOrUndefined();
68
- if (!schema) {
69
- return ToolResult.Error(`Schema not found: ${typename}`);
70
- }
71
-
72
- const intent = Function.pipe(
73
- createIntent(KanbanAction.Create, {
74
- space: extensions.space,
75
- typename,
76
- initialPivotColumn: pivotColumn,
53
+ caption: 'Creating kanban board...',
54
+ schema: Schema.Struct({
55
+ typename: Schema.String.annotations({
56
+ description: 'The fully qualified name of the record type to use for the kanban cards.',
77
57
  }),
78
- chain(SpaceAction.AddObject, { target: extensions.space }),
79
- );
80
-
81
- const { data, error } = await extensions.dispatch(intent);
82
- if (!data || error) {
83
- return ToolResult.Error(error?.message ?? 'Failed to create kanban board');
84
- }
85
-
86
- return ToolResult.Success(createArtifactElement(data.id));
87
- },
88
- }),
89
- createTool(meta.id, {
90
- name: 'list',
91
- description: 'List all kanban boards in the current space.',
92
- caption: 'Listing kanban boards...',
93
- schema: Schema.Struct({}),
94
- execute: async (_input, { extensions }) => {
95
- invariant(extensions?.space, 'No space');
96
- const space = extensions.space;
97
- const { objects } = await space.db.query(Filter.type(DataType.View)).run();
98
-
99
- const boardInfo = await Promise.all(
100
- objects.map(async (view) => {
101
- const kanban = await view.presentation.load();
102
- if (!Obj.instanceOf(KanbanView, kanban)) {
103
- return null;
104
- }
105
-
106
- return {
107
- id: fullyQualifiedId(view),
108
- name: view.name ?? 'Unnamed Kanban',
109
- typename: view.query.typename,
110
- };
58
+ pivotColumn: Schema.optional(Schema.String).annotations({
59
+ description: 'Optional field name to use as the column pivot.',
111
60
  }),
112
- );
113
-
114
- return ToolResult.Success(boardInfo.filter(isNonNullable));
115
- },
116
- }),
117
- createTool(meta.id, {
118
- name: 'inspect',
119
- description: 'Get details about a specific kanban board.',
120
- caption: 'Inspecting kanban board...',
121
- schema: Schema.Struct({ id: QualifiedId }),
122
- execute: async ({ id }, { extensions }) => {
123
- invariant(extensions?.space, 'No space');
124
- const space = extensions.space;
125
- const view = (await space.db
126
- // TODO(wittjosiah): Filter.and should aggregate type
127
- .query(Query.select(Filter.and(Filter.type(DataType.View), Filter.ids(id))))
128
- .first()) as DataType.View;
129
-
130
- const kanban = await view.presentation.load();
131
- invariant(Obj.instanceOf(KanbanView, kanban));
132
-
133
- const typename = view.query.typename;
134
- const schema = await space.db.schemaRegistry.query({ typename }).firstOrUndefined();
135
- invariant(schema);
136
-
137
- return ToolResult.Success({
138
- schema,
139
- columnField: kanban.columnFieldId,
140
- viewFields: view.projection.fields,
141
- });
142
- },
143
- }),
144
- ],
145
- });
146
-
147
- return contributes(Capabilities.ArtifactDefinition, definition);
148
- };
61
+ }),
62
+ execute: async ({ typename, pivotColumn }, { extensions }) => {
63
+ invariant(extensions?.space, 'No space');
64
+ invariant(extensions?.invoke, 'No operation invoker');
65
+
66
+ // Validate schema exists first
67
+ const schema = await extensions.space.db.schemaRegistry.query({ typename }).firstOrUndefined();
68
+ if (!schema) {
69
+ return ToolResult.Error(`Schema not found: ${typename}`);
70
+ }
71
+
72
+ const { view } = await ViewModel.makeFromDatabase({
73
+ db: extensions.space.db,
74
+ typename,
75
+ pivotFieldName: pivotColumn,
76
+ });
77
+ const kanban = Kanban.make({ view });
78
+
79
+ const { error } = await extensions.invoke(SpaceOperation.AddObject, {
80
+ target: extensions.space,
81
+ object: kanban,
82
+ });
83
+ if (error) {
84
+ return ToolResult.Error(error?.message ?? 'Failed to add kanban board to space');
85
+ }
86
+
87
+ return ToolResult.Success(createArtifactElement(kanban.id));
88
+ },
89
+ }),
90
+ createTool(meta.id, {
91
+ name: 'list',
92
+ description: 'List all kanban boards in the current space.',
93
+ caption: 'Listing kanban boards...',
94
+ schema: Schema.Struct({}),
95
+ execute: async (_input, { extensions }) => {
96
+ invariant(extensions?.space, 'No space');
97
+ const space = extensions.space;
98
+ const { objects } = await space.db.query(Filter.type(View.View)).run();
99
+
100
+ const boardInfo = await Promise.all(
101
+ objects.map(async (view) => {
102
+ const kanban = await view.presentation.load();
103
+ if (!Obj.instanceOf(Kanban.Kanban, kanban)) {
104
+ return null;
105
+ }
106
+
107
+ return {
108
+ id: Obj.getDXN(view).toString(),
109
+ name: view.name ?? 'Unnamed Kanban',
110
+ typename: view.query.typename,
111
+ };
112
+ }),
113
+ );
114
+
115
+ return ToolResult.Success(boardInfo.filter(isNonNullable));
116
+ },
117
+ }),
118
+ createTool(meta.id, {
119
+ name: 'inspect',
120
+ description: 'Get details about a specific kanban board.',
121
+ caption: 'Inspecting kanban board...',
122
+ schema: Schema.Struct({ id: QualifiedId }),
123
+ execute: async ({ id }, { extensions }) => {
124
+ invariant(extensions?.space, 'No space');
125
+ const space = extensions.space;
126
+ const view = (await space.db
127
+ // TODO(wittjosiah): Filter.and should aggregate type
128
+ .query(Query.select(Filter.and(Filter.type(View.View), Filter.id(id))))
129
+ .first()) as View.View;
130
+
131
+ const kanban = await view.presentation.load();
132
+ invariant(Obj.instanceOf(Kanban.Kanban, kanban));
133
+
134
+ const typename = view.query.typename;
135
+ const schema = await space.db.schemaRegistry.query({ typename }).firstOrUndefined();
136
+ invariant(schema);
137
+
138
+ return ToolResult.Success({
139
+ schema,
140
+ columnField: view.projection.pivotFieldId,
141
+ viewFields: view.projection.fields,
142
+ });
143
+ },
144
+ }),
145
+ ],
146
+ });
147
+
148
+ return Capability.contributes(Capabilities.ArtifactDefinition, definition);
149
+ }),
150
+ );
@@ -2,29 +2,18 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes } from '@dxos/app-framework';
6
- import { Blueprint, Template } from '@dxos/blueprints';
7
- import { type FunctionDefinition } from '@dxos/functions';
8
- import { trim } from '@dxos/util';
5
+ import * as Effect from 'effect/Effect';
9
6
 
10
- const functions: FunctionDefinition[] = [];
11
- const tools: string[] = [];
7
+ import { Capability } from '@dxos/app-framework';
8
+ import { AppCapabilities } from '@dxos/app-toolkit';
9
+ // eslint-disable-next-line unused-imports/no-unused-imports
10
+ import type { Blueprint } from '@dxos/compute';
12
11
 
13
- export default () => {
14
- return [
15
- contributes(Capabilities.Functions, functions),
16
- contributes(
17
- Capabilities.BlueprintDefinition,
18
- Blueprint.make({
19
- key: 'dxos.org/blueprint/kanban',
20
- name: 'Kanban',
21
- tools: Blueprint.toolDefinitions({ functions, tools }),
22
- instructions: Template.make({
23
- source: trim`
24
- You can create and update kanban boards to show data in sorted columns defined by schema.
25
- `,
26
- }),
27
- }),
28
- ),
29
- ];
30
- };
12
+ import { KanbanBlueprint } from '#blueprints';
13
+
14
+ const blueprintDefinition = Capability.makeModule<
15
+ [],
16
+ Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[]
17
+ >(() => Effect.succeed([Capability.contributes(AppCapabilities.BlueprintDefinition, KanbanBlueprint)]));
18
+
19
+ export default blueprintDefinition;
@@ -0,0 +1,40 @@
1
+ //
2
+ // Copyright 2023 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 { Type } from '@dxos/echo';
10
+ import { SpaceOperation } from '@dxos/plugin-space';
11
+ import { SpaceCapabilities } from '@dxos/plugin-space';
12
+ import { ViewModel } from '@dxos/schema';
13
+
14
+ import { CreateKanbanSchema, Kanban } from '#types';
15
+
16
+ export default Capability.makeModule(
17
+ Effect.fnUntraced(function* () {
18
+ return Capability.contributes(SpaceCapabilities.CreateObjectEntry, {
19
+ id: Type.getTypename(Kanban.Kanban),
20
+ inputSchema: CreateKanbanSchema,
21
+ createObject: (props, options) =>
22
+ Effect.gen(function* () {
23
+ const object = yield* Effect.promise(async () => {
24
+ const { view } = await ViewModel.makeFromDatabase({
25
+ db: options.db,
26
+ typename: props.typename,
27
+ pivotFieldName: props.initialPivotColumn,
28
+ });
29
+ return Kanban.make({ name: props.name, view });
30
+ });
31
+ return yield* Operation.invoke(SpaceOperation.AddObject, {
32
+ object,
33
+ target: options.target,
34
+ hidden: true,
35
+ targetNodeId: options.targetNodeId,
36
+ });
37
+ }),
38
+ });
39
+ }),
40
+ );
@@ -2,8 +2,16 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { lazy } from '@dxos/app-framework';
5
+ import { Capability } from '@dxos/app-framework';
6
+ // eslint-disable-next-line unused-imports/no-unused-imports
7
+ import type { Blueprint, OperationHandlerSet } from '@dxos/compute';
6
8
 
7
- export const BlueprintDefinition = lazy(() => import('./blueprint-definition'));
8
- export const IntentResolver = lazy(() => import('./intent-resolver'));
9
- export const ReactSurface = lazy(() => import('./react-surface'));
9
+ export const BlueprintDefinition = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
10
+ export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
11
+ export const Migrations = Capability.lazy('Migrations', () => import('./migrations'));
12
+ export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
13
+ 'OperationHandler',
14
+ () => import('./operation-handler'),
15
+ );
16
+ export const ReactSurface = Capability.lazy('ReactSurface', () => import('./react-surface'));
17
+ export const UndoMappings = Capability.lazy('UndoMappings', () => import('./undo-mappings'));
@@ -0,0 +1,35 @@
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 { Migration } from '@dxos/echo';
9
+ import { ClientCapabilities } from '@dxos/plugin-client';
10
+
11
+ import { Kanban } from '#types';
12
+
13
+ /**
14
+ * v0.1.0 → v0.2.0: nests the existing `view` ref under a `spec: { kind: 'view', view }`
15
+ * discriminated union. v0.2.0 introduced an items-variant for externally-synced kanbans;
16
+ * pre-migration objects were all view-based by construction.
17
+ */
18
+ const migrations = [
19
+ Migration.define({
20
+ from: Kanban.KanbanV1,
21
+ to: Kanban.Kanban,
22
+ transform: async (from) => ({
23
+ name: from.name,
24
+ arrangement: from.arrangement,
25
+ spec: { kind: 'view' as const, view: from.view },
26
+ }),
27
+ onMigration: async () => {},
28
+ }),
29
+ ];
30
+
31
+ export default Capability.makeModule(
32
+ Effect.fnUntraced(function* () {
33
+ return Capability.contributes(ClientCapabilities.Migration, migrations);
34
+ }),
35
+ );
@@ -0,0 +1,14 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Capabilities, Capability } from '@dxos/app-framework';
6
+ import type { OperationHandlerSet } from '@dxos/compute';
7
+
8
+ import { KanbanOperationHandlerSet } from '#operations';
9
+
10
+ export default Capability.makeModule<OperationHandlerSet.OperationHandlerSet>(
11
+ Effect.fnUntraced(function* () {
12
+ return Capability.contributes(Capabilities.OperationHandler, KanbanOperationHandlerSet);
13
+ }),
14
+ );
@@ -2,83 +2,93 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import * as Effect from 'effect/Effect';
5
6
  import type * as Schema from 'effect/Schema';
7
+ import * as SchemaAST from 'effect/SchemaAST';
6
8
  import React, { useMemo } from 'react';
7
9
 
8
- import { Capabilities, contributes, createSurface, useCapabilities } from '@dxos/app-framework';
9
- import { Obj, Type } from '@dxos/echo';
10
+ import { Capabilities, Capability } from '@dxos/app-framework';
11
+ import { Surface } from '@dxos/app-framework/ui';
12
+ import { AppSurface } from '@dxos/app-toolkit/ui';
13
+ import { type Collection, Database, JsonSchema, Obj } from '@dxos/echo';
10
14
  import { findAnnotation } from '@dxos/effect';
11
- import { ClientCapabilities } from '@dxos/plugin-client';
12
- import { type Space, getSpace, isSpace } from '@dxos/react-client/echo';
13
- import { type InputProps, SelectInput, useFormValues } from '@dxos/react-ui-form';
14
- import { Kanban } from '@dxos/react-ui-kanban/types';
15
- import { DataType } from '@dxos/schema';
15
+ import { type FormFieldComponentProps, SelectField, useFormValues } from '@dxos/react-ui-form';
16
16
 
17
- import { KanbanContainer, KanbanViewEditor } from '../components';
18
- import { meta } from '../meta';
19
- import { PivotColumnAnnotationId } from '../types';
17
+ import { KanbanArticle, KanbanSettings } from '#containers';
18
+ import { Kanban, PivotColumnAnnotationId } from '#types';
20
19
 
21
- export default () =>
22
- contributes(Capabilities.ReactSurface, [
23
- createSurface({
24
- id: meta.id,
25
- role: ['article', 'section'],
26
- filter: (data): data is { subject: DataType.View } =>
27
- Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
28
- component: ({ data, role }) => <KanbanContainer view={data.subject} role={role} />,
29
- }),
30
- createSurface({
31
- id: `${meta.id}/object-settings`,
32
- role: 'object-settings',
33
- position: 'hoist',
34
- filter: (data): data is { subject: DataType.View } =>
35
- Obj.instanceOf(DataType.View, data.subject) && Obj.instanceOf(Kanban.Kanban, data.subject.presentation.target),
36
- component: ({ data }) => <KanbanViewEditor view={data.subject} />,
37
- }),
38
- createSurface({
39
- id: `${meta.id}/create-initial-schema-form-[pivot-column]`,
40
- role: 'form-input',
41
- filter: (
42
- data,
43
- ): data is { prop: string; schema: Schema.Schema<any>; target: Space | DataType.Collection | undefined } => {
44
- const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
45
- return !!annotation;
46
- },
47
- component: ({ data: { target }, ...inputProps }) => {
48
- const props = inputProps as any as InputProps;
49
- const space = isSpace(target) ? target : getSpace(target);
50
- if (!space) {
51
- return null;
52
- }
53
- const { typename } = useFormValues();
54
- // TODO(wittjosiah): Unify this schema lookup.
55
- const schemaWhitelists = useCapabilities(ClientCapabilities.SchemaWhiteList);
56
- const staticSchema = schemaWhitelists.flat().find((schema) => Type.getTypename(schema) === typename);
57
- const [selectedSchema] = space?.db.schemaRegistry.query({ typename }).runSync();
20
+ export default Capability.makeModule(() =>
21
+ Effect.succeed(
22
+ Capability.contributes(Capabilities.ReactSurface, [
23
+ Surface.create({
24
+ id: 'root',
25
+ // TODO(wittjosiah): Split into multiple surfaces if this filter proves too strict for non-article roles.
26
+ filter: AppSurface.oneOf(
27
+ AppSurface.object(AppSurface.Article, Kanban.Kanban),
28
+ AppSurface.object(AppSurface.Section, Kanban.Kanban),
29
+ ),
30
+ component: ({ data, role }) => <KanbanArticle role={role} subject={data.subject} />,
31
+ }),
32
+ Surface.create({
33
+ id: 'object-properties',
34
+ position: 'hoist',
35
+ filter: AppSurface.object(AppSurface.ObjectProperties, Kanban.Kanban),
36
+ component: ({ data }) => <KanbanSettings subject={data.subject} />,
37
+ }),
38
+ Surface.create({
39
+ id: 'create-initial-schema-form-[pivot-column]',
40
+ role: 'form-input',
41
+ filter: (
42
+ data,
43
+ ): data is {
44
+ prop: string;
45
+ schema: Schema.Schema<any>;
46
+ target: Database.Database | Collection.Collection | undefined;
47
+ fieldPropertyAst?: SchemaAST.AST;
48
+ } => {
49
+ const annotation = findAnnotation<boolean>((data.schema as Schema.Schema.All).ast, PivotColumnAnnotationId);
50
+ return !!annotation;
51
+ },
52
+ component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {
53
+ const ast = fieldPropertyAst;
54
+ if (!ast) {
55
+ return null;
56
+ }
58
57
 
59
- const singleSelectColumns = useMemo(() => {
60
- const properties = staticSchema
61
- ? Type.toJsonSchema(staticSchema).properties
62
- : selectedSchema?.jsonSchema?.properties;
63
- if (!properties) {
64
- return [];
58
+ const props = { ...inputProps, type: ast } as any as FormFieldComponentProps;
59
+ const db = Database.isDatabase(target) ? target : target && Obj.getDatabase(target);
60
+ if (!db) {
61
+ return null;
65
62
  }
66
63
 
67
- const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
68
- if (typeof value === 'object' && value?.format === 'single-select') {
69
- acc.push(key);
64
+ const { typename } = useFormValues('KanbanForm');
65
+ const [selectedSchema] = useMemo(
66
+ () => db.schemaRegistry.query({ location: ['database', 'runtime'], typename }).runSync(),
67
+ [db, typename],
68
+ );
69
+ const singleSelectColumns = useMemo(() => {
70
+ const properties = JsonSchema.toJsonSchema(selectedSchema).properties;
71
+ if (!properties) {
72
+ return [];
70
73
  }
71
- return acc;
72
- }, []);
73
74
 
74
- return columns;
75
- }, [selectedSchema?.jsonSchema, staticSchema]);
75
+ const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
76
+ if (typeof value === 'object' && value?.format === 'single-select') {
77
+ acc.push(key);
78
+ }
79
+ return acc;
80
+ }, []);
81
+
82
+ return columns;
83
+ }, [selectedSchema]);
76
84
 
77
- if (!typename) {
78
- return null;
79
- }
85
+ if (!typename) {
86
+ return null;
87
+ }
80
88
 
81
- return <SelectInput {...props} options={singleSelectColumns.map((column) => ({ value: column }))} />;
82
- },
83
- }),
84
- ]);
89
+ return <SelectField {...props} options={singleSelectColumns.map((column) => ({ value: column }))} />;
90
+ },
91
+ }),
92
+ ]),
93
+ ),
94
+ );
@@ -0,0 +1,34 @@
1
+ // Copyright 2025 DXOS.org
2
+
3
+ import * as Effect from 'effect/Effect';
4
+
5
+ import { Capabilities, Capability, UndoMapping } from '@dxos/app-framework';
6
+
7
+ import { meta } from '#meta';
8
+ import { KanbanOperation } from '#types';
9
+
10
+ export default Capability.makeModule(() =>
11
+ Effect.succeed(
12
+ Capability.contributes(Capabilities.UndoMapping, [
13
+ UndoMapping.make({
14
+ operation: KanbanOperation.DeleteCardField,
15
+ inverse: KanbanOperation.RestoreCardField,
16
+ deriveContext: (input, output) => ({
17
+ view: input.view,
18
+ field: output.field,
19
+ props: output.props,
20
+ index: output.index,
21
+ }),
22
+ message: ['card-field-deleted.label', { ns: meta.id }],
23
+ }),
24
+ UndoMapping.make({
25
+ operation: KanbanOperation.DeleteCard,
26
+ inverse: KanbanOperation.RestoreCard,
27
+ deriveContext: (_input, output) => ({
28
+ card: output.card,
29
+ }),
30
+ message: ['card-deleted.label', { ns: meta.id }],
31
+ }),
32
+ ]),
33
+ ),
34
+ );