fastmode-mcp 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/README.md +561 -0
  2. package/bin/run.js +50 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +802 -0
  6. package/dist/lib/api-client.d.ts +81 -0
  7. package/dist/lib/api-client.d.ts.map +1 -0
  8. package/dist/lib/api-client.js +237 -0
  9. package/dist/lib/auth-state.d.ts +13 -0
  10. package/dist/lib/auth-state.d.ts.map +1 -0
  11. package/dist/lib/auth-state.js +24 -0
  12. package/dist/lib/context-fetcher.d.ts +67 -0
  13. package/dist/lib/context-fetcher.d.ts.map +1 -0
  14. package/dist/lib/context-fetcher.js +190 -0
  15. package/dist/lib/credentials.d.ts +52 -0
  16. package/dist/lib/credentials.d.ts.map +1 -0
  17. package/dist/lib/credentials.js +196 -0
  18. package/dist/lib/device-flow.d.ts +14 -0
  19. package/dist/lib/device-flow.d.ts.map +1 -0
  20. package/dist/lib/device-flow.js +244 -0
  21. package/dist/tools/cms-items.d.ts +56 -0
  22. package/dist/tools/cms-items.d.ts.map +1 -0
  23. package/dist/tools/cms-items.js +376 -0
  24. package/dist/tools/create-site.d.ts +9 -0
  25. package/dist/tools/create-site.d.ts.map +1 -0
  26. package/dist/tools/create-site.js +202 -0
  27. package/dist/tools/deploy-package.d.ts +9 -0
  28. package/dist/tools/deploy-package.d.ts.map +1 -0
  29. package/dist/tools/deploy-package.js +434 -0
  30. package/dist/tools/generate-samples.d.ts +19 -0
  31. package/dist/tools/generate-samples.d.ts.map +1 -0
  32. package/dist/tools/generate-samples.js +272 -0
  33. package/dist/tools/get-conversion-guide.d.ts +7 -0
  34. package/dist/tools/get-conversion-guide.d.ts.map +1 -0
  35. package/dist/tools/get-conversion-guide.js +1323 -0
  36. package/dist/tools/get-example.d.ts +7 -0
  37. package/dist/tools/get-example.d.ts.map +1 -0
  38. package/dist/tools/get-example.js +1568 -0
  39. package/dist/tools/get-field-types.d.ts +30 -0
  40. package/dist/tools/get-field-types.d.ts.map +1 -0
  41. package/dist/tools/get-field-types.js +154 -0
  42. package/dist/tools/get-schema.d.ts +5 -0
  43. package/dist/tools/get-schema.d.ts.map +1 -0
  44. package/dist/tools/get-schema.js +320 -0
  45. package/dist/tools/get-started.d.ts +21 -0
  46. package/dist/tools/get-started.d.ts.map +1 -0
  47. package/dist/tools/get-started.js +624 -0
  48. package/dist/tools/get-tenant-schema.d.ts +18 -0
  49. package/dist/tools/get-tenant-schema.d.ts.map +1 -0
  50. package/dist/tools/get-tenant-schema.js +158 -0
  51. package/dist/tools/list-projects.d.ts +5 -0
  52. package/dist/tools/list-projects.d.ts.map +1 -0
  53. package/dist/tools/list-projects.js +101 -0
  54. package/dist/tools/sync-schema.d.ts +41 -0
  55. package/dist/tools/sync-schema.d.ts.map +1 -0
  56. package/dist/tools/sync-schema.js +483 -0
  57. package/dist/tools/validate-manifest.d.ts +5 -0
  58. package/dist/tools/validate-manifest.d.ts.map +1 -0
  59. package/dist/tools/validate-manifest.js +311 -0
  60. package/dist/tools/validate-package.d.ts +5 -0
  61. package/dist/tools/validate-package.d.ts.map +1 -0
  62. package/dist/tools/validate-package.js +337 -0
  63. package/dist/tools/validate-template.d.ts +12 -0
  64. package/dist/tools/validate-template.d.ts.map +1 -0
  65. package/dist/tools/validate-template.js +790 -0
  66. package/package.json +54 -0
  67. package/scripts/postinstall.js +129 -0
@@ -0,0 +1,624 @@
1
+ "use strict";
2
+ /**
3
+ * Get Started Tool
4
+ *
5
+ * Intelligent entry point for the MCP server that performs:
6
+ * 1. State Detection - Understand project state automatically
7
+ * 2. Intent Inference - Determine what user wants to do
8
+ * 3. Guided Execution - Provide exact tool calls with real values
9
+ */
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
+ exports.getStarted = getStarted;
12
+ const context_fetcher_1 = require("../lib/context-fetcher");
13
+ const device_flow_1 = require("../lib/device-flow");
14
+ const api_client_1 = require("../lib/api-client");
15
+ // ============ Response Builders ============
16
+ /**
17
+ * Build the explore response - overview of all projects
18
+ */
19
+ function buildExploreResponse(context) {
20
+ let output = `# Fast Mode MCP - Project Overview
21
+
22
+ ## Authentication
23
+ Status: ✓ Authenticated
24
+
25
+ `;
26
+ if (context.projects.length === 0) {
27
+ output += `## No Projects Yet
28
+
29
+ You don't have any projects. Let's create one!
30
+
31
+ ### Create Your First Project
32
+ \`\`\`
33
+ create_site(name: "My Website")
34
+ \`\`\`
35
+
36
+ Or get help converting an existing website:
37
+ \`\`\`
38
+ get_started(intent: "convert")
39
+ \`\`\`
40
+ `;
41
+ return output;
42
+ }
43
+ output += `## Your Projects (${context.projects.length})
44
+
45
+ | Project | URL | Collections | Items | Status |
46
+ |---------|-----|-------------|-------|--------|
47
+ `;
48
+ for (const project of context.projects) {
49
+ const url = project.customDomain || `${project.subdomain}.fastmode.ai`;
50
+ output += `| ${project.name} | ${url} | ${project.collectionCount} | ${project.totalItems} | ${project.status} |\n`;
51
+ }
52
+ output += `
53
+ ## Quick Actions
54
+
55
+ `;
56
+ // Suggest actions based on project state
57
+ const firstProject = context.projects[0];
58
+ output += `### See project details
59
+ \`\`\`
60
+ get_started(intent: "explore", projectId: "${firstProject.id}")
61
+ \`\`\`
62
+
63
+ ### Add content
64
+ \`\`\`
65
+ get_started(intent: "add_content", projectId: "${firstProject.id}")
66
+ \`\`\`
67
+
68
+ ### Update schema (add collections/fields)
69
+ \`\`\`
70
+ get_started(intent: "update_schema", projectId: "${firstProject.id}")
71
+ \`\`\`
72
+
73
+ ### Deploy a new website
74
+ \`\`\`
75
+ get_started(intent: "deploy", projectId: "${firstProject.id}")
76
+ \`\`\`
77
+
78
+ ### Create a new site from scratch
79
+ \`\`\`
80
+ get_started(intent: "convert")
81
+ \`\`\`
82
+
83
+ ## Available Intents
84
+
85
+ | Intent | Description |
86
+ |--------|-------------|
87
+ | \`explore\` | See what projects and content exist |
88
+ | \`add_content\` | Create/edit CMS items (blog posts, team, etc.) |
89
+ | \`update_schema\` | Add collections or fields |
90
+ | \`convert\` | Build a new website from scratch |
91
+ | \`deploy\` | Push changes to an existing site |
92
+ `;
93
+ return output;
94
+ }
95
+ /**
96
+ * Build the add_content response with schema details
97
+ */
98
+ function buildAddContentResponse(project) {
99
+ let output = `# Fast Mode MCP - Add Content
100
+
101
+ ## Project: ${project.name}
102
+ **URL:** https://${project.subdomain}.fastmode.ai
103
+ **Status:** ${project.status}
104
+
105
+ `;
106
+ if (project.collections.length === 0) {
107
+ output += `## No Collections Yet
108
+
109
+ This project doesn't have any collections. Create collections first:
110
+ \`\`\`
111
+ get_started(intent: "update_schema", projectId: "${project.id}")
112
+ \`\`\`
113
+ `;
114
+ return output;
115
+ }
116
+ output += `## Collections
117
+
118
+ `;
119
+ for (const collection of project.collections) {
120
+ output += buildCollectionTable(collection);
121
+ }
122
+ output += `---
123
+
124
+ ## Workflow: Add Content
125
+
126
+ ### Step 1: See existing content
127
+ \`\`\`
128
+ list_cms_items(projectId: "${project.id}", collectionSlug: "${project.collections[0]?.slug || 'posts'}")
129
+ \`\`\`
130
+
131
+ ### Step 2: Create new item
132
+ \`\`\`
133
+ create_cms_item(
134
+ projectId: "${project.id}",
135
+ collectionSlug: "${project.collections[0]?.slug || 'posts'}",
136
+ name: "Item Title",
137
+ data: {
138
+ ${buildExampleData(project.collections[0])}
139
+ }
140
+ )
141
+ \`\`\`
142
+
143
+ ### Step 3: Update existing item
144
+ \`\`\`
145
+ update_cms_item(
146
+ projectId: "${project.id}",
147
+ collectionSlug: "${project.collections[0]?.slug || 'posts'}",
148
+ itemSlug: "existing-item-slug",
149
+ data: { fieldToUpdate: "new value" }
150
+ )
151
+ \`\`\`
152
+
153
+ ---
154
+
155
+ ## ⚠️ Common Mistakes to Avoid
156
+
157
+ ### Rich text fields
158
+ Rich text fields (type: \`richText\`) accept HTML content:
159
+ \`\`\`
160
+ data: { body: "<p>Your content with <strong>formatting</strong></p>" }
161
+ \`\`\`
162
+
163
+ ### Relation fields
164
+ Relation fields require the **ID** of the related item, not the name:
165
+ \`\`\`
166
+ // WRONG:
167
+ data: { author: "John Smith" }
168
+
169
+ // CORRECT:
170
+ data: { author: "abc-123-uuid-of-john" }
171
+ \`\`\`
172
+
173
+ To get the ID, first list items in the related collection:
174
+ \`\`\`
175
+ list_cms_items(projectId: "${project.id}", collectionSlug: "authors")
176
+ \`\`\`
177
+
178
+ ### Delete requires confirmation
179
+ Always ask the user before deleting:
180
+ \`\`\`
181
+ delete_cms_item(projectId: "...", collectionSlug: "...", itemSlug: "...", confirmDelete: true)
182
+ \`\`\`
183
+ `;
184
+ return output;
185
+ }
186
+ /**
187
+ * Build a table for a collection's fields
188
+ */
189
+ function buildCollectionTable(collection) {
190
+ let output = `### ${collection.name} (${collection.itemCount} items)
191
+
192
+ | Field | Type | Required | Token |
193
+ |-------|------|----------|-------|
194
+ `;
195
+ for (const field of collection.fields) {
196
+ const token = field.type === 'richText'
197
+ ? `\`{{{${field.slug}}}}\``
198
+ : field.type === 'relation'
199
+ ? `\`{{${field.slug}.name}}\``
200
+ : `\`{{${field.slug}}}\``;
201
+ const typeDisplay = field.type === 'relation' && field.referenceCollection
202
+ ? `relation→${field.referenceCollection}`
203
+ : field.type;
204
+ output += `| ${field.name} | ${typeDisplay} | ${field.isRequired ? 'yes' : 'no'} | ${token} |\n`;
205
+ }
206
+ output += '\n';
207
+ return output;
208
+ }
209
+ /**
210
+ * Build example data object for a collection
211
+ */
212
+ function buildExampleData(collection) {
213
+ if (!collection || collection.fields.length === 0) {
214
+ return ' // Add your field values here';
215
+ }
216
+ const lines = [];
217
+ for (const field of collection.fields.slice(0, 5)) {
218
+ let exampleValue;
219
+ switch (field.type) {
220
+ case 'text':
221
+ exampleValue = `"Your ${field.name.toLowerCase()}"`;
222
+ break;
223
+ case 'richText':
224
+ exampleValue = `"<p>Your ${field.name.toLowerCase()} content here...</p>"`;
225
+ break;
226
+ case 'number':
227
+ exampleValue = '0';
228
+ break;
229
+ case 'boolean':
230
+ exampleValue = 'true';
231
+ break;
232
+ case 'image':
233
+ case 'url':
234
+ exampleValue = '"https://example.com/..."';
235
+ break;
236
+ case 'relation':
237
+ exampleValue = '"RELATED_ITEM_ID" // Get ID from list_cms_items';
238
+ break;
239
+ default:
240
+ exampleValue = `"..."`;
241
+ }
242
+ lines.push(` ${field.slug}: ${exampleValue}`);
243
+ }
244
+ return lines.join(',\n');
245
+ }
246
+ /**
247
+ * Build the update_schema response
248
+ */
249
+ function buildUpdateSchemaResponse(project) {
250
+ let output = `# Fast Mode MCP - Update Schema
251
+
252
+ ## Project: ${project.name}
253
+ **Current Collections:** ${project.collections.map(c => c.slug).join(', ') || 'none'}
254
+
255
+ `;
256
+ if (project.collections.length > 0) {
257
+ output += `## Current Schema Summary
258
+
259
+ | Collection | Fields | Items |
260
+ |------------|--------|-------|
261
+ `;
262
+ for (const col of project.collections) {
263
+ const fieldNames = col.fields.slice(0, 4).map(f => f.slug).join(', ');
264
+ const more = col.fields.length > 4 ? ` +${col.fields.length - 4} more` : '';
265
+ output += `| ${col.slug} | ${fieldNames}${more} | ${col.itemCount} |\n`;
266
+ }
267
+ output += '\n';
268
+ }
269
+ output += `---
270
+
271
+ ## Workflow: Add New Schema
272
+
273
+ ### Option A: Add fields to existing collection
274
+ \`\`\`
275
+ sync_schema(
276
+ projectId: "${project.id}",
277
+ fieldsToAdd: [{
278
+ collectionSlug: "${project.collections[0]?.slug || 'posts'}",
279
+ fields: [
280
+ { slug: "new_field", name: "New Field", type: "text" },
281
+ { slug: "featured", name: "Featured", type: "boolean" }
282
+ ]
283
+ }]
284
+ )
285
+ \`\`\`
286
+
287
+ ### Option B: Create new collection
288
+ \`\`\`
289
+ sync_schema(
290
+ projectId: "${project.id}",
291
+ collections: [{
292
+ slug: "testimonials",
293
+ name: "Testimonials",
294
+ nameSingular: "Testimonial",
295
+ fields: [
296
+ { slug: "quote", name: "Quote", type: "richText" },
297
+ { slug: "company", name: "Company", type: "text" },
298
+ { slug: "photo", name: "Photo", type: "image" }
299
+ ]
300
+ }]
301
+ )
302
+ \`\`\`
303
+
304
+ ### After creating schema, optionally add sample content:
305
+ \`\`\`
306
+ generate_sample_items(projectId: "${project.id}", collectionSlugs: ["testimonials"])
307
+ \`\`\`
308
+
309
+ ---
310
+
311
+ ## ⚠️ Field Type Guidance
312
+
313
+ ### For Video Content
314
+ Use \`videoEmbed\` (NOT \`url\` or \`text\`):
315
+ \`\`\`json
316
+ { "slug": "video", "name": "Video", "type": "videoEmbed" }
317
+ \`\`\`
318
+ Supports: YouTube, Vimeo, Wistia, Loom
319
+
320
+ ### For Linked Content
321
+ Use \`relation\` (NOT \`text\`):
322
+ \`\`\`json
323
+ {
324
+ "slug": "author",
325
+ "name": "Author",
326
+ "type": "relation",
327
+ "referenceCollection": "authors"
328
+ }
329
+ \`\`\`
330
+
331
+ ---
332
+
333
+ ## Available Field Types
334
+
335
+ | Type | Description | Token Usage |
336
+ |------|-------------|-------------|
337
+ | text | Short text | \`{{field}}\` |
338
+ | richText | HTML content | \`{{{field}}}\` (triple braces!) |
339
+ | number | Numeric value | \`{{field}}\` |
340
+ | boolean | True/false | \`{{#if field}}...{{/if}}\` |
341
+ | date | Date picker | \`{{field}}\` |
342
+ | image | Image URL | \`{{field}}\` in src |
343
+ | url | Web link | \`{{field}}\` in href |
344
+ | email | Email address | \`{{field}}\` |
345
+ | videoEmbed | YouTube/Vimeo/etc | \`{{#videoEmbed field}}{{/videoEmbed}}\` |
346
+ | select | Single choice | \`{{field}}\` (requires \`options\`) |
347
+ | multiSelect | Multiple choices | \`{{#each field}}...{{/each}}\` |
348
+ | relation | Link to collection | \`{{field.name}}\`, \`{{field.url}}\` |
349
+ `;
350
+ return output;
351
+ }
352
+ /**
353
+ * Build the convert response for new websites
354
+ */
355
+ function buildConvertResponse(context) {
356
+ let output = `# Fast Mode MCP - Convert Website
357
+
358
+ ## Getting Started
359
+
360
+ `;
361
+ if (context.projects.length > 0) {
362
+ output += `### Your existing projects:
363
+ `;
364
+ for (const p of context.projects.slice(0, 5)) {
365
+ output += `- ${p.name} (\`${p.id}\`)\n`;
366
+ }
367
+ output += `
368
+ **Ask the user:** "Should I add this website to an existing project, or create a new one?"
369
+
370
+ `;
371
+ }
372
+ output += `### To create a new project:
373
+ \`\`\`
374
+ create_site(name: "New Website Name")
375
+ \`\`\`
376
+
377
+ ---
378
+
379
+ ## ⚠️ REQUIRED: Read Before Building
380
+
381
+ **DO NOT SKIP THIS STEP.** The conversion guide contains CRITICAL information that prevents common failures:
382
+
383
+ ### Step 1: Read common mistakes FIRST
384
+ \`\`\`
385
+ get_conversion_guide(section: "common_mistakes")
386
+ \`\`\`
387
+
388
+ This section covers:
389
+ - **Asset paths** - Why CSS/JS might 404 (MUST use /public/ prefix!)
390
+ - **Form handling** - Why forms might not work (MUST remove original handlers!)
391
+ - **data-edit-key** - Why text won't be editable (REQUIRED for static pages!)
392
+
393
+ ### Step 2: Read the full guide
394
+ \`\`\`
395
+ get_conversion_guide(section: "full")
396
+ \`\`\`
397
+
398
+ All sections:
399
+ - \`first_steps\` - Required initial setup
400
+ - \`structure\` - Package folder structure
401
+ - \`manifest\` - manifest.json configuration
402
+ - \`templates\` - Template creation patterns
403
+ - \`tokens\` - CMS token reference
404
+ - \`forms\` - Form submission setup
405
+ - \`common_mistakes\` - Critical errors to avoid
406
+
407
+ ### Step 2: Build and validate as you go
408
+ \`\`\`
409
+ validate_manifest(manifest: "{ ... }")
410
+ validate_template(html: "...", templateType: "custom_index", collectionSlug: "posts")
411
+ validate_package(fileList: [...], manifestContent: "...")
412
+ \`\`\`
413
+
414
+ ### Step 3: Create schema (if new collections needed)
415
+ \`\`\`
416
+ sync_schema(projectId: "PROJECT_ID", collections: [...])
417
+ \`\`\`
418
+
419
+ ### Step 4: Deploy
420
+ \`\`\`
421
+ deploy_package(packagePath: "./my-site.zip", projectId: "PROJECT_ID")
422
+ \`\`\`
423
+
424
+ ---
425
+
426
+ ## Key Resources
427
+
428
+ | Example | Description |
429
+ |---------|-------------|
430
+ | \`get_example("manifest_basic")\` | Basic manifest.json |
431
+ | \`get_example("blog_post_template")\` | Blog post detail template |
432
+ | \`get_example("blog_index_template")\` | Blog listing template |
433
+ | \`get_example("form_handling")\` | Form submission setup |
434
+ | \`get_example("common_mistakes")\` | What to avoid |
435
+ | \`get_example("relation_fields")\` | Linking collections |
436
+ `;
437
+ return output;
438
+ }
439
+ /**
440
+ * Build the deploy response
441
+ */
442
+ function buildDeployResponse(project) {
443
+ let output = `# Fast Mode MCP - Deploy Changes
444
+
445
+ ## Project: ${project.name}
446
+ **URL:** https://${project.subdomain}.fastmode.ai
447
+ **Status:** ${project.status}
448
+
449
+ ## Pre-Deploy Checklist
450
+
451
+ `;
452
+ if (project.githubConnected) {
453
+ output += `⚠️ **GitHub Connected:** Yes
454
+ Consider pushing to GitHub instead for automatic deployment.
455
+
456
+ `;
457
+ }
458
+ else {
459
+ output += `✓ **GitHub Connected:** No (manual deploy available)
460
+
461
+ `;
462
+ }
463
+ if (project.hasPendingChanges) {
464
+ output += `⚠️ **Pending Changes:** Yes
465
+ There are unsaved changes in the editor.
466
+
467
+ `;
468
+ }
469
+ else {
470
+ output += `✓ **Pending Changes:** None
471
+
472
+ `;
473
+ }
474
+ output += `---
475
+
476
+ ## Workflow: Deploy
477
+
478
+ ### Step 1: Validate your package first
479
+ \`\`\`
480
+ validate_package(
481
+ fileList: ["manifest.json", "pages/index.html", "public/css/style.css", ...],
482
+ manifestContent: "{ ... }"
483
+ )
484
+ \`\`\`
485
+
486
+ ### Step 2: If validation passes, deploy
487
+ \`\`\`
488
+ deploy_package(
489
+ packagePath: "./my-site.zip",
490
+ projectId: "${project.id}"
491
+ )
492
+ \`\`\`
493
+
494
+ ---
495
+
496
+ ## Deployment Notes
497
+
498
+ - **Pre-deploy validation:** deploy_package now validates automatically and blocks if there are errors
499
+ - **Incremental deploys:** CMS item changes trigger automatic page rebuilds
500
+ - **Full deploys:** Package uploads trigger full site rebuild
501
+ - **CDN cache:** Automatically purged after successful deploy
502
+ `;
503
+ return output;
504
+ }
505
+ /**
506
+ * Build unauthenticated response
507
+ */
508
+ function buildUnauthenticatedResponse() {
509
+ return `# Fast Mode MCP - Authentication Required
510
+
511
+ You need to authenticate before using Fast Mode tools.
512
+
513
+ ## How to Authenticate
514
+
515
+ ### Option 1: Environment Variable (Recommended for CI/CD)
516
+ Set the \`FASTMODE_AUTH_TOKEN\` environment variable with your API token.
517
+
518
+ ### Option 2: Browser Login
519
+ Run any authenticated command (like \`list_projects\`) and follow the browser-based login flow.
520
+
521
+ ## Try It Now
522
+ \`\`\`
523
+ list_projects()
524
+ \`\`\`
525
+
526
+ This will prompt you to authenticate if needed.
527
+
528
+ ## After Authentication
529
+
530
+ Call \`get_started()\` again to see your projects and available actions.
531
+ `;
532
+ }
533
+ // ============ Main Function ============
534
+ /**
535
+ * Get Started - Intelligent entry point for the MCP server
536
+ *
537
+ * @param input.intent - What the user wants to do (explore, add_content, update_schema, convert, deploy)
538
+ * @param input.projectId - Specific project to get details for
539
+ */
540
+ async function getStarted(input) {
541
+ const { intent, projectId } = input;
542
+ // Check authentication first
543
+ if (await (0, api_client_1.needsAuthentication)()) {
544
+ // Try to authenticate
545
+ const authResult = await (0, device_flow_1.ensureAuthenticated)();
546
+ if (!authResult.authenticated) {
547
+ return buildUnauthenticatedResponse();
548
+ }
549
+ }
550
+ // Fetch project context
551
+ const context = await (0, context_fetcher_1.fetchProjectContext)(projectId);
552
+ if (!context.isAuthenticated) {
553
+ return buildUnauthenticatedResponse();
554
+ }
555
+ // Route based on intent
556
+ switch (intent) {
557
+ case 'add_content':
558
+ if (!context.selectedProject) {
559
+ if (!projectId) {
560
+ return `# Project Required
561
+
562
+ To add content, specify which project:
563
+ \`\`\`
564
+ get_started(intent: "add_content", projectId: "your-project-id")
565
+ \`\`\`
566
+
567
+ ${buildExploreResponse(context)}`;
568
+ }
569
+ return `# Project Not Found
570
+
571
+ Could not find project: "${projectId}"
572
+
573
+ Use \`list_projects\` to see available projects.`;
574
+ }
575
+ return buildAddContentResponse(context.selectedProject);
576
+ case 'update_schema':
577
+ if (!context.selectedProject) {
578
+ if (!projectId) {
579
+ return `# Project Required
580
+
581
+ To update schema, specify which project:
582
+ \`\`\`
583
+ get_started(intent: "update_schema", projectId: "your-project-id")
584
+ \`\`\`
585
+
586
+ ${buildExploreResponse(context)}`;
587
+ }
588
+ return `# Project Not Found
589
+
590
+ Could not find project: "${projectId}"
591
+
592
+ Use \`list_projects\` to see available projects.`;
593
+ }
594
+ return buildUpdateSchemaResponse(context.selectedProject);
595
+ case 'convert':
596
+ return buildConvertResponse(context);
597
+ case 'deploy':
598
+ if (!context.selectedProject) {
599
+ if (!projectId) {
600
+ return `# Project Required
601
+
602
+ To deploy, specify which project:
603
+ \`\`\`
604
+ get_started(intent: "deploy", projectId: "your-project-id")
605
+ \`\`\`
606
+
607
+ ${buildExploreResponse(context)}`;
608
+ }
609
+ return `# Project Not Found
610
+
611
+ Could not find project: "${projectId}"
612
+
613
+ Use \`list_projects\` to see available projects.`;
614
+ }
615
+ return buildDeployResponse(context.selectedProject);
616
+ case 'explore':
617
+ default:
618
+ // If projectId provided, show detailed project info
619
+ if (context.selectedProject) {
620
+ return buildAddContentResponse(context.selectedProject);
621
+ }
622
+ return buildExploreResponse(context);
623
+ }
624
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Fetches the complete schema for a specific project including:
3
+ * - All custom collections with their fields
4
+ * - Field tokens, types, and descriptions for AI context
5
+ * - Template patterns and example usage
6
+ *
7
+ * Each field includes:
8
+ * - Field Name (display name)
9
+ * - Token (the exact syntax to use in templates)
10
+ * - Type (text, richText, image, etc.)
11
+ * - Description (help text for context)
12
+ *
13
+ * Uses stored credentials or triggers device flow for authentication.
14
+ *
15
+ * @param projectId - Project ID (UUID) or project name
16
+ */
17
+ export declare function getTenantSchema(projectId: string): Promise<string>;
18
+ //# sourceMappingURL=get-tenant-schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-tenant-schema.d.ts","sourceRoot":"","sources":["../../src/tools/get-tenant-schema.ts"],"names":[],"mappings":"AA2EA;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAmFxE"}