@framingui/mcp-server 0.6.26 → 0.6.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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -2
  3. package/dist/__tests__/react-native-contract.test.d.ts +2 -0
  4. package/dist/__tests__/react-native-contract.test.d.ts.map +1 -0
  5. package/dist/__tests__/react-native-contract.test.js +50 -0
  6. package/dist/__tests__/react-native-contract.test.js.map +1 -0
  7. package/dist/auth/state.d.ts +5 -0
  8. package/dist/auth/state.d.ts.map +1 -1
  9. package/dist/auth/state.js +33 -0
  10. package/dist/auth/state.js.map +1 -1
  11. package/dist/cli/agent-md-templates.d.ts.map +1 -1
  12. package/dist/cli/agent-md-templates.js +54 -36
  13. package/dist/cli/agent-md-templates.js.map +1 -1
  14. package/dist/cli/guide-template.d.ts.map +1 -1
  15. package/dist/cli/guide-template.js +17 -35
  16. package/dist/cli/guide-template.js.map +1 -1
  17. package/dist/cli/init.d.ts +2 -3
  18. package/dist/cli/init.d.ts.map +1 -1
  19. package/dist/cli/init.js +33 -48
  20. package/dist/cli/init.js.map +1 -1
  21. package/dist/data/component-fallback-catalog.d.ts +26 -0
  22. package/dist/data/component-fallback-catalog.d.ts.map +1 -0
  23. package/dist/data/component-fallback-catalog.js +149 -0
  24. package/dist/data/component-fallback-catalog.js.map +1 -0
  25. package/dist/data/react-native-runtime-catalog.d.ts +24 -0
  26. package/dist/data/react-native-runtime-catalog.d.ts.map +1 -0
  27. package/dist/data/react-native-runtime-catalog.js +265 -0
  28. package/dist/data/react-native-runtime-catalog.js.map +1 -0
  29. package/dist/index.js +114 -47
  30. package/dist/index.js.map +1 -1
  31. package/dist/platform-support.d.ts +22 -0
  32. package/dist/platform-support.d.ts.map +1 -0
  33. package/dist/platform-support.js +148 -0
  34. package/dist/platform-support.js.map +1 -0
  35. package/dist/project-context-resolution.d.ts +7 -0
  36. package/dist/project-context-resolution.d.ts.map +1 -0
  37. package/dist/project-context-resolution.js +21 -0
  38. package/dist/project-context-resolution.js.map +1 -0
  39. package/dist/project-context-state.d.ts +12 -0
  40. package/dist/project-context-state.d.ts.map +1 -0
  41. package/dist/project-context-state.js +14 -0
  42. package/dist/project-context-state.js.map +1 -0
  43. package/dist/project-context.d.ts +15 -0
  44. package/dist/project-context.d.ts.map +1 -0
  45. package/dist/project-context.js +78 -0
  46. package/dist/project-context.js.map +1 -0
  47. package/dist/prompts/getting-started.d.ts.map +1 -1
  48. package/dist/prompts/getting-started.js +27 -7
  49. package/dist/prompts/getting-started.js.map +1 -1
  50. package/dist/prompts/screen-workflow.d.ts.map +1 -1
  51. package/dist/prompts/screen-workflow.js +53 -2
  52. package/dist/prompts/screen-workflow.js.map +1 -1
  53. package/dist/schemas/mcp-schemas.d.ts +1058 -528
  54. package/dist/schemas/mcp-schemas.d.ts.map +1 -1
  55. package/dist/schemas/mcp-schemas.js +98 -0
  56. package/dist/schemas/mcp-schemas.js.map +1 -1
  57. package/dist/tools/detect-project-context.d.ts +3 -0
  58. package/dist/tools/detect-project-context.d.ts.map +1 -0
  59. package/dist/tools/detect-project-context.js +36 -0
  60. package/dist/tools/detect-project-context.js.map +1 -0
  61. package/dist/tools/get-screen-generation-context.d.ts.map +1 -1
  62. package/dist/tools/get-screen-generation-context.js +118 -18
  63. package/dist/tools/get-screen-generation-context.js.map +1 -1
  64. package/dist/tools/list-components.d.ts.map +1 -1
  65. package/dist/tools/list-components.js +42 -3
  66. package/dist/tools/list-components.js.map +1 -1
  67. package/dist/tools/preview-component.d.ts.map +1 -1
  68. package/dist/tools/preview-component.js +57 -7
  69. package/dist/tools/preview-component.js.map +1 -1
  70. package/dist/tools/preview-theme.d.ts.map +1 -1
  71. package/dist/tools/preview-theme.js +20 -2
  72. package/dist/tools/preview-theme.js.map +1 -1
  73. package/dist/tools/theme-authority.js +1 -1
  74. package/dist/tools/theme-authority.js.map +1 -1
  75. package/dist/tools/validate-environment.d.ts.map +1 -1
  76. package/dist/tools/validate-environment.js +102 -9
  77. package/dist/tools/validate-environment.js.map +1 -1
  78. package/dist/tools/validate-screen-definition.d.ts.map +1 -1
  79. package/dist/tools/validate-screen-definition.js +41 -7
  80. package/dist/tools/validate-screen-definition.js.map +1 -1
  81. package/package.json +16 -17
@@ -0,0 +1,22 @@
1
+ export declare const PLATFORM_TARGETS: readonly ["web", "react-native"];
2
+ export type PlatformTarget = (typeof PLATFORM_TARGETS)[number];
3
+ export interface DirectWriteAuditRule {
4
+ id: string;
5
+ severity: 'warning' | 'error';
6
+ description: string;
7
+ pattern: RegExp;
8
+ guidance: string;
9
+ }
10
+ export interface PlatformSupportInfo {
11
+ supported: boolean;
12
+ recommended: boolean;
13
+ status: 'full' | 'partial' | 'avoid';
14
+ notes: string[];
15
+ recommendedImports: string[];
16
+ recommendedPackages: string[];
17
+ }
18
+ export declare function getSupportedPlatforms(): PlatformTarget[];
19
+ export declare function getPlatformSupportInfo(componentName: string, platform?: PlatformTarget): PlatformSupportInfo;
20
+ export declare function getReactNativeAuditRules(): DirectWriteAuditRule[];
21
+ export declare function getImportStatementForPlatform(componentName: string, platform?: PlatformTarget): string;
22
+ //# sourceMappingURL=platform-support.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-support.d.ts","sourceRoot":"","sources":["../src/platform-support.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB,kCAAmC,CAAC;AAEjE,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE/D,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,SAAS,GAAG,OAAO,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;IACrC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AA2ED,wBAAgB,qBAAqB,IAAI,cAAc,EAAE,CAExD;AAED,wBAAgB,sBAAsB,CACpC,aAAa,EAAE,MAAM,EACrB,QAAQ,GAAE,cAAsB,GAC/B,mBAAmB,CAqErB;AAED,wBAAgB,wBAAwB,IAAI,oBAAoB,EAAE,CAEjE;AAED,wBAAgB,6BAA6B,CAC3C,aAAa,EAAE,MAAM,EACrB,QAAQ,GAAE,cAAsB,GAC/B,MAAM,CAWR"}
@@ -0,0 +1,148 @@
1
+ export const PLATFORM_TARGETS = ['web', 'react-native'];
2
+ const REACT_NATIVE_SUPPORTED_COMPONENTS = new Set([
3
+ 'Button',
4
+ 'Input',
5
+ 'Text',
6
+ 'Heading',
7
+ 'Checkbox',
8
+ 'Radio',
9
+ 'Switch',
10
+ 'Slider',
11
+ 'Badge',
12
+ 'Avatar',
13
+ 'Card',
14
+ 'List',
15
+ 'Image',
16
+ 'Progress',
17
+ ]);
18
+ const REACT_NATIVE_PARTIAL_COMPONENTS = new Set(['Form', 'Link']);
19
+ const REACT_NATIVE_AVOID_COMPONENTS = new Set(['Modal', 'Tabs', 'Table', 'Dropdown']);
20
+ const REACT_NATIVE_RECOMMENDED_PACKAGES = ['react-native', 'react-native-safe-area-context'];
21
+ const REACT_NATIVE_RUNTIME_IMPORT_STATEMENTS = {
22
+ Button: "import { Button } from '@framingui/react-native';",
23
+ Input: "import { TextField } from '@framingui/react-native';",
24
+ };
25
+ const REACT_NATIVE_IMPORT_STATEMENTS = {
26
+ Avatar: "import { Image, View } from 'react-native';",
27
+ Badge: "import { Text, View } from 'react-native';",
28
+ Button: "import { Pressable, Text } from 'react-native';",
29
+ Card: "import { View } from 'react-native';",
30
+ Checkbox: "import { Pressable, View } from 'react-native';",
31
+ Form: "import { View } from 'react-native';",
32
+ Heading: "import { Text } from 'react-native';",
33
+ Image: "import { Image } from 'react-native';",
34
+ Input: "import { TextInput } from 'react-native';",
35
+ Link: "import { Pressable, Text } from 'react-native';",
36
+ List: "import { FlatList, View } from 'react-native';",
37
+ Progress: "import { View } from 'react-native';",
38
+ Radio: "import { Pressable, View } from 'react-native';",
39
+ Slider: "import { View } from 'react-native';",
40
+ Switch: "import { Switch } from 'react-native';",
41
+ Text: "import { Text } from 'react-native';",
42
+ };
43
+ const REACT_NATIVE_AUDIT_RULES = [
44
+ {
45
+ id: 'rn-hardcoded-color',
46
+ severity: 'warning',
47
+ description: 'Hardcoded color literal found in a React Native style object',
48
+ pattern: /#[0-9a-fA-F]{3,8}\b|rgba?\(/,
49
+ guidance: 'Replace raw colors with theme or token-backed helpers before handoff.',
50
+ },
51
+ {
52
+ id: 'rn-hardcoded-spacing',
53
+ severity: 'warning',
54
+ description: 'Hardcoded spacing or radius value found in a style declaration',
55
+ pattern: /\b(?:margin|padding|gap|top|right|bottom|left|width|height|minWidth|minHeight|maxWidth|maxHeight|borderRadius)\s*:\s*(?:[1-9]\d?|\d{3,})\b/,
56
+ guidance: 'Replace raw spacing and radius values with token-backed spacing helpers.',
57
+ },
58
+ {
59
+ id: 'rn-web-classname',
60
+ severity: 'error',
61
+ description: 'Web-only className usage found in a React Native target file',
62
+ pattern: /\bclassName\s*=/,
63
+ guidance: 'Use style/style arrays or host app abstractions instead of className in React Native.',
64
+ },
65
+ ];
66
+ export function getSupportedPlatforms() {
67
+ return [...PLATFORM_TARGETS];
68
+ }
69
+ export function getPlatformSupportInfo(componentName, platform = 'web') {
70
+ if (platform === 'web') {
71
+ return {
72
+ supported: true,
73
+ recommended: true,
74
+ status: 'full',
75
+ notes: ['Use the published FramingUI React components and detected style contract.'],
76
+ recommendedImports: ['@framingui/ui'],
77
+ recommendedPackages: ['@framingui/ui'],
78
+ };
79
+ }
80
+ if (REACT_NATIVE_SUPPORTED_COMPONENTS.has(componentName)) {
81
+ const hasRuntimeExport = componentName in REACT_NATIVE_RUNTIME_IMPORT_STATEMENTS;
82
+ return {
83
+ supported: true,
84
+ recommended: true,
85
+ status: 'full',
86
+ notes: [
87
+ hasRuntimeExport
88
+ ? 'Prefer the matching export from @framingui/react-native, then compose with host primitives as needed.'
89
+ : 'Write this component directly using React Native primitives or existing app abstractions.',
90
+ 'Keep FramingUI as the contract and validation layer for native direct-write.',
91
+ ],
92
+ recommendedImports: hasRuntimeExport
93
+ ? ['@framingui/react-native', 'react-native']
94
+ : ['react-native'],
95
+ recommendedPackages: hasRuntimeExport
96
+ ? ['@framingui/react-native', ...REACT_NATIVE_RECOMMENDED_PACKAGES]
97
+ : REACT_NATIVE_RECOMMENDED_PACKAGES,
98
+ };
99
+ }
100
+ if (REACT_NATIVE_PARTIAL_COMPONENTS.has(componentName)) {
101
+ return {
102
+ supported: true,
103
+ recommended: false,
104
+ status: 'partial',
105
+ notes: [
106
+ 'This component needs app-specific composition in React Native.',
107
+ 'Prefer composing from primitive building blocks instead of assuming web parity.',
108
+ ],
109
+ recommendedImports: ['react-native'],
110
+ recommendedPackages: REACT_NATIVE_RECOMMENDED_PACKAGES,
111
+ };
112
+ }
113
+ if (REACT_NATIVE_AVOID_COMPONENTS.has(componentName)) {
114
+ return {
115
+ supported: false,
116
+ recommended: false,
117
+ status: 'avoid',
118
+ notes: [
119
+ 'This component depends on web-only interaction or layout assumptions in the current FramingUI catalog.',
120
+ 'Model the UX using native navigation, bottom sheets, or app-specific abstractions instead.',
121
+ ],
122
+ recommendedImports: ['react-native'],
123
+ recommendedPackages: REACT_NATIVE_RECOMMENDED_PACKAGES,
124
+ };
125
+ }
126
+ return {
127
+ supported: false,
128
+ recommended: false,
129
+ status: 'avoid',
130
+ notes: ['No React Native contract is defined yet for this component.'],
131
+ recommendedImports: ['react-native'],
132
+ recommendedPackages: REACT_NATIVE_RECOMMENDED_PACKAGES,
133
+ };
134
+ }
135
+ export function getReactNativeAuditRules() {
136
+ return [...REACT_NATIVE_AUDIT_RULES];
137
+ }
138
+ export function getImportStatementForPlatform(componentName, platform = 'web') {
139
+ if (platform === 'web') {
140
+ return `import { ${componentName} } from '@framingui/ui';`;
141
+ }
142
+ const runtimeImport = REACT_NATIVE_RUNTIME_IMPORT_STATEMENTS[componentName];
143
+ if (runtimeImport) {
144
+ return runtimeImport;
145
+ }
146
+ return REACT_NATIVE_IMPORT_STATEMENTS[componentName] || "import { View } from 'react-native';";
147
+ }
148
+ //# sourceMappingURL=platform-support.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"platform-support.js","sourceRoot":"","sources":["../src/platform-support.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { PlatformTarget } from './schemas/mcp-schemas.js';
2
+ export interface ResolvedPlatformTarget {
3
+ platform: PlatformTarget;
4
+ source: 'explicit' | 'session-default' | 'legacy-fallback';
5
+ }
6
+ export declare function resolvePlatformTarget(explicitPlatform?: PlatformTarget): ResolvedPlatformTarget;
7
+ //# sourceMappingURL=project-context-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context-resolution.d.ts","sourceRoot":"","sources":["../src/project-context-resolution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAG/D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,cAAc,CAAC;IACzB,MAAM,EAAE,UAAU,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;CAC5D;AAED,wBAAgB,qBAAqB,CAAC,gBAAgB,CAAC,EAAE,cAAc,GAAG,sBAAsB,CAoB/F"}
@@ -0,0 +1,21 @@
1
+ import { getActiveProjectContext } from './project-context-state.js';
2
+ export function resolvePlatformTarget(explicitPlatform) {
3
+ if (explicitPlatform) {
4
+ return {
5
+ platform: explicitPlatform,
6
+ source: 'explicit',
7
+ };
8
+ }
9
+ const activeProjectContext = getActiveProjectContext();
10
+ if (activeProjectContext) {
11
+ return {
12
+ platform: activeProjectContext.platform,
13
+ source: 'session-default',
14
+ };
15
+ }
16
+ return {
17
+ platform: 'web',
18
+ source: 'legacy-fallback',
19
+ };
20
+ }
21
+ //# sourceMappingURL=project-context-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context-resolution.js","sourceRoot":"","sources":["../src/project-context-resolution.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAOrE,MAAM,UAAU,qBAAqB,CAAC,gBAAiC;IACrE,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO;YACL,QAAQ,EAAE,gBAAgB;YAC1B,MAAM,EAAE,UAAU;SACnB,CAAC;IACJ,CAAC;IAED,MAAM,oBAAoB,GAAG,uBAAuB,EAAE,CAAC;IACvD,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO;YACL,QAAQ,EAAE,oBAAoB,CAAC,QAAQ;YACvC,MAAM,EAAE,iBAAiB;SAC1B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,iBAAiB;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { PlatformTarget, ProjectEnvironment } from './schemas/mcp-schemas.js';
2
+ export interface ActiveProjectContext {
3
+ projectPath: string;
4
+ packageJsonPath: string;
5
+ platform: PlatformTarget;
6
+ environment: ProjectEnvironment;
7
+ detectedAt: string;
8
+ }
9
+ export declare function setActiveProjectContext(context: Omit<ActiveProjectContext, 'detectedAt'>): void;
10
+ export declare function getActiveProjectContext(): ActiveProjectContext | null;
11
+ export declare function clearActiveProjectContext(): void;
12
+ //# sourceMappingURL=project-context-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context-state.d.ts","sourceRoot":"","sources":["../src/project-context-state.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnF,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,kBAAkB,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC,GAAG,IAAI,CAK/F;AAED,wBAAgB,uBAAuB,IAAI,oBAAoB,GAAG,IAAI,CAErE;AAED,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
@@ -0,0 +1,14 @@
1
+ let activeProjectContext = null;
2
+ export function setActiveProjectContext(context) {
3
+ activeProjectContext = {
4
+ ...context,
5
+ detectedAt: new Date().toISOString(),
6
+ };
7
+ }
8
+ export function getActiveProjectContext() {
9
+ return activeProjectContext;
10
+ }
11
+ export function clearActiveProjectContext() {
12
+ activeProjectContext = null;
13
+ }
14
+ //# sourceMappingURL=project-context-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context-state.js","sourceRoot":"","sources":["../src/project-context-state.ts"],"names":[],"mappings":"AAUA,IAAI,oBAAoB,GAAgC,IAAI,CAAC;AAE7D,MAAM,UAAU,uBAAuB,CAAC,OAAiD;IACvF,oBAAoB,GAAG;QACrB,GAAG,OAAO;QACV,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,OAAO,oBAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,oBAAoB,GAAG,IAAI,CAAC;AAC9B,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { PackageManager, PlatformTarget, ProjectEnvironment } from './schemas/mcp-schemas.js';
2
+ export interface DetectedProjectContext {
3
+ projectPath: string;
4
+ packageJsonPath: string;
5
+ platform: PlatformTarget;
6
+ environment: ProjectEnvironment;
7
+ }
8
+ export interface DetectProjectContextResult {
9
+ success: boolean;
10
+ context?: DetectedProjectContext;
11
+ error?: string;
12
+ }
13
+ export declare function detectProjectContext(projectPath: string): DetectProjectContextResult;
14
+ export declare function detectPackageManager(projectPath: string, packageManagerField?: string): PackageManager;
15
+ //# sourceMappingURL=project-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context.d.ts","sourceRoot":"","sources":["../src/project-context.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInG,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,cAAc,CAAC;IACzB,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,0BAA0B,CAoCpF;AAED,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE,MAAM,GAC3B,cAAc,CAgChB"}
@@ -0,0 +1,78 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import { readPackageJson } from './utils/package-json-reader.js';
4
+ const EXPO_CONFIG_CANDIDATES = ['app.json', 'app.config.js', 'app.config.ts', 'app.config.mjs'];
5
+ export function detectProjectContext(projectPath) {
6
+ const readResult = readPackageJson(projectPath);
7
+ if (!readResult.success || !readResult.packageJson || !readResult.installedPackages) {
8
+ return {
9
+ success: false,
10
+ error: readResult.error || 'Failed to read package.json',
11
+ };
12
+ }
13
+ const rootPath = projectPath.endsWith('package.json') ? path.dirname(projectPath) : projectPath;
14
+ const resolvedRootPath = path.resolve(rootPath);
15
+ const packageJsonPath = path.resolve(projectPath.endsWith('package.json') ? projectPath : path.join(rootPath, 'package.json'));
16
+ const installedPackages = readResult.installedPackages;
17
+ const runtime = detectRuntime(resolvedRootPath, installedPackages);
18
+ return {
19
+ success: true,
20
+ context: {
21
+ projectPath: resolvedRootPath,
22
+ packageJsonPath,
23
+ platform: runtime === 'web' ? 'web' : 'react-native',
24
+ environment: {
25
+ runtime,
26
+ projectType: runtime,
27
+ packageManager: detectPackageManager(resolvedRootPath, typeof readResult.packageJson.packageManager === 'string'
28
+ ? readResult.packageJson.packageManager
29
+ : undefined),
30
+ },
31
+ },
32
+ };
33
+ }
34
+ export function detectPackageManager(projectPath, packageManagerField) {
35
+ if (packageManagerField) {
36
+ if (packageManagerField.startsWith('pnpm')) {
37
+ return 'pnpm';
38
+ }
39
+ if (packageManagerField.startsWith('yarn')) {
40
+ return 'yarn';
41
+ }
42
+ if (packageManagerField.startsWith('bun')) {
43
+ return 'bun';
44
+ }
45
+ if (packageManagerField.startsWith('npm')) {
46
+ return 'npm';
47
+ }
48
+ }
49
+ if (fs.existsSync(path.join(projectPath, 'pnpm-lock.yaml'))) {
50
+ return 'pnpm';
51
+ }
52
+ if (fs.existsSync(path.join(projectPath, 'yarn.lock'))) {
53
+ return 'yarn';
54
+ }
55
+ if (fs.existsSync(path.join(projectPath, 'bun.lock')) ||
56
+ fs.existsSync(path.join(projectPath, 'bun.lockb'))) {
57
+ return 'bun';
58
+ }
59
+ if (fs.existsSync(path.join(projectPath, 'package-lock.json'))) {
60
+ return 'npm';
61
+ }
62
+ return 'unknown';
63
+ }
64
+ function detectRuntime(projectPath, installedPackages) {
65
+ const hasExpoDependency = Boolean(installedPackages.expo);
66
+ const hasReactNativeDependency = Boolean(installedPackages['react-native']);
67
+ const hasExpoConfig = EXPO_CONFIG_CANDIDATES.some(fileName => fs.existsSync(path.join(projectPath, fileName)));
68
+ const hasNativeFolders = fs.existsSync(path.join(projectPath, 'ios')) ||
69
+ fs.existsSync(path.join(projectPath, 'android'));
70
+ if (hasExpoDependency || hasExpoConfig) {
71
+ return 'expo';
72
+ }
73
+ if (hasReactNativeDependency || hasNativeFolders) {
74
+ return 'react-native';
75
+ }
76
+ return 'web';
77
+ }
78
+ //# sourceMappingURL=project-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context.js","sourceRoot":"","sources":["../src/project-context.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"getting-started.d.ts","sourceRoot":"","sources":["../../src/prompts/getting-started.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,uBAAuB;;;;;;;;EA2GtC"}
1
+ {"version":3,"file":"getting-started.d.ts","sourceRoot":"","sources":["../../src/prompts/getting-started.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,wBAAgB,uBAAuB;;;;;;;;EA+HtC"}
@@ -67,7 +67,19 @@ You can call \`list-themes\` and \`preview-theme\` directly after authentication
67
67
  - pebble - Round minimal
68
68
  - square-minimalism - Square minimalism
69
69
 
70
- ## Step 4: Check Component Availability
70
+ ## Step 4: Bootstrap Project Context
71
+
72
+ If the project path is known, call \`detect-project-context\` before the main workflow.
73
+
74
+ \`\`\`
75
+ 1. Call detect-project-context with the project root or package.json path
76
+ 2. Let FramingUI store the detected default platform/runtime for the session
77
+ 3. Continue with discovery tools without repeating platform flags unless overriding on purpose
78
+ \`\`\`
79
+
80
+ For Expo / React Native targets, this is the preferred path. If no project path is available, you can still pass \`platform: "react-native"\` explicitly as a fallback.
81
+
82
+ ## Step 5: Check Component Availability
71
83
 
72
84
  Before creating screen definitions:
73
85
 
@@ -77,19 +89,26 @@ Before creating screen definitions:
77
89
  3. Identify components needed for your screen
78
90
  \`\`\`
79
91
 
80
- ## Step 5: Generate Your First Screen
92
+ ## Step 6: Generate Your First Screen
81
93
 
82
94
  Follow the 3-step workflow:
83
95
 
84
96
  **Step 1/3:** Call \`get-screen-generation-context\` with your screen description
85
97
  - Returns: Template hints, component suggestions with inline props, schema
86
98
  - Use \`includeExamples: false\` when you want a smaller response and do not need sample screen definitions
99
+ - If \`detect-project-context\` already ran, omit \`platform\` and let the stored default apply
87
100
 
88
101
  **Step 2/3:** Create Screen Definition JSON, then call \`validate-screen-definition\`
89
102
  - Returns: Validation results, errors with auto-fix patches, suggestions
90
103
 
91
104
  **After validation passes:** Write React code directly using the components and props from Step 1
92
105
 
106
+ For Expo / React Native targets:
107
+ - use the direct-write guidance from \`get-screen-generation-context\`
108
+ - prefer \`@framingui/react-native\` exports where that runtime surface exists
109
+ - do **not** import \`@framingui/ui\`
110
+ - run \`validate-environment\` with \`sourceFiles\` before handoff
111
+
93
112
  **Step 3/3 (Optional):** Call \`validate-environment\` with project path
94
113
  - Returns: Missing packages, install commands, Tailwind config status
95
114
 
@@ -98,11 +117,12 @@ Follow the 3-step workflow:
98
117
  1. ❌ Skipping authentication - All themes require licenses
99
118
  2. ❌ Assuming whoami is a hard prerequisite - it is optional session inspection, not a hidden unlock step
100
119
  3. ❌ Using non-existent theme IDs - Only 6 themes exist
101
- 4. ❌ Skipping validate-screen-definition - Always validate before writing code
102
- 5. ❌ Ignoring dependencies warnings - Check required packages before running code
103
- 6. ❌ Using unlicensed themes - Only use themes from whoami licensedThemes list
104
- 7. ❌ Parsing MCP transcript text with shell/python/json tools - Use tool output directly instead
105
- 8. ❌ Treating templateMatch as the source of truth - components and preview tools are the contract
120
+ 4. ❌ Skipping detect-project-context when the project path is known - you lose automatic platform defaults
121
+ 5. ❌ Skipping validate-screen-definition for web work - Always validate before writing code
122
+ 6. ❌ Ignoring dependencies warnings - Check required packages before running code
123
+ 7. ❌ Using unlicensed themes - Only use themes from whoami licensedThemes list
124
+ 8. ❌ Parsing MCP transcript text with shell/python/json tools - Use tool output directly instead
125
+ 9. ❌ Treating templateMatch as the source of truth - components and preview tools are the contract
106
126
 
107
127
  ## Need Help?
108
128
 
@@ -1 +1 @@
1
- {"version":3,"file":"getting-started.js","sourceRoot":"","sources":["../../src/prompts/getting-started.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEA+FkD;iBACzD;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"getting-started.js","sourceRoot":"","sources":["../../src/prompts/getting-started.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;GAGG;AACH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEAmHkD;iBACzD;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"screen-workflow.d.ts","sourceRoot":"","sources":["../../src/prompts/screen-workflow.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,uBAAuB;;;;;;;;EAuJtC"}
1
+ {"version":3,"file":"screen-workflow.d.ts","sourceRoot":"","sources":["../../src/prompts/screen-workflow.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAgB,uBAAuB;;;;;;;;EA0MtC"}
@@ -24,10 +24,29 @@ The production workflow is **guarded direct write**:
24
24
  - ✅ Write React code directly using FramingUI components and props from context
25
25
  - ✅ Verify dependencies, Tailwind setup, and raw HTML/style escapes before delivery
26
26
 
27
+ React Native is also supported through a **direct-write contract path**:
28
+ - ✅ Prefer \`detect-project-context\` once when the project path is known
29
+ - ✅ Gather platform-aware component guidance without repeating platform flags
30
+ - ✅ Write Expo / React Native code directly using \`@framingui/react-native\` where available, then host primitives or app abstractions for the rest
31
+ - ✅ Use \`validate-environment\` with \`sourceFiles\` for package checks and QC
32
+ - 🚫 Do not import \`@framingui/ui\` into React Native projects
33
+
27
34
  This is **not** the old \`generate_screen\`-first workflow.
28
35
  \`generate_screen\` may still be used as an optional helper, but the default production path is:
29
36
 
30
- \`preview-theme\` \`get-screen-generation-context\` \`preview-component\` / \`list-icon-libraries\` when needed → \`validate-screen-definition\` → write code directly → \`validate-environment\`
37
+ If the project path is known:
38
+
39
+ \`detect-project-context\` → \`preview-theme\` → \`get-screen-generation-context\` → \`preview-component\` / \`list-icon-libraries\` when needed → \`validate-screen-definition\` → write code directly → \`validate-environment\`
40
+
41
+ If the project path is not known, start at \`get-screen-generation-context\` and use explicit platform overrides only when needed.
42
+
43
+ ## React Native Note
44
+
45
+ For Expo or React Native projects:
46
+ - pass \`"platform": "react-native"\` to \`get-screen-generation-context\`
47
+ - prefer \`@framingui/react-native\` exports over app-local wrappers for common UI
48
+ - write code directly with \`StyleSheet.create\`
49
+ - run \`validate-environment\` with \`sourceFiles\` to catch web-only imports, \`className\`, and raw token drift
31
50
 
32
51
  ## Step 1/4: Gather Context
33
52
 
@@ -46,6 +65,15 @@ Use this at the start of every screen task.
46
65
 
47
66
  Set \`includeExamples: false\` when you want a smaller response and do not need example screen definitions.
48
67
 
68
+ For React Native direct-write work without a detected session default, pass:
69
+ \`\`\`json
70
+ {
71
+ "description": "Profile screen with subscription card and settings actions",
72
+ "platform": "react-native",
73
+ "includeExamples": false
74
+ }
75
+ \`\`\`
76
+
49
77
  **What to review from the response:**
50
78
  - \`templateMatch\` as a layout hint only
51
79
  - \`components\` as the source of truth for imports, props, and variants
@@ -136,15 +164,38 @@ Use it to verify:
136
164
 
137
165
  If the tool reports missing setup or raw primitive drift, fix the code before delivery.
138
166
 
167
+ ## React Native Direct-Write Path
168
+
169
+ Use this instead of the web screen-definition path when the target app is Expo or React Native.
170
+
171
+ 1. Call \`detect-project-context\` with \`projectPath\` when the app path is available
172
+ 2. Call \`get-screen-generation-context\` and let the stored session default pick React Native automatically
173
+ 3. If the project path is not available, call \`get-screen-generation-context\` with \`platform: "react-native"\`
174
+ 4. Review React Native compatible components and hints
175
+ 5. Write the screen directly using \`@framingui/react-native\` exports where available, then \`react-native\` primitives or local app abstractions
176
+ 6. Run \`validate-environment\` with:
177
+ - \`platform: "react-native"\`
178
+ - \`projectPath\`
179
+ - \`requiredPackages\`
180
+ - \`sourceFiles\`
181
+ 7. Fix missing packages, hardcoded color/spacing/radius values, and web-only patterns such as \`className\`
182
+
183
+ React Native rules:
184
+ - Do **not** import \`@framingui/ui\`
185
+ - Do **not** require Tailwind or CSS imports
186
+ - Prefer \`StyleSheet\` plus \`@framingui/react-native\` helpers or host app token helpers over raw style literals
187
+ - Treat \`@framingui/react-native\` as a minimal runtime, not as full \`@framingui/ui\` parity or code generation
188
+
139
189
  ## Best Practices
140
190
 
141
- 1. Start with \`get-screen-generation-context\`
191
+ 1. Start with \`detect-project-context\` when project path is known
142
192
  2. Use \`includeExamples: false\` unless examples are actually needed
143
193
  3. Treat \`templateMatch\` as a hint, not a hard constraint
144
194
  4. Treat \`components\` as the source of truth
145
195
  5. Validate the definition before writing JSX
146
196
  6. Never parse MCP transcript text with shell or Python JSON tooling
147
197
  7. Run \`validate-environment\` before handoff
198
+ 8. Use the React Native direct-write path when the target project is Expo or React Native
148
199
 
149
200
  ## Optional Helper Path
150
201
 
@@ -1 +1 @@
1
- {"version":3,"file":"screen-workflow.js","sourceRoot":"","sources":["../../src/prompts/screen-workflow.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gMA2IgL;iBACvL;aACF;SACF;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"screen-workflow.js","sourceRoot":"","sources":["../../src/prompts/screen-workflow.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,UAAU,uBAAuB;IACrC,OAAO;QACL,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gMA8LgL;iBACvL;aACF;SACF;KACF,CAAC;AACJ,CAAC"}