@abraca/mcp 1.6.0 → 1.8.1
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/dist/abracadabra-mcp.cjs +1165 -190
- package/dist/abracadabra-mcp.cjs.map +1 -1
- package/dist/abracadabra-mcp.esm.js +1165 -190
- package/dist/abracadabra-mcp.esm.js.map +1 -1
- package/dist/index.d.ts +32 -1
- package/package.json +1 -1
- package/src/converters/page-types.ts +408 -0
- package/src/converters/types.ts +15 -11
- package/src/hook-bridge.ts +18 -8
- package/src/index.ts +29 -2
- package/src/mentions.ts +42 -0
- package/src/resources/agent-guide.ts +151 -29
- package/src/server.ts +139 -14
- package/src/tools/awareness.ts +3 -0
- package/src/tools/channel.ts +18 -8
- package/src/tools/content.ts +0 -5
- package/src/tools/files.ts +8 -0
- package/src/tools/meta.ts +1 -7
- package/src/tools/svg.ts +0 -3
- package/src/tools/tree.ts +28 -22
package/dist/index.d.ts
CHANGED
|
@@ -3,12 +3,23 @@ import { AbracadabraClient, AbracadabraProvider, ServerInfo, SpaceMeta } from "@
|
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
|
|
5
5
|
//#region packages/mcp/src/server.d.ts
|
|
6
|
+
/**
|
|
7
|
+
* Controls when the agent reacts to incoming chat:
|
|
8
|
+
* - `all` — respond to every message in every visible channel (legacy)
|
|
9
|
+
* - `mention` — group chats require `@<alias>`; DMs always respond
|
|
10
|
+
* - `task` — ignore chat entirely; only respond to ai:task awareness events
|
|
11
|
+
* - `mention+task` — group chats require mention OR ai:task; DMs always respond (default)
|
|
12
|
+
*/
|
|
13
|
+
type TriggerMode = 'all' | 'mention' | 'task' | 'mention+task';
|
|
6
14
|
interface MCPServerConfig {
|
|
7
15
|
url: string;
|
|
8
16
|
agentName?: string;
|
|
9
17
|
agentColor?: string;
|
|
10
18
|
inviteCode?: string;
|
|
11
19
|
keyFile?: string;
|
|
20
|
+
triggerMode?: TriggerMode;
|
|
21
|
+
/** Aliases matched in `@<alias>` tokens. Defaults to `[agentName]`. */
|
|
22
|
+
mentionAliases?: string[];
|
|
12
23
|
}
|
|
13
24
|
declare class AbracadabraMCPServer {
|
|
14
25
|
readonly config: MCPServerConfig;
|
|
@@ -28,9 +39,14 @@ declare class AbracadabraMCPServer {
|
|
|
28
39
|
private _typingInterval;
|
|
29
40
|
private _lastChatChannel;
|
|
30
41
|
private _signFn;
|
|
42
|
+
/** Rolling buffer of the last N tool calls in the current turn, surfaced via awareness. */
|
|
43
|
+
private _toolHistory;
|
|
44
|
+
private static readonly TOOL_HISTORY_MAX;
|
|
31
45
|
constructor(config: MCPServerConfig);
|
|
32
46
|
get agentName(): string;
|
|
33
47
|
get agentColor(): string;
|
|
48
|
+
get triggerMode(): TriggerMode;
|
|
49
|
+
get mentionAliases(): string[];
|
|
34
50
|
get serverInfo(): ServerInfo | null;
|
|
35
51
|
get rootDocId(): string | null;
|
|
36
52
|
get spaces(): SpaceMeta[];
|
|
@@ -50,6 +66,8 @@ declare class AbracadabraMCPServer {
|
|
|
50
66
|
getTreeMap(): Y.Map<any> | null;
|
|
51
67
|
/** Get the root doc-trash Y.Map of the active space. */
|
|
52
68
|
getTrashMap(): Y.Map<any> | null;
|
|
69
|
+
/** Get plugin names enabled in the active space via space-plugins Y.Map. */
|
|
70
|
+
getEnabledPluginNames(): string[];
|
|
53
71
|
/**
|
|
54
72
|
* Get or create a child provider for a given document ID.
|
|
55
73
|
* Caches providers and waits for sync before returning.
|
|
@@ -84,12 +102,25 @@ declare class AbracadabraMCPServer {
|
|
|
84
102
|
* dashboard only shows it in the relevant chat. Defaults to `_lastChatChannel`.
|
|
85
103
|
*/
|
|
86
104
|
setAutoStatus(status: string | null, docId?: string, statusContext?: string | null): void;
|
|
105
|
+
/**
|
|
106
|
+
* Start a new agent turn. Mints a fresh UUID and writes it to awareness so
|
|
107
|
+
* the dashboard can gate the incantation on "there is an active turn",
|
|
108
|
+
* decoupled from the (racier) status field. Called from chat arrival and
|
|
109
|
+
* ai:task dispatch right before `setAutoStatus('thinking')`.
|
|
110
|
+
*/
|
|
111
|
+
private _beginTurn;
|
|
87
112
|
/** Re-send typing indicator every 2s so dashboard keeps showing it (expires at 3s). */
|
|
88
113
|
private _startTypingInterval;
|
|
89
114
|
private _stopTypingInterval;
|
|
90
115
|
/**
|
|
91
116
|
* Broadcast which tool the agent is currently executing.
|
|
92
|
-
*
|
|
117
|
+
*
|
|
118
|
+
* Renders as a ChatTool pill on the dashboard. On non-null calls, the tool
|
|
119
|
+
* is also appended to `toolHistory` (capped at TOOL_HISTORY_MAX) and written
|
|
120
|
+
* to awareness so the dashboard's inline trace can show the turn's recent
|
|
121
|
+
* activity. Tools do NOT clear (`setActiveToolCall(null)`) on completion —
|
|
122
|
+
* the pill stays until the next tool replaces it or `setAutoStatus(null)`
|
|
123
|
+
* flushes the turn. This keeps pills visible long enough to see.
|
|
93
124
|
*/
|
|
94
125
|
setActiveToolCall(toolCall: {
|
|
95
126
|
name: string;
|
package/package.json
CHANGED
|
@@ -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
|
+
}
|
package/src/converters/types.ts
CHANGED
|
@@ -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
|
package/src/hook-bridge.ts
CHANGED
|
@@ -149,6 +149,9 @@ export class HookBridge {
|
|
|
149
149
|
private routeEvent(payload: Record<string, any>): void {
|
|
150
150
|
const event = payload.hook_event_name
|
|
151
151
|
switch (event) {
|
|
152
|
+
case 'UserPromptSubmit':
|
|
153
|
+
this.onUserPromptSubmit()
|
|
154
|
+
break
|
|
152
155
|
case 'PreToolUse':
|
|
153
156
|
this.onPreToolUse(payload)
|
|
154
157
|
break
|
|
@@ -159,7 +162,7 @@ export class HookBridge {
|
|
|
159
162
|
this.onSubagentStart(payload)
|
|
160
163
|
break
|
|
161
164
|
case 'SubagentStop':
|
|
162
|
-
this.onSubagentStop(
|
|
165
|
+
this.onSubagentStop()
|
|
163
166
|
break
|
|
164
167
|
case 'Stop':
|
|
165
168
|
this.onStop()
|
|
@@ -167,6 +170,12 @@ export class HookBridge {
|
|
|
167
170
|
}
|
|
168
171
|
}
|
|
169
172
|
|
|
173
|
+
/** New user turn — reset any lingering status/tool state from the previous turn. */
|
|
174
|
+
private onUserPromptSubmit(): void {
|
|
175
|
+
this.server.setAutoStatus(null)
|
|
176
|
+
this.server.setActiveToolCall(null)
|
|
177
|
+
}
|
|
178
|
+
|
|
170
179
|
private onPreToolUse(payload: Record<string, any>): void {
|
|
171
180
|
const toolName: string = payload.tool_name ?? ''
|
|
172
181
|
// Skip Abracadabra MCP tools — they set awareness themselves
|
|
@@ -184,10 +193,10 @@ export class HookBridge {
|
|
|
184
193
|
const toolName: string = payload.tool_name ?? ''
|
|
185
194
|
if (toolName.startsWith('mcp__abracadabra__')) return
|
|
186
195
|
|
|
187
|
-
// Don't
|
|
188
|
-
//
|
|
189
|
-
//
|
|
190
|
-
|
|
196
|
+
// Don't touch status — let the short auto-clear timer handle idle
|
|
197
|
+
// detection, or the next PreToolUse / Stop / UserPromptSubmit override it.
|
|
198
|
+
// Don't clear activeToolCall either: the pill stays until the next tool
|
|
199
|
+
// replaces it or the turn ends, preventing flashes between tool calls.
|
|
191
200
|
}
|
|
192
201
|
|
|
193
202
|
private onSubagentStart(payload: Record<string, any>): void {
|
|
@@ -196,9 +205,10 @@ export class HookBridge {
|
|
|
196
205
|
this.server.setAutoStatus('thinking')
|
|
197
206
|
}
|
|
198
207
|
|
|
199
|
-
private onSubagentStop(
|
|
200
|
-
//
|
|
201
|
-
this
|
|
208
|
+
private onSubagentStop(): void {
|
|
209
|
+
// No-op — the parent agent continues working; the next Pre/PostToolUse or
|
|
210
|
+
// Stop will update state. Previously this reset status to 'thinking',
|
|
211
|
+
// which kept the auto-clear timer resetting forever.
|
|
202
212
|
}
|
|
203
213
|
|
|
204
214
|
private onStop(): void {
|