vibefast-cli 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/FEATURE-DEPENDENCY-SPEC.md +338 -0
- package/dist/__tests__/integration.test.d.ts +2 -0
- package/dist/__tests__/integration.test.d.ts.map +1 -0
- package/dist/__tests__/integration.test.js +219 -0
- package/dist/__tests__/integration.test.js.map +1 -0
- package/dist/__tests__/recipes.test.d.ts +2 -0
- package/dist/__tests__/recipes.test.d.ts.map +1 -0
- package/dist/__tests__/recipes.test.js +143 -0
- package/dist/__tests__/recipes.test.js.map +1 -0
- package/dist/commands/__tests__/init.test.d.ts +2 -0
- package/dist/commands/__tests__/init.test.d.ts.map +1 -0
- package/dist/commands/__tests__/init.test.js +95 -0
- package/dist/commands/__tests__/init.test.js.map +1 -0
- package/dist/commands/__tests__/platform.test.d.ts +2 -0
- package/dist/commands/__tests__/platform.test.d.ts.map +1 -0
- package/dist/commands/__tests__/platform.test.js +123 -0
- package/dist/commands/__tests__/platform.test.js.map +1 -0
- package/dist/commands/add.d.ts.map +1 -1
- package/dist/commands/add.js +4 -5
- package/dist/commands/add.js.map +1 -1
- package/dist/core/journal.d.ts.map +1 -1
- package/dist/core/journal.js +36 -19
- package/dist/core/journal.js.map +1 -1
- package/dist/core/recipes.d.ts.map +1 -1
- package/dist/core/recipes.js +8 -39
- package/dist/core/recipes.js.map +1 -1
- package/package.json +1 -1
- package/recipes/ios-widget/recipe.json +78 -0
- package/recipes/ios-widget/targets/widget/AppIntent.swift +46 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@1x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-20x20@3x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@1x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-29x29@3x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@1x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-40x40@3x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-60x60@3x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@1x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-76x76@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/App-Icon-83.5x83.5@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/Contents.json +122 -0
- package/recipes/ios-widget/targets/widget/Assets.xcassets/AppIcon.appiconset/ItunesArtwork@2x.png +0 -0
- package/recipes/ios-widget/targets/widget/CalorieTrackerWidget.swift +424 -0
- package/recipes/ios-widget/targets/widget/HabitTrackerWidget.swift +305 -0
- package/recipes/ios-widget/targets/widget/Info.plist +11 -0
- package/recipes/ios-widget/targets/widget/WidgetLiveActivity.swift +75 -0
- package/recipes/ios-widget/targets/widget/expo-target.config.js +10 -0
- package/recipes/ios-widget/targets/widget/generated.entitlements +5 -0
- package/recipes/ios-widget/targets/widget/index.swift +18 -0
- package/recipes/ios-widget/targets/widget/widgets.swift +96 -0
- package/recipes/ios-widget@latest.zip +0 -0
- package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/index.tsx +74 -0
- package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/local.tsx +25 -0
- package/recipes/payments/apps/native/src/app/(root)/(protected)/paywall/remote.tsx +23 -0
- package/recipes/payments/apps/native/src/features/payments/README.md +200 -0
- package/recipes/payments/apps/native/src/features/payments/app/local-paywall.tsx +194 -0
- package/recipes/payments/apps/native/src/features/payments/app/remote-paywall.tsx +79 -0
- package/recipes/payments/apps/native/src/features/payments/components/payment-initializer.tsx +95 -0
- package/recipes/payments/apps/native/src/features/payments/components/paywall-error-state.tsx +60 -0
- package/recipes/payments/apps/native/src/features/payments/components/paywall-local-mode.tsx +116 -0
- package/recipes/payments/apps/native/src/features/payments/components/paywall-product-card.tsx +133 -0
- package/recipes/payments/apps/native/src/features/payments/components/paywall-remote-mode.tsx +146 -0
- package/recipes/payments/apps/native/src/features/payments/hooks/use-entitlement.ts +63 -0
- package/recipes/payments/apps/native/src/features/payments/index.ts +8 -0
- package/recipes/payments/apps/native/src/features/payments/services/revenuecat-adapter.ts +407 -0
- package/recipes/payments/recipe.json +58 -0
- package/recipes/payments@latest.zip +0 -0
- package/src/__tests__/integration.test.ts +249 -0
- package/src/__tests__/recipes.test.ts +168 -0
- package/src/commands/__tests__/init.test.ts +112 -0
- package/src/commands/__tests__/platform.test.ts +141 -0
- package/src/commands/add.ts +4 -5
- package/src/core/journal.ts +42 -25
- package/src/core/recipes.ts +8 -40
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"recipes.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/recipes.test.ts"],"names":[],"mappings":""}
|