@stellisoft/stellify-mcp 0.1.26 → 0.1.27

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/index.js CHANGED
@@ -26,7 +26,7 @@ const STELLIFY_FRAMEWORK_API = {
26
26
  List: ['create', 'from', 'range', 'add', 'remove', 'removeWhere', 'set', 'get', 'first', 'last', 'sort', 'sortBy', 'reverse', 'filter', 'find', 'findIndex', 'map', 'reduce', 'forEach', 'includes', 'indexOf', 'every', 'some', 'slice', 'take', 'skip', 'chunk', 'unique', 'uniqueBy', 'groupBy', 'flatten', 'concat', 'isEmpty', 'isNotEmpty', 'count', 'clear', 'toArray', 'toJSON', 'clone', 'sum', 'avg', 'min', 'max'],
27
27
  Tree: ['create', 'setRoot', 'addChild', 'removeNode', 'getNode', 'getRoot', 'getChildren', 'getParent', 'getSiblings', 'getAncestors', 'getDescendants', 'getDepth', 'getPath', 'traverse', 'find', 'findAll', 'move', 'toArray', 'size'],
28
28
  // Network
29
- Http: ['create', 'get', 'post', 'put', 'patch', 'delete', 'withHeaders', 'withToken', 'withTimeout'],
29
+ Http: ['create', 'get', 'post', 'put', 'patch', 'delete', 'items', 'withHeaders', 'withToken', 'withTimeout'],
30
30
  Socket: ['create', 'connect', 'disconnect', 'send', 'sendEvent', 'on', 'off', 'once', 'isConnected', 'getState'],
31
31
  Auth: ['create', 'login', 'logout', 'fetchUser', 'getUser', 'getToken', 'isAuthenticated', 'setToken', 'setUser', 'refresh', 'onAuthChange', 'offAuthChange', 'getAuthHeader'],
32
32
  Stream: ['create', 'headers', 'withToken', 'onChunk', 'onComplete', 'onError', 'get', 'post', 'abort', 'getBuffer', 'getChunks', 'isStreaming', 'clear'],
@@ -77,12 +77,8 @@ The npm package is "stellify-framework" (NOT @stellify/core).
77
77
  Import like: import { Http, List, Form } from 'stellify-framework';
78
78
 
79
79
  IMPORTANT - List class and Vue reactivity:
80
- The List class methods return List instances, NOT plain arrays.
81
- Vue's v-for directive cannot iterate over List instances directly.
82
-
83
- When assigning to a Vue ref that will be used with v-for, call .toArray():
84
- - CORRECT: notes.value = List.from(response.data).toArray();
85
- - INCORRECT (v-for won't work): notes.value = List.from(response.data);
80
+ List is iterable and works directly with Vue's v-for directive.
81
+ Use List.from() to wrap arrays for chainable operations (filter, map, sort, etc.).
86
82
 
87
83
  Example response:
88
84
  {
@@ -138,13 +134,16 @@ LEGACY (still supported but prefer combined tools above):
138
134
 
139
135
  For PHP: Use type='class', 'model', 'controller', or 'middleware'.
140
136
  For Vue: Use type='js' and extension='vue'. Place in the 'js' directory.
137
+ - Auto-creates app.js (check response.appJs)
138
+ - Auto-creates template route for visual editor (check response.templateRoute.uuid)
141
139
 
142
140
  DEPENDENCY RESOLUTION (automatic):
143
- Pass 'includes' as an array of namespace strings (e.g., ["App\\Models\\User", "Illuminate\\Support\\Facades\\Hash"]).
144
- The system resolves these to UUIDs automatically, creating missing dependencies on-demand:
145
- - App\\* classes → creates stub file in your project (tenant DB)
141
+ Pass 'includes' as an array of namespace strings for FRAMEWORK classes (e.g., ["Illuminate\\Http\\Request", "Illuminate\\Support\\Facades\\Hash"]).
142
+ The system resolves these to UUIDs automatically:
146
143
  - Illuminate\\*/Laravel\\* → fetches from Laravel API, creates in Application DB
147
- - Vendor packages → fetches from vendor, creates in Application DB`,
144
+ - Vendor packages → fetches from vendor, creates in Application DB
145
+
146
+ NOTE: For controllers that use PROJECT models (Feedback, Vote, etc.), add those to the 'models' array in save_file instead. Do NOT put project models in includes - this causes duplicate use statement errors.`,
148
147
  inputSchema: {
149
148
  type: 'object',
150
149
  properties: {
@@ -186,7 +185,7 @@ The system resolves these to UUIDs automatically, creating missing dependencies
186
185
  name: 'create_method',
187
186
  description: `Create a method in a file. Can optionally include the body and async flag in a single call.
188
187
 
189
- **NEW: Combined creation** - You can now pass 'body' and 'is_async' to create the complete method in ONE call instead of three (create_method add_method_body → save_method).
188
+ **NEW: Combined creation** - Pass 'body' to create the complete method in ONE call. Async is auto-detected when body contains \`await\`.
190
189
 
191
190
  Parameters are automatically created as clauses. The response includes the clause UUIDs for each parameter.
192
191
 
@@ -202,12 +201,11 @@ Example request (simple - signature only):
202
201
  ]
203
202
  }
204
203
 
205
- Example request (combined - with body and async):
204
+ Example request (combined - with body, async auto-detected):
206
205
  {
207
206
  "file": "file-uuid",
208
207
  "name": "fetchData",
209
- "body": "const response = await Http.get('/api/data');\\nreturn response.data;",
210
- "is_async": true
208
+ "body": "const response = await Http.get('/api/data');\\nreturn response.data;"
211
209
  }
212
210
 
213
211
  Example response includes:
@@ -456,7 +454,9 @@ Example - Remove duplicate/unwanted statements:
456
454
  },
457
455
  {
458
456
  name: 'create_route',
459
- description: `Create a route/page. For API routes, pass controller and controller_method UUIDs to wire execution.
457
+ description: `Create a route/page. For API routes, you MUST pass BOTH controller AND controller_method UUIDs to wire execution.
458
+
459
+ IMPORTANT: Both 'controller' (file UUID) and 'controller_method' (method UUID) are required together for API routes to execute code. Without both, the route won't run any code.
460
460
 
461
461
  Route params like {id} auto-inject into controller method parameters when names match.`,
462
462
  inputSchema: {
@@ -488,11 +488,11 @@ Route params like {id} auto-inject into controller method parameters when names
488
488
  },
489
489
  controller: {
490
490
  type: 'string',
491
- description: 'UUID of the controller file to handle this route. Required for API routes to execute code.',
491
+ description: 'UUID of the controller file. MUST be provided together with controller_method for API routes to execute code.',
492
492
  },
493
493
  controller_method: {
494
494
  type: 'string',
495
- description: 'UUID of the method within the controller to execute. Required for API routes to execute code.',
495
+ description: 'UUID of the method to execute. MUST be provided together with controller for API routes to execute code.',
496
496
  },
497
497
  data: {
498
498
  type: 'object',
@@ -527,6 +527,7 @@ Use this to look up a route you created or to find existing routes in the projec
527
527
  description: `Update an existing route/page. Use this to wire a route to a controller method.
528
528
 
529
529
  IMPORTANT: This is how you connect API routes to controller methods!
530
+ IMPORTANT: You MUST provide BOTH controller AND controller_method together - they are a pair.
530
531
 
531
532
  Example - Wire an API route to a controller method:
532
533
  {
@@ -536,8 +537,8 @@ Example - Wire an API route to a controller method:
536
537
  }
537
538
 
538
539
  Available fields:
539
- - controller: UUID of the controller file
540
- - controller_method: UUID of the method to execute
540
+ - controller: UUID of the controller file (MUST be paired with controller_method)
541
+ - controller_method: UUID of the method to execute (MUST be paired with controller)
541
542
  - path: URL path
542
543
  - name: Route name
543
544
  - type: "web" or "api"
@@ -553,11 +554,11 @@ Available fields:
553
554
  },
554
555
  controller: {
555
556
  type: 'string',
556
- description: 'UUID of the controller file to handle this route',
557
+ description: 'UUID of the controller file. MUST be provided together with controller_method.',
557
558
  },
558
559
  controller_method: {
559
560
  type: 'string',
560
- description: 'UUID of the method within the controller to execute',
561
+ description: 'UUID of the method to execute. MUST be provided together with controller.',
561
562
  },
562
563
  path: {
563
564
  type: 'string',
@@ -679,11 +680,22 @@ Generates: <div class="card p-4" v-for="note in notes" :key="note.id">`,
679
680
  name: 'update_element',
680
681
  description: `Update a UI element's attributes.
681
682
 
682
- Pass data object with: tag, classes (array), text, variable (for v-model), and event handlers (click, submit, etc. = method UUID).
683
+ Pass data object with: tag, classes (array), text, variable (for v-model), and event handlers.
683
684
 
684
685
  Key fields: inputType (not 'type') for button/input HTML type. clickArgs for handler arguments in v-for loops.
685
686
 
686
- Event handlers: click, submit, change, input, focus, blur, keydown, keyup, mouseenter, mouseleave.`,
687
+ EVENT HANDLERS - Use method UUIDs:
688
+ { "click": "method-uuid" } → @click="methodName"
689
+ { "click": "method-uuid", "clickArgs": "item" } → @click="methodName(item)"
690
+
691
+ Create methods for all handlers, including simple state changes like opening modals or toggling flags.
692
+
693
+ Event types: click, submit, change, input, focus, blur, keydown, keyup, mouseenter, mouseleave.
694
+
695
+ EFFICIENCY - Prefer updates over delete/recreate:
696
+ - Move between routes: change \`routeParent\` attribute
697
+ - Reparent elements: change \`parent\` attribute
698
+ - Reorder children: update parent's \`data\` array with new UUID order`,
687
699
  inputSchema: {
688
700
  type: 'object',
689
701
  properties: {
@@ -776,6 +788,8 @@ Note: To reorder elements, use update_element to modify the parent element's 'da
776
788
 
777
789
  Auto-detects Vue bindings ({{ var }}). For Vue components, omit 'page'. For pages, provide route UUID.
778
790
 
791
+ **@click auto-wiring:** Pass 'file' UUID to auto-resolve @click="methodName" handlers. Methods must exist in the file first.
792
+
779
793
  Prefer SVG icons over emoji (encoding issues).`,
780
794
  inputSchema: {
781
795
  type: 'object',
@@ -792,6 +806,10 @@ Prefer SVG icons over emoji (encoding issues).`,
792
806
  type: 'string',
793
807
  description: 'Parent element UUID to attach to (alternative to page)',
794
808
  },
809
+ file: {
810
+ type: 'string',
811
+ description: 'Vue component file UUID. Pass this to auto-wire @click handlers to method UUIDs.',
812
+ },
795
813
  test: {
796
814
  type: 'boolean',
797
815
  description: 'If true, returns structure without creating elements',
@@ -1018,12 +1036,12 @@ This works the same as create_file's dependency resolution.`,
1018
1036
  includes: {
1019
1037
  type: 'array',
1020
1038
  items: { type: 'string' },
1021
- description: 'Array of file UUIDs OR namespace strings to import. Namespace strings (e.g., "Illuminate\\\\Http\\\\JsonResponse") are auto-resolved to UUIDs.',
1039
+ description: 'Array of file UUIDs OR namespace strings for FRAMEWORK classes only (Request, JsonResponse, etc.). Do NOT put project models here - use the models array instead.',
1022
1040
  },
1023
1041
  models: {
1024
1042
  type: 'array',
1025
1043
  items: { type: 'string' },
1026
- description: 'Array of model file UUIDs that this controller uses (required for model class loading)',
1044
+ description: 'Array of model file UUIDs for PROJECT models (Feedback, Vote, etc.). These get sandbox namespace automatically. Do NOT also add these to includes or you will get duplicate use statement errors.',
1027
1045
  },
1028
1046
  },
1029
1047
  required: ['uuid', 'name', 'type'],
@@ -1486,114 +1504,72 @@ Key concepts:
1486
1504
 
1487
1505
  1. get_project → find 'js' directory UUID (or create it)
1488
1506
  2. create_file → type='js', extension='vue' for the component
1489
- 3. **Create a template route** for editor access:
1490
- - create_route with name like "notes-template" or "component-name-template"
1491
- - This route is NOT where the component displays - it's only for accessing the template in the Stellify visual editor
1492
- - The actual display route (e.g., "/notes") will have just \`<div id="app"></div>\` where Vue mounts
1493
- 4. Create statements for imports using **create_statement_with_code** (ONE call each):
1507
+ - **Auto-creates app.js** and **template route** (check response for appJs and templateRoute fields)
1508
+ 3. Create statements for imports using **create_statement_with_code** (ONE call each):
1494
1509
  - create_statement_with_code(file, "import { ref, onMounted } from 'vue';")
1495
1510
  - create_statement_with_code(file, "import { Http } from 'stellify-framework';")
1496
- NOTE: The npm package is "stellify-framework" (NOT @stellify/core)
1497
- 5. Create statements for reactive data: create_statement_with_code(file, "const notes = ref([]);")
1498
- 6. **create_method with body and is_async** (ONE call instead of three). Example:
1511
+ 4. Create statements for reactive data: create_statement_with_code(file, "const notes = ref([]);")
1512
+ 5. **create_method with body** (async auto-detected from \`await\`). Example:
1499
1513
  \`\`\`
1500
1514
  create_method({
1501
1515
  file: fileUuid,
1502
1516
  name: "fetchNotes",
1503
- body: "const response = await Http.get('/api/notes');\\nnotes.value = response.data || [];",
1504
- is_async: true
1517
+ body: "const response = await Http.get('/api/notes');\\nnotes.value = response.data || [];"
1505
1518
  })
1506
1519
  \`\`\`
1507
- 7. Create statement for onMounted: create_statement_with_code(file, "onMounted(fetchNotes);")
1508
- 8. html_to_elements template **with page=templateRouteUuid** (attach to the template route for editor access)
1509
- 9. update_element → wire click handlers to method UUIDs
1510
- 10. save_file with: extension='vue', template=[elementUuid], data=[methodUuids], statements=[importUuids, refUuids, onMountedUuid]
1511
- - **data = method UUIDs only** (functions)
1512
- - **statements = statement UUIDs** (imports, refs, onMounted)
1513
- 11. **MANDATORY: Create app.js entry file** (see "CRITICAL: JavaScript Entry File" section below)
1514
- 12. Create web route for the display page (e.g., "/notes")
1515
- 13. **MANDATORY: Add a div with id="app"** to the display page using html_to_elements:
1516
- - html_to_elements with page=routeUuid and elements='<div id="app"></div>'
1517
- - This is where Vue mounts the component. Without it, nothing renders!
1518
-
1519
- ## Real-Time UI (broadcast_element_command)
1520
-
1521
- Use for SHOW/DISPLAY/DEMONSTRATE requests - sends instant WebSocket updates to browser.
1522
- Use html_to_elements/update_element for permanent/saved changes.
1523
-
1524
- ## CRITICAL: Http Response Handling (Most Common Error)
1525
-
1526
- **This is the #1 cause of "notes not displaying" bugs.**
1527
-
1528
- When fetching data from API endpoints, stellify-framework's Http class returns the JSON body DIRECTLY - it does NOT wrap responses like axios does.
1520
+ 6. Create statement for onMounted: create_statement_with_code(file, "onMounted(fetchData);")
1521
+ 7. **Create UI interaction methods** for any button that changes state:
1522
+ \`\`\`
1523
+ create_method({ file: fileUuid, name: "openModal", body: "showModal.value = true;" })
1524
+ create_method({ file: fileUuid, name: "closeModal", body: "showModal.value = false;" })
1525
+ \`\`\`
1526
+ 8. html_to_elements with @click handlers auto-wired:
1527
+ \`\`\`
1528
+ html_to_elements({
1529
+ elements: '<button @click="openModal">Open</button>',
1530
+ page: templateRoute.uuid,
1531
+ file: fileUuid // Auto-wires @click="openModal" to the method UUID
1532
+ })
1533
+ \`\`\`
1534
+ 9. save_file with: extension='vue', template=[elementUuid], data=[methodUuids], statements=[importUuids, refUuids, onMountedUuid]
1535
+ 11. Create web route for the display page (e.g., "/notes")
1536
+ 12. Add \`<div id="app"></div>\` to the display page: html_to_elements(page=routeUuid, elements='<div id="app"></div>')
1529
1537
 
1530
- Laravel pagination returns: \`{ data: [...items], current_page: 1, per_page: 15, ... }\`
1538
+ ## Fetching Paginated Data
1531
1539
 
1532
- Since Http.get() returns this JSON directly (no axios wrapper), you access the array with ONE \`.data\`:
1540
+ Use \`Http.items()\` for paginated endpoints - it auto-extracts the array from Laravel responses:
1533
1541
 
1534
1542
  \`\`\`javascript
1535
- // CORRECT - Http returns JSON directly, .data gets the paginated array
1536
- const response = await Http.get('/api/notes');
1537
- notes.value = response.data || [];
1543
+ // Recommended - auto-extracts .data from paginated response
1544
+ notes.value = await Http.items('/api/notes');
1538
1545
 
1539
- // WRONG - Double .data (axios habit) - returns undefined, notes stay empty!
1546
+ // Alternative - manual extraction
1540
1547
  const response = await Http.get('/api/notes');
1541
- notes.value = response.data.data || []; // BUG: response.data.data is undefined
1548
+ notes.value = response.data || [];
1542
1549
  \`\`\`
1543
1550
 
1544
- **Why this mistake happens:** With axios, you write \`response.data.data\` because axios wraps the HTTP response (\`response.data\` unwraps axios, then \`.data\` gets the pagination array). Stellify's Http skips the wrapper, so you only need ONE \`.data\`.
1545
-
1546
- **Symptom:** Notes exist in database, API returns them, but UI shows empty list or "No notes yet" message.
1547
-
1548
1551
  ## Common Pitfalls
1549
1552
 
1550
- - **Vue template editor access:** Templates MUST be attached to a route for users to edit them in the visual editor. Create a separate "template route" (e.g., "notes-template") and pass its UUID to html_to_elements. This is different from the display route where the component renders.
1553
+ - **@click auto-wiring:** Pass the file UUID to html_to_elements to auto-wire @click handlers. Methods must be created BEFORE calling html_to_elements.
1551
1554
  - **Stellify imports:** Use "stellify-framework" package (NOT @stellify/core)
1552
1555
  CORRECT: import { Http, List, Form } from 'stellify-framework';
1553
1556
  WRONG: import { Http } from '@stellify/core';
1554
1557
  - v-model requires ref(), NOT Form class: const formData = ref({title: ''})
1555
- - List.from() returns List, not array - use .toArray() for v-for
1558
+ - List is iterable and works directly with v-for (no .toArray() needed)
1556
1559
  - add_method_body APPENDS, doesn't replace - create new method to replace
1557
1560
  - 'data' array = method UUIDs, 'statements' array = import/variable UUIDs
1558
1561
  - For buttons in forms, set inputType: "button" to prevent auto-submit
1559
- - **Async methods:** Methods using await MUST be marked async. Use is_async: true in create_method (preferred) or save_method
1562
+ - **Async methods:** Auto-detected when body contains \`await\`. Response includes \`is_async: true\` if detected.
1560
1563
  - **onMounted:** Use direct method reference: "onMounted(fetchNotes);"
1561
1564
  The assembler automatically outputs lifecycle hooks after method definitions.
1562
1565
 
1563
- ## CRITICAL: Nullable Refs and v-if Guards
1564
-
1565
- **This causes "Cannot read properties of null" errors.**
1566
-
1567
- When using a nullable ref (e.g., \`const editingNote = ref(null)\`) with v-model or property access in templates, you MUST guard with an explicit v-if that checks the ref is not null.
1568
-
1569
- **WRONG - v-else does NOT protect against null evaluation:**
1570
- \`\`\`html
1571
- <template v-if="!editingItem">
1572
- <!-- view mode -->
1573
- </template>
1574
- <template v-else>
1575
- <input v-model="editingItem.title" /> <!-- ERROR: editingItem could be null -->
1576
- </template>
1577
- \`\`\`
1578
-
1579
- **CORRECT - explicit v-if with null check:**
1580
- \`\`\`html
1581
- <template v-if="!editingItem || editingItem.id !== item.id">
1582
- <!-- view mode -->
1583
- </template>
1584
- <template v-if="editingItem && editingItem.id === item.id">
1585
- <input v-model="editingItem.title" /> <!-- Safe: editingItem is guaranteed non-null -->
1586
- </template>
1587
- \`\`\`
1566
+ ## Nullable Refs: Use explicit v-if, NOT v-else
1588
1567
 
1589
- **Why v-else fails:** Vue evaluates v-model bindings during compilation/render setup, before the v-else condition is fully applied. The explicit v-if with \`editingItem &&\` ensures the binding is only evaluated when the ref exists.
1568
+ When using nullable refs (e.g., \`const editingItem = ref(null)\`) with v-model, use explicit v-if guards:
1569
+ - WRONG: \`<template v-else><input v-model="editingItem.title"/></template>\`
1570
+ - CORRECT: \`<template v-if="editingItem && editingItem.id === item.id"><input v-model="editingItem.title"/></template>\`
1590
1571
 
1591
- **Inline editing pattern (CRUD apps):**
1592
- 1. Create ref: \`const editingItem = ref(null);\`
1593
- 2. View template: \`v-if="!editingItem || editingItem.id !== item.id"\`
1594
- 3. Edit template: \`v-if="editingItem && editingItem.id === item.id"\` (NOT v-else!)
1595
- 4. Start editing: \`editingItem.value = { ...item };\`
1596
- 5. Cancel/save: \`editingItem.value = null;\`
1572
+ Vue evaluates v-model bindings before v-else is applied, causing "Cannot read properties of null" errors.
1597
1573
 
1598
1574
  ## Stack and Business Logic
1599
1575
 
@@ -1601,65 +1577,16 @@ When using a nullable ref (e.g., \`const editingNote = ref(null)\`) with v-model
1601
1577
 
1602
1578
  **All business logic** (controllers, models, middleware, etc.) goes in the tenant DB via MCP tools. If a required capability is not available, use \`request_capability\` to log it.
1603
1579
 
1604
- ## Project Modules (Code Organization)
1605
-
1606
- When building features, group related files by passing a "module" parameter.
1607
-
1608
- - create_file(..., module: "blog-posts") - auto-groups file
1609
- - create_route(..., module: "blog-posts") - auto-groups route
1610
-
1611
- Modules are auto-created if they don't exist. This helps users see all code related to a feature grouped together.
1612
-
1613
- ## CRITICAL: JavaScript Entry File (app.js)
1580
+ ## JavaScript Entry File (app.js) - Auto-Generated
1614
1581
 
1615
- **You MUST have a JS entry file to register Vue components for use on pages.**
1582
+ When you create a Vue component, **app.js is automatically created/updated** with component registration. The create_file response will confirm this with an \`appJs\` field.
1616
1583
 
1617
- ### First component in a project:
1618
- 1. Create app.js in the 'js' directory with the component in includes array:
1619
- - create_file with type='js', extension='js', name='app', includes=[component-file-uuid]
1620
- 2. Add statements for NAMED imports only:
1621
- - "import { createApp } from 'vue';"
1622
- - "createApp(NotesApp).mount('#app');"
1623
- NOTE: The component import (NotesApp) is handled by the includes array, NOT a statement!
1624
- 3. save_file with statement UUIDs
1625
-
1626
- ### Adding more components (app.js already exists):
1627
- 1. **search_files** for "app" to find existing app.js
1628
- 2. **get_file** to retrieve current includes and statements
1629
- 3. Add the new component UUID to the includes array via save_file
1630
- 4. Update the mount code to register the new component:
1631
- - Create new statement: "app.component('Counter', Counter);"
1632
- 5. save_file with updated includes and statements arrays
1633
-
1634
- **DO NOT create duplicate app.js files or duplicate createApp imports!**
1635
- **DO NOT use statements for file imports - use the includes array!**
1636
-
1637
- ### Page mount point (div#app):
1638
- Each page that uses Vue components needs a \`<div id="app"></div>\`.
1639
-
1640
- - **First time on a page:** html_to_elements(page=routeUuid, elements='<div id="app"></div>')
1641
- - **Page already has it:** Do NOT add another one. Check with get_route first if unsure.
1642
-
1643
- **Without app.js AND div#app, Vue components will NOT render!**
1644
-
1645
- ### Import types summary:
1646
- - **File imports (components, classes):** Use \`includes\` array with file UUIDs
1647
- - **Named imports (vue, stellify-framework):** Use statements with add_statement_code
1648
-
1649
- Example app.js structure:
1650
- - includes: [notesAppFileUuid, counterFileUuid]
1651
- - statements: ["import { createApp } from 'vue';", "const app = createApp({});", "app.component('NotesApp', NotesApp);", "app.component('Counter', Counter);", "app.mount('#app');"]
1652
-
1653
- ## Efficiency Tips
1654
-
1655
- - **Move elements between routes:** Use \`update_element\` to change \`routeParent\` - don't delete/recreate
1656
- - **Reparent elements:** Update \`parent\` attribute instead of recreating
1657
- - **Reorder children:** Update parent's \`data\` array with new UUID order
1658
- - Always prefer updating over deleting and recreating`;
1584
+ **Page mount point:** Each page using Vue needs \`<div id="app"></div>\`:
1585
+ - html_to_elements(page=routeUuid, elements='<div id="app"></div>')`;
1659
1586
  // Create MCP server
1660
1587
  const server = new Server({
1661
1588
  name: 'stellify-mcp',
1662
- version: '0.1.26',
1589
+ version: '0.1.27',
1663
1590
  }, {
1664
1591
  capabilities: {
1665
1592
  tools: {},
@@ -1722,14 +1649,23 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
1722
1649
  case 'create_file': {
1723
1650
  const result = await stellify.createFile(args);
1724
1651
  const fileData = result.data || result;
1652
+ const appJs = fileData.appJs || result.appJs;
1653
+ let message = `Created file "${args.name}" (UUID: ${fileData.uuid})`;
1654
+ if (appJs?.created) {
1655
+ message += `. Auto-created app.js (UUID: ${appJs.uuid}) with component registration.`;
1656
+ }
1657
+ else if (appJs?.updated) {
1658
+ message += `. Auto-updated app.js to include this component.`;
1659
+ }
1725
1660
  return {
1726
1661
  content: [
1727
1662
  {
1728
1663
  type: 'text',
1729
1664
  text: JSON.stringify({
1730
1665
  success: true,
1731
- message: `Created file "${args.name}" (UUID: ${fileData.uuid})`,
1666
+ message,
1732
1667
  file: fileData,
1668
+ appJs: appJs || null,
1733
1669
  }, null, 2),
1734
1670
  },
1735
1671
  ],
@@ -120,6 +120,7 @@ export declare class StellifyClient {
120
120
  elements: string;
121
121
  page?: string;
122
122
  selection?: string;
123
+ file?: string;
123
124
  test?: boolean;
124
125
  }): Promise<any>;
125
126
  getDirectory(uuid: string): Promise<any>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stellisoft/stellify-mcp",
3
- "version": "0.1.26",
3
+ "version": "0.1.27",
4
4
  "mcpName": "io.github.MattStellisoft/stellify-mcp",
5
5
  "description": "MCP server for Stellify - AI-native code generation platform",
6
6
  "main": "dist/index.js",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/Stellify-Software-Ltd/stellify-mcp",
7
7
  "source": "github"
8
8
  },
9
- "version": "0.1.26",
9
+ "version": "0.1.27",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "@stellisoft/stellify-mcp",
14
- "version": "0.1.26",
14
+ "version": "0.1.27",
15
15
  "transport": {
16
16
  "type": "stdio"
17
17
  },