flutterflow-mcp 0.2.3 → 0.3.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 (48) hide show
  1. package/build/index.js +24 -0
  2. package/build/prompts/generate-page.js +6 -5
  3. package/build/prompts/modify-component.js +6 -5
  4. package/build/tools/find-component-usages.js +1 -10
  5. package/build/tools/find-page-navigations.js +1 -9
  6. package/build/tools/get-api-endpoints.d.ts +2 -0
  7. package/build/tools/get-api-endpoints.js +126 -0
  8. package/build/tools/get-app-settings.d.ts +2 -0
  9. package/build/tools/get-app-settings.js +169 -0
  10. package/build/tools/get-app-state.d.ts +2 -0
  11. package/build/tools/get-app-state.js +96 -0
  12. package/build/tools/get-custom-code.d.ts +2 -0
  13. package/build/tools/get-custom-code.js +380 -0
  14. package/build/tools/get-data-models.d.ts +2 -0
  15. package/build/tools/get-data-models.js +266 -0
  16. package/build/tools/get-editing-guide.d.ts +7 -0
  17. package/build/tools/get-editing-guide.js +185 -0
  18. package/build/tools/get-general-settings.d.ts +2 -0
  19. package/build/tools/get-general-settings.js +116 -0
  20. package/build/tools/get-in-app-purchases.d.ts +2 -0
  21. package/build/tools/get-in-app-purchases.js +51 -0
  22. package/build/tools/get-integrations.d.ts +2 -0
  23. package/build/tools/get-integrations.js +137 -0
  24. package/build/tools/get-page-summary.js +1 -18
  25. package/build/tools/get-project-setup.d.ts +2 -0
  26. package/build/tools/get-project-setup.js +212 -0
  27. package/build/tools/get-theme.d.ts +2 -0
  28. package/build/tools/get-theme.js +199 -0
  29. package/build/tools/get-yaml-docs.js +1 -111
  30. package/build/tools/list-files.js +22 -3
  31. package/build/tools/search-project-files.d.ts +2 -0
  32. package/build/tools/search-project-files.js +69 -0
  33. package/build/tools/sync-project.js +4 -1
  34. package/build/tools/update-yaml.js +1 -1
  35. package/build/tools/validate-yaml.js +19 -2
  36. package/build/utils/batch-process.d.ts +2 -0
  37. package/build/utils/batch-process.js +10 -0
  38. package/build/utils/cache.d.ts +5 -0
  39. package/build/utils/cache.js +16 -1
  40. package/build/utils/resolve-data-type.d.ts +2 -0
  41. package/build/utils/resolve-data-type.js +18 -0
  42. package/build/utils/topic-map.d.ts +7 -0
  43. package/build/utils/topic-map.js +115 -0
  44. package/docs/ff-yaml/00-overview.md +30 -1
  45. package/docs/ff-yaml/01-project-files.md +1380 -4
  46. package/docs/ff-yaml/08-custom-code.md +77 -1
  47. package/docs/ff-yaml/09-theming.md +46 -0
  48. package/package.json +1 -1
@@ -1,6 +1,11 @@
1
1
  import { z } from "zod";
2
+ /** Extract widget type from a node-level fileKey, e.g. "Button" from "node/id-Button_xyz" */
3
+ function extractWidgetTypeFromFileKey(fileKey) {
4
+ const match = fileKey.match(/node\/id-([A-Z][a-zA-Z]+)_/);
5
+ return match ? match[1] : null;
6
+ }
2
7
  export function registerValidateYamlTool(server, client) {
3
- server.tool("validate_yaml", "Validate YAML content before pushing changes to a FlutterFlow project. Always call this before update_project_yaml.", {
8
+ server.tool("validate_yaml", "Validate YAML content before pushing changes to a FlutterFlow project. Always call this before update_project_yaml. Tip: Call get_editing_guide or get_yaml_docs BEFORE writing YAML to understand the correct schema and field names. Validation catches syntax errors but not semantic mistakes.", {
4
9
  projectId: z.string().describe("The FlutterFlow project ID"),
5
10
  fileKey: z
6
11
  .string()
@@ -10,11 +15,23 @@ export function registerValidateYamlTool(server, client) {
10
15
  .describe("Pass YAML content as a normal multi-line string."),
11
16
  }, async ({ projectId, fileKey, fileContent }) => {
12
17
  const result = await client.validateProjectYaml(projectId, fileKey, fileContent);
18
+ let text = JSON.stringify(result, null, 2);
19
+ // Add doc hint on validation failure
20
+ const isFailure = result && typeof result === "object" && result.valid === false;
21
+ if (isFailure) {
22
+ const widgetType = extractWidgetTypeFromFileKey(fileKey);
23
+ if (widgetType) {
24
+ text += `\n\nHint: Use get_yaml_docs(topic: "${widgetType}") to look up the correct field schema for ${widgetType} widgets.`;
25
+ }
26
+ else {
27
+ text += `\n\nHint: Use get_yaml_docs to look up the correct YAML schema for the file you're editing.`;
28
+ }
29
+ }
13
30
  return {
14
31
  content: [
15
32
  {
16
33
  type: "text",
17
- text: JSON.stringify(result, null, 2),
34
+ text,
18
35
  },
19
36
  ],
20
37
  };
@@ -0,0 +1,2 @@
1
+ /** Batch-process items in groups to avoid overwhelming the file system. */
2
+ export declare function batchProcess<T, R>(items: T[], batchSize: number, fn: (item: T) => Promise<R>): Promise<R[]>;
@@ -0,0 +1,10 @@
1
+ /** Batch-process items in groups to avoid overwhelming the file system. */
2
+ export async function batchProcess(items, batchSize, fn) {
3
+ const results = [];
4
+ for (let i = 0; i < items.length; i += batchSize) {
5
+ const batch = items.slice(i, i + batchSize);
6
+ const batchResults = await Promise.all(batch.map(fn));
7
+ results.push(...batchResults);
8
+ }
9
+ return results;
10
+ }
@@ -24,6 +24,11 @@ export declare function cacheWrite(projectId: string, fileKey: string, content:
24
24
  * Delete a single cached file. No-op if the file does not exist.
25
25
  */
26
26
  export declare function cacheInvalidate(projectId: string, fileKey: string): Promise<void>;
27
+ /**
28
+ * Delete the entire cache directory for a project, removing all cached files
29
+ * and metadata. No-op if the directory does not exist.
30
+ */
31
+ export declare function cacheClear(projectId: string): Promise<void>;
27
32
  /**
28
33
  * Write multiple YAML entries to the cache in one call.
29
34
  * Returns the number of entries written.
@@ -1,4 +1,4 @@
1
- import { mkdir, readFile, writeFile, unlink, readdir } from "node:fs/promises";
1
+ import { mkdir, readFile, writeFile, unlink, readdir, rm } from "node:fs/promises";
2
2
  import { join, dirname, resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  // ---------------------------------------------------------------------------
@@ -73,6 +73,21 @@ export async function cacheInvalidate(projectId, fileKey) {
73
73
  throw err;
74
74
  }
75
75
  }
76
+ /**
77
+ * Delete the entire cache directory for a project, removing all cached files
78
+ * and metadata. No-op if the directory does not exist.
79
+ */
80
+ export async function cacheClear(projectId) {
81
+ try {
82
+ await rm(cacheDir(projectId), { recursive: true, force: true });
83
+ }
84
+ catch (err) {
85
+ if (isNodeError(err) && err.code === "ENOENT") {
86
+ return; // already gone — no-op
87
+ }
88
+ throw err;
89
+ }
90
+ }
76
91
  /**
77
92
  * Write multiple YAML entries to the cache in one call.
78
93
  * Returns the number of entries written.
@@ -0,0 +1,2 @@
1
+ /** Resolve a scalar/list data type to a readable string. */
2
+ export declare function resolveDataType(dt: Record<string, unknown>): string;
@@ -0,0 +1,18 @@
1
+ /** Resolve a scalar/list data type to a readable string. */
2
+ export function resolveDataType(dt) {
3
+ if (dt.listType) {
4
+ const inner = dt.listType;
5
+ return `List<${inner.scalarType || "unknown"}>`;
6
+ }
7
+ if (dt.scalarType === "DataStruct") {
8
+ const sub = dt.subType;
9
+ const dsi = sub?.dataStructIdentifier;
10
+ return dsi?.name ? `DataStruct:${dsi.name}` : "DataStruct";
11
+ }
12
+ if (dt.enumType) {
13
+ const en = dt.enumType;
14
+ const eid = en.enumIdentifier;
15
+ return eid?.name ? `Enum:${eid.name}` : "Enum";
16
+ }
17
+ return dt.scalarType || "unknown";
18
+ }
@@ -0,0 +1,7 @@
1
+ export declare const DOCS_DIR: string;
2
+ /** Topic-to-file mapping for fuzzy search. */
3
+ export declare const TOPIC_MAP: Record<string, string>;
4
+ /** List all doc files recursively. */
5
+ export declare function listDocFiles(dir: string, prefix?: string): string[];
6
+ /** Read a doc file. Returns null if not found. */
7
+ export declare function readDoc(relPath: string): string | null;
@@ -0,0 +1,115 @@
1
+ /**
2
+ * Shared TOPIC_MAP, DOCS_DIR, and doc-reading helpers.
3
+ * Used by get_yaml_docs and get_editing_guide tools.
4
+ */
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import { fileURLToPath } from "url";
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const __dirname = path.dirname(__filename);
10
+ export const DOCS_DIR = path.resolve(__dirname, "../../docs/ff-yaml");
11
+ /** Topic-to-file mapping for fuzzy search. */
12
+ export const TOPIC_MAP = {
13
+ // Widgets
14
+ button: "04-widgets/button.md",
15
+ iconbutton: "04-widgets/button.md",
16
+ text: "04-widgets/text.md",
17
+ richtext: "04-widgets/text.md",
18
+ richtextspan: "04-widgets/text.md",
19
+ textfield: "04-widgets/text-field.md",
20
+ "text-field": "04-widgets/text-field.md",
21
+ input: "04-widgets/text-field.md",
22
+ container: "04-widgets/container.md",
23
+ boxdecoration: "04-widgets/container.md",
24
+ column: "04-widgets/layout.md",
25
+ row: "04-widgets/layout.md",
26
+ stack: "04-widgets/layout.md",
27
+ wrap: "04-widgets/layout.md",
28
+ layout: "04-widgets/layout.md",
29
+ image: "04-widgets/image.md",
30
+ form: "04-widgets/form.md",
31
+ validation: "04-widgets/form.md",
32
+ dropdown: "04-widgets/dropdown.md",
33
+ choicechips: "04-widgets/dropdown.md",
34
+ icon: "04-widgets/misc.md",
35
+ progressbar: "04-widgets/misc.md",
36
+ appbar: "04-widgets/misc.md",
37
+ conditionalbuilder: "04-widgets/misc.md",
38
+ widget: "04-widgets/README.md",
39
+ widgets: "04-widgets/README.md",
40
+ // Non-widget topics
41
+ actions: "05-actions.md",
42
+ action: "05-actions.md",
43
+ trigger: "05-actions.md",
44
+ navigate: "05-actions.md",
45
+ navigation: "05-actions.md",
46
+ ontap: "05-actions.md",
47
+ variables: "06-variables.md",
48
+ variable: "06-variables.md",
49
+ binding: "06-variables.md",
50
+ "data-binding": "06-variables.md",
51
+ data: "07-data.md",
52
+ collections: "07-data.md",
53
+ firestore: "07-data.md",
54
+ api: "07-data.md",
55
+ custom: "08-custom-code.md",
56
+ dart: "08-custom-code.md",
57
+ "custom-code": "08-custom-code.md",
58
+ theme: "09-theming.md",
59
+ theming: "09-theming.md",
60
+ color: "09-theming.md",
61
+ colors: "09-theming.md",
62
+ font: "09-theming.md",
63
+ typography: "09-theming.md",
64
+ editing: "10-editing-guide.md",
65
+ workflow: "10-editing-guide.md",
66
+ "editing-guide": "10-editing-guide.md",
67
+ push: "10-editing-guide.md",
68
+ overview: "00-overview.md",
69
+ structure: "00-overview.md",
70
+ "project-files": "01-project-files.md",
71
+ config: "01-project-files.md",
72
+ settings: "01-project-files.md",
73
+ pages: "02-pages.md",
74
+ page: "02-pages.md",
75
+ scaffold: "02-pages.md",
76
+ components: "03-components.md",
77
+ component: "03-components.md",
78
+ createcomponent: "03-components.md",
79
+ refactor: "03-components.md",
80
+ refactoring: "03-components.md",
81
+ isdummyroot: "03-components.md",
82
+ dummyroot: "03-components.md",
83
+ componentclasskeyref: "03-components.md",
84
+ parametervalues: "03-components.md",
85
+ callback: "03-components.md",
86
+ executecallbackaction: "03-components.md",
87
+ // Universal patterns
88
+ inputvalue: "README.md",
89
+ mostrecentinputvalue: "README.md",
90
+ padding: "README.md",
91
+ "border-radius": "README.md",
92
+ };
93
+ /** List all doc files recursively. */
94
+ export function listDocFiles(dir, prefix = "") {
95
+ const results = [];
96
+ if (!fs.existsSync(dir))
97
+ return results;
98
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
99
+ const relPath = prefix ? `${prefix}/${entry.name}` : entry.name;
100
+ if (entry.isDirectory()) {
101
+ results.push(...listDocFiles(path.join(dir, entry.name), relPath));
102
+ }
103
+ else if (entry.name.endsWith(".md")) {
104
+ results.push(relPath);
105
+ }
106
+ }
107
+ return results;
108
+ }
109
+ /** Read a doc file. Returns null if not found. */
110
+ export function readDoc(relPath) {
111
+ const filePath = path.join(DOCS_DIR, relPath);
112
+ if (!fs.existsSync(filePath))
113
+ return null;
114
+ return fs.readFileSync(filePath, "utf-8");
115
+ }
@@ -11,13 +11,14 @@ Every FlutterFlow project is a collection of YAML files accessed via file keys.
11
11
  | `app-details` | App metadata: name, routing config, initial page, auth pages, theme mode, platform settings |
12
12
  | `authentication` | Firebase/Supabase auth configuration, providers, login/signup page refs |
13
13
  | `theme` | Typography definitions, color palette, breakpoints, widget defaults |
14
+ | `theme/color-scheme` | Full color palette: core, background, text, accent, semantic colors with dark mode variants |
14
15
  | `folders` | Page and component folder organization (scaffold-to-folder mapping) |
15
16
  | `app-state` | App-wide persisted state variables (shared across all pages) |
16
17
  | `app-constants` | Read-only constants available app-wide |
17
18
  | `app-assets` | Uploaded asset references (images, fonts, files) |
18
19
  | `nav-bar` | Bottom navigation bar configuration (pages, icons, labels) |
19
20
  | `app-bar` | App bar configuration |
20
- | `permissions` | Permission definitions and role-based access rules |
21
+ | `permissions` | Platform permission declarations (CAMERA, LOCATION, etc.) — abstraction layer that FF maps to AndroidManifest.xml and Info.plist at build time |
21
22
  | `revenue-cat` | RevenueCat paywall and entitlement configuration |
22
23
  | `languages` | Internationalization strings and locale mappings |
23
24
  | `page/id-Scaffold_XXX` | Page metadata: name, params, classModel (state fields), route config |
@@ -35,6 +36,34 @@ Every FlutterFlow project is a collection of YAML files accessed via file keys.
35
36
  | `enums/id-XXX` | Enum definition with named values |
36
37
  | `collections/id-XXX` | Firestore collection schema: fields, types, subcollections |
37
38
  | `agent/id-XXX` | AI agent configuration |
39
+ | `custom-file/id-<TYPE>` | Custom file configs for native platform files. Known types: `MAIN` (main.dart startup actions), `ANDROID_MANIFEST` (XML injection hooks for AndroidManifest.xml), `PROGUARD` (ProGuard rule injection for proguard-rules.pro), `BUILD_GRADLE` (Gradle plugin/dependency/repository injection for build.gradle). Only appear after enabled in FF editor. Sub-file `custom-file/id-MAIN/custom-file-code.dart` contains generated Dart source. |
40
+ | `environment-settings` | Per-environment configuration values (API URLs, keys) |
41
+ | `dependencies` | FlutterFlow library package dependencies |
42
+ | `custom-code-dependencies` | Dart/Flutter pub dependencies for custom code |
43
+ | `supabase` | Supabase connection config and database schema |
44
+ | `firebase-analytics` | Firebase Analytics settings |
45
+ | `firebase-crashlytics` | Firebase Crashlytics settings |
46
+ | `firebase-performance-monitoring` | Firebase Performance Monitoring settings |
47
+ | `firebase-app-check` | Firebase App Check configuration and debug token |
48
+ | `firebase-remote-config` | Firebase Remote Config — field definitions with default values |
49
+ | `firestore-settings` | Firestore security rules (per-collection CRUD permissions), storage rules, validation hashes |
50
+ | `push-notifications` | Push notification configuration |
51
+ | `google-maps` | Google Maps API keys per platform |
52
+ | `ad-mob` | AdMob advertising configuration |
53
+ | `algolia` | Algolia search integration — app ID, API key, indexed collections |
54
+ | `app-assets` | App icon, splash screen, error image settings |
55
+ | `platforms` | Platform enablement flags (web, etc.) |
56
+ | `mobile-deployment` | Codemagic CI/CD settings — App Store Connect credentials, build version/number, Play Store track, signing config |
57
+ | `web-publishing` | Web platform settings — SEO description, page title, status bar color, orientation |
58
+ | `library-values` | Values passed to FlutterFlow library dependencies |
59
+ | `library-configurations/id-<projectId>` | Route overrides for library pages |
60
+ | `download-code-settings` | Code download/GitHub push settings |
61
+ | `tests` | FlutterFlow test runner configuration |
62
+ | `app-query-cache` | Named database request cache managers |
63
+ | `date-picker` | Date picker style toggle (legacy vs modern Material date picker) |
64
+ | `material-theme` | Material Design version toggle (Material 2 vs Material 3) |
65
+ | `storyboard` | Editor-only page positions on the FF storyboard canvas (no functional impact) |
66
+ | `miscellaneous` | Misc app-level settings and feature flags |
38
67
 
39
68
  ---
40
69