@stellisoft/stellify-mcp 0.1.2 → 0.1.5
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/README.md +505 -83
- package/dist/index.js +1492 -113
- package/dist/stellify-client.d.ts +103 -7
- package/dist/stellify-client.js +139 -4
- package/manifest.json +92 -0
- package/package.json +1 -1
- package/stellify-mcp.mcpb +0 -0
- package/test-elements.js +96 -0
- package/test-full-workflow.js +118 -0
- package/test-html-conversion.js +117 -0
- package/test-read-delete.js +133 -0
- package/.mcpregistry_github_token +0 -1
- package/.mcpregistry_registry_token +0 -1
- package/ANNOUNCEMENTS.md +0 -322
- package/REGISTRY_SUBMISSIONS.md +0 -117
package/dist/index.js
CHANGED
|
@@ -17,84 +17,254 @@ const stellify = new StellifyClient({
|
|
|
17
17
|
apiUrl: API_URL,
|
|
18
18
|
apiToken: API_TOKEN,
|
|
19
19
|
});
|
|
20
|
+
// =============================================================================
|
|
21
|
+
// STELLIFY AI WORKFLOW GUIDE
|
|
22
|
+
// =============================================================================
|
|
23
|
+
// Stellify stores code as structured JSON, not text files.
|
|
24
|
+
// This enables surgical AI edits at the statement level.
|
|
25
|
+
//
|
|
26
|
+
// -----------------------------------------------------------------------------
|
|
27
|
+
// REAL-TIME UI BROADCASTING (use this for demonstrations!)
|
|
28
|
+
// -----------------------------------------------------------------------------
|
|
29
|
+
// When users ask you to SHOW, DISPLAY, BUILD, or DEMONSTRATE anything visually,
|
|
30
|
+
// use broadcast_element_command FIRST. This sends real-time updates via WebSocket
|
|
31
|
+
// directly to the user's browser - no database storage, instant feedback.
|
|
32
|
+
//
|
|
33
|
+
// Use broadcast_element_command for:
|
|
34
|
+
// - Showing the user something visually
|
|
35
|
+
// - Building UI elements as you discuss them
|
|
36
|
+
// - Sending messages/content to the browser
|
|
37
|
+
// - Any "live" or "real-time" interaction
|
|
38
|
+
//
|
|
39
|
+
// Use html_to_elements/update_element for:
|
|
40
|
+
// - Permanent changes that should persist
|
|
41
|
+
// - Building components that will be saved
|
|
42
|
+
//
|
|
43
|
+
// SUPPORTED FILE TYPES:
|
|
44
|
+
// - PHP: Controllers, Models, Middleware, Classes
|
|
45
|
+
// - JavaScript/TypeScript: JS files, Vue SFCs
|
|
46
|
+
// - UI: Elements (HTML structure stored as JSON)
|
|
47
|
+
//
|
|
48
|
+
// -----------------------------------------------------------------------------
|
|
49
|
+
// GENERAL WORKFLOW (applies to all file types)
|
|
50
|
+
// -----------------------------------------------------------------------------
|
|
51
|
+
// 1. Create file skeleton (create_file) - empty structure, no methods yet
|
|
52
|
+
// 2. Add methods (create_method) - creates signature only
|
|
53
|
+
// 3. Add method bodies (add_method_body) - implementation code
|
|
54
|
+
// 4. Add statements (create_statement + add_statement_code) - for non-method code
|
|
55
|
+
// 5. Save file (save_file) - finalize with all references
|
|
56
|
+
//
|
|
57
|
+
// -----------------------------------------------------------------------------
|
|
58
|
+
// PHP EXAMPLE: Creating a Controller
|
|
59
|
+
// -----------------------------------------------------------------------------
|
|
60
|
+
// 1. create_file: type='controller', name='UserController'
|
|
61
|
+
// 2. create_method: name='store', parameters=[{name:'request', type:'Request'}]
|
|
62
|
+
// 3. add_method_body: code='return response()->json($request->all());'
|
|
63
|
+
//
|
|
64
|
+
// -----------------------------------------------------------------------------
|
|
65
|
+
// VUE COMPONENT WORKFLOW (step-by-step)
|
|
66
|
+
// -----------------------------------------------------------------------------
|
|
67
|
+
// Vue components combine UI elements with reactive data. Follow this order:
|
|
68
|
+
//
|
|
69
|
+
// 1. get_project - Find the 'js' directory UUID
|
|
70
|
+
// 2. create_file - type='js', extension='vue' in js directory
|
|
71
|
+
// 3. Create statements for IMPORTS and DATA (each needs create_statement + add_statement_code):
|
|
72
|
+
// - "import { ref } from 'vue';" ← REQUIRED for using ref()
|
|
73
|
+
// - "const count = ref(0);"
|
|
74
|
+
// NOTE: Vue imports are NOT auto-generated. You must add them manually.
|
|
75
|
+
// 4. create_method - Creates method signature (returns UUID)
|
|
76
|
+
// add_method_body - Add implementation: "count.value++;"
|
|
77
|
+
// 5. html_to_elements - Convert template HTML to elements (no 'page' needed)
|
|
78
|
+
// NOTE: Vue bindings like {{ count }} auto-create statements linked to elements
|
|
79
|
+
// 6. update_element - Wire event handlers (e.g., click → method UUID)
|
|
80
|
+
// 7. save_file - Finalize with:
|
|
81
|
+
// - extension: 'vue'
|
|
82
|
+
// - template: [rootElementUuid] (from html_to_elements)
|
|
83
|
+
// - data: [methodUuid] (METHOD UUIDs only!)
|
|
84
|
+
// - statements: [importStmtUuid, countStmtUuid] (STATEMENT UUIDs - imports, refs)
|
|
85
|
+
//
|
|
86
|
+
// Vue SFC file structure:
|
|
87
|
+
// - extension: 'vue'
|
|
88
|
+
// - template: Array of root element UUIDs (<template> section)
|
|
89
|
+
// - data: Array of METHOD UUIDs only (<script setup> functions)
|
|
90
|
+
// - statements: Array of STATEMENT UUIDs (<script setup> imports, variables, refs)
|
|
91
|
+
// - includes: Array of file UUIDs to import
|
|
92
|
+
//
|
|
93
|
+
// -----------------------------------------------------------------------------
|
|
94
|
+
// ELEMENT EVENT HANDLERS (for frontend files)
|
|
95
|
+
// -----------------------------------------------------------------------------
|
|
96
|
+
// Elements can have these event properties (value is method UUID):
|
|
97
|
+
// - click: Fires on click (@click)
|
|
98
|
+
// - submit: Fires on form submit (@submit)
|
|
99
|
+
// - change: Fires on input change (@change)
|
|
100
|
+
// - input: Fires on input in real-time (@input)
|
|
101
|
+
// - focus: Fires when element receives focus (@focus)
|
|
102
|
+
// - blur: Fires when element loses focus (@blur)
|
|
103
|
+
// - keydown: Fires on key press (@keydown)
|
|
104
|
+
// - keyup: Fires on key release (@keyup)
|
|
105
|
+
// - mouseenter: Fires on mouse enter (@mouseenter)
|
|
106
|
+
// - mouseleave: Fires on mouse leave (@mouseleave)
|
|
107
|
+
//
|
|
108
|
+
// =============================================================================
|
|
20
109
|
// Define MCP tools
|
|
21
110
|
const tools = [
|
|
111
|
+
{
|
|
112
|
+
name: 'get_project',
|
|
113
|
+
description: `Get the active Stellify project for the authenticated user.
|
|
114
|
+
|
|
115
|
+
IMPORTANT: Call this first before any other operations.
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
- uuid: Project UUID (needed for most operations)
|
|
119
|
+
- name: Project name
|
|
120
|
+
- branch/branches: Git branch info
|
|
121
|
+
- directories: Array of {uuid, name} for existing directories (js, controllers, models, etc.)
|
|
122
|
+
|
|
123
|
+
Use the directories array to find existing directories before creating new ones.
|
|
124
|
+
For example, look for a "js" directory before creating Vue components.`,
|
|
125
|
+
inputSchema: {
|
|
126
|
+
type: 'object',
|
|
127
|
+
properties: {},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
22
130
|
{
|
|
23
131
|
name: 'create_file',
|
|
24
|
-
description:
|
|
132
|
+
description: `Create a new file in a Stellify project.
|
|
133
|
+
|
|
134
|
+
This creates an EMPTY file shell - no methods, statements, or template yet. The file exists but has no content.
|
|
135
|
+
|
|
136
|
+
COMPLETE WORKFLOW:
|
|
137
|
+
1. create_file → creates empty shell, returns file UUID
|
|
138
|
+
2. create_statement + add_statement_code → add variables/imports (returns statement UUIDs)
|
|
139
|
+
3. create_method + add_method_body → add functions (returns method UUIDs)
|
|
140
|
+
4. html_to_elements → create template elements (returns element UUIDs)
|
|
141
|
+
5. save_file → FINALIZE by wiring template/data arrays with all collected UUIDs
|
|
142
|
+
|
|
143
|
+
For PHP: Use type='class', 'model', 'controller', or 'middleware'.
|
|
144
|
+
For Vue: Use type='js' and extension='vue'. Place in the 'js' directory.
|
|
145
|
+
|
|
146
|
+
DEPENDENCY RESOLUTION (automatic):
|
|
147
|
+
Pass 'includes' as an array of namespace strings (e.g., ["App\\Models\\User", "Illuminate\\Support\\Facades\\Hash"]).
|
|
148
|
+
The system resolves these to UUIDs automatically, creating missing dependencies on-demand:
|
|
149
|
+
- App\\* classes → creates stub file in your project (tenant DB)
|
|
150
|
+
- Illuminate\\*/Laravel\\* → fetches from Laravel API, creates in Application DB
|
|
151
|
+
- Vendor packages → fetches from vendor, creates in Application DB`,
|
|
25
152
|
inputSchema: {
|
|
26
153
|
type: 'object',
|
|
27
154
|
properties: {
|
|
28
|
-
|
|
155
|
+
directory: {
|
|
29
156
|
type: 'string',
|
|
30
|
-
description: 'The UUID of the
|
|
157
|
+
description: 'The UUID of the directory to create the file in (get from get_project directories array)',
|
|
31
158
|
},
|
|
32
159
|
name: {
|
|
33
160
|
type: 'string',
|
|
34
|
-
description: 'File name (e.g., "
|
|
161
|
+
description: 'File name without extension (e.g., "Counter", "UserController")',
|
|
35
162
|
},
|
|
36
163
|
type: {
|
|
37
164
|
type: 'string',
|
|
38
|
-
enum: ['class', 'model', 'controller', 'middleware'],
|
|
39
|
-
description: 'Type of file
|
|
165
|
+
enum: ['class', 'model', 'controller', 'middleware', 'js'],
|
|
166
|
+
description: 'Type of file: "js" for JavaScript/Vue, others for PHP',
|
|
167
|
+
},
|
|
168
|
+
extension: {
|
|
169
|
+
type: 'string',
|
|
170
|
+
description: 'File extension. Use "vue" for Vue components, omit for PHP files.',
|
|
40
171
|
},
|
|
41
172
|
namespace: {
|
|
42
173
|
type: 'string',
|
|
43
|
-
description: 'PHP namespace (e.g., "App\\Services\\"
|
|
174
|
+
description: 'PHP namespace (e.g., "App\\Services\\"). Only for PHP files.',
|
|
175
|
+
},
|
|
176
|
+
includes: {
|
|
177
|
+
type: 'array',
|
|
178
|
+
items: { type: 'string' },
|
|
179
|
+
description: 'Array of namespace strings to include as dependencies (e.g., ["App\\Models\\User", "Illuminate\\Support\\Facades\\Hash"]). These are resolved to UUIDs automatically.',
|
|
44
180
|
},
|
|
45
181
|
},
|
|
46
|
-
required: ['
|
|
182
|
+
required: ['directory', 'name', 'type'],
|
|
47
183
|
},
|
|
48
184
|
},
|
|
49
185
|
{
|
|
50
186
|
name: 'create_method',
|
|
51
|
-
description:
|
|
187
|
+
description: `Create a method signature in a file. This only creates the method declaration, not the body. Use add_method_body to add implementation.
|
|
188
|
+
|
|
189
|
+
Parameters are automatically created as clauses. The response includes the clause UUIDs for each parameter.
|
|
190
|
+
|
|
191
|
+
Example request:
|
|
192
|
+
{
|
|
193
|
+
"file": "file-uuid",
|
|
194
|
+
"name": "verify",
|
|
195
|
+
"visibility": "public",
|
|
196
|
+
"returnType": "object",
|
|
197
|
+
"nullable": true,
|
|
198
|
+
"parameters": [
|
|
199
|
+
{ "name": "credentials", "datatype": "array" }
|
|
200
|
+
]
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
Example response includes:
|
|
204
|
+
{
|
|
205
|
+
"uuid": "method-uuid",
|
|
206
|
+
"name": "verify",
|
|
207
|
+
"returnType": "object",
|
|
208
|
+
"nullable": true,
|
|
209
|
+
"parameters": ["clause-uuid-for-credentials"],
|
|
210
|
+
...
|
|
211
|
+
}`,
|
|
52
212
|
inputSchema: {
|
|
53
213
|
type: 'object',
|
|
54
214
|
properties: {
|
|
55
|
-
|
|
215
|
+
file: {
|
|
56
216
|
type: 'string',
|
|
57
217
|
description: 'UUID of the file to add the method to',
|
|
58
218
|
},
|
|
59
219
|
name: {
|
|
60
220
|
type: 'string',
|
|
61
|
-
description: 'Method name (e.g., "
|
|
221
|
+
description: 'Method name (e.g., "increment", "store", "handleClick")',
|
|
62
222
|
},
|
|
63
223
|
visibility: {
|
|
64
224
|
type: 'string',
|
|
65
225
|
enum: ['public', 'protected', 'private'],
|
|
66
|
-
description: 'Method visibility',
|
|
67
|
-
default: 'public',
|
|
226
|
+
description: 'Method visibility (PHP only)',
|
|
68
227
|
},
|
|
69
228
|
is_static: {
|
|
70
229
|
type: 'boolean',
|
|
71
|
-
description: 'Whether the method is static',
|
|
72
|
-
default: false,
|
|
230
|
+
description: 'Whether the method is static (PHP only)',
|
|
73
231
|
},
|
|
74
|
-
|
|
232
|
+
returnType: {
|
|
75
233
|
type: 'string',
|
|
76
|
-
description: 'Return type (e.g., "int", "string", "
|
|
234
|
+
description: 'Return type (e.g., "int", "string", "void", "object")',
|
|
235
|
+
},
|
|
236
|
+
nullable: {
|
|
237
|
+
type: 'boolean',
|
|
238
|
+
description: 'Whether the return type is nullable (e.g., ?object)',
|
|
77
239
|
},
|
|
78
240
|
parameters: {
|
|
79
241
|
type: 'array',
|
|
80
|
-
description: 'Array of method parameters',
|
|
242
|
+
description: 'Array of method parameters. Each parameter is created as a clause.',
|
|
81
243
|
items: {
|
|
82
244
|
type: 'object',
|
|
83
245
|
properties: {
|
|
84
246
|
name: {
|
|
85
247
|
type: 'string',
|
|
86
|
-
description: 'Parameter name (
|
|
248
|
+
description: 'Parameter name (e.g., "credentials", "id")',
|
|
249
|
+
},
|
|
250
|
+
datatype: {
|
|
251
|
+
type: 'string',
|
|
252
|
+
description: 'Parameter data type (e.g., "array", "int", "string", "Request")',
|
|
87
253
|
},
|
|
88
254
|
type: {
|
|
89
255
|
type: 'string',
|
|
90
|
-
description: '
|
|
256
|
+
description: 'Clause type, defaults to "variable"',
|
|
257
|
+
},
|
|
258
|
+
value: {
|
|
259
|
+
type: 'string',
|
|
260
|
+
description: 'Parameter value, defaults to the name',
|
|
91
261
|
},
|
|
92
262
|
},
|
|
93
|
-
required: ['name'
|
|
263
|
+
required: ['name'],
|
|
94
264
|
},
|
|
95
265
|
},
|
|
96
266
|
},
|
|
97
|
-
required: ['
|
|
267
|
+
required: ['file', 'name'],
|
|
98
268
|
},
|
|
99
269
|
},
|
|
100
270
|
{
|
|
@@ -103,11 +273,11 @@ const tools = [
|
|
|
103
273
|
inputSchema: {
|
|
104
274
|
type: 'object',
|
|
105
275
|
properties: {
|
|
106
|
-
|
|
276
|
+
file: {
|
|
107
277
|
type: 'string',
|
|
108
278
|
description: 'UUID of the file containing the method',
|
|
109
279
|
},
|
|
110
|
-
|
|
280
|
+
method: {
|
|
111
281
|
type: 'string',
|
|
112
282
|
description: 'UUID of the method to add code to',
|
|
113
283
|
},
|
|
@@ -116,7 +286,56 @@ const tools = [
|
|
|
116
286
|
description: 'PHP code for the method body (just the statements, no function declaration). Example: "return $a + $b;"',
|
|
117
287
|
},
|
|
118
288
|
},
|
|
119
|
-
required: ['
|
|
289
|
+
required: ['file', 'method', 'code'],
|
|
290
|
+
},
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
name: 'save_method',
|
|
294
|
+
description: `Update an existing method's properties (name, visibility, returnType, nullable, parameters).
|
|
295
|
+
|
|
296
|
+
Use this to modify a method after creation. For updating the method body, use add_method_body instead.
|
|
297
|
+
|
|
298
|
+
Example:
|
|
299
|
+
{
|
|
300
|
+
"uuid": "method-uuid",
|
|
301
|
+
"returnType": "object",
|
|
302
|
+
"nullable": true
|
|
303
|
+
}`,
|
|
304
|
+
inputSchema: {
|
|
305
|
+
type: 'object',
|
|
306
|
+
properties: {
|
|
307
|
+
uuid: {
|
|
308
|
+
type: 'string',
|
|
309
|
+
description: 'UUID of the method to update',
|
|
310
|
+
},
|
|
311
|
+
name: {
|
|
312
|
+
type: 'string',
|
|
313
|
+
description: 'Method name',
|
|
314
|
+
},
|
|
315
|
+
visibility: {
|
|
316
|
+
type: 'string',
|
|
317
|
+
enum: ['public', 'protected', 'private'],
|
|
318
|
+
description: 'Method visibility (PHP only)',
|
|
319
|
+
},
|
|
320
|
+
is_static: {
|
|
321
|
+
type: 'boolean',
|
|
322
|
+
description: 'Whether the method is static (PHP only)',
|
|
323
|
+
},
|
|
324
|
+
returnType: {
|
|
325
|
+
type: 'string',
|
|
326
|
+
description: 'Return type (e.g., "int", "string", "void", "object")',
|
|
327
|
+
},
|
|
328
|
+
nullable: {
|
|
329
|
+
type: 'boolean',
|
|
330
|
+
description: 'Whether the return type is nullable',
|
|
331
|
+
},
|
|
332
|
+
parameters: {
|
|
333
|
+
type: 'array',
|
|
334
|
+
description: 'Array of parameter clause UUIDs',
|
|
335
|
+
items: { type: 'string' },
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
required: ['uuid'],
|
|
120
339
|
},
|
|
121
340
|
},
|
|
122
341
|
{
|
|
@@ -153,96 +372,1256 @@ const tools = [
|
|
|
153
372
|
},
|
|
154
373
|
},
|
|
155
374
|
},
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
375
|
+
{
|
|
376
|
+
name: 'create_route',
|
|
377
|
+
description: 'Create a new route/page in a Stellify project',
|
|
378
|
+
inputSchema: {
|
|
379
|
+
type: 'object',
|
|
380
|
+
properties: {
|
|
381
|
+
project_id: {
|
|
382
|
+
type: 'string',
|
|
383
|
+
description: 'The UUID of the Stellify project',
|
|
384
|
+
},
|
|
385
|
+
name: {
|
|
386
|
+
type: 'string',
|
|
387
|
+
description: 'Route/page name (e.g., "Home", "Counter", "About")',
|
|
388
|
+
},
|
|
389
|
+
path: {
|
|
390
|
+
type: 'string',
|
|
391
|
+
description: 'URL path (e.g., "/", "/counter", "/about")',
|
|
392
|
+
},
|
|
393
|
+
method: {
|
|
394
|
+
type: 'string',
|
|
395
|
+
enum: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'],
|
|
396
|
+
description: 'HTTP method',
|
|
397
|
+
default: 'GET',
|
|
398
|
+
},
|
|
399
|
+
type: {
|
|
400
|
+
type: 'string',
|
|
401
|
+
enum: ['web', 'api'],
|
|
402
|
+
description: 'Route type: "web" for pages, "api" for API endpoints',
|
|
403
|
+
default: 'web',
|
|
404
|
+
},
|
|
405
|
+
data: {
|
|
406
|
+
type: 'object',
|
|
407
|
+
description: 'Additional route data (title, description, element UUIDs)',
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
required: ['project_id', 'name', 'path', 'method'],
|
|
411
|
+
},
|
|
164
412
|
},
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
content: [
|
|
227
|
-
{
|
|
228
|
-
type: 'text',
|
|
229
|
-
text: JSON.stringify({
|
|
230
|
-
success: true,
|
|
231
|
-
results: result,
|
|
232
|
-
}, null, 2),
|
|
233
|
-
},
|
|
413
|
+
{
|
|
414
|
+
name: 'get_route',
|
|
415
|
+
description: `Get a route/page by UUID. Returns route details including name, path, and attached elements.
|
|
416
|
+
|
|
417
|
+
Use this to look up a route you created or to find existing routes in the project.`,
|
|
418
|
+
inputSchema: {
|
|
419
|
+
type: 'object',
|
|
420
|
+
properties: {
|
|
421
|
+
uuid: {
|
|
422
|
+
type: 'string',
|
|
423
|
+
description: 'The UUID of the route to retrieve',
|
|
424
|
+
},
|
|
425
|
+
},
|
|
426
|
+
required: ['uuid'],
|
|
427
|
+
},
|
|
428
|
+
},
|
|
429
|
+
{
|
|
430
|
+
name: 'search_routes',
|
|
431
|
+
description: `Search for routes/pages in the project by name. Use this to find existing routes before creating new ones.
|
|
432
|
+
|
|
433
|
+
Returns paginated results with route details including UUID, name, path, and type.
|
|
434
|
+
Use the returned UUID with html_to_elements (page parameter) or get_route for full details.`,
|
|
435
|
+
inputSchema: {
|
|
436
|
+
type: 'object',
|
|
437
|
+
properties: {
|
|
438
|
+
search: {
|
|
439
|
+
type: 'string',
|
|
440
|
+
description: 'Search term to match route names (e.g., "Counter", "Home")',
|
|
441
|
+
},
|
|
442
|
+
type: {
|
|
443
|
+
type: 'string',
|
|
444
|
+
enum: ['web', 'api'],
|
|
445
|
+
description: 'Filter by route type: "web" for pages, "api" for endpoints',
|
|
446
|
+
},
|
|
447
|
+
per_page: {
|
|
448
|
+
type: 'number',
|
|
449
|
+
description: 'Results per page (default: 10)',
|
|
450
|
+
},
|
|
451
|
+
},
|
|
452
|
+
},
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
name: 'create_element',
|
|
456
|
+
description: `Create a new UI element on a page (for Elements v2). Provide either page (route UUID) for root elements, or parent (element UUID) for child elements.
|
|
457
|
+
|
|
458
|
+
Valid element types:
|
|
459
|
+
- HTML5: s-wrapper, s-input, s-form, s-svg, s-shape, s-media, s-iframe
|
|
460
|
+
- Components: s-loop, s-transition, s-freestyle, s-motion
|
|
461
|
+
- Blade: s-directive
|
|
462
|
+
- Shadcn/ui: s-chart, s-table, s-combobox, s-accordion, s-calendar, s-contiguous`,
|
|
463
|
+
inputSchema: {
|
|
464
|
+
type: 'object',
|
|
465
|
+
properties: {
|
|
466
|
+
type: {
|
|
467
|
+
type: 'string',
|
|
468
|
+
enum: [
|
|
469
|
+
's-wrapper', 's-input', 's-form', 's-svg', 's-shape', 's-media', 's-iframe',
|
|
470
|
+
's-loop', 's-transition', 's-freestyle', 's-motion',
|
|
471
|
+
's-directive',
|
|
472
|
+
's-chart', 's-table', 's-combobox', 's-accordion', 's-calendar', 's-contiguous'
|
|
234
473
|
],
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
474
|
+
description: 'Element type - must be one of the valid Stellify element types',
|
|
475
|
+
},
|
|
476
|
+
page: {
|
|
477
|
+
type: 'string',
|
|
478
|
+
description: 'UUID of the page/route to add the element to (for root elements)',
|
|
479
|
+
},
|
|
480
|
+
parent: {
|
|
481
|
+
type: 'string',
|
|
482
|
+
description: 'UUID of the parent element (for child elements)',
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
required: ['type'],
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
{
|
|
489
|
+
name: 'update_element',
|
|
490
|
+
description: `Update an existing UI element (for Elements v2).
|
|
491
|
+
|
|
492
|
+
Use standard HTML attributes directly (placeholder, href, src, type, etc.).
|
|
493
|
+
|
|
494
|
+
Special Stellify fields:
|
|
495
|
+
- name: Element name in editor
|
|
496
|
+
- type: Element type (s-wrapper, s-input, etc.)
|
|
497
|
+
- locked: Prevent editing (boolean)
|
|
498
|
+
- tag: HTML tag (div, input, button, etc.)
|
|
499
|
+
- classes: CSS classes array ["class1", "class2"]
|
|
500
|
+
- text: Element text content
|
|
501
|
+
|
|
502
|
+
EVENT HANDLERS (set value to method UUID):
|
|
503
|
+
- click: @click - buttons, links, any clickable element
|
|
504
|
+
- submit: @submit - form submission
|
|
505
|
+
- change: @change - input/select value changed (on blur)
|
|
506
|
+
- input: @input - input value changing (real-time, as user types)
|
|
507
|
+
- focus: @focus - element receives focus
|
|
508
|
+
- blur: @blur - element loses focus
|
|
509
|
+
- keydown: @keydown - key pressed down
|
|
510
|
+
- keyup: @keyup - key released
|
|
511
|
+
- mouseenter: @mouseenter - mouse enters element
|
|
512
|
+
- mouseleave: @mouseleave - mouse leaves element
|
|
513
|
+
|
|
514
|
+
Example wiring a button click to a method:
|
|
515
|
+
{
|
|
516
|
+
"uuid": "button-element-uuid",
|
|
517
|
+
"data": {
|
|
518
|
+
"click": "increment-method-uuid"
|
|
519
|
+
}
|
|
520
|
+
}`,
|
|
521
|
+
inputSchema: {
|
|
522
|
+
type: 'object',
|
|
523
|
+
properties: {
|
|
524
|
+
uuid: {
|
|
525
|
+
type: 'string',
|
|
526
|
+
description: 'UUID of the element to update',
|
|
527
|
+
},
|
|
528
|
+
data: {
|
|
529
|
+
type: 'object',
|
|
530
|
+
description: 'Flat object with HTML attributes and Stellify fields (name, type, locked, tag, classes, text)',
|
|
531
|
+
},
|
|
532
|
+
},
|
|
533
|
+
required: ['uuid', 'data'],
|
|
534
|
+
},
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
name: 'get_element',
|
|
538
|
+
description: 'Get a single element by UUID. Returns the element data with all its attributes.',
|
|
539
|
+
inputSchema: {
|
|
540
|
+
type: 'object',
|
|
541
|
+
properties: {
|
|
542
|
+
uuid: {
|
|
543
|
+
type: 'string',
|
|
544
|
+
description: 'UUID of the element to retrieve',
|
|
545
|
+
},
|
|
546
|
+
},
|
|
547
|
+
required: ['uuid'],
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
{
|
|
551
|
+
name: 'get_element_tree',
|
|
552
|
+
description: 'Get an element with all its descendants (children, grandchildren, etc.) as a hierarchical tree structure.',
|
|
553
|
+
inputSchema: {
|
|
554
|
+
type: 'object',
|
|
555
|
+
properties: {
|
|
556
|
+
uuid: {
|
|
557
|
+
type: 'string',
|
|
558
|
+
description: 'UUID of the root element',
|
|
559
|
+
},
|
|
560
|
+
},
|
|
561
|
+
required: ['uuid'],
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
name: 'delete_element',
|
|
566
|
+
description: 'Delete an element and all its children (CASCADE). Returns the count of deleted elements.',
|
|
567
|
+
inputSchema: {
|
|
568
|
+
type: 'object',
|
|
569
|
+
properties: {
|
|
570
|
+
uuid: {
|
|
571
|
+
type: 'string',
|
|
572
|
+
description: 'UUID of the element to delete',
|
|
573
|
+
},
|
|
574
|
+
},
|
|
575
|
+
required: ['uuid'],
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
name: 'search_elements',
|
|
580
|
+
description: `Search for elements in the project. Useful for finding elements by name, type, or content.
|
|
581
|
+
|
|
582
|
+
Note: To reorder elements, use update_element to modify the parent element's 'data' array with the new order of child UUIDs.`,
|
|
583
|
+
inputSchema: {
|
|
584
|
+
type: 'object',
|
|
585
|
+
properties: {
|
|
586
|
+
search: {
|
|
587
|
+
type: 'string',
|
|
588
|
+
description: 'Search query to match against element name, type, or content',
|
|
589
|
+
},
|
|
590
|
+
type: {
|
|
591
|
+
type: 'string',
|
|
592
|
+
description: 'Filter by element type (e.g., s-wrapper, s-input)',
|
|
593
|
+
},
|
|
594
|
+
include_metadata: {
|
|
595
|
+
type: 'boolean',
|
|
596
|
+
description: 'Include additional metadata',
|
|
597
|
+
default: false,
|
|
598
|
+
},
|
|
599
|
+
per_page: {
|
|
600
|
+
type: 'number',
|
|
601
|
+
description: 'Results per page (1-100)',
|
|
602
|
+
default: 20,
|
|
603
|
+
},
|
|
604
|
+
},
|
|
605
|
+
},
|
|
606
|
+
},
|
|
607
|
+
{
|
|
608
|
+
name: 'html_to_elements',
|
|
609
|
+
description: `Convert HTML to Stellify elements in ONE operation. This is the FASTEST way to build interfaces!
|
|
610
|
+
|
|
611
|
+
This will:
|
|
612
|
+
1. Parse the HTML structure
|
|
613
|
+
2. Create all elements with proper nesting and types
|
|
614
|
+
3. Preserve all attributes, classes, text content
|
|
615
|
+
4. Auto-detect Vue bindings ({{ variable }}) and create linked statements
|
|
616
|
+
5. Return element UUIDs to use in save_file template array
|
|
617
|
+
|
|
618
|
+
Element type mapping:
|
|
619
|
+
- button, input, textarea, select → s-input
|
|
620
|
+
- div, span, p, section, etc. → s-wrapper
|
|
621
|
+
- form → s-form
|
|
622
|
+
- img, video, audio → s-media
|
|
623
|
+
|
|
624
|
+
VUE BINDING AUTO-DETECTION:
|
|
625
|
+
Text like {{ count }} is automatically detected and:
|
|
626
|
+
- A statement is created with the binding code
|
|
627
|
+
- The statement UUID is added to the element's 'statements' array
|
|
628
|
+
- You still need to create the reactive data source separately (const count = ref(0))
|
|
629
|
+
|
|
630
|
+
For Vue components: Omit 'page' - elements are created standalone for the component template.
|
|
631
|
+
For page content: Provide 'page' (route UUID) to attach elements directly.
|
|
632
|
+
|
|
633
|
+
IMPORTANT: Use the returned root element UUID in save_file's template array.`,
|
|
634
|
+
inputSchema: {
|
|
635
|
+
type: 'object',
|
|
636
|
+
properties: {
|
|
637
|
+
elements: {
|
|
638
|
+
type: 'string',
|
|
639
|
+
description: 'HTML string to convert',
|
|
640
|
+
},
|
|
641
|
+
page: {
|
|
642
|
+
type: 'string',
|
|
643
|
+
description: 'Route UUID to attach elements to. Optional for Vue components.',
|
|
644
|
+
},
|
|
645
|
+
selection: {
|
|
646
|
+
type: 'string',
|
|
647
|
+
description: 'Parent element UUID to attach to (alternative to page)',
|
|
648
|
+
},
|
|
649
|
+
test: {
|
|
650
|
+
type: 'boolean',
|
|
651
|
+
description: 'If true, returns structure without creating elements',
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
required: ['elements'],
|
|
655
|
+
},
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
name: 'list_globals',
|
|
659
|
+
description: 'List all global files in the Application database. Globals are reusable, curated code (controllers, models, services) that can be installed into tenant projects.',
|
|
660
|
+
inputSchema: {
|
|
661
|
+
type: 'object',
|
|
662
|
+
properties: {},
|
|
663
|
+
},
|
|
664
|
+
},
|
|
665
|
+
{
|
|
666
|
+
name: 'get_global',
|
|
667
|
+
description: 'Get a global file with all its methods, statements, and clauses. Returns the full structure of a reusable code file.',
|
|
668
|
+
inputSchema: {
|
|
669
|
+
type: 'object',
|
|
670
|
+
properties: {
|
|
671
|
+
uuid: {
|
|
672
|
+
type: 'string',
|
|
673
|
+
description: 'UUID of the global file to retrieve',
|
|
674
|
+
},
|
|
675
|
+
},
|
|
676
|
+
required: ['uuid'],
|
|
677
|
+
},
|
|
678
|
+
},
|
|
679
|
+
{
|
|
680
|
+
name: 'install_global',
|
|
681
|
+
description: 'Install a global file from the Application database into a tenant project. Copies the file, methods, and statements to the tenant database with the same UUIDs (for deduplication). Clauses remain shared in the Application DB.',
|
|
682
|
+
inputSchema: {
|
|
683
|
+
type: 'object',
|
|
684
|
+
properties: {
|
|
685
|
+
file_uuid: {
|
|
686
|
+
type: 'string',
|
|
687
|
+
description: 'UUID of the global file to install',
|
|
688
|
+
},
|
|
689
|
+
directory_uuid: {
|
|
690
|
+
type: 'string',
|
|
691
|
+
description: 'UUID of the directory in the tenant project to install the file into',
|
|
692
|
+
},
|
|
693
|
+
},
|
|
694
|
+
required: ['file_uuid', 'directory_uuid'],
|
|
695
|
+
},
|
|
696
|
+
},
|
|
697
|
+
{
|
|
698
|
+
name: 'search_global_methods',
|
|
699
|
+
description: 'Search for methods across the Application database (global/framework methods). Use this to find reusable Laravel framework methods, facades, and shared code.',
|
|
700
|
+
inputSchema: {
|
|
701
|
+
type: 'object',
|
|
702
|
+
properties: {
|
|
703
|
+
query: {
|
|
704
|
+
type: 'string',
|
|
705
|
+
description: 'Search query to find methods by name',
|
|
706
|
+
},
|
|
707
|
+
},
|
|
708
|
+
required: ['query'],
|
|
709
|
+
},
|
|
710
|
+
},
|
|
711
|
+
// Module tools (groups of globals)
|
|
712
|
+
{
|
|
713
|
+
name: 'list_modules',
|
|
714
|
+
description: 'List all available modules. A module is a named collection of related global files that can be installed together as a package.',
|
|
715
|
+
inputSchema: {
|
|
716
|
+
type: 'object',
|
|
717
|
+
properties: {},
|
|
718
|
+
},
|
|
719
|
+
},
|
|
720
|
+
{
|
|
721
|
+
name: 'get_module',
|
|
722
|
+
description: 'Get a module with all its files. Returns the module metadata and list of global files it contains, in installation order.',
|
|
723
|
+
inputSchema: {
|
|
724
|
+
type: 'object',
|
|
725
|
+
properties: {
|
|
726
|
+
uuid: {
|
|
727
|
+
type: 'string',
|
|
728
|
+
description: 'UUID of the module to retrieve',
|
|
729
|
+
},
|
|
730
|
+
},
|
|
731
|
+
required: ['uuid'],
|
|
732
|
+
},
|
|
733
|
+
},
|
|
734
|
+
{
|
|
735
|
+
name: 'create_module',
|
|
736
|
+
description: 'Create a new module to group related global files together.',
|
|
737
|
+
inputSchema: {
|
|
738
|
+
type: 'object',
|
|
739
|
+
properties: {
|
|
740
|
+
name: {
|
|
741
|
+
type: 'string',
|
|
742
|
+
description: 'Unique name for the module (e.g., "laravel-sanctum-auth")',
|
|
743
|
+
},
|
|
744
|
+
description: {
|
|
745
|
+
type: 'string',
|
|
746
|
+
description: 'Description of what the module provides',
|
|
747
|
+
},
|
|
748
|
+
version: {
|
|
749
|
+
type: 'string',
|
|
750
|
+
description: 'Version string (default: "1.0.0")',
|
|
751
|
+
},
|
|
752
|
+
tags: {
|
|
753
|
+
type: 'array',
|
|
754
|
+
items: { type: 'string' },
|
|
755
|
+
description: 'Tags for categorization (e.g., ["auth", "api", "sanctum"])',
|
|
756
|
+
},
|
|
757
|
+
},
|
|
758
|
+
required: ['name'],
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
name: 'add_file_to_module',
|
|
763
|
+
description: 'Add a global file to a module. Files are installed in order when the module is installed.',
|
|
764
|
+
inputSchema: {
|
|
765
|
+
type: 'object',
|
|
766
|
+
properties: {
|
|
767
|
+
module_uuid: {
|
|
768
|
+
type: 'string',
|
|
769
|
+
description: 'UUID of the module',
|
|
770
|
+
},
|
|
771
|
+
file_uuid: {
|
|
772
|
+
type: 'string',
|
|
773
|
+
description: 'UUID of the global file to add',
|
|
774
|
+
},
|
|
775
|
+
order: {
|
|
776
|
+
type: 'number',
|
|
777
|
+
description: 'Installation order (optional, auto-increments if not specified)',
|
|
778
|
+
},
|
|
779
|
+
},
|
|
780
|
+
required: ['module_uuid', 'file_uuid'],
|
|
781
|
+
},
|
|
782
|
+
},
|
|
783
|
+
{
|
|
784
|
+
name: 'install_module',
|
|
785
|
+
description: 'Install all files from a module into a tenant project. Copies files, methods, and statements in the defined order. Clauses remain shared in the Application DB.',
|
|
786
|
+
inputSchema: {
|
|
787
|
+
type: 'object',
|
|
788
|
+
properties: {
|
|
789
|
+
module_uuid: {
|
|
790
|
+
type: 'string',
|
|
791
|
+
description: 'UUID of the module to install',
|
|
792
|
+
},
|
|
793
|
+
directory_uuid: {
|
|
794
|
+
type: 'string',
|
|
795
|
+
description: 'UUID of the directory in the tenant project to install files into',
|
|
796
|
+
},
|
|
797
|
+
},
|
|
798
|
+
required: ['module_uuid', 'directory_uuid'],
|
|
799
|
+
},
|
|
800
|
+
},
|
|
801
|
+
// =============================================================================
|
|
802
|
+
// STATEMENT & FILE MANAGEMENT TOOLS
|
|
803
|
+
// =============================================================================
|
|
804
|
+
{
|
|
805
|
+
name: 'get_statement',
|
|
806
|
+
description: `Get a statement by UUID. Returns the statement data including its clauses (code tokens).`,
|
|
807
|
+
inputSchema: {
|
|
808
|
+
type: 'object',
|
|
809
|
+
properties: {
|
|
810
|
+
uuid: {
|
|
811
|
+
type: 'string',
|
|
812
|
+
description: 'The UUID of the statement to retrieve',
|
|
813
|
+
},
|
|
814
|
+
},
|
|
815
|
+
required: ['uuid'],
|
|
816
|
+
},
|
|
817
|
+
},
|
|
818
|
+
{
|
|
819
|
+
name: 'create_statement',
|
|
820
|
+
description: `Create an empty statement in a file. This is step 1 of 2 - you MUST call add_statement_code next to add the actual code.
|
|
821
|
+
|
|
822
|
+
IMPORTANT: This is a TWO-STEP process:
|
|
823
|
+
1. create_statement → returns statement UUID
|
|
824
|
+
2. add_statement_code → adds the actual code to that statement
|
|
825
|
+
|
|
826
|
+
Use cases:
|
|
827
|
+
- PHP: Class properties, use statements, constants
|
|
828
|
+
- JS/Vue: Variable declarations, imports, reactive refs
|
|
829
|
+
|
|
830
|
+
For Vue components, include the returned statement UUID in save_file's 'data' array.`,
|
|
831
|
+
inputSchema: {
|
|
832
|
+
type: 'object',
|
|
833
|
+
properties: {
|
|
834
|
+
file: {
|
|
835
|
+
type: 'string',
|
|
836
|
+
description: 'UUID of the file to add the statement to',
|
|
837
|
+
},
|
|
838
|
+
method: {
|
|
839
|
+
type: 'string',
|
|
840
|
+
description: 'UUID of the method to add the statement to (for method body statements)',
|
|
841
|
+
},
|
|
842
|
+
},
|
|
843
|
+
},
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
name: 'add_statement_code',
|
|
847
|
+
description: `Add code to an existing statement. This is step 2 of 2 - call this AFTER create_statement.
|
|
848
|
+
|
|
849
|
+
The statement must already exist (created via create_statement). This parses and stores the code.
|
|
850
|
+
|
|
851
|
+
Examples:
|
|
852
|
+
- PHP: "use Illuminate\\Http\\Request;" or "private $items = [];"
|
|
853
|
+
- JS/Vue: "const count = ref(0);" or "import { ref } from 'vue';"`,
|
|
854
|
+
inputSchema: {
|
|
855
|
+
type: 'object',
|
|
856
|
+
properties: {
|
|
857
|
+
file: {
|
|
858
|
+
type: 'string',
|
|
859
|
+
description: 'UUID of the file containing the statement',
|
|
860
|
+
},
|
|
861
|
+
statement: {
|
|
862
|
+
type: 'string',
|
|
863
|
+
description: 'UUID of the statement to add code to',
|
|
864
|
+
},
|
|
865
|
+
code: {
|
|
866
|
+
type: 'string',
|
|
867
|
+
description: 'The code to add (e.g., "const count = ref(0);")',
|
|
868
|
+
},
|
|
869
|
+
},
|
|
870
|
+
required: ['file', 'statement', 'code'],
|
|
871
|
+
},
|
|
872
|
+
},
|
|
873
|
+
{
|
|
874
|
+
name: 'save_file',
|
|
875
|
+
description: `Save/update a file with its full configuration. This FINALIZES the file after create_file.
|
|
876
|
+
|
|
877
|
+
WORKFLOW: create_file creates an empty shell → add methods/statements → save_file wires everything together.
|
|
878
|
+
|
|
879
|
+
IMPORTANT: This is a full replacement, not a partial update. To update an existing file:
|
|
880
|
+
1. Call get_file to fetch current state
|
|
881
|
+
2. Modify the returned object
|
|
882
|
+
3. Call save_file with the complete object
|
|
883
|
+
|
|
884
|
+
Required fields: uuid, name, type
|
|
885
|
+
|
|
886
|
+
IMPORTANT - data vs statements:
|
|
887
|
+
- 'data' array = METHOD UUIDs only (functions)
|
|
888
|
+
- 'statements' array = STATEMENT UUIDs (imports, variables, refs - code outside methods)
|
|
889
|
+
|
|
890
|
+
Vue SFC example:
|
|
891
|
+
save_file({
|
|
892
|
+
uuid: fileUuid,
|
|
893
|
+
name: "Counter",
|
|
894
|
+
type: "js",
|
|
895
|
+
extension: "vue",
|
|
896
|
+
template: [rootElementUuid], // From html_to_elements
|
|
897
|
+
data: [methodUuid], // Method UUIDs only
|
|
898
|
+
statements: [importStmtUuid, refStmtUuid] // Statement UUIDs (imports, refs)
|
|
899
|
+
})
|
|
900
|
+
|
|
901
|
+
For <script setup> content, the order in statements array determines output order.`,
|
|
902
|
+
inputSchema: {
|
|
903
|
+
type: 'object',
|
|
904
|
+
properties: {
|
|
905
|
+
uuid: {
|
|
906
|
+
type: 'string',
|
|
907
|
+
description: 'UUID of the file to save',
|
|
908
|
+
},
|
|
909
|
+
name: {
|
|
910
|
+
type: 'string',
|
|
911
|
+
description: 'File name (without extension)',
|
|
912
|
+
},
|
|
913
|
+
type: {
|
|
914
|
+
type: 'string',
|
|
915
|
+
enum: ['js', 'class', 'controller', 'model', 'middleware'],
|
|
916
|
+
description: 'File type: "js" for JavaScript/Vue, others for PHP',
|
|
917
|
+
},
|
|
918
|
+
extension: {
|
|
919
|
+
type: 'string',
|
|
920
|
+
description: 'File extension: "vue" for Vue SFCs, "js" for JavaScript',
|
|
921
|
+
},
|
|
922
|
+
template: {
|
|
923
|
+
type: 'array',
|
|
924
|
+
items: { type: 'string' },
|
|
925
|
+
description: 'Array of root element UUIDs for Vue <template> section (from html_to_elements)',
|
|
926
|
+
},
|
|
927
|
+
data: {
|
|
928
|
+
type: 'array',
|
|
929
|
+
items: { type: 'string' },
|
|
930
|
+
description: 'Array of METHOD UUIDs only (functions created via create_method)',
|
|
931
|
+
},
|
|
932
|
+
statements: {
|
|
933
|
+
type: 'array',
|
|
934
|
+
items: { type: 'string' },
|
|
935
|
+
description: 'Array of STATEMENT UUIDs (imports, variables, refs - created via create_statement)',
|
|
936
|
+
},
|
|
937
|
+
includes: {
|
|
938
|
+
type: 'array',
|
|
939
|
+
items: { type: 'string' },
|
|
940
|
+
description: 'Array of file UUIDs to import',
|
|
941
|
+
},
|
|
942
|
+
},
|
|
943
|
+
required: ['uuid', 'name', 'type'],
|
|
944
|
+
},
|
|
945
|
+
},
|
|
946
|
+
{
|
|
947
|
+
name: 'get_file',
|
|
948
|
+
description: 'Get a file by UUID with all its metadata, methods, and statements.',
|
|
949
|
+
inputSchema: {
|
|
950
|
+
type: 'object',
|
|
951
|
+
properties: {
|
|
952
|
+
uuid: {
|
|
953
|
+
type: 'string',
|
|
954
|
+
description: 'UUID of the file to retrieve',
|
|
955
|
+
},
|
|
956
|
+
},
|
|
957
|
+
required: ['uuid'],
|
|
958
|
+
},
|
|
959
|
+
},
|
|
960
|
+
{
|
|
961
|
+
name: 'get_directory',
|
|
962
|
+
description: `Get a directory by UUID to see its contents.
|
|
963
|
+
|
|
964
|
+
Use this to inspect directories returned by get_project. The project's data array contains directory UUIDs.
|
|
965
|
+
Returns the directory name and list of files/subdirectories inside it.`,
|
|
966
|
+
inputSchema: {
|
|
967
|
+
type: 'object',
|
|
968
|
+
properties: {
|
|
969
|
+
uuid: {
|
|
970
|
+
type: 'string',
|
|
971
|
+
description: 'The UUID of the directory to retrieve',
|
|
972
|
+
},
|
|
973
|
+
},
|
|
974
|
+
required: ['uuid'],
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
name: 'create_directory',
|
|
979
|
+
description: `Create a new directory for organizing files.
|
|
980
|
+
|
|
981
|
+
Common directories:
|
|
982
|
+
- 'js' for JavaScript/Vue files
|
|
983
|
+
- 'css' for stylesheets
|
|
984
|
+
- 'components' for reusable components
|
|
985
|
+
|
|
986
|
+
IMPORTANT: Check existing directories first using get_project and get_directory before creating new ones.`,
|
|
987
|
+
inputSchema: {
|
|
988
|
+
type: 'object',
|
|
989
|
+
properties: {
|
|
990
|
+
name: {
|
|
991
|
+
type: 'string',
|
|
992
|
+
description: 'Directory name (e.g., "js", "css", "components")',
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
required: ['name'],
|
|
996
|
+
},
|
|
997
|
+
},
|
|
998
|
+
{
|
|
999
|
+
name: 'broadcast_element_command',
|
|
1000
|
+
description: `Broadcast a real-time command to update UI elements via WebSocket.
|
|
1001
|
+
|
|
1002
|
+
IMPORTANT: USE THIS TOOL FIRST when the user asks you to:
|
|
1003
|
+
- Show, display, or demonstrate something visually
|
|
1004
|
+
- Update, change, or modify what's on screen
|
|
1005
|
+
- Build or create UI elements for demonstration
|
|
1006
|
+
- Send messages or content to the browser
|
|
1007
|
+
- Do anything "live" or "in real-time"
|
|
1008
|
+
|
|
1009
|
+
This is the PRIMARY tool for real-time AI-to-browser communication. It pushes changes instantly to all connected browsers. Changes are EPHEMERAL (not saved to database) - perfect for demonstrations, live content, and interactive sessions.
|
|
1010
|
+
|
|
1011
|
+
ACTIONS:
|
|
1012
|
+
- update: Modify an existing element's attributes (text, classes, styles, etc.)
|
|
1013
|
+
- create: Create a new ephemeral element (provide any UUID string you want)
|
|
1014
|
+
- batch: Modify multiple elements at once
|
|
1015
|
+
- delete: Remove an element from the UI state
|
|
1016
|
+
|
|
1017
|
+
TO CREATE EPHEMERAL ELEMENTS (not stored in database):
|
|
1018
|
+
1. First, use action="create" with any UUID (e.g., "msg-001") and full element structure in changes
|
|
1019
|
+
2. Then, use action="update" on the PARENT element to add your new UUID to its "data" array
|
|
1020
|
+
|
|
1021
|
+
Example - Update existing element text:
|
|
1022
|
+
{ action: "update", element: "existing-uuid", changes: { text: "Hello world!", classes: ["p-4", "bg-blue-500"] } }
|
|
1023
|
+
|
|
1024
|
+
Example - Create ephemeral child element:
|
|
1025
|
+
Step 1: { action: "create", element: "my-new-element", changes: { type: "s-wrapper", tag: "div", text: "I exist!", classes: ["p-2", "bg-green-500"] } }
|
|
1026
|
+
Step 2: { action: "update", element: "parent-uuid", changes: { data: ["my-new-element"] } }
|
|
1027
|
+
|
|
1028
|
+
For PERSISTENT changes (saved to database), use update_element or html_to_elements instead.`,
|
|
1029
|
+
inputSchema: {
|
|
1030
|
+
type: 'object',
|
|
1031
|
+
properties: {
|
|
1032
|
+
action: {
|
|
1033
|
+
type: 'string',
|
|
1034
|
+
enum: ['update', 'batch', 'delete', 'create'],
|
|
1035
|
+
description: 'The type of command to broadcast',
|
|
1036
|
+
},
|
|
1037
|
+
element: {
|
|
1038
|
+
type: 'string',
|
|
1039
|
+
description: 'UUID of the element to modify (required for update, delete, create)',
|
|
1040
|
+
},
|
|
1041
|
+
changes: {
|
|
1042
|
+
type: 'object',
|
|
1043
|
+
description: 'Object containing attribute changes (e.g., { classes: ["bg-blue-500"], text: "Hello" })',
|
|
1044
|
+
},
|
|
1045
|
+
updates: {
|
|
1046
|
+
type: 'array',
|
|
1047
|
+
description: 'Array of updates for batch action: [{ element: "uuid", changes: {...} }]',
|
|
1048
|
+
items: {
|
|
1049
|
+
type: 'object',
|
|
1050
|
+
properties: {
|
|
1051
|
+
element: { type: 'string' },
|
|
1052
|
+
changes: { type: 'object' },
|
|
1053
|
+
},
|
|
1054
|
+
required: ['element', 'changes'],
|
|
1055
|
+
},
|
|
1056
|
+
},
|
|
1057
|
+
},
|
|
1058
|
+
required: ['action'],
|
|
1059
|
+
},
|
|
1060
|
+
},
|
|
1061
|
+
];
|
|
1062
|
+
// Server instructions for tool discovery (used by MCP Tool Search)
|
|
1063
|
+
const SERVER_INSTRUCTIONS = `Stellify is a coding platform where you code alongside AI on a codebase maintained and curated by AI. Build Laravel/PHP and Vue.js applications.
|
|
1064
|
+
|
|
1065
|
+
Use Stellify tools when:
|
|
1066
|
+
- Building PHP controllers, models, middleware, or classes
|
|
1067
|
+
- Creating Vue.js components with reactive state and UI
|
|
1068
|
+
- Managing UI elements (HTML stored as structured JSON)
|
|
1069
|
+
- Working with a Stellify project (user will mention "Stellify" or provide project UUID)
|
|
1070
|
+
|
|
1071
|
+
Key concepts:
|
|
1072
|
+
- Code is stored as structured JSON, enabling surgical AI edits at the statement level
|
|
1073
|
+
- Files contain methods and statements (code outside methods)
|
|
1074
|
+
- Vue components link to UI elements via the 'template' field
|
|
1075
|
+
- Event handlers (click, submit) wire UI elements to methods by UUID`;
|
|
1076
|
+
// Create MCP server
|
|
1077
|
+
const server = new Server({
|
|
1078
|
+
name: 'stellify-mcp',
|
|
1079
|
+
version: '0.1.0',
|
|
1080
|
+
}, {
|
|
1081
|
+
capabilities: {
|
|
1082
|
+
tools: {},
|
|
1083
|
+
},
|
|
1084
|
+
instructions: SERVER_INSTRUCTIONS,
|
|
1085
|
+
});
|
|
1086
|
+
// Handle tool list requests
|
|
1087
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
1088
|
+
return { tools };
|
|
1089
|
+
});
|
|
1090
|
+
// Handle tool execution
|
|
1091
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1092
|
+
const { name, arguments: args } = request.params;
|
|
1093
|
+
if (!args) {
|
|
1094
|
+
throw new Error('Arguments are required');
|
|
1095
|
+
}
|
|
1096
|
+
try {
|
|
1097
|
+
switch (name) {
|
|
1098
|
+
case 'get_project': {
|
|
1099
|
+
const result = await stellify.getProject();
|
|
1100
|
+
return {
|
|
1101
|
+
content: [
|
|
1102
|
+
{
|
|
1103
|
+
type: 'text',
|
|
1104
|
+
text: JSON.stringify({
|
|
1105
|
+
success: true,
|
|
1106
|
+
message: `Active project: "${result.data?.name || result.name}" (${result.data?.uuid || result.uuid})`,
|
|
1107
|
+
project: result.data || result,
|
|
1108
|
+
}, null, 2),
|
|
1109
|
+
},
|
|
1110
|
+
],
|
|
1111
|
+
};
|
|
1112
|
+
}
|
|
1113
|
+
case 'create_file': {
|
|
1114
|
+
const result = await stellify.createFile(args);
|
|
1115
|
+
const fileData = result.data || result;
|
|
1116
|
+
return {
|
|
1117
|
+
content: [
|
|
1118
|
+
{
|
|
1119
|
+
type: 'text',
|
|
1120
|
+
text: JSON.stringify({
|
|
1121
|
+
success: true,
|
|
1122
|
+
message: `Created file "${args.name}" (UUID: ${fileData.uuid})`,
|
|
1123
|
+
file: fileData,
|
|
1124
|
+
}, null, 2),
|
|
1125
|
+
},
|
|
1126
|
+
],
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
case 'create_method': {
|
|
1130
|
+
const result = await stellify.createMethod(args);
|
|
1131
|
+
const methodData = result.data || result;
|
|
1132
|
+
return {
|
|
1133
|
+
content: [
|
|
1134
|
+
{
|
|
1135
|
+
type: 'text',
|
|
1136
|
+
text: JSON.stringify({
|
|
1137
|
+
success: true,
|
|
1138
|
+
message: `Created method "${args.name}" (UUID: ${methodData.uuid})`,
|
|
1139
|
+
method: methodData,
|
|
1140
|
+
}, null, 2),
|
|
1141
|
+
},
|
|
1142
|
+
],
|
|
1143
|
+
};
|
|
1144
|
+
}
|
|
1145
|
+
case 'save_method': {
|
|
1146
|
+
const { uuid, ...data } = args;
|
|
1147
|
+
const result = await stellify.saveMethod(uuid, { uuid, ...data });
|
|
1148
|
+
return {
|
|
1149
|
+
content: [
|
|
1150
|
+
{
|
|
1151
|
+
type: 'text',
|
|
1152
|
+
text: JSON.stringify({
|
|
1153
|
+
success: true,
|
|
1154
|
+
message: `Updated method "${uuid}"`,
|
|
1155
|
+
method: result,
|
|
1156
|
+
}, null, 2),
|
|
1157
|
+
},
|
|
1158
|
+
],
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
case 'add_method_body': {
|
|
1162
|
+
const result = await stellify.addMethodBody(args);
|
|
1163
|
+
return {
|
|
1164
|
+
content: [
|
|
1165
|
+
{
|
|
1166
|
+
type: 'text',
|
|
1167
|
+
text: JSON.stringify({
|
|
1168
|
+
success: true,
|
|
1169
|
+
message: 'Method body parsed and saved successfully',
|
|
1170
|
+
data: result,
|
|
1171
|
+
}, null, 2),
|
|
1172
|
+
},
|
|
1173
|
+
],
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
case 'search_methods': {
|
|
1177
|
+
const result = await stellify.searchMethods(args);
|
|
1178
|
+
return {
|
|
1179
|
+
content: [
|
|
1180
|
+
{
|
|
1181
|
+
type: 'text',
|
|
1182
|
+
text: JSON.stringify({
|
|
1183
|
+
success: true,
|
|
1184
|
+
results: result,
|
|
1185
|
+
}, null, 2),
|
|
1186
|
+
},
|
|
1187
|
+
],
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
case 'search_files': {
|
|
1191
|
+
const result = await stellify.searchFiles(args);
|
|
1192
|
+
return {
|
|
1193
|
+
content: [
|
|
1194
|
+
{
|
|
1195
|
+
type: 'text',
|
|
1196
|
+
text: JSON.stringify({
|
|
1197
|
+
success: true,
|
|
1198
|
+
results: result,
|
|
1199
|
+
}, null, 2),
|
|
1200
|
+
},
|
|
1201
|
+
],
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
case 'create_route': {
|
|
1205
|
+
const result = await stellify.createRoute(args);
|
|
1206
|
+
const routeData = result.data || result;
|
|
1207
|
+
return {
|
|
1208
|
+
content: [
|
|
1209
|
+
{
|
|
1210
|
+
type: 'text',
|
|
1211
|
+
text: JSON.stringify({
|
|
1212
|
+
success: true,
|
|
1213
|
+
message: `Created route "${args.name}" at ${args.path} (UUID: ${routeData.uuid}). Use this UUID for html_to_elements page parameter.`,
|
|
1214
|
+
route: routeData,
|
|
1215
|
+
}, null, 2),
|
|
1216
|
+
},
|
|
1217
|
+
],
|
|
1218
|
+
};
|
|
1219
|
+
}
|
|
1220
|
+
case 'get_route': {
|
|
1221
|
+
const result = await stellify.getRoute(args.uuid);
|
|
1222
|
+
const routeData = result.data || result;
|
|
1223
|
+
return {
|
|
1224
|
+
content: [
|
|
1225
|
+
{
|
|
1226
|
+
type: 'text',
|
|
1227
|
+
text: JSON.stringify({
|
|
1228
|
+
success: true,
|
|
1229
|
+
message: `Route: "${routeData.name}" at ${routeData.path}`,
|
|
1230
|
+
route: routeData,
|
|
1231
|
+
}, null, 2),
|
|
1232
|
+
},
|
|
1233
|
+
],
|
|
1234
|
+
};
|
|
1235
|
+
}
|
|
1236
|
+
case 'search_routes': {
|
|
1237
|
+
const result = await stellify.searchRoutes(args);
|
|
1238
|
+
const routes = result.data || result;
|
|
1239
|
+
// Handle paginated response - data.data contains the actual routes array
|
|
1240
|
+
const routeData = routes.data || routes;
|
|
1241
|
+
const routeCount = Array.isArray(routeData) ? routeData.length : routes.total || 0;
|
|
1242
|
+
return {
|
|
1243
|
+
content: [
|
|
1244
|
+
{
|
|
1245
|
+
type: 'text',
|
|
1246
|
+
text: JSON.stringify({
|
|
1247
|
+
success: true,
|
|
1248
|
+
message: `Found ${routeCount} routes`,
|
|
1249
|
+
routes: routes,
|
|
1250
|
+
}, null, 2),
|
|
1251
|
+
},
|
|
1252
|
+
],
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
case 'create_element': {
|
|
1256
|
+
const result = await stellify.createElement(args);
|
|
1257
|
+
return {
|
|
1258
|
+
content: [
|
|
1259
|
+
{
|
|
1260
|
+
type: 'text',
|
|
1261
|
+
text: JSON.stringify({
|
|
1262
|
+
success: true,
|
|
1263
|
+
message: `Created element of type "${args.type}"`,
|
|
1264
|
+
element: result,
|
|
1265
|
+
}, null, 2),
|
|
1266
|
+
},
|
|
1267
|
+
],
|
|
1268
|
+
};
|
|
1269
|
+
}
|
|
1270
|
+
case 'update_element': {
|
|
1271
|
+
const { uuid, data } = args;
|
|
1272
|
+
const result = await stellify.updateElement(uuid, data);
|
|
1273
|
+
return {
|
|
1274
|
+
content: [
|
|
1275
|
+
{
|
|
1276
|
+
type: 'text',
|
|
1277
|
+
text: JSON.stringify({
|
|
1278
|
+
success: true,
|
|
1279
|
+
message: `Updated element ${uuid}`,
|
|
1280
|
+
element: result,
|
|
1281
|
+
}, null, 2),
|
|
1282
|
+
},
|
|
1283
|
+
],
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
case 'get_element': {
|
|
1287
|
+
const { uuid } = args;
|
|
1288
|
+
const result = await stellify.getElement(uuid);
|
|
1289
|
+
return {
|
|
1290
|
+
content: [
|
|
1291
|
+
{
|
|
1292
|
+
type: 'text',
|
|
1293
|
+
text: JSON.stringify({
|
|
1294
|
+
success: true,
|
|
1295
|
+
element: result,
|
|
1296
|
+
}, null, 2),
|
|
1297
|
+
},
|
|
1298
|
+
],
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
case 'get_element_tree': {
|
|
1302
|
+
const { uuid } = args;
|
|
1303
|
+
const result = await stellify.getElementTree(uuid);
|
|
1304
|
+
return {
|
|
1305
|
+
content: [
|
|
1306
|
+
{
|
|
1307
|
+
type: 'text',
|
|
1308
|
+
text: JSON.stringify({
|
|
1309
|
+
success: true,
|
|
1310
|
+
message: `Retrieved element tree for ${uuid}`,
|
|
1311
|
+
tree: result,
|
|
1312
|
+
}, null, 2),
|
|
1313
|
+
},
|
|
1314
|
+
],
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
case 'delete_element': {
|
|
1318
|
+
const { uuid } = args;
|
|
1319
|
+
const result = await stellify.deleteElement(uuid);
|
|
1320
|
+
return {
|
|
1321
|
+
content: [
|
|
1322
|
+
{
|
|
1323
|
+
type: 'text',
|
|
1324
|
+
text: JSON.stringify({
|
|
1325
|
+
success: true,
|
|
1326
|
+
message: `Deleted element ${uuid} and ${result.deleted_count} total elements`,
|
|
1327
|
+
deleted_count: result.deleted_count,
|
|
1328
|
+
}, null, 2),
|
|
1329
|
+
},
|
|
1330
|
+
],
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
case 'search_elements': {
|
|
1334
|
+
const result = await stellify.searchElements(args);
|
|
1335
|
+
return {
|
|
1336
|
+
content: [
|
|
1337
|
+
{
|
|
1338
|
+
type: 'text',
|
|
1339
|
+
text: JSON.stringify({
|
|
1340
|
+
success: true,
|
|
1341
|
+
message: `Found ${result.data.length} elements`,
|
|
1342
|
+
elements: result.data,
|
|
1343
|
+
pagination: result.pagination,
|
|
1344
|
+
}, null, 2),
|
|
1345
|
+
},
|
|
1346
|
+
],
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
case 'html_to_elements': {
|
|
1350
|
+
const result = await stellify.htmlToElements(args);
|
|
1351
|
+
const elementCount = Object.keys(result.data || {}).length;
|
|
1352
|
+
const testMode = args.test ? ' (TEST MODE - not created)' : '';
|
|
1353
|
+
return {
|
|
1354
|
+
content: [
|
|
1355
|
+
{
|
|
1356
|
+
type: 'text',
|
|
1357
|
+
text: JSON.stringify({
|
|
1358
|
+
success: true,
|
|
1359
|
+
message: `Converted HTML to ${elementCount} elements${testMode}`,
|
|
1360
|
+
elements: result.data,
|
|
1361
|
+
}, null, 2),
|
|
1362
|
+
},
|
|
1363
|
+
],
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
case 'list_globals': {
|
|
1367
|
+
const result = await stellify.listGlobals();
|
|
1368
|
+
return {
|
|
1369
|
+
content: [
|
|
1370
|
+
{
|
|
1371
|
+
type: 'text',
|
|
1372
|
+
text: JSON.stringify({
|
|
1373
|
+
success: true,
|
|
1374
|
+
message: `Found ${result.data?.length || 0} globals`,
|
|
1375
|
+
globals: result.data,
|
|
1376
|
+
}, null, 2),
|
|
1377
|
+
},
|
|
1378
|
+
],
|
|
1379
|
+
};
|
|
1380
|
+
}
|
|
1381
|
+
case 'get_global': {
|
|
1382
|
+
const { uuid } = args;
|
|
1383
|
+
const result = await stellify.getGlobal(uuid);
|
|
1384
|
+
return {
|
|
1385
|
+
content: [
|
|
1386
|
+
{
|
|
1387
|
+
type: 'text',
|
|
1388
|
+
text: JSON.stringify({
|
|
1389
|
+
success: true,
|
|
1390
|
+
global: result,
|
|
1391
|
+
}, null, 2),
|
|
1392
|
+
},
|
|
1393
|
+
],
|
|
1394
|
+
};
|
|
1395
|
+
}
|
|
1396
|
+
case 'install_global': {
|
|
1397
|
+
const result = await stellify.installGlobal(args);
|
|
1398
|
+
return {
|
|
1399
|
+
content: [
|
|
1400
|
+
{
|
|
1401
|
+
type: 'text',
|
|
1402
|
+
text: JSON.stringify({
|
|
1403
|
+
success: true,
|
|
1404
|
+
message: `Installed global "${result.data?.file_name}" (${result.data?.methods_copied} methods, ${result.data?.statements_copied} statements)`,
|
|
1405
|
+
data: result.data,
|
|
1406
|
+
}, null, 2),
|
|
1407
|
+
},
|
|
1408
|
+
],
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
case 'search_global_methods': {
|
|
1412
|
+
const result = await stellify.searchGlobalMethods(args);
|
|
1413
|
+
return {
|
|
1414
|
+
content: [
|
|
1415
|
+
{
|
|
1416
|
+
type: 'text',
|
|
1417
|
+
text: JSON.stringify({
|
|
1418
|
+
success: true,
|
|
1419
|
+
message: `Found ${result.data?.length || 0} global methods`,
|
|
1420
|
+
methods: result.data,
|
|
1421
|
+
}, null, 2),
|
|
1422
|
+
},
|
|
1423
|
+
],
|
|
1424
|
+
};
|
|
1425
|
+
}
|
|
1426
|
+
// Module handlers
|
|
1427
|
+
case 'list_modules': {
|
|
1428
|
+
const result = await stellify.listModules();
|
|
1429
|
+
return {
|
|
1430
|
+
content: [
|
|
1431
|
+
{
|
|
1432
|
+
type: 'text',
|
|
1433
|
+
text: JSON.stringify({
|
|
1434
|
+
success: true,
|
|
1435
|
+
message: `Found ${result.data?.length || 0} modules`,
|
|
1436
|
+
modules: result.data,
|
|
1437
|
+
}, null, 2),
|
|
1438
|
+
},
|
|
1439
|
+
],
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
case 'get_module': {
|
|
1443
|
+
const { uuid } = args;
|
|
1444
|
+
const result = await stellify.getModule(uuid);
|
|
1445
|
+
return {
|
|
1446
|
+
content: [
|
|
1447
|
+
{
|
|
1448
|
+
type: 'text',
|
|
1449
|
+
text: JSON.stringify({
|
|
1450
|
+
success: true,
|
|
1451
|
+
module: result.module,
|
|
1452
|
+
files: result.files,
|
|
1453
|
+
}, null, 2),
|
|
1454
|
+
},
|
|
1455
|
+
],
|
|
1456
|
+
};
|
|
1457
|
+
}
|
|
1458
|
+
case 'create_module': {
|
|
1459
|
+
const result = await stellify.createModule(args);
|
|
1460
|
+
return {
|
|
1461
|
+
content: [
|
|
1462
|
+
{
|
|
1463
|
+
type: 'text',
|
|
1464
|
+
text: JSON.stringify({
|
|
1465
|
+
success: true,
|
|
1466
|
+
message: `Created module "${result.data?.name}"`,
|
|
1467
|
+
data: result.data,
|
|
1468
|
+
}, null, 2),
|
|
1469
|
+
},
|
|
1470
|
+
],
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
case 'add_file_to_module': {
|
|
1474
|
+
const result = await stellify.addFileToModule(args);
|
|
1475
|
+
return {
|
|
1476
|
+
content: [
|
|
1477
|
+
{
|
|
1478
|
+
type: 'text',
|
|
1479
|
+
text: JSON.stringify({
|
|
1480
|
+
success: true,
|
|
1481
|
+
message: `Added "${result.data?.file_name}" to module (order: ${result.data?.order})`,
|
|
1482
|
+
data: result.data,
|
|
1483
|
+
}, null, 2),
|
|
1484
|
+
},
|
|
1485
|
+
],
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
case 'install_module': {
|
|
1489
|
+
const result = await stellify.installModule(args);
|
|
1490
|
+
return {
|
|
1491
|
+
content: [
|
|
1492
|
+
{
|
|
1493
|
+
type: 'text',
|
|
1494
|
+
text: JSON.stringify({
|
|
1495
|
+
success: true,
|
|
1496
|
+
message: `Installed module "${result.data?.module_name}" (${result.data?.files_installed} files, ${result.data?.methods_copied} methods, ${result.data?.statements_copied} statements)`,
|
|
1497
|
+
data: result.data,
|
|
1498
|
+
}, null, 2),
|
|
1499
|
+
},
|
|
1500
|
+
],
|
|
1501
|
+
};
|
|
1502
|
+
}
|
|
1503
|
+
// Statement & File Management handlers
|
|
1504
|
+
case 'get_statement': {
|
|
1505
|
+
const result = await stellify.getStatement(args.uuid);
|
|
1506
|
+
return {
|
|
1507
|
+
content: [
|
|
1508
|
+
{
|
|
1509
|
+
type: 'text',
|
|
1510
|
+
text: JSON.stringify({
|
|
1511
|
+
success: true,
|
|
1512
|
+
message: `Statement retrieved`,
|
|
1513
|
+
statement: result.statement || result,
|
|
1514
|
+
clauses: result.clauses || null,
|
|
1515
|
+
}, null, 2),
|
|
1516
|
+
},
|
|
1517
|
+
],
|
|
1518
|
+
};
|
|
1519
|
+
}
|
|
1520
|
+
case 'create_statement': {
|
|
1521
|
+
const result = await stellify.createStatement(args);
|
|
1522
|
+
return {
|
|
1523
|
+
content: [
|
|
1524
|
+
{
|
|
1525
|
+
type: 'text',
|
|
1526
|
+
text: JSON.stringify({
|
|
1527
|
+
success: true,
|
|
1528
|
+
message: `Created statement (${result.data?.uuid || result.uuid})`,
|
|
1529
|
+
statement: result.data || result,
|
|
1530
|
+
}, null, 2),
|
|
1531
|
+
},
|
|
1532
|
+
],
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
case 'add_statement_code': {
|
|
1536
|
+
const result = await stellify.addStatementCode(args);
|
|
1537
|
+
return {
|
|
1538
|
+
content: [
|
|
1539
|
+
{
|
|
1540
|
+
type: 'text',
|
|
1541
|
+
text: JSON.stringify({
|
|
1542
|
+
success: true,
|
|
1543
|
+
message: 'Statement code added successfully',
|
|
1544
|
+
data: result,
|
|
1545
|
+
}, null, 2),
|
|
1546
|
+
},
|
|
1547
|
+
],
|
|
1548
|
+
};
|
|
1549
|
+
}
|
|
1550
|
+
case 'save_file': {
|
|
1551
|
+
const { uuid, ...data } = args;
|
|
1552
|
+
const result = await stellify.saveFile(uuid, { uuid, ...data });
|
|
1553
|
+
return {
|
|
1554
|
+
content: [
|
|
1555
|
+
{
|
|
1556
|
+
type: 'text',
|
|
1557
|
+
text: JSON.stringify({
|
|
1558
|
+
success: true,
|
|
1559
|
+
message: `Saved file "${data.name || uuid}"`,
|
|
1560
|
+
file: result,
|
|
1561
|
+
}, null, 2),
|
|
1562
|
+
},
|
|
1563
|
+
],
|
|
1564
|
+
};
|
|
1565
|
+
}
|
|
1566
|
+
case 'get_file': {
|
|
1567
|
+
const { uuid } = args;
|
|
1568
|
+
const result = await stellify.getFile(uuid);
|
|
1569
|
+
return {
|
|
1570
|
+
content: [
|
|
1571
|
+
{
|
|
1572
|
+
type: 'text',
|
|
1573
|
+
text: JSON.stringify({
|
|
1574
|
+
success: true,
|
|
1575
|
+
file: result,
|
|
1576
|
+
}, null, 2),
|
|
1577
|
+
},
|
|
1578
|
+
],
|
|
1579
|
+
};
|
|
1580
|
+
}
|
|
1581
|
+
case 'get_directory': {
|
|
1582
|
+
const result = await stellify.getDirectory(args.uuid);
|
|
1583
|
+
const dirData = result.data || result;
|
|
1584
|
+
return {
|
|
1585
|
+
content: [
|
|
1586
|
+
{
|
|
1587
|
+
type: 'text',
|
|
1588
|
+
text: JSON.stringify({
|
|
1589
|
+
success: true,
|
|
1590
|
+
message: `Directory: "${dirData.name}" (${dirData.uuid})`,
|
|
1591
|
+
directory: dirData,
|
|
1592
|
+
}, null, 2),
|
|
1593
|
+
},
|
|
1594
|
+
],
|
|
1595
|
+
};
|
|
1596
|
+
}
|
|
1597
|
+
case 'create_directory': {
|
|
1598
|
+
const result = await stellify.createDirectory(args);
|
|
1599
|
+
return {
|
|
1600
|
+
content: [
|
|
1601
|
+
{
|
|
1602
|
+
type: 'text',
|
|
1603
|
+
text: JSON.stringify({
|
|
1604
|
+
success: true,
|
|
1605
|
+
message: result.existing
|
|
1606
|
+
? `Using existing directory "${args.name}" (${result.data?.uuid || result.uuid})`
|
|
1607
|
+
: `Created directory "${args.name}" (${result.data?.uuid || result.uuid})`,
|
|
1608
|
+
directory: result.data || result,
|
|
1609
|
+
existing: result.existing || false,
|
|
1610
|
+
}, null, 2),
|
|
1611
|
+
},
|
|
1612
|
+
],
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
case 'broadcast_element_command': {
|
|
1616
|
+
const result = await stellify.broadcastElementCommand(args);
|
|
1617
|
+
return {
|
|
1618
|
+
content: [
|
|
1619
|
+
{
|
|
1620
|
+
type: 'text',
|
|
1621
|
+
text: JSON.stringify({
|
|
1622
|
+
success: true,
|
|
1623
|
+
message: `Broadcast ${args.action} command${args.element ? ` for element ${args.element}` : ''}`,
|
|
1624
|
+
data: result,
|
|
246
1625
|
}, null, 2),
|
|
247
1626
|
},
|
|
248
1627
|
],
|