@dxos/plugin-kanban 0.9.0 → 0.9.1-staging.ee54ba693a

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 (137) hide show
  1. package/PLUGIN.mdl +3 -3
  2. package/dist/lib/neutral/{KanbanArticle-T4CPKAZH.mjs → KanbanArticle-JQMQQHRB.mjs} +1 -1
  3. package/dist/lib/neutral/{KanbanArticle-T4CPKAZH.mjs.map → KanbanArticle-JQMQQHRB.mjs.map} +2 -2
  4. package/dist/lib/neutral/KanbanPlugin.mjs +6 -6
  5. package/dist/lib/neutral/KanbanPlugin.mjs.map +4 -4
  6. package/dist/lib/neutral/KanbanPlugin.node.mjs +3 -3
  7. package/dist/lib/neutral/KanbanPlugin.node.mjs.map +3 -3
  8. package/dist/lib/neutral/{KanbanSettings-5WOS4CUE.mjs → KanbanProperties-W7MZNZVJ.mjs} +6 -6
  9. package/dist/lib/neutral/KanbanProperties-W7MZNZVJ.mjs.map +7 -0
  10. package/dist/lib/neutral/capabilities/index.mjs +5 -5
  11. package/dist/lib/neutral/capabilities/index.mjs.map +3 -3
  12. package/dist/lib/neutral/{chunk-DAKIZO46.mjs → chunk-7TVVF45P.mjs} +7 -6
  13. package/dist/lib/neutral/chunk-7TVVF45P.mjs.map +7 -0
  14. package/dist/lib/neutral/chunk-7YLGUKDJ.mjs +8 -0
  15. package/dist/lib/neutral/chunk-CFPH5R6P.mjs +26 -0
  16. package/dist/lib/neutral/chunk-CFPH5R6P.mjs.map +7 -0
  17. package/dist/lib/neutral/chunk-V4AVOJVU.mjs +50 -0
  18. package/dist/lib/neutral/chunk-V4AVOJVU.mjs.map +7 -0
  19. package/dist/lib/neutral/components/index.mjs +9 -7
  20. package/dist/lib/neutral/components/index.mjs.map +3 -3
  21. package/dist/lib/neutral/containers/index.mjs +3 -3
  22. package/dist/lib/neutral/containers/index.mjs.map +3 -3
  23. package/dist/lib/neutral/{create-object-DKBSI46K.mjs → create-object-DIIFRS57.mjs} +14 -9
  24. package/dist/lib/neutral/create-object-DIIFRS57.mjs.map +7 -0
  25. package/dist/lib/neutral/{delete-card-VNAV3CZV.mjs → delete-card-TK2G6YHX.mjs} +2 -2
  26. package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs → delete-card-field-LGWPBOUW.mjs} +2 -2
  27. package/dist/lib/neutral/index.mjs +6 -6
  28. package/dist/lib/neutral/meta.json +1 -1
  29. package/dist/lib/neutral/meta.mjs +1 -1
  30. package/dist/lib/neutral/operations/index.mjs +1 -1
  31. package/dist/lib/neutral/plugin.mjs +2 -2
  32. package/dist/lib/neutral/{react-surface-VZEVEJL5.mjs → react-surface-FQGXRR3X.mjs} +11 -13
  33. package/dist/lib/neutral/react-surface-FQGXRR3X.mjs.map +7 -0
  34. package/dist/lib/neutral/{restore-card-EKVEPATL.mjs → restore-card-3O6PVN7J.mjs} +2 -2
  35. package/dist/lib/neutral/{restore-card-field-TQCTGGNO.mjs → restore-card-field-5G4DVYYY.mjs} +2 -2
  36. package/dist/lib/neutral/skill-definition-YGTCKXGP.mjs +15 -0
  37. package/dist/lib/neutral/skill-definition-YGTCKXGP.mjs.map +7 -0
  38. package/dist/lib/neutral/skills/index.mjs +8 -0
  39. package/dist/lib/neutral/testing/index.mjs +7 -5
  40. package/dist/lib/neutral/testing/index.mjs.map +3 -3
  41. package/dist/lib/neutral/translations.mjs +1 -1
  42. package/dist/lib/neutral/translations.mjs.map +3 -3
  43. package/dist/lib/neutral/types/index.mjs +1 -1
  44. package/dist/lib/neutral/{undo-mappings-6CHW6BOF.mjs → undo-mappings-EZTHO4UL.mjs} +3 -3
  45. package/dist/lib/neutral/{undo-mappings-6CHW6BOF.mjs.map → undo-mappings-EZTHO4UL.mjs.map} +3 -3
  46. package/dist/types/dx.config.d.ts +28 -0
  47. package/dist/types/dx.config.d.ts.map +1 -0
  48. package/dist/types/src/capabilities/artifact-definition.d.ts +1 -1
  49. package/dist/types/src/capabilities/create-object.d.ts +1 -7
  50. package/dist/types/src/capabilities/create-object.d.ts.map +1 -1
  51. package/dist/types/src/capabilities/index.d.ts +4 -10
  52. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  53. package/dist/types/src/capabilities/react-surface.d.ts +2 -2
  54. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  55. package/dist/types/src/capabilities/skill-definition.d.ts +5 -0
  56. package/dist/types/src/capabilities/skill-definition.d.ts.map +1 -0
  57. package/dist/types/src/capabilities/undo-mappings.d.ts +2 -2
  58. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -1
  59. package/dist/types/src/components/KanbanBoard/KanbanCard.d.ts.map +1 -1
  60. package/dist/types/src/containers/KanbanArticle/KanbanArticle.d.ts.map +1 -1
  61. package/dist/types/src/containers/{KanbanSettings/KanbanSettings.d.ts → KanbanProperties/KanbanProperties.d.ts} +4 -4
  62. package/dist/types/src/containers/KanbanProperties/KanbanProperties.d.ts.map +1 -0
  63. package/dist/types/src/containers/KanbanProperties/index.d.ts +2 -0
  64. package/dist/types/src/containers/KanbanProperties/index.d.ts.map +1 -0
  65. package/dist/types/src/containers/index.d.ts +1 -1
  66. package/dist/types/src/containers/index.d.ts.map +1 -1
  67. package/dist/types/src/index.d.ts +1 -1
  68. package/dist/types/src/index.d.ts.map +1 -1
  69. package/dist/types/src/meta.d.ts +32 -2
  70. package/dist/types/src/meta.d.ts.map +1 -1
  71. package/dist/types/src/skills/index.d.ts +2 -0
  72. package/dist/types/src/skills/index.d.ts.map +1 -0
  73. package/dist/types/src/skills/kanban-skill.d.ts +4 -0
  74. package/dist/types/src/skills/kanban-skill.d.ts.map +1 -0
  75. package/dist/types/src/testing/KanbanCardTileSimple.d.ts.map +1 -1
  76. package/dist/types/src/types/Kanban.d.ts +3 -6
  77. package/dist/types/src/types/Kanban.d.ts.map +1 -1
  78. package/dist/types/src/types/KanbanOperation.d.ts.map +1 -1
  79. package/dist/types/src/types/schema.d.ts +1 -1
  80. package/dist/types/tsconfig.tsbuildinfo +1 -1
  81. package/dx.config.ts +36 -0
  82. package/package.json +48 -47
  83. package/src/KanbanPlugin.node.ts +2 -2
  84. package/src/KanbanPlugin.test.ts +3 -3
  85. package/src/KanbanPlugin.tsx +3 -3
  86. package/src/capabilities/create-object.ts +9 -7
  87. package/src/capabilities/index.ts +1 -7
  88. package/src/capabilities/react-surface.tsx +17 -27
  89. package/src/capabilities/skill-definition.ts +14 -0
  90. package/src/capabilities/undo-mappings.ts +2 -2
  91. package/src/components/KanbanBoard/KanbanBoard.tsx +1 -1
  92. package/src/components/KanbanBoard/KanbanCard.tsx +14 -12
  93. package/src/containers/KanbanArticle/KanbanArticle.stories.tsx +1 -1
  94. package/src/containers/KanbanArticle/KanbanArticle.tsx +1 -1
  95. package/src/containers/{KanbanSettings/KanbanSettings.tsx → KanbanProperties/KanbanProperties.tsx} +13 -6
  96. package/src/containers/KanbanProperties/index.ts +5 -0
  97. package/src/containers/index.ts +1 -1
  98. package/src/hooks/useKanbanBoardModel.browser.test.ts +20 -18
  99. package/src/index.ts +1 -1
  100. package/src/meta.ts +2 -29
  101. package/src/skills/index.ts +5 -0
  102. package/src/{blueprints/kanban-blueprint.ts → skills/kanban-skill.ts} +8 -8
  103. package/src/testing/KanbanCardTileSimple.tsx +13 -11
  104. package/src/translations.ts +1 -1
  105. package/src/types/Kanban.ts +13 -17
  106. package/src/types/KanbanOperation.ts +2 -2
  107. package/src/types/schema.ts +1 -1
  108. package/dist/lib/neutral/KanbanSettings-5WOS4CUE.mjs.map +0 -7
  109. package/dist/lib/neutral/blueprint-definition-6DV3Q5MC.mjs +0 -15
  110. package/dist/lib/neutral/blueprint-definition-6DV3Q5MC.mjs.map +0 -7
  111. package/dist/lib/neutral/blueprints/index.mjs +0 -8
  112. package/dist/lib/neutral/chunk-6ZHHQWO5.mjs +0 -39
  113. package/dist/lib/neutral/chunk-6ZHHQWO5.mjs.map +0 -7
  114. package/dist/lib/neutral/chunk-DAKIZO46.mjs.map +0 -7
  115. package/dist/lib/neutral/chunk-M5ISZWZU.mjs +0 -8
  116. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs +0 -26
  117. package/dist/lib/neutral/chunk-ZTQW5KQS.mjs.map +0 -7
  118. package/dist/lib/neutral/create-object-DKBSI46K.mjs.map +0 -7
  119. package/dist/lib/neutral/react-surface-VZEVEJL5.mjs.map +0 -7
  120. package/dist/types/src/blueprints/index.d.ts +0 -2
  121. package/dist/types/src/blueprints/index.d.ts.map +0 -1
  122. package/dist/types/src/blueprints/kanban-blueprint.d.ts +0 -4
  123. package/dist/types/src/blueprints/kanban-blueprint.d.ts.map +0 -1
  124. package/dist/types/src/capabilities/blueprint-definition.d.ts +0 -6
  125. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +0 -1
  126. package/dist/types/src/containers/KanbanSettings/KanbanSettings.d.ts.map +0 -1
  127. package/dist/types/src/containers/KanbanSettings/index.d.ts +0 -2
  128. package/dist/types/src/containers/KanbanSettings/index.d.ts.map +0 -1
  129. package/src/blueprints/index.ts +0 -5
  130. package/src/capabilities/blueprint-definition.ts +0 -19
  131. package/src/containers/KanbanSettings/index.ts +0 -5
  132. /package/dist/lib/neutral/{chunk-M5ISZWZU.mjs.map → chunk-7YLGUKDJ.mjs.map} +0 -0
  133. /package/dist/lib/neutral/{delete-card-VNAV3CZV.mjs.map → delete-card-TK2G6YHX.mjs.map} +0 -0
  134. /package/dist/lib/neutral/{delete-card-field-XHOLGS6L.mjs.map → delete-card-field-LGWPBOUW.mjs.map} +0 -0
  135. /package/dist/lib/neutral/{restore-card-EKVEPATL.mjs.map → restore-card-3O6PVN7J.mjs.map} +0 -0
  136. /package/dist/lib/neutral/{restore-card-field-TQCTGGNO.mjs.map → restore-card-field-5G4DVYYY.mjs.map} +0 -0
  137. /package/dist/lib/neutral/{blueprints → skills}/index.mjs.map +0 -0
package/dx.config.ts ADDED
@@ -0,0 +1,36 @@
1
+ //
2
+ // Copyright 2025 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.kanban',
11
+ name: 'Kanban',
12
+ author: 'DXOS',
13
+ description: trim`
14
+ Visual project management using customizable kanban boards to track workflow progress.
15
+ Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards
16
+ between stages, and reorder both columns and cards — all changes are persisted to ECHO and
17
+ replicated to collaborators in real time.
18
+
19
+ Kanban boards come in two variants: view-variant boards source their cards through a linked
20
+ View query (any ECHO type can be pivoted on a single-select field), while items-variant boards
21
+ own their cards explicitly and are used by external sync integrations such as Linear or GitHub.
22
+ Both variants share the same arrangement storage and drag-and-drop mechanics.
23
+
24
+ Board settings let users choose which single-select field drives the column layout and
25
+ optionally hide the uncategorized column for items that have no pivot value.
26
+ Field-level undo support allows deleted card fields to be restored without data loss.
27
+
28
+ The plugin contributes a Kanban skill that exposes board creation and card management
29
+ to AI agents, enabling automated project tracking workflows.
30
+ `,
31
+ source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
32
+ icon: { key: 'ph--kanban--regular', hue: 'green' },
33
+ spec: 'PLUGIN.mdl',
34
+ screenshots: [{ dark: 'https://dxos.network/plugin-details-kanban-dark.png' }],
35
+ },
36
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-kanban",
3
- "version": "0.9.0",
3
+ "version": "0.9.1-staging.ee54ba693a",
4
4
  "description": "Kanban DXOS Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -13,10 +13,10 @@
13
13
  "sideEffects": true,
14
14
  "type": "module",
15
15
  "imports": {
16
- "#blueprints": {
17
- "source": "./src/blueprints/index.ts",
18
- "types": "./dist/types/src/blueprints/index.d.ts",
19
- "default": "./dist/lib/neutral/blueprints/index.mjs"
16
+ "#skills": {
17
+ "source": "./src/skills/index.ts",
18
+ "types": "./dist/types/src/skills/index.d.ts",
19
+ "default": "./dist/lib/neutral/skills/index.mjs"
20
20
  },
21
21
  "#capabilities": {
22
22
  "source": "./src/capabilities/index.ts",
@@ -78,10 +78,10 @@
78
78
  "default": "./dist/lib/neutral/index.mjs"
79
79
  },
80
80
  "./assets/PLUGIN.mdl": "./PLUGIN.mdl",
81
- "./blueprints": {
82
- "source": "./src/blueprints/index.ts",
83
- "types": "./dist/types/src/blueprints/index.d.ts",
84
- "default": "./dist/lib/neutral/blueprints/index.mjs"
81
+ "./skills": {
82
+ "source": "./src/skills/index.ts",
83
+ "types": "./dist/types/src/skills/index.d.ts",
84
+ "default": "./dist/lib/neutral/skills/index.mjs"
85
85
  },
86
86
  "./plugin": {
87
87
  "source": "./src/plugin.ts",
@@ -102,56 +102,57 @@
102
102
  "types": "dist/types/src/index.d.ts",
103
103
  "files": [
104
104
  "dist",
105
+ "dx.config.ts",
105
106
  "src",
106
107
  "PLUGIN.mdl"
107
108
  ],
108
109
  "dependencies": {
109
110
  "@effect-atom/atom-react": "^0.5.0",
110
111
  "@radix-ui/react-context": "1.1.1",
111
- "effect": "3.21.3",
112
- "@dxos/ai": "0.9.0",
113
- "@dxos/app-framework": "0.9.0",
114
- "@dxos/app-toolkit": "0.9.0",
115
- "@dxos/assistant": "0.9.0",
116
- "@dxos/echo": "0.9.0",
117
- "@dxos/compute": "0.9.0",
118
- "@dxos/log": "0.9.0",
119
- "@dxos/effect": "0.9.0",
120
- "@dxos/plugin-space": "0.9.0",
121
- "@dxos/plugin-client": "0.9.0",
122
- "@dxos/invariant": "0.9.0",
123
- "@dxos/random": "0.9.0",
124
- "@dxos/react-client": "0.9.0",
125
- "@dxos/react-ui-form": "0.9.0",
126
- "@dxos/react-ui-menu": "0.9.0",
127
- "@dxos/schema": "0.9.0",
128
- "@dxos/react-ui": "0.9.0",
129
- "@dxos/react-ui-mosaic": "0.9.0",
130
- "@dxos/util": "0.9.0",
131
- "@dxos/types": "0.9.0"
112
+ "effect": "3.21.4",
113
+ "@dxos/ai": "0.9.1-staging.ee54ba693a",
114
+ "@dxos/app-framework": "0.9.1-staging.ee54ba693a",
115
+ "@dxos/assistant": "0.9.1-staging.ee54ba693a",
116
+ "@dxos/compute": "0.9.1-staging.ee54ba693a",
117
+ "@dxos/echo": "0.9.1-staging.ee54ba693a",
118
+ "@dxos/effect": "0.9.1-staging.ee54ba693a",
119
+ "@dxos/invariant": "0.9.1-staging.ee54ba693a",
120
+ "@dxos/log": "0.9.1-staging.ee54ba693a",
121
+ "@dxos/random": "0.9.1-staging.ee54ba693a",
122
+ "@dxos/react-client": "0.9.1-staging.ee54ba693a",
123
+ "@dxos/plugin-client": "0.9.1-staging.ee54ba693a",
124
+ "@dxos/react-ui-form": "0.9.1-staging.ee54ba693a",
125
+ "@dxos/plugin-space": "0.9.1-staging.ee54ba693a",
126
+ "@dxos/react-ui": "0.9.1-staging.ee54ba693a",
127
+ "@dxos/react-ui-menu": "0.9.1-staging.ee54ba693a",
128
+ "@dxos/react-ui-mosaic": "0.9.1-staging.ee54ba693a",
129
+ "@dxos/schema": "0.9.1-staging.ee54ba693a",
130
+ "@dxos/app-toolkit": "0.9.1-staging.ee54ba693a",
131
+ "@dxos/types": "0.9.1-staging.ee54ba693a",
132
+ "@dxos/util": "0.9.1-staging.ee54ba693a"
132
133
  },
133
134
  "devDependencies": {
134
- "@types/react": "~19.2.7",
135
+ "@types/react": "~19.2.17",
135
136
  "@types/react-dom": "~19.2.3",
136
- "react": "~19.2.3",
137
- "react-dom": "~19.2.3",
137
+ "react": "~19.2.7",
138
+ "react-dom": "~19.2.7",
138
139
  "vite": "^8.0.16",
139
- "@dxos/keys": "0.9.0",
140
- "@dxos/echo-client": "0.9.0",
141
- "@dxos/plugin-preview": "0.9.0",
142
- "@dxos/plugin-testing": "0.9.0",
143
- "@dxos/plugin-theme": "0.9.0",
144
- "@dxos/test-utils": "0.9.0",
145
- "@dxos/ui-theme": "0.9.0",
146
- "@dxos/react-ui-syntax-highlighter": "0.9.0",
147
- "@dxos/storybook-utils": "0.9.0"
140
+ "@dxos/keys": "0.9.1-staging.ee54ba693a",
141
+ "@dxos/echo-client": "0.9.1-staging.ee54ba693a",
142
+ "@dxos/plugin-preview": "0.9.1-staging.ee54ba693a",
143
+ "@dxos/plugin-testing": "0.9.1-staging.ee54ba693a",
144
+ "@dxos/plugin-theme": "0.9.1-staging.ee54ba693a",
145
+ "@dxos/react-ui-syntax-highlighter": "0.9.1-staging.ee54ba693a",
146
+ "@dxos/test-utils": "0.9.1-staging.ee54ba693a",
147
+ "@dxos/ui-theme": "0.9.1-staging.ee54ba693a",
148
+ "@dxos/storybook-utils": "0.9.1-staging.ee54ba693a"
148
149
  },
149
150
  "peerDependencies": {
150
- "effect": "3.21.3",
151
- "react": "~19.2.3",
152
- "react-dom": "~19.2.3",
153
- "@dxos/react-ui": "0.9.0",
154
- "@dxos/ui-theme": "0.9.0"
151
+ "effect": "3.21.4",
152
+ "react": "~19.2.7",
153
+ "react-dom": "~19.2.7",
154
+ "@dxos/ui-theme": "0.9.1-staging.ee54ba693a",
155
+ "@dxos/react-ui": "0.9.1-staging.ee54ba693a"
155
156
  },
156
157
  "publishConfig": {
157
158
  "access": "public"
@@ -5,12 +5,12 @@
5
5
  import { Plugin } from '@dxos/app-framework';
6
6
  import { AppPlugin } from '@dxos/app-toolkit';
7
7
 
8
- import { BlueprintDefinition, CreateObject, OperationHandler, UndoMappings } from '#capabilities';
8
+ import { CreateObject, OperationHandler, SkillDefinition, UndoMappings } from '#capabilities';
9
9
  import { meta } from '#meta';
10
10
  import { Kanban } from '#types';
11
11
 
12
12
  export const KanbanPlugin = Plugin.define(meta).pipe(
13
- AppPlugin.addBlueprintDefinitionModule({ activate: BlueprintDefinition }),
13
+ AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
14
14
  AppPlugin.addCreateObjectModule({ activate: CreateObject }),
15
15
  AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
16
16
  AppPlugin.addUndoMappingsModule({ activate: UndoMappings }),
@@ -11,7 +11,7 @@ import { KanbanPlugin } from '#plugin';
11
11
 
12
12
  import { meta } from './meta';
13
13
 
14
- const moduleId = (name: string) => `${meta.id}.module.${name}`;
14
+ const moduleId = (name: string) => `${meta.profile.key}.module.${name}`;
15
15
 
16
16
  describe('KanbanPlugin', () => {
17
17
  test('modules activate on the expected events', async ({ expect }) => {
@@ -24,8 +24,8 @@ describe('KanbanPlugin', () => {
24
24
  expect.arrayContaining([moduleId('OperationHandler'), moduleId('UndoMappings')]),
25
25
  );
26
26
 
27
- // BlueprintDefinition fires when AssistantPlugin loads blueprint definitions.
27
+ // SkillDefinition fires when AssistantPlugin loads skill definitions.
28
28
  await harness.fire(AppActivationEvents.SetupArtifactDefinition);
29
- expect(harness.manager.getActive()).toContain(moduleId('BlueprintDefinition'));
29
+ expect(harness.manager.getActive()).toContain(moduleId('SkillDefinition'));
30
30
  });
31
31
  });
@@ -5,7 +5,7 @@
5
5
  import { Plugin } from '@dxos/app-framework';
6
6
  import { AppPlugin } from '@dxos/app-toolkit';
7
7
 
8
- import { BlueprintDefinition, CreateObject, OperationHandler, UndoMappings, ReactSurface } from '#capabilities';
8
+ import { CreateObject, OperationHandler, ReactSurface, SkillDefinition, UndoMappings } from '#capabilities';
9
9
  import { meta } from '#meta';
10
10
  import { translations } from '#translations';
11
11
  import { Kanban } from '#types';
@@ -14,7 +14,7 @@ import { Kanban } from '#types';
14
14
  import pluginSpec from '../PLUGIN.mdl?raw';
15
15
 
16
16
  export const KanbanPlugin = Plugin.define(meta).pipe(
17
- AppPlugin.addBlueprintDefinitionModule({ activate: BlueprintDefinition }),
17
+ AppPlugin.addSkillDefinitionModule({ activate: SkillDefinition }),
18
18
  AppPlugin.addCreateObjectModule({ activate: CreateObject }),
19
19
  AppPlugin.addOperationHandlerModule({ activate: OperationHandler }),
20
20
  AppPlugin.addUndoMappingsModule({ activate: UndoMappings }),
@@ -22,7 +22,7 @@ export const KanbanPlugin = Plugin.define(meta).pipe(
22
22
  AppPlugin.addSurfaceModule({ activate: ReactSurface }),
23
23
  AppPlugin.addTranslationsModule({ translations }),
24
24
  AppPlugin.addPluginAssetModule({
25
- asset: { pluginId: meta.id, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
25
+ asset: { pluginId: meta.profile.key, path: 'PLUGIN.mdl', content: pluginSpec, mimeType: 'application/x-mdl' },
26
26
  }),
27
27
  Plugin.make,
28
28
  );
@@ -21,17 +21,19 @@ export default Capability.makeModule(
21
21
  createObject: (props, options) =>
22
22
  Effect.gen(function* () {
23
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 });
24
+ if (props.typename) {
25
+ const { view } = await ViewModel.makeFromDatabase({
26
+ db: options.db,
27
+ typename: props.typename,
28
+ pivotFieldName: props.initialPivotColumn,
29
+ });
30
+ return Kanban.make({ name: props.name, view });
31
+ }
32
+ return Kanban.makeItems({ name: props.name, pivotField: props.initialPivotColumn ?? '' });
30
33
  });
31
34
  return yield* Operation.invoke(SpaceOperation.AddObject, {
32
35
  object,
33
36
  target: options.target,
34
- hidden: true,
35
37
  targetNodeId: options.targetNodeId,
36
38
  });
37
39
  }),
@@ -3,15 +3,9 @@
3
3
  //
4
4
 
5
5
  import { Capability } from '@dxos/app-framework';
6
- import { type AppCapabilities } from '@dxos/app-toolkit';
7
6
  import type { OperationHandlerSet } from '@dxos/compute';
8
7
 
9
- // The contributed capability type references Blueprint types from @dxos/compute, so the lazy
10
- // wrapper needs an explicit annotation to keep the inferred type portable (TS2883).
11
- export const BlueprintDefinition: Capability.LazyCapability<
12
- void,
13
- Capability.Capability<typeof AppCapabilities.BlueprintDefinition>[]
14
- > = Capability.lazy('BlueprintDefinition', () => import('./blueprint-definition'));
8
+ export const SkillDefinition = Capability.lazy('SkillDefinition', () => import('./skill-definition'));
15
9
  export const CreateObject = Capability.lazy('CreateObject', () => import('./create-object'));
16
10
  export const OperationHandler = Capability.lazy<OperationHandlerSet.OperationHandlerSet>(
17
11
  'OperationHandler',
@@ -3,18 +3,17 @@
3
3
  //
4
4
 
5
5
  import * as Effect from 'effect/Effect';
6
- import type * as Schema from 'effect/Schema';
7
- import * as SchemaAST from 'effect/SchemaAST';
8
6
  import React, { useMemo } from 'react';
9
7
 
10
8
  import { Capabilities, Capability } from '@dxos/app-framework';
11
9
  import { Surface } from '@dxos/app-framework/ui';
12
10
  import { AppSurface } from '@dxos/app-toolkit/ui';
13
- import { type Collection, Database, Obj, Type } from '@dxos/echo';
11
+ import { Database, Obj, Type } from '@dxos/echo';
14
12
  import { SchemaEx } from '@dxos/effect';
15
- import { type FormFieldComponentProps, SelectField, useFormValues } from '@dxos/react-ui-form';
13
+ import { type FormFieldRendererProps, SelectField, useFormValues } from '@dxos/react-ui-form';
14
+ import { Position } from '@dxos/util';
16
15
 
17
- import { KanbanArticle, KanbanSettings } from '#containers';
16
+ import { KanbanArticle, KanbanProperties } from '#containers';
18
17
  import { Kanban, PivotColumnAnnotationId } from '#types';
19
18
 
20
19
  export default Capability.makeModule(() =>
@@ -31,35 +30,22 @@ export default Capability.makeModule(() =>
31
30
  }),
32
31
  Surface.create({
33
32
  id: 'objectProperties',
34
- position: 'first',
33
+ position: Position.first,
35
34
  filter: AppSurface.object(AppSurface.ObjectProperties, Kanban.Kanban),
36
- component: ({ data }) => <KanbanSettings subject={data.subject} />,
35
+ component: ({ data }) => <KanbanProperties subject={data.subject} />,
37
36
  }),
38
37
  Surface.create({
39
38
  id: 'createInitialSchemaForm',
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 = SchemaEx.findAnnotation<boolean>(
50
- (data.schema as Schema.Schema.All).ast,
51
- PivotColumnAnnotationId,
52
- );
53
- return !!annotation;
54
- },
55
- component: ({ data: { target, fieldPropertyAst }, ...inputProps }) => {
56
- const ast = fieldPropertyAst;
39
+ filter: AppSurface.formInputBySchema((ast) => !!SchemaEx.findAnnotation<boolean>(ast, PivotColumnAnnotationId)),
40
+ component: ({ data, ...inputProps }) => {
41
+ const ast = data.fieldPropertyAst;
57
42
  if (!ast) {
58
43
  return null;
59
44
  }
60
45
 
61
- const props = { ...inputProps, type: ast } as any as FormFieldComponentProps;
62
- const db = Database.isDatabase(target) ? target : target && Obj.getDatabase(target);
46
+ const props = { ...inputProps, type: ast } as any as FormFieldRendererProps;
47
+ const target = data.target;
48
+ const db = Database.isDatabase(target) ? target : Obj.isObject(target) ? Obj.getDatabase(target) : undefined;
63
49
  if (!db) {
64
50
  return null;
65
51
  }
@@ -84,7 +70,11 @@ export default Capability.makeModule(() =>
84
70
  }
85
71
 
86
72
  const columns = Object.entries(properties).reduce<string[]>((acc, [key, value]) => {
87
- if (typeof value === 'object' && value?.format === 'single-select') {
73
+ if (
74
+ typeof value === 'object' &&
75
+ value !== null &&
76
+ (value as { format?: string }).format === 'single-select'
77
+ ) {
88
78
  acc.push(key);
89
79
  }
90
80
  return acc;
@@ -0,0 +1,14 @@
1
+ //
2
+ // Copyright 2025 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 { KanbanSkill } from '#skills';
11
+
12
+ const skillDefinition = () => Effect.succeed([Capability.contributes(AppCapabilities.SkillDefinition, KanbanSkill)]);
13
+
14
+ export default skillDefinition;
@@ -19,7 +19,7 @@ export default Capability.makeModule(() =>
19
19
  props: output.props,
20
20
  index: output.index,
21
21
  }),
22
- message: ['card-field-deleted.label', { ns: meta.id }],
22
+ message: ['card-field-deleted.label', { ns: meta.profile.key }],
23
23
  }),
24
24
  UndoMapping.make({
25
25
  operation: KanbanOperation.DeleteCard,
@@ -27,7 +27,7 @@ export default Capability.makeModule(() =>
27
27
  deriveContext: (_input, output) => ({
28
28
  card: output.card,
29
29
  }),
30
- message: ['card-deleted.label', { ns: meta.id }],
30
+ message: ['card-deleted.label', { ns: meta.profile.key }],
31
31
  }),
32
32
  ]),
33
33
  ),
@@ -57,7 +57,7 @@ export const KanbanBoardRoot = ({
57
57
  onCardRemove,
58
58
  }: KanbanBoardRootProps) => {
59
59
  const registry = useContext(RegistryContext);
60
- const { t } = useTranslation(meta.id);
60
+ const { t } = useTranslation(meta.profile.key);
61
61
  const model = useKanbanBoardModel(kanban, projection, items, registry);
62
62
  const columns = model?.getColumns?.() ?? [];
63
63
  const view = kanban?.spec.kind === 'view' ? kanban.spec.view.target : undefined;
@@ -7,7 +7,7 @@ import React, { forwardRef, useCallback, useMemo, useState } from 'react';
7
7
  import { Surface } from '@dxos/app-framework/ui';
8
8
  import { AppSurface, useObjectMenuItems } from '@dxos/app-toolkit/ui';
9
9
  import { Obj } from '@dxos/echo';
10
- import { Card, Toolbar, useTranslation } from '@dxos/react-ui';
10
+ import { Card, IconButton, useTranslation } from '@dxos/react-ui';
11
11
  import { Menu, createMenuAction } from '@dxos/react-ui-menu';
12
12
  import { Focus, Mosaic, useBoard } from '@dxos/react-ui-mosaic';
13
13
 
@@ -25,7 +25,7 @@ const KANBAN_CARD_TILE_NAME = 'KanbanBoard.Card';
25
25
  */
26
26
  export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(
27
27
  ({ data, location, debug, draggable }, forwardedRef) => {
28
- const { t } = useTranslation(meta.id);
28
+ const { t } = useTranslation(meta.profile.key);
29
29
  const { model } = useBoard(KANBAN_CARD_TILE_NAME);
30
30
  const { projection, columnFieldPath, onCardRemove } = useKanbanBoard(KANBAN_CARD_TILE_NAME);
31
31
  const [dragHandle, setDragHandle] = useState<HTMLButtonElement | null>(null);
@@ -65,20 +65,22 @@ export const KanbanCard = forwardRef<HTMLDivElement, KanbanCardProps>(
65
65
  <Card.DragHandle ref={dragHandleRef} testId='mosaicBoard.cardDragHandle' />
66
66
  <Card.Title data-testid='mosaicBoard.cardTitle'>{Obj.getLabel(data)}</Card.Title>
67
67
  {/* TODO(wittjosiah): Reconcile with Card.Menu. */}
68
- <Menu.Trigger asChild disabled={!menuItems?.length}>
69
- <Toolbar.IconButton
70
- iconOnly
71
- variant='ghost'
72
- icon='ph--dots-three-vertical--regular'
73
- label={t('action-menu.label')}
74
- />
75
- </Menu.Trigger>
76
- <Menu.Content items={menuItems} />
68
+ <Card.Block end>
69
+ <Menu.Trigger asChild disabled={!menuItems?.length}>
70
+ <IconButton
71
+ iconOnly
72
+ variant='ghost'
73
+ icon='ph--dots-three-vertical--regular'
74
+ label={t('action-menu.label')}
75
+ />
76
+ </Menu.Trigger>
77
+ <Menu.Content items={menuItems} />
78
+ </Card.Block>
77
79
  </Card.Header>
78
80
  <Card.Body>
79
81
  {projection && (
80
82
  <Surface.Surface
81
- type={AppSurface.Card}
83
+ type={AppSurface.CardContent}
82
84
  limit={1}
83
85
  data={{
84
86
  subject: data,
@@ -22,7 +22,7 @@ import { PreviewPlugin } from '@dxos/plugin-preview/testing';
22
22
  import { SpacePlugin } from '@dxos/plugin-space/testing';
23
23
  import { StorybookPlugin, corePlugins } from '@dxos/plugin-testing';
24
24
  import { random } from '@dxos/random';
25
- import { type Space, useQuery, useType, useSpaces } from '@dxos/react-client/echo';
25
+ import { type Space, useQuery, useSpaces, useType } from '@dxos/react-client/echo';
26
26
  import { ViewEditor } from '@dxos/react-ui-form';
27
27
  import { Syntax } from '@dxos/react-ui-syntax-highlighter';
28
28
  import { withLayout } from '@dxos/react-ui/testing';
@@ -7,7 +7,7 @@ import React, { useCallback, useContext, useMemo } from 'react';
7
7
 
8
8
  import { useCapabilities, useOperationInvoker } from '@dxos/app-framework/ui';
9
9
  import { AppCapabilities } from '@dxos/app-toolkit';
10
- import { useSchemaFilter, type AppSurface } from '@dxos/app-toolkit/ui';
10
+ import { type AppSurface, useSchemaFilter } from '@dxos/app-toolkit/ui';
11
11
  import { Filter, Obj, Query, type Ref, Type } from '@dxos/echo';
12
12
  import { useObject, useType } from '@dxos/react-client/echo';
13
13
  import { Panel, Toolbar } from '@dxos/react-ui';
@@ -15,16 +15,16 @@ import { getTypeURIFromQuery } from '@dxos/schema';
15
15
  import { useProjectionModel } from '#hooks';
16
16
  import { type Kanban, KanbanSettingsSchema, KanbanViewSettingsSchema, UNCATEGORIZED_VALUE } from '#types';
17
17
 
18
- export type KanbanSettingsProps = AppSurface.ObjectPropertiesProps<Kanban.Kanban>;
18
+ export type KanbanPropertiesProps = AppSurface.ObjectPropertiesProps<Kanban.Kanban>;
19
19
 
20
20
  /**
21
- * Settings panel for a Kanban. Renders fields common to every kanban
21
+ * Object-properties panel for a Kanban. Renders fields common to every kanban
22
22
  * (currently the "Hide uncategorized column" toggle); for view-variant
23
23
  * kanbans an additional "Column field" picker drives the View's pivot
24
24
  * field. Items-variant kanbans use a hardcoded `spec.pivotField`, so that
25
25
  * field is omitted there.
26
26
  */
27
- export const KanbanSettings = ({ subject: object }: KanbanSettingsProps) => {
27
+ export const KanbanProperties = ({ subject: object }: KanbanPropertiesProps) => {
28
28
  const registry = useContext(RegistryContext);
29
29
  const db = Obj.getDatabase(object);
30
30
  const isView = object.spec.kind === 'view';
@@ -87,8 +87,15 @@ export const KanbanSettings = ({ subject: object }: KanbanSettingsProps) => {
87
87
  const settingsSchema = (isView ? KanbanViewSettingsSchema : KanbanSettingsSchema) as any;
88
88
 
89
89
  return (
90
- <Form.Root schema={settingsSchema} values={initialValues} fieldMap={fieldMap} onValuesChanged={handleValuesChanged}>
91
- <Form.FieldSet />
92
- </Form.Root>
90
+ <Form.Section>
91
+ <Form.Root
92
+ schema={settingsSchema}
93
+ values={initialValues}
94
+ fieldMap={fieldMap}
95
+ onValuesChanged={handleValuesChanged}
96
+ >
97
+ <Form.FieldSet />
98
+ </Form.Root>
99
+ </Form.Section>
93
100
  );
94
101
  };
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2026 DXOS.org
3
+ //
4
+
5
+ export { KanbanProperties as default } from './KanbanProperties';
@@ -5,4 +5,4 @@
5
5
  import { type ComponentType, lazy } from 'react';
6
6
 
7
7
  export const KanbanArticle: ComponentType<any> = lazy(() => import('./KanbanArticle'));
8
- export const KanbanSettings: ComponentType<any> = lazy(() => import('./KanbanSettings'));
8
+ export const KanbanProperties: ComponentType<any> = lazy(() => import('./KanbanProperties'));
@@ -18,25 +18,27 @@ import { Kanban } from '#types';
18
18
  import { useKanbanBoardModel } from './useKanbanBoardModel';
19
19
 
20
20
  // TODO(wittjosiah): Consider adding single-select to TestSchema.Task and using that instead.
21
- const KanbanTaskSchema = Schema.Struct({
22
- title: Schema.optional(Schema.String),
23
- status: Schema.Literal('__uncategorized__', 'a', 'b').pipe(
24
- FormatAnnotation.set(Format.TypeFormat.SingleSelect),
25
- Schema.annotations({
26
- title: 'Status',
27
- [PropertyMetaAnnotationId]: {
28
- singleSelect: {
29
- options: [
30
- { id: '__uncategorized__', title: 'Uncategorized', color: 'neutral' },
31
- { id: 'a', title: 'A', color: 'blue' },
32
- { id: 'b', title: 'B', color: 'green' },
33
- ],
21
+ const KanbanTaskSchema = Type.makeObject(DXN.make('com.example.type.kanbanTask', '0.1.0'))(
22
+ Schema.Struct({
23
+ title: Schema.optional(Schema.String),
24
+ status: Schema.Literal('__uncategorized__', 'a', 'b').pipe(
25
+ FormatAnnotation.set(Format.TypeFormat.SingleSelect),
26
+ Schema.annotations({
27
+ title: 'Status',
28
+ [PropertyMetaAnnotationId]: {
29
+ singleSelect: {
30
+ options: [
31
+ { id: '__uncategorized__', title: 'Uncategorized', color: 'neutral' },
32
+ { id: 'a', title: 'A', color: 'blue' },
33
+ { id: 'b', title: 'B', color: 'green' },
34
+ ],
35
+ },
34
36
  },
35
- },
36
- }),
37
- Schema.optional,
38
- ),
39
- }).pipe(Type.makeObject(DXN.make('com.example.type.kanbanTask', '0.1.0')));
37
+ }),
38
+ Schema.optional,
39
+ ),
40
+ }),
41
+ );
40
42
 
41
43
  type KanbanTask = Type.InstanceType<typeof KanbanTaskSchema>;
42
44
 
package/src/index.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- export * from './blueprints';
5
+ export * from './skills';
6
6
  export * from './meta';
7
7
  export * from './operations';
8
8
  export * from './types';
package/src/meta.ts CHANGED
@@ -3,34 +3,7 @@
3
3
  //
4
4
 
5
5
  import { Plugin } from '@dxos/app-framework';
6
- import { DXN } from '@dxos/echo';
7
- import { trim } from '@dxos/util';
8
6
 
9
- export const meta = Plugin.makeMeta({
10
- key: DXN.make('org.dxos.plugin.kanban'),
11
- name: 'Kanban',
12
- author: 'DXOS',
13
- description: trim`
14
- Visual project management using customizable kanban boards to track workflow progress.
15
- Organize any ECHO type into drag-and-drop columns defined by a single-select field, move cards
16
- between stages, and reorder both columns and cards — all changes are persisted to ECHO and
17
- replicated to collaborators in real time.
7
+ import config from '../dx.config';
18
8
 
19
- Kanban boards come in two variants: view-variant boards source their cards through a linked
20
- View query (any ECHO type can be pivoted on a single-select field), while items-variant boards
21
- own their cards explicitly and are used by external sync integrations such as Linear or GitHub.
22
- Both variants share the same arrangement storage and drag-and-drop mechanics.
23
-
24
- Board settings let users choose which single-select field drives the column layout and
25
- optionally hide the uncategorized column for items that have no pivot value.
26
- Field-level undo support allows deleted card fields to be restored without data loss.
27
-
28
- The plugin contributes a Kanban blueprint that exposes board creation and card management
29
- to AI agents, enabling automated project tracking workflows.
30
- `,
31
- icon: 'ph--kanban--regular',
32
- iconHue: 'green',
33
- source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-kanban',
34
- spec: 'PLUGIN.mdl',
35
- screenshots: ['https://dxos.network/plugin-details-kanban-dark.png'],
36
- });
9
+ export const meta = Plugin.getMetaFromConfig(config);
@@ -0,0 +1,5 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ export { default as KanbanSkill } from './kanban-skill';