vibefast-cli 0.5.0 → 0.5.2

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 (78) hide show
  1. package/FEATURE-DEPENDENCY-SPEC.md +338 -0
  2. package/dist/__tests__/integration.test.d.ts +2 -0
  3. package/dist/__tests__/integration.test.d.ts.map +1 -0
  4. package/dist/__tests__/integration.test.js +219 -0
  5. package/dist/__tests__/integration.test.js.map +1 -0
  6. package/dist/__tests__/recipes.test.d.ts +2 -0
  7. package/dist/__tests__/recipes.test.d.ts.map +1 -0
  8. package/dist/__tests__/recipes.test.js +143 -0
  9. package/dist/__tests__/recipes.test.js.map +1 -0
  10. package/dist/commands/__tests__/init.test.d.ts +2 -0
  11. package/dist/commands/__tests__/init.test.d.ts.map +1 -0
  12. package/dist/commands/__tests__/init.test.js +95 -0
  13. package/dist/commands/__tests__/init.test.js.map +1 -0
  14. package/dist/commands/__tests__/platform.test.d.ts +2 -0
  15. package/dist/commands/__tests__/platform.test.d.ts.map +1 -0
  16. package/dist/commands/__tests__/platform.test.js +123 -0
  17. package/dist/commands/__tests__/platform.test.js.map +1 -0
  18. package/dist/commands/add.d.ts.map +1 -1
  19. package/dist/commands/add.js +8 -5
  20. package/dist/commands/add.js.map +1 -1
  21. package/dist/core/journal.d.ts.map +1 -1
  22. package/dist/core/journal.js +36 -19
  23. package/dist/core/journal.js.map +1 -1
  24. package/dist/core/recipes.d.ts +1 -1
  25. package/dist/core/recipes.d.ts.map +1 -1
  26. package/dist/core/recipes.js +12 -41
  27. package/dist/core/recipes.js.map +1 -1
  28. package/package.json +1 -1
  29. package/recipes/ios-widget/recipe.json +78 -0
  30. package/recipes/ios-widget/targets/widget/AppIntent.swift +46 -0
  31. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png +0 -0
  32. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png +0 -0
  33. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png +0 -0
  34. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png +0 -0
  35. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png +0 -0
  36. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png +0 -0
  37. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png +0 -0
  38. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png +0 -0
  39. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png +0 -0
  40. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png +0 -0
  41. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png +0 -0
  42. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png +0 -0
  43. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png +0 -0
  44. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png +0 -0
  45. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/Contents.json +122 -0
  46. package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png +0 -0
  47. package/recipes/ios-widget/targets/widget/CalorieTrackerWidget.swift +424 -0
  48. package/recipes/ios-widget/targets/widget/HabitTrackerWidget.swift +305 -0
  49. package/recipes/ios-widget/targets/widget/Info.plist +11 -0
  50. package/recipes/ios-widget/targets/widget/WidgetLiveActivity.swift +75 -0
  51. package/recipes/ios-widget/targets/widget/expo-target.config.js +10 -0
  52. package/recipes/ios-widget/targets/widget/generated.entitlements +5 -0
  53. package/recipes/ios-widget/targets/widget/index.swift +18 -0
  54. package/recipes/ios-widget/targets/widget/widgets.swift +96 -0
  55. package/recipes/ios-widget@latest.zip +0 -0
  56. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/index.tsx +74 -0
  57. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/local.tsx +25 -0
  58. package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/remote.tsx +23 -0
  59. package/recipes/payments/apps/native/src/features/payments/README.md +200 -0
  60. package/recipes/payments/apps/native/src/features/payments/app/local-paywall.tsx +194 -0
  61. package/recipes/payments/apps/native/src/features/payments/app/remote-paywall.tsx +79 -0
  62. package/recipes/payments/apps/native/src/features/payments/components/payment-initializer.tsx +95 -0
  63. package/recipes/payments/apps/native/src/features/payments/components/paywall-error-state.tsx +60 -0
  64. package/recipes/payments/apps/native/src/features/payments/components/paywall-local-mode.tsx +116 -0
  65. package/recipes/payments/apps/native/src/features/payments/components/paywall-product-card.tsx +133 -0
  66. package/recipes/payments/apps/native/src/features/payments/components/paywall-remote-mode.tsx +146 -0
  67. package/recipes/payments/apps/native/src/features/payments/hooks/use-entitlement.ts +63 -0
  68. package/recipes/payments/apps/native/src/features/payments/index.ts +8 -0
  69. package/recipes/payments/apps/native/src/features/payments/services/revenuecat-adapter.ts +407 -0
  70. package/recipes/payments/recipe.json +58 -0
  71. package/recipes/payments@latest.zip +0 -0
  72. package/src/__tests__/integration.test.ts +249 -0
  73. package/src/__tests__/recipes.test.ts +168 -0
  74. package/src/commands/__tests__/init.test.ts +112 -0
  75. package/src/commands/__tests__/platform.test.ts +141 -0
  76. package/src/commands/add.ts +9 -5
  77. package/src/core/journal.ts +42 -25
  78. package/src/core/recipes.ts +12 -42
@@ -0,0 +1,338 @@
1
+ # Feature Dependency Specification
2
+
3
+ This document specifies exactly what each feature needs to add to the clean baseline.
4
+
5
+ ## Format
6
+
7
+ Each feature specifies:
8
+ - **npm packages** to install
9
+ - **env.js changes** (schema + values)
10
+ - **app.config.ts changes** (plugins, permissions, entitlements)
11
+ - **scripts** to add to package.json
12
+
13
+ ---
14
+
15
+ ## iOS Widget
16
+
17
+ ### NPM Packages
18
+ ```json
19
+ {
20
+ "dependencies": {
21
+ "@bacons/apple-targets": "^3.0.2"
22
+ }
23
+ }
24
+ ```
25
+
26
+ ### env.js Changes
27
+ ```javascript
28
+ // Add to buildTime schema:
29
+ APPLE_TEAM_ID: z.string(),
30
+
31
+ // Add to _buildTimeEnv:
32
+ APPLE_TEAM_ID,
33
+
34
+ // Add constant:
35
+ const APPLE_TEAM_ID = 'replace_me';
36
+ ```
37
+
38
+ ### app.config.ts Changes
39
+ ```typescript
40
+ // Add to ios.entitlements:
41
+ entitlements: {
42
+ 'com.apple.security.application-groups': [`group.${Env.BUNDLE_ID}.shared`],
43
+ },
44
+
45
+ // Add to plugins array:
46
+ ['@bacons/apple-targets', {
47
+ targets: [{
48
+ name: 'YourAppWidget', // Use app name + Widget
49
+ type: 'widget',
50
+ bundleIdentifier: `${Env.BUNDLE_ID}.widget`,
51
+ entitlements: {
52
+ 'com.apple.security.application-groups': [`group.${Env.BUNDLE_ID}.shared`],
53
+ },
54
+ }],
55
+ }],
56
+ ```
57
+
58
+ **Important:** Use `${Env.BUNDLE_ID}` not hardcoded values!
59
+
60
+ ---
61
+
62
+ ## Voice Bot
63
+
64
+ ### NPM Packages
65
+ ```json
66
+ {
67
+ "dependencies": {
68
+ "@livekit/react-native": "^2.9.1",
69
+ "@livekit/react-native-expo-plugin": "^1.0.1",
70
+ "@livekit/react-native-webrtc": "^137.0.1",
71
+ "@config-plugins/react-native-webrtc": "^12.0.0",
72
+ "livekit-client": "^2.15.6"
73
+ }
74
+ }
75
+ ```
76
+
77
+ ### env.js Changes
78
+ ```javascript
79
+ // Add to client schema:
80
+ ELEVENLABS_AGENT_ID: z.string(),
81
+
82
+ // Add to _clientEnv:
83
+ ELEVENLABS_AGENT_ID: process.env.ELEVENLABS_AGENT_ID,
84
+ ```
85
+
86
+ ### app.config.ts Changes
87
+ ```typescript
88
+ // Add to ios.infoPlist:
89
+ NSMicrophoneUsageDescription: 'This app needs access to your microphone for voice conversations.',
90
+ UIBackgroundModes: ['audio', 'remote-notification'],
91
+
92
+ // Add to android.permissions:
93
+ 'android.permission.RECORD_AUDIO',
94
+ 'android.permission.WAKE_LOCK',
95
+ 'android.permission.MODIFY_AUDIO_SETTINGS',
96
+ 'android.permission.BLUETOOTH',
97
+
98
+ // Add to plugins array:
99
+ '@livekit/react-native-expo-plugin',
100
+ '@config-plugins/react-native-webrtc',
101
+ ['expo-audio', {
102
+ microphonePermission: 'Allow $(PRODUCT_NAME) to access your microphone for voice conversations.',
103
+ }],
104
+ ```
105
+
106
+ ---
107
+
108
+ ## Wake Word Detection
109
+
110
+ ### NPM Packages
111
+ ```json
112
+ {
113
+ "dependencies": {
114
+ "react-native-vosk": "^2.1.6"
115
+ }
116
+ }
117
+ ```
118
+
119
+ ### env.js Changes
120
+ None (uses same microphone permission as voice-bot)
121
+
122
+ ### app.config.ts Changes
123
+ ```typescript
124
+ // Add to ios.infoPlist (if not already added by voice-bot):
125
+ NSMicrophoneUsageDescription: 'This app needs access to your microphone for voice conversations and on-device wake-word detection.',
126
+
127
+ // Add to android.permissions (if not already added by voice-bot):
128
+ 'android.permission.RECORD_AUDIO',
129
+
130
+ // Add to plugins array:
131
+ ['react-native-vosk', {
132
+ models: ['assets/vosk-model/model-en-us'],
133
+ iOSMicrophonePermission: 'We use the mic for on-device wake-phrase detection.',
134
+ }],
135
+ ```
136
+
137
+ ### Scripts
138
+ ```json
139
+ {
140
+ "scripts": {
141
+ "setup:vosk": "node scripts/download-vosk-model.mjs"
142
+ }
143
+ }
144
+ ```
145
+
146
+ ### Post-Install
147
+ Run: `pnpm setup:vosk` to download the wake word model
148
+
149
+ ---
150
+
151
+ ## Chatbot
152
+
153
+ ### NPM Packages
154
+ ```json
155
+ {
156
+ "dependencies": {
157
+ "@ai-sdk/google": "^1.2.22",
158
+ "@ai-sdk/openai": "^1.3.24",
159
+ "@ai-sdk/react": "^1.2.12",
160
+ "@convex-dev/agent": "^0.1.6",
161
+ "@convex-dev/persistent-text-streaming": "^0.2.3",
162
+ "@convex-dev/rag": "^0.5.4",
163
+ "ai": "^4.3.19",
164
+ "markdown-it": "^14.1.0",
165
+ "react-native-markdown-display": "^7.0.2",
166
+ "react-native-syntax-highlighter": "^2.1.0"
167
+ }
168
+ }
169
+ ```
170
+
171
+ ### env.js Changes
172
+ ```javascript
173
+ // Add to client schema:
174
+ CHAT_LATENCY_TELEMETRY_MODE: z.enum(['off', 'sample', 'debug']).optional().default('off'),
175
+
176
+ // Add to _clientEnv:
177
+ CHAT_LATENCY_TELEMETRY_MODE: process.env.CHAT_LATENCY_TELEMETRY_MODE ?? 'off',
178
+ ```
179
+
180
+ ### app.config.ts Changes
181
+ None (uses core dependencies)
182
+
183
+ ---
184
+
185
+ ## Image Generator
186
+
187
+ ### NPM Packages
188
+ None (uses core dependencies)
189
+
190
+ ### env.js Changes
191
+ None
192
+
193
+ ### app.config.ts Changes
194
+ None (uses core camera/image picker)
195
+
196
+ ---
197
+
198
+ ## Image Analysis
199
+
200
+ ### NPM Packages
201
+ None (uses core dependencies)
202
+
203
+ ### env.js Changes
204
+ None
205
+
206
+ ### app.config.ts Changes
207
+ None (uses core camera/image picker)
208
+
209
+ ---
210
+
211
+ ## Payments
212
+
213
+ ### NPM Packages
214
+ ```json
215
+ {
216
+ "dependencies": {
217
+ "react-native-purchases": "^8.11.10",
218
+ "react-native-purchases-ui": "^8.11.10"
219
+ }
220
+ }
221
+ ```
222
+
223
+ ### env.js Changes
224
+ ```javascript
225
+ // Add to client schema:
226
+ REVENUECAT_API_KEY_APPLE: z.string(),
227
+ REVENUECAT_API_KEY_GOOGLE: z.string(),
228
+
229
+ // Add to _clientEnv:
230
+ REVENUECAT_API_KEY_APPLE: process.env.REVENUECAT_API_KEY_APPLE,
231
+ REVENUECAT_API_KEY_GOOGLE: process.env.REVENUECAT_API_KEY_GOOGLE,
232
+ ```
233
+
234
+ ### app.config.ts Changes
235
+ None
236
+
237
+ ---
238
+
239
+ ## Audio Recorder
240
+
241
+ ### NPM Packages
242
+ None (uses expo-audio which is core)
243
+
244
+ ### env.js Changes
245
+ None
246
+
247
+ ### app.config.ts Changes
248
+ ```typescript
249
+ // Add to ios.infoPlist (if not already added):
250
+ NSMicrophoneUsageDescription: 'This app needs access to your microphone for recording audio.',
251
+
252
+ // Add to android.permissions (if not already added):
253
+ 'android.permission.RECORD_AUDIO',
254
+
255
+ // Add to plugins array (if not already added):
256
+ ['expo-audio', {
257
+ microphonePermission: 'Allow $(PRODUCT_NAME) to access your microphone for recording audio.',
258
+ }],
259
+ ```
260
+
261
+ ---
262
+
263
+ ## Charts
264
+
265
+ ### NPM Packages
266
+ None (uses core dependencies like @shopify/react-native-skia, d3-shape)
267
+
268
+ ### env.js Changes
269
+ None
270
+
271
+ ### app.config.ts Changes
272
+ None
273
+
274
+ ---
275
+
276
+ ## Quiz
277
+
278
+ ### NPM Packages
279
+ None (uses core dependencies)
280
+
281
+ ### env.js Changes
282
+ None
283
+
284
+ ### app.config.ts Changes
285
+ None
286
+
287
+ ---
288
+
289
+ ## Tracker App
290
+
291
+ ### NPM Packages
292
+ None (uses core dependencies)
293
+
294
+ ### env.js Changes
295
+ None
296
+
297
+ ### app.config.ts Changes
298
+ None
299
+
300
+ ---
301
+
302
+ ## Implementation Notes
303
+
304
+ ### Dynamic Values
305
+ Always use environment variables, never hardcode:
306
+ - ❌ `'group.com.vibefast.shared'`
307
+ - ✅ `` `group.${Env.BUNDLE_ID}.shared` ``
308
+
309
+ ### Conditional Additions
310
+ Some features share dependencies:
311
+ - voice-bot + wake-word both need microphone permissions
312
+ - Only add once, check if already exists
313
+
314
+ ### Order Matters
315
+ In app.config.ts plugins array:
316
+ 1. Core plugins first
317
+ 2. Feature plugins after
318
+ 3. Maintain alphabetical order within each group
319
+
320
+ ### Testing
321
+ After adding a feature:
322
+ 1. Run `pnpm install`
323
+ 2. Run `pnpm prebuild` to regenerate native projects
324
+ 3. Test on both iOS and Android
325
+ 4. Verify env vars are accessible in app
326
+
327
+ ---
328
+
329
+ ## CLI Implementation Checklist
330
+
331
+ - [ ] Parse recipe.json for dependencies
332
+ - [ ] Modify package.json (add packages)
333
+ - [ ] Modify env.js (add schema + values)
334
+ - [ ] Modify app.config.ts (add plugins/permissions)
335
+ - [ ] Run `pnpm install`
336
+ - [ ] Run post-install scripts if specified
337
+ - [ ] Update .vibefast/journal.json
338
+ - [ ] Show success message with next steps
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,219 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { existsSync, rmSync } from 'fs';
3
+ import { join } from 'path';
4
+ import { tmpdir } from 'os';
5
+ describe('VibeFast CLI Integration Tests', () => {
6
+ let testDir;
7
+ beforeEach(() => {
8
+ testDir = join(tmpdir(), `vibefast-integration-${Date.now()}`);
9
+ });
10
+ afterEach(() => {
11
+ if (existsSync(testDir)) {
12
+ rmSync(testDir, { recursive: true, force: true });
13
+ }
14
+ });
15
+ describe('Complete Workflows', () => {
16
+ it('should complete full init -> add features -> platform add workflow', async () => {
17
+ // 1. vf init (clean, native-only)
18
+ // 2. vf add chatbot
19
+ // 3. vf add image-generator
20
+ // 4. vf platform add (add web)
21
+ // 5. vf add quiz --target web
22
+ // Verify: All features installed correctly
23
+ // Verify: Both platforms exist
24
+ // Verify: Project is usable
25
+ expect(true).toBe(true);
26
+ });
27
+ it('should complete init with custom features workflow', async () => {
28
+ // 1. vf init (custom, select: chatbot, charts, image-generator)
29
+ // 2. Verify all features installed
30
+ // 3. Verify Vosk model downloaded (if wake-word selected)
31
+ // 4. Verify env vars detected
32
+ expect(true).toBe(true);
33
+ });
34
+ it('should complete platform removal workflow', async () => {
35
+ // 1. vf init (both platforms)
36
+ // 2. vf platform remove (remove web)
37
+ // 3. Verify web removed, native intact
38
+ // 4. vf platform add (add web back)
39
+ // 5. Verify web restored
40
+ expect(true).toBe(true);
41
+ });
42
+ });
43
+ describe('Feature Installation During Init', () => {
44
+ it('should install all selected features', async () => {
45
+ // Verify: chatbot files exist
46
+ // Verify: image-generator files exist
47
+ // Verify: charts files exist
48
+ // Verify: Navigation links added
49
+ // Verify: Dependencies listed
50
+ expect(true).toBe(true);
51
+ });
52
+ it('should handle feature installation failures', async () => {
53
+ // If one feature fails, others should continue
54
+ // Verify: Partial installation handled
55
+ // Verify: Error message shown
56
+ // Verify: User can retry
57
+ expect(true).toBe(true);
58
+ });
59
+ it('should auto-download Vosk for wake-word', async () => {
60
+ // Select wake-word feature
61
+ // Verify: Vosk model downloaded
62
+ // Verify: Model extracted correctly
63
+ // Verify: Model in correct location
64
+ expect(true).toBe(true);
65
+ });
66
+ it('should detect missing environment variables', async () => {
67
+ // Select chatbot (needs OPENAI_API_KEY)
68
+ // Verify: Missing vars detected
69
+ // Verify: User shown what's needed
70
+ // Verify: Links provided to get keys
71
+ expect(true).toBe(true);
72
+ });
73
+ });
74
+ describe('Configuration Management', () => {
75
+ it('should maintain valid package.json', async () => {
76
+ // After init, add, remove operations
77
+ // Verify: package.json is valid JSON
78
+ // Verify: workspaces array is correct
79
+ // Verify: No duplicate entries
80
+ expect(true).toBe(true);
81
+ });
82
+ it('should maintain valid turbo.json', async () => {
83
+ // After init, add, remove operations
84
+ // Verify: turbo.json is valid JSON
85
+ // Verify: pipeline tasks are correct
86
+ // Verify: No orphaned tasks
87
+ expect(true).toBe(true);
88
+ });
89
+ it('should handle concurrent operations safely', async () => {
90
+ // Run multiple operations in sequence
91
+ // Verify: No race conditions
92
+ // Verify: Configurations stay consistent
93
+ expect(true).toBe(true);
94
+ });
95
+ });
96
+ describe('User Input Handling', () => {
97
+ it('should handle back navigation in menus', async () => {
98
+ // In init menu, select back
99
+ // Verify: Goes to previous menu
100
+ // Verify: Can navigate back multiple times
101
+ expect(true).toBe(true);
102
+ });
103
+ it('should handle Ctrl+C gracefully', async () => {
104
+ // During init, press Ctrl+C
105
+ // Verify: Process exits cleanly
106
+ // Verify: No partial files left
107
+ expect(true).toBe(true);
108
+ });
109
+ it('should validate user inputs', async () => {
110
+ // Try invalid project names
111
+ // Try empty selections
112
+ // Verify: Shows error messages
113
+ // Verify: Prompts again
114
+ expect(true).toBe(true);
115
+ });
116
+ it('should handle --yes flag correctly', async () => {
117
+ // Run with --yes flag
118
+ // Verify: Skips all prompts
119
+ // Verify: Uses defaults
120
+ // Verify: Completes successfully
121
+ expect(true).toBe(true);
122
+ });
123
+ it('should handle --dry-run flag', async () => {
124
+ // Run vf add with --dry-run
125
+ // Verify: Shows what would happen
126
+ // Verify: No files created
127
+ // Verify: No changes made
128
+ expect(true).toBe(true);
129
+ });
130
+ });
131
+ describe('File System Operations', () => {
132
+ it('should create correct directory structure', async () => {
133
+ // After init
134
+ // Verify: apps/native exists (if selected)
135
+ // Verify: apps/web exists (if selected)
136
+ // Verify: packages/backend exists
137
+ // Verify: packages/ui exists
138
+ expect(true).toBe(true);
139
+ });
140
+ it('should handle file conflicts', async () => {
141
+ // Try to init in existing directory
142
+ // Verify: Shows error
143
+ // Verify: Doesn't overwrite
144
+ expect(true).toBe(true);
145
+ });
146
+ it('should clean up temporary files', async () => {
147
+ // After operations
148
+ // Verify: No .temp-* directories left
149
+ // Verify: No orphaned files
150
+ expect(true).toBe(true);
151
+ });
152
+ it('should handle permission errors', async () => {
153
+ // Try to write to read-only directory
154
+ // Verify: Shows error
155
+ // Verify: Doesn't crash
156
+ expect(true).toBe(true);
157
+ });
158
+ });
159
+ describe('Dependency Management', () => {
160
+ it('should install dependencies correctly', async () => {
161
+ // After init
162
+ // Verify: pnpm install runs
163
+ // Verify: node_modules created
164
+ // Verify: All deps installed
165
+ expect(true).toBe(true);
166
+ });
167
+ it('should handle missing pnpm', async () => {
168
+ // If pnpm not installed
169
+ // Verify: Offers to install
170
+ // Verify: Provides instructions
171
+ expect(true).toBe(true);
172
+ });
173
+ it('should update dependencies on platform add', async () => {
174
+ // After platform add
175
+ // Verify: New platform deps installed
176
+ // Verify: No conflicts
177
+ expect(true).toBe(true);
178
+ });
179
+ });
180
+ describe('Cross-Platform Paths', () => {
181
+ it('should handle Windows paths correctly', async () => {
182
+ // Verify: Path separators handled
183
+ // Verify: No hardcoded slashes
184
+ // Verify: Using path.join()
185
+ expect(true).toBe(true);
186
+ });
187
+ it('should handle Linux paths correctly', async () => {
188
+ // Verify: Paths work on Linux
189
+ // Verify: Permissions handled
190
+ expect(true).toBe(true);
191
+ });
192
+ it('should handle macOS paths correctly', async () => {
193
+ // Verify: Paths work on macOS
194
+ // Verify: Case sensitivity handled
195
+ expect(true).toBe(true);
196
+ });
197
+ });
198
+ describe('Error Recovery', () => {
199
+ it('should recover from network errors', async () => {
200
+ // Simulate network failure during download
201
+ // Verify: Shows error
202
+ // Verify: Suggests retry
203
+ expect(true).toBe(true);
204
+ });
205
+ it('should recover from corrupted downloads', async () => {
206
+ // Simulate corrupted zip file
207
+ // Verify: Shows error
208
+ // Verify: Cleans up
209
+ expect(true).toBe(true);
210
+ });
211
+ it('should recover from partial installations', async () => {
212
+ // Simulate failure mid-installation
213
+ // Verify: Can retry
214
+ // Verify: Doesn't duplicate
215
+ expect(true).toBe(true);
216
+ });
217
+ });
218
+ });
219
+ //# sourceMappingURL=integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration.test.js","sourceRoot":"","sources":["../../src/__tests__/integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=recipes.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipes.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/recipes.test.ts"],"names":[],"mappings":""}