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.
- 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 +8 -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 +1 -1
- package/dist/core/recipes.d.ts.map +1 -1
- package/dist/core/recipes.js +12 -41
- 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 +9 -5
- package/src/core/journal.ts +42 -25
- package/src/core/recipes.ts +12 -42
package/src/commands/add.ts
CHANGED
|
@@ -57,14 +57,17 @@ export const addCommand = new Command('add')
|
|
|
57
57
|
log.plain('');
|
|
58
58
|
log.info('Examples:');
|
|
59
59
|
log.plain(' vf add # Interactive menu');
|
|
60
|
-
log.plain(' vf add
|
|
61
|
-
log.plain(' vf add
|
|
62
|
-
log.plain(' vf add
|
|
63
|
-
log.plain(' vf add
|
|
64
|
-
log.plain(' vf add chatbot --dry-run');
|
|
60
|
+
log.plain(' vf add chatbot # Add specific feature');
|
|
61
|
+
log.plain(' vf add chatbot --dry-run # Preview changes');
|
|
62
|
+
log.plain(' vf add chatbot --force # Force reinstall');
|
|
63
|
+
log.plain(' vf add chatbot --yes # Skip prompts');
|
|
65
64
|
})
|
|
66
65
|
.action(async (feature: string | undefined, options) => {
|
|
67
66
|
try {
|
|
67
|
+
// Fix MaxListeners warning for batch operations
|
|
68
|
+
process.stdin.setMaxListeners(0);
|
|
69
|
+
process.stdout.setMaxListeners(0);
|
|
70
|
+
|
|
68
71
|
const paths = getPaths();
|
|
69
72
|
|
|
70
73
|
// Interactive mode if no feature specified
|
|
@@ -202,6 +205,7 @@ async function installFeature(feature: string, options: any, paths: any) {
|
|
|
202
205
|
if (existing && !options.force) {
|
|
203
206
|
log.warn(`${feature} is already installed for ${target}`);
|
|
204
207
|
log.info('Use --force to reinstall');
|
|
208
|
+
log.plain('');
|
|
205
209
|
return;
|
|
206
210
|
}
|
|
207
211
|
|
package/src/core/journal.ts
CHANGED
|
@@ -30,35 +30,52 @@ export async function readJournal(journalPath: string): Promise<Journal> {
|
|
|
30
30
|
if (!(await exists(journalPath))) {
|
|
31
31
|
return { entries: [] };
|
|
32
32
|
}
|
|
33
|
-
const content = await readFileContent(journalPath);
|
|
34
|
-
const journal = JSON.parse(content) as Journal;
|
|
35
33
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
34
|
+
try {
|
|
35
|
+
const content = await readFileContent(journalPath);
|
|
36
|
+
const journal = JSON.parse(content) as Journal;
|
|
37
|
+
|
|
38
|
+
// Ensure entries is an array
|
|
39
|
+
if (!journal.entries || !Array.isArray(journal.entries)) {
|
|
40
|
+
console.warn('Invalid journal format, resetting to empty journal');
|
|
41
|
+
return { entries: [] };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Migrate old format to new format
|
|
45
|
+
let needsMigration = false;
|
|
46
|
+
|
|
47
|
+
for (const entry of journal.entries) {
|
|
48
|
+
if (entry.files && entry.files.length > 0 && typeof entry.files[0] === 'string') {
|
|
49
|
+
needsMigration = true;
|
|
50
|
+
// Old format: array of strings
|
|
51
|
+
const oldFiles = entry.files as string[];
|
|
52
|
+
|
|
53
|
+
// Convert to new format with hashes
|
|
54
|
+
const newFiles: FileEntry[] = [];
|
|
55
|
+
for (const filePath of oldFiles) {
|
|
56
|
+
try {
|
|
57
|
+
const hash = await hashFile(filePath);
|
|
58
|
+
newFiles.push({ path: filePath, hash });
|
|
59
|
+
} catch (err) {
|
|
60
|
+
// File might not exist anymore, skip it
|
|
61
|
+
console.warn(`Could not hash file ${filePath}, skipping`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
entry.files = newFiles;
|
|
50
66
|
}
|
|
51
|
-
|
|
52
|
-
entry.files = newFiles;
|
|
53
67
|
}
|
|
68
|
+
|
|
69
|
+
// Save migrated journal
|
|
70
|
+
if (needsMigration) {
|
|
71
|
+
await writeJournal(journalPath, journal);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return journal;
|
|
75
|
+
} catch (err) {
|
|
76
|
+
console.warn('Failed to read journal, resetting to empty journal:', err);
|
|
77
|
+
return { entries: [] };
|
|
54
78
|
}
|
|
55
|
-
|
|
56
|
-
// Save migrated journal
|
|
57
|
-
if (needsMigration) {
|
|
58
|
-
await writeJournal(journalPath, journal);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
return journal;
|
|
62
79
|
}
|
|
63
80
|
|
|
64
81
|
export async function writeJournal(journalPath: string, journal: Journal): Promise<void> {
|
package/src/core/recipes.ts
CHANGED
|
@@ -70,49 +70,17 @@ export const RECIPES: RecipeInfo[] = [
|
|
|
70
70
|
description: 'Wake word detection with Vosk',
|
|
71
71
|
icon: '🎙️',
|
|
72
72
|
},
|
|
73
|
-
|
|
74
|
-
// Advanced UI Components
|
|
75
73
|
{
|
|
76
|
-
name: '
|
|
77
|
-
category: '
|
|
78
|
-
description: '
|
|
79
|
-
icon: '
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: 'animated-switch',
|
|
83
|
-
category: 'advanced-ui',
|
|
84
|
-
description: 'Smooth animated toggle switch',
|
|
85
|
-
icon: '🎚️',
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: 'animated-chip',
|
|
89
|
-
category: 'advanced-ui',
|
|
90
|
-
description: 'Animated chip/tag component with press effects',
|
|
91
|
-
icon: '🏷️',
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'number-stepper',
|
|
95
|
-
category: 'advanced-ui',
|
|
96
|
-
description: 'Number input with +/- buttons',
|
|
97
|
-
icon: '🔢',
|
|
98
|
-
},
|
|
99
|
-
{
|
|
100
|
-
name: 'progress-circle',
|
|
101
|
-
category: 'advanced-ui',
|
|
102
|
-
description: 'Circular progress indicator with animation',
|
|
103
|
-
icon: '⭕',
|
|
104
|
-
},
|
|
105
|
-
{
|
|
106
|
-
name: 'swipe-slider',
|
|
107
|
-
category: 'advanced-ui',
|
|
108
|
-
description: 'Interactive swipe-to-confirm slider',
|
|
109
|
-
icon: '👆',
|
|
74
|
+
name: 'ios-widget',
|
|
75
|
+
category: 'feature',
|
|
76
|
+
description: 'iOS Home Screen widgets with Live Activities',
|
|
77
|
+
icon: '📱',
|
|
110
78
|
},
|
|
111
79
|
{
|
|
112
|
-
name: '
|
|
113
|
-
category: '
|
|
114
|
-
description: '
|
|
115
|
-
icon: '
|
|
80
|
+
name: 'payments',
|
|
81
|
+
category: 'feature',
|
|
82
|
+
description: 'In-app purchases and subscriptions with RevenueCat',
|
|
83
|
+
icon: '💳',
|
|
116
84
|
},
|
|
117
85
|
];
|
|
118
86
|
|
|
@@ -124,10 +92,12 @@ export function getRecipesByCategory(category: RecipeCategory): RecipeInfo[] {
|
|
|
124
92
|
}
|
|
125
93
|
|
|
126
94
|
/**
|
|
127
|
-
* Get all categories
|
|
95
|
+
* Get all categories that have recipes
|
|
128
96
|
*/
|
|
129
97
|
export function getCategories(): RecipeCategory[] {
|
|
130
|
-
|
|
98
|
+
const categories = new Set<RecipeCategory>();
|
|
99
|
+
RECIPES.forEach(r => categories.add(r.category));
|
|
100
|
+
return Array.from(categories);
|
|
131
101
|
}
|
|
132
102
|
|
|
133
103
|
/**
|