@abraca/mcp 1.5.0 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/mcp",
3
- "version": "1.5.0",
3
+ "version": "1.8.0",
4
4
  "description": "MCP server for Abracadabra — AI agent collaboration on CRDT documents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -28,9 +28,9 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@modelcontextprotocol/sdk": "^1.27.1",
31
+ "@modelcontextprotocol/sdk": "^1.29.0",
32
32
  "@noble/hashes": "^1.8.0",
33
- "zod": "^3.25.0"
33
+ "zod": "^4.3.6"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@abraca/dabra": ">=1.0.0",
@@ -0,0 +1,408 @@
1
+ /**
2
+ * Static catalog of Abracadabra page types and their metadata schemas.
3
+ *
4
+ * Kept in sync with `cou-sh/app/utils/docTypes.ts` and the plugin definitions
5
+ * under `cou-sh/plugin-<name>/src/index.ts`. No UI dependencies — it
6
+ * is a plain data description so agents (via MCP) and CLI tooling can discover
7
+ * what fields apply to which renderer without having to read the dashboard
8
+ * source code.
9
+ *
10
+ * Schema semantics (from page-type-guidelines.md):
11
+ *
12
+ * - `metaSchema` — fields that apply to DESCENDANTS (children, grandchildren,
13
+ * and beyond) of a page of this type. E.g. the calendar's schema describes
14
+ * what an *event* meta looks like, not the calendar itself.
15
+ * - `defaultMetaFields` — fields inserted into the page doc's own metadata
16
+ * when first rendered; these are view config knobs (e.g. `calendarView`).
17
+ */
18
+
19
+ export type MetaFieldType
20
+ = | 'datetimerange'
21
+ | 'daterange'
22
+ | 'timerange'
23
+ | 'datetime'
24
+ | 'date'
25
+ | 'time'
26
+ | 'slider'
27
+ | 'number'
28
+ | 'toggle'
29
+ | 'select'
30
+ | 'multiselect'
31
+ | 'colorPreset'
32
+ | 'colorPicker'
33
+ | 'location'
34
+ | 'icon'
35
+ | 'textarea'
36
+ | 'url'
37
+ | 'rating'
38
+ | 'tags'
39
+ | 'members'
40
+
41
+ export interface PageTypeMetaField {
42
+ type: MetaFieldType
43
+ label?: string
44
+ /** single-value fields */
45
+ key?: string
46
+ /** location */
47
+ latKey?: string
48
+ lngKey?: string
49
+ /** ranges */
50
+ startKey?: string
51
+ endKey?: string
52
+ allDayKey?: string
53
+ /** color preset */
54
+ presets?: string[]
55
+ /** icon / select / tags */
56
+ options?: string[]
57
+ /** slider / number */
58
+ min?: number
59
+ max?: number
60
+ step?: number
61
+ unit?: string
62
+ /** toggle default */
63
+ default?: boolean
64
+ }
65
+
66
+ export interface PageTypeInfo {
67
+ key: string
68
+ label: string
69
+ icon: string
70
+ description?: string
71
+ /** true = core type (always available); false = requires plugin */
72
+ core: boolean
73
+ plugin?: string
74
+ supportsChildren: boolean
75
+ childLabel?: string
76
+ grandchildLabel?: string
77
+ /** -1 = unlimited depth */
78
+ defaultDepth?: number
79
+ /** Fields that apply to this doc's descendants (children, grandchildren, ...) */
80
+ metaSchema?: PageTypeMetaField[]
81
+ /** Fields written to this doc's own meta on first render (renderer config) */
82
+ defaultMetaFields?: PageTypeMetaField[]
83
+ }
84
+
85
+ const GEO_COLOR_PRESETS = ['#3b82f6', '#f97316', '#22c55e', '#ef4444', '#a855f7']
86
+ const GEO_ICON_OPTIONS = [
87
+ 'map-pin', 'star', 'flag', 'home', 'building-2', 'coffee', 'utensils',
88
+ 'camera', 'heart', 'zap', 'triangle-alert', 'car', 'plane', 'anchor',
89
+ 'tree-pine', 'mountain', 'waves', 'shield', 'crosshair', 'circle-dot',
90
+ 'bookmark', 'gem', 'radio', 'compass',
91
+ ]
92
+
93
+ export const GEO_TYPE_META_SCHEMAS: Record<string, PageTypeMetaField[]> = {
94
+ marker: [
95
+ { type: 'location', latKey: 'geoLat', lngKey: 'geoLng', label: 'Location' },
96
+ { type: 'icon', key: 'icon', options: GEO_ICON_OPTIONS, label: 'Icon' },
97
+ { type: 'colorPreset', key: 'color', presets: GEO_COLOR_PRESETS, label: 'Color' },
98
+ ],
99
+ line: [
100
+ { type: 'colorPreset', key: 'color', presets: GEO_COLOR_PRESETS, label: 'Color' },
101
+ ],
102
+ measure: [],
103
+ }
104
+
105
+ export const PAGE_TYPES: Record<string, PageTypeInfo> = {
106
+ doc: {
107
+ key: 'doc',
108
+ label: 'Document',
109
+ icon: 'file-text',
110
+ description: 'Rich text document with real-time collaboration',
111
+ core: true,
112
+ supportsChildren: true,
113
+ },
114
+ kanban: {
115
+ key: 'kanban',
116
+ label: 'Kanban',
117
+ icon: 'kanban',
118
+ description: 'Drag-and-drop task board with columns and cards',
119
+ core: true,
120
+ supportsChildren: true,
121
+ childLabel: 'Column',
122
+ grandchildLabel: 'Card',
123
+ defaultMetaFields: [
124
+ { type: 'select', key: 'kanbanColumnWidth', options: ['narrow', 'default', 'wide'], label: 'Column Width' },
125
+ ],
126
+ },
127
+ gallery: {
128
+ key: 'gallery',
129
+ label: 'Gallery',
130
+ icon: 'images',
131
+ description: 'Visual grid of items with rich content',
132
+ core: true,
133
+ supportsChildren: true,
134
+ childLabel: 'Item',
135
+ metaSchema: [
136
+ { type: 'location', latKey: 'geoLat', lngKey: 'geoLng', label: 'Location' },
137
+ { type: 'datetime', key: 'datetimeStart', label: 'Date' },
138
+ { type: 'tags', key: 'tags', label: 'Tags' },
139
+ { type: 'rating', key: 'rating', max: 5, label: 'Rating' },
140
+ { type: 'icon', key: 'icon', label: 'Icon' },
141
+ { type: 'colorPreset', key: 'color', presets: ['#6366f1', '#ec4899', '#f97316', '#22c55e', '#3b82f6', '#a855f7'], label: 'Color' },
142
+ ],
143
+ defaultMetaFields: [
144
+ { type: 'number', key: 'galleryColumns', min: 1, max: 6, step: 1, label: 'Columns' },
145
+ { type: 'select', key: 'galleryAspect', options: ['square', '4:3', '3:2', '16:9', 'free'], label: 'Aspect Ratio' },
146
+ { type: 'select', key: 'galleryCardStyle', options: ['default', 'compact', 'detailed'], label: 'Card Style' },
147
+ { type: 'toggle', key: 'galleryShowLabels', label: 'Show Labels' },
148
+ { type: 'select', key: 'gallerySortBy', options: ['manual', 'date', 'name', 'rating'], label: 'Sort' },
149
+ ],
150
+ },
151
+ table: {
152
+ key: 'table',
153
+ label: 'Table',
154
+ icon: 'table',
155
+ description: 'Collaborative spreadsheet with custom fields',
156
+ core: true,
157
+ supportsChildren: true,
158
+ childLabel: 'Column',
159
+ grandchildLabel: 'Row',
160
+ defaultMetaFields: [
161
+ { type: 'select', key: 'tableMode', options: ['hierarchy', 'flat'], label: 'Mode' },
162
+ { type: 'select', key: 'tableSortDir', options: ['asc', 'desc'], label: 'Sort Direction' },
163
+ ],
164
+ },
165
+ outline: {
166
+ key: 'outline',
167
+ label: 'Outline',
168
+ icon: 'list-tree',
169
+ description: 'Hierarchical outline with keyboard navigation',
170
+ core: true,
171
+ supportsChildren: true,
172
+ childLabel: 'Item',
173
+ defaultDepth: -1,
174
+ },
175
+ checklist: {
176
+ key: 'checklist',
177
+ label: 'Checklist',
178
+ icon: 'check-square',
179
+ description: 'Collaborative checklist with sub-tasks, drag-and-drop, and due dates',
180
+ core: true,
181
+ supportsChildren: true,
182
+ childLabel: 'Task',
183
+ defaultDepth: -1,
184
+ metaSchema: [
185
+ { type: 'toggle', key: 'checked', label: 'Done' },
186
+ { type: 'select', key: 'priority', options: ['none', 'low', 'medium', 'high'], label: 'Priority' },
187
+ { type: 'date', key: 'dateEnd', label: 'Due date' },
188
+ ],
189
+ defaultMetaFields: [
190
+ { type: 'select', key: 'checklistFilter', options: ['all', 'active', 'completed'], label: 'Filter' },
191
+ { type: 'select', key: 'checklistSort', options: ['manual', 'priority', 'due'], label: 'Sort' },
192
+ ],
193
+ },
194
+ graph: {
195
+ key: 'graph',
196
+ label: 'Graph',
197
+ icon: 'git-fork',
198
+ description: 'Force-directed knowledge graph — full document tree as nodes & edges',
199
+ core: true,
200
+ supportsChildren: true,
201
+ childLabel: 'Node',
202
+ defaultMetaFields: [
203
+ { type: 'toggle', key: 'showRefEdges', label: 'Show Ref Edges', default: true },
204
+ ],
205
+ },
206
+ timeline: {
207
+ key: 'timeline',
208
+ label: 'Timeline',
209
+ icon: 'gantt-chart',
210
+ description: 'Gantt-style project timeline with epics and tasks',
211
+ core: true,
212
+ supportsChildren: true,
213
+ childLabel: 'Epic',
214
+ grandchildLabel: 'Task',
215
+ metaSchema: [
216
+ { type: 'daterange', startKey: 'dateStart', endKey: 'dateEnd' },
217
+ { type: 'slider', key: 'taskProgress', min: 0, max: 100, label: 'Progress' },
218
+ { type: 'colorPreset', key: 'color', presets: ['#6366f1', '#818cf8', '#f97316', '#22c55e', '#3b82f6', '#a855f7'], label: 'Color' },
219
+ ],
220
+ },
221
+ calendar: {
222
+ key: 'calendar',
223
+ label: 'Calendar',
224
+ icon: 'calendar',
225
+ description: 'Event calendar with month, week, and day views',
226
+ core: true,
227
+ supportsChildren: true,
228
+ childLabel: 'Event',
229
+ metaSchema: [
230
+ { type: 'datetimerange', startKey: 'datetimeStart', endKey: 'datetimeEnd', allDayKey: 'allDay' },
231
+ { type: 'colorPreset', key: 'color', presets: ['#6366f1', '#ec4899', '#f97316', '#22c55e', '#3b82f6', '#a855f7'], label: 'Color' },
232
+ { type: 'icon', key: 'icon', label: 'Icon' },
233
+ ],
234
+ defaultMetaFields: [
235
+ { type: 'select', key: 'calendarWeekStart', options: ['sun', 'mon'], label: 'Week Starts' },
236
+ { type: 'select', key: 'calendarView', options: ['month', 'week', 'day'], label: 'Default View' },
237
+ { type: 'toggle', key: 'calendarShowWeekNumbers', label: 'Show Week Numbers' },
238
+ ],
239
+ },
240
+ map: {
241
+ key: 'map',
242
+ label: 'Map',
243
+ icon: 'map',
244
+ description: 'Collaborative world map with shared markers',
245
+ core: true,
246
+ supportsChildren: true,
247
+ childLabel: 'Location',
248
+ defaultMetaFields: [
249
+ { type: 'toggle', key: 'mapShowLabels', label: 'Show Labels', default: true },
250
+ ],
251
+ },
252
+ dashboard: {
253
+ key: 'dashboard',
254
+ label: 'Dashboard',
255
+ icon: 'layout-dashboard',
256
+ description: 'Arrange documents as draggable icons with optional widget views',
257
+ core: true,
258
+ supportsChildren: true,
259
+ childLabel: 'Item',
260
+ },
261
+ call: {
262
+ key: 'call',
263
+ label: 'Call',
264
+ icon: 'phone',
265
+ description: 'Video call room with live audio and screen sharing',
266
+ core: true,
267
+ supportsChildren: false,
268
+ },
269
+ chart: {
270
+ key: 'chart',
271
+ label: 'Chart',
272
+ icon: 'bar-chart-3',
273
+ description: 'Charts — manual data points or aggregation over document trees',
274
+ core: true,
275
+ supportsChildren: true,
276
+ childLabel: 'Data Point',
277
+ grandchildLabel: 'Data Point',
278
+ metaSchema: [
279
+ { type: 'number', key: 'number', step: 0.01, label: 'Value' },
280
+ { type: 'colorPreset', key: 'color', presets: ['#6366f1', '#ec4899', '#f97316', '#22c55e', '#3b82f6', '#a855f7', '#14b8a6', '#eab308'], label: 'Color' },
281
+ { type: 'tags', key: 'tags', label: 'Tags' },
282
+ ],
283
+ defaultMetaFields: [
284
+ { type: 'select', key: 'chartType', options: ['bar', 'stacked bar', 'line', 'donut', 'treemap'], label: 'Chart Type' },
285
+ { type: 'select', key: 'chartMetric', options: ['value', 'type', 'tag', 'status', 'priority', 'activity', 'completion'], label: 'Metric' },
286
+ { type: 'select', key: 'chartColorScheme', options: ['default', 'warm', 'cool', 'mono'], label: 'Colors' },
287
+ { type: 'number', key: 'chartLimit', min: 3, max: 30, step: 1, label: 'Max Items' },
288
+ { type: 'toggle', key: 'chartShowLegend', label: 'Show Legend', default: true },
289
+ { type: 'toggle', key: 'chartShowValues', label: 'Show Values' },
290
+ ],
291
+ },
292
+ sheets: {
293
+ key: 'sheets',
294
+ label: 'Sheets',
295
+ icon: 'grid-3x3',
296
+ description: 'Spreadsheet — cells, formulas, and formatting in a collaborative grid',
297
+ core: true,
298
+ supportsChildren: true,
299
+ childLabel: 'Column',
300
+ grandchildLabel: 'Cell',
301
+ defaultMetaFields: [
302
+ { type: 'number', key: 'sheetsDefaultColWidth', min: 40, max: 500, step: 10, label: 'Column Width' },
303
+ { type: 'number', key: 'sheetsDefaultRowHeight', min: 20, max: 100, step: 2, label: 'Row Height' },
304
+ { type: 'toggle', key: 'sheetsShowGridlines', label: 'Gridlines' },
305
+ ],
306
+ },
307
+ slides: {
308
+ key: 'slides',
309
+ label: 'Slides',
310
+ icon: 'presentation',
311
+ description: 'Presentation slides with two-axis navigation',
312
+ core: true,
313
+ supportsChildren: true,
314
+ childLabel: 'Slide',
315
+ grandchildLabel: 'Sub-slide',
316
+ metaSchema: [
317
+ { type: 'select', key: 'slidesTransition', options: ['none', 'fade', 'slide'], label: 'Transition' },
318
+ { type: 'colorPreset', key: 'color', presets: ['#6366f1', '#ec4899', '#f97316', '#22c55e', '#3b82f6', '#a855f7'], label: 'Accent' },
319
+ ],
320
+ defaultMetaFields: [
321
+ { type: 'select', key: 'slidesTheme', options: ['dark', 'light'], label: 'Theme' },
322
+ ],
323
+ },
324
+ overview: {
325
+ key: 'overview',
326
+ label: 'Overview',
327
+ icon: 'radar',
328
+ description: 'Space home — activity, people, stats, and health at a glance',
329
+ core: true,
330
+ supportsChildren: true,
331
+ childLabel: 'Page',
332
+ },
333
+
334
+ // Plugin-contributed types — require the named plugin to be enabled server-side.
335
+
336
+ spatial: {
337
+ key: 'spatial',
338
+ label: 'Spatial',
339
+ icon: 'box',
340
+ description: '3D scene with collaborative objects and real-time presence',
341
+ core: false,
342
+ plugin: 'spatial',
343
+ supportsChildren: true,
344
+ childLabel: 'Object',
345
+ grandchildLabel: 'Part',
346
+ defaultDepth: -1,
347
+ metaSchema: [
348
+ { type: 'select', key: 'spShape', options: ['box', 'sphere', 'cylinder', 'cone', 'plane', 'torus', 'glb'], label: 'Shape' },
349
+ { type: 'colorPreset', key: 'color', presets: ['#6366f1', '#ef4444', '#22c55e', '#3b82f6', '#f97316', '#a855f7', '#ec4899', '#14b8a6'], label: 'Color' },
350
+ { type: 'slider', key: 'spOpacity', min: 0, max: 100, label: 'Opacity' },
351
+ { type: 'number', key: 'spX', step: 0.1, label: 'X' },
352
+ { type: 'number', key: 'spY', step: 0.1, label: 'Y' },
353
+ { type: 'number', key: 'spZ', step: 0.1, label: 'Z' },
354
+ { type: 'number', key: 'spRX', min: -180, max: 180, step: 1, label: 'Rot X' },
355
+ { type: 'number', key: 'spRY', min: -180, max: 180, step: 1, label: 'Rot Y' },
356
+ { type: 'number', key: 'spRZ', min: -180, max: 180, step: 1, label: 'Rot Z' },
357
+ { type: 'number', key: 'spSX', min: 0.01, max: 100, step: 0.1, label: 'Scale X' },
358
+ { type: 'number', key: 'spSY', min: 0.01, max: 100, step: 0.1, label: 'Scale Y' },
359
+ { type: 'number', key: 'spSZ', min: 0.01, max: 100, step: 0.1, label: 'Scale Z' },
360
+ ],
361
+ defaultMetaFields: [
362
+ { type: 'toggle', key: 'spatialGridVisible', label: 'Show Grid', default: true },
363
+ ],
364
+ },
365
+ media: {
366
+ key: 'media',
367
+ label: 'Media',
368
+ icon: 'disc-3',
369
+ description: 'Media player with synced listening and playlists',
370
+ core: false,
371
+ plugin: 'media',
372
+ supportsChildren: true,
373
+ childLabel: 'Track',
374
+ defaultDepth: -1,
375
+ metaSchema: [
376
+ { type: 'tags', key: 'tags', label: 'Tags' },
377
+ ],
378
+ defaultMetaFields: [
379
+ { type: 'select', key: 'mediaRepeat', options: ['off', 'all', 'one'], label: 'Repeat' },
380
+ { type: 'toggle', key: 'mediaShuffle', label: 'Shuffle' },
381
+ ],
382
+ },
383
+ coder: {
384
+ key: 'coder',
385
+ label: 'Coder',
386
+ icon: 'code-2',
387
+ description: 'Collaborative multi-file coding environment',
388
+ core: false,
389
+ plugin: 'coder',
390
+ supportsChildren: true,
391
+ childLabel: 'File',
392
+ defaultDepth: -1,
393
+ metaSchema: [
394
+ { type: 'select', key: 'fileType', options: ['vue', 'ts', 'js', 'css', 'json', 'folder'], label: 'Type' },
395
+ { type: 'toggle', key: 'entry', label: 'Entry Point' },
396
+ ],
397
+ },
398
+ }
399
+
400
+ export const TYPE_ALIASES: Record<string, string> = {
401
+ desktop: 'dashboard',
402
+ }
403
+
404
+ export function resolvePageType(key: string | undefined): PageTypeInfo | undefined {
405
+ if (!key) return undefined
406
+ const resolved = TYPE_ALIASES[key] ?? key
407
+ return PAGE_TYPES[resolved]
408
+ }
@@ -14,6 +14,7 @@ export interface UserMetaField {
14
14
  max?: number
15
15
  step?: number
16
16
  unit?: string
17
+ default?: boolean
17
18
  }
18
19
 
19
20
  export interface PageMeta extends Record<string, unknown> {
@@ -31,6 +32,7 @@ export interface PageMeta extends Record<string, unknown> {
31
32
  dateEnd?: string
32
33
  timeStart?: string
33
34
  timeEnd?: string
35
+ dateTaken?: string
34
36
 
35
37
  // Task/status
36
38
  checked?: boolean
@@ -59,13 +61,6 @@ export interface PageMeta extends Record<string, unknown> {
59
61
  geoLng?: number
60
62
  geoDescription?: string
61
63
 
62
- // Whiteboard
63
- wbX?: number
64
- wbY?: number
65
- wbW?: number
66
- wbH?: number
67
- wbBg?: string
68
-
69
64
  // Dashboard
70
65
  deskX?: number
71
66
  deskY?: number
@@ -80,11 +75,9 @@ export interface PageMeta extends Record<string, unknown> {
80
75
  graphX?: number
81
76
  graphY?: number
82
77
  graphPinned?: boolean
83
- showRefEdges?: boolean
84
78
 
85
- // Spatial (3D)
79
+ // Spatial (3D) — spatial uses the universal `color` key (no spColor)
86
80
  spShape?: string
87
- spColor?: string
88
81
  spOpacity?: number
89
82
  spX?: number
90
83
  spY?: number
@@ -116,7 +109,6 @@ export interface PageMeta extends Record<string, unknown> {
116
109
  mediaAlbum?: string
117
110
  mediaGenre?: string
118
111
  mediaYear?: number
119
- dateTaken?: string
120
112
 
121
113
  // Sheets cell formatting
122
114
  bold?: boolean
@@ -126,6 +118,10 @@ export interface PageMeta extends Record<string, unknown> {
126
118
  align?: string
127
119
  formula?: string
128
120
 
121
+ // Coder plugin (per-file)
122
+ fileType?: string
123
+ entry?: boolean
124
+
129
125
  // Renderer config (set on the page doc itself, not children)
130
126
  kanbanColumnWidth?: string
131
127
  galleryColumns?: number
@@ -137,15 +133,23 @@ export interface PageMeta extends Record<string, unknown> {
137
133
  calendarWeekStart?: string
138
134
  calendarShowWeekNumbers?: boolean
139
135
  tableMode?: string
136
+ tableSortKey?: string
140
137
  tableSortDir?: string
141
138
  tableColumns?: any[]
142
139
  tableColumnWidths?: Record<string, number>
143
140
  tableColumnOrder?: string[]
144
141
  timelineZoom?: string
142
+ timelinePixelsPerDay?: number
143
+ timelineCenterDate?: string
145
144
  checklistFilter?: string
146
145
  checklistSort?: string
147
146
  mapShowLabels?: boolean
148
147
  spatialGridVisible?: boolean
148
+ graphSpacing?: string
149
+ graphShowLabels?: boolean
150
+ graphEdgeThickness?: string
151
+ mmSpacing?: string
152
+ showRefEdges?: boolean
149
153
  chartType?: string
150
154
  chartMetric?: string
151
155
  chartColorScheme?: string