vibefast-cli 0.1.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.
Files changed (250) hide show
  1. package/FINAL-STATUS.md +144 -0
  2. package/HOW-IT-WORKS.md +559 -0
  3. package/PLAN.md +453 -0
  4. package/README.md +129 -0
  5. package/RECIPES-READY.md +172 -0
  6. package/STATUS.md +199 -0
  7. package/SUCCESS.md +259 -0
  8. package/TESTING-CHECKLIST.md +450 -0
  9. package/cloudflare-worker/.wrangler/state/v3/kv/64907821e2634080acce34618d2f3d4c/blobs/11f2769953c717e188062bc644da97c1fd1e4d6d0813a226ce7567dba759afab0000019a736fb8d4 +1 -0
  10. package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite +0 -0
  11. package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite-shm +0 -0
  12. package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite-wal +0 -0
  13. package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite +0 -0
  14. package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite-shm +0 -0
  15. package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite-wal +0 -0
  16. package/cloudflare-worker/.wrangler/state/v3/r2/vibefast-recipes/blobs/620e8cf7c35d9806da25dee237e1d7e8b2432bd98f755b60e2c7f08a48d2c7b90000019a73736484 +0 -0
  17. package/cloudflare-worker/MIGRATION.md +160 -0
  18. package/cloudflare-worker/QUICKSTART.md +200 -0
  19. package/cloudflare-worker/README.md +242 -0
  20. package/cloudflare-worker/generate-token.js +32 -0
  21. package/cloudflare-worker/mini-native@latest.zip +0 -0
  22. package/cloudflare-worker/setup.sh +143 -0
  23. package/cloudflare-worker/test-recipe/apps/native/src/app/mini/index.tsx +15 -0
  24. package/cloudflare-worker/test-recipe/recipe.json +16 -0
  25. package/cloudflare-worker/worker.js +308 -0
  26. package/cloudflare-worker/wrangler.toml +13 -0
  27. package/dist/commands/add.d.ts +3 -0
  28. package/dist/commands/add.d.ts.map +1 -0
  29. package/dist/commands/add.js +149 -0
  30. package/dist/commands/add.js.map +1 -0
  31. package/dist/commands/devices.d.ts +3 -0
  32. package/dist/commands/devices.d.ts.map +1 -0
  33. package/dist/commands/devices.js +35 -0
  34. package/dist/commands/devices.js.map +1 -0
  35. package/dist/commands/doctor.d.ts +3 -0
  36. package/dist/commands/doctor.d.ts.map +1 -0
  37. package/dist/commands/doctor.js +67 -0
  38. package/dist/commands/doctor.js.map +1 -0
  39. package/dist/commands/list.d.ts +3 -0
  40. package/dist/commands/list.d.ts.map +1 -0
  41. package/dist/commands/list.js +40 -0
  42. package/dist/commands/list.js.map +1 -0
  43. package/dist/commands/login.d.ts +3 -0
  44. package/dist/commands/login.d.ts.map +1 -0
  45. package/dist/commands/login.js +23 -0
  46. package/dist/commands/login.js.map +1 -0
  47. package/dist/commands/logout.d.ts +3 -0
  48. package/dist/commands/logout.d.ts.map +1 -0
  49. package/dist/commands/logout.js +16 -0
  50. package/dist/commands/logout.js.map +1 -0
  51. package/dist/commands/remove.d.ts +3 -0
  52. package/dist/commands/remove.d.ts.map +1 -0
  53. package/dist/commands/remove.js +67 -0
  54. package/dist/commands/remove.js.map +1 -0
  55. package/dist/core/__tests__/journal.test.d.ts +2 -0
  56. package/dist/core/__tests__/journal.test.d.ts.map +1 -0
  57. package/dist/core/__tests__/journal.test.js +101 -0
  58. package/dist/core/__tests__/journal.test.js.map +1 -0
  59. package/dist/core/__tests__/validate.test.d.ts +2 -0
  60. package/dist/core/__tests__/validate.test.d.ts.map +1 -0
  61. package/dist/core/__tests__/validate.test.js +53 -0
  62. package/dist/core/__tests__/validate.test.js.map +1 -0
  63. package/dist/core/archive.d.ts +2 -0
  64. package/dist/core/archive.d.ts.map +1 -0
  65. package/dist/core/archive.js +59 -0
  66. package/dist/core/archive.js.map +1 -0
  67. package/dist/core/auth.d.ts +15 -0
  68. package/dist/core/auth.d.ts.map +1 -0
  69. package/dist/core/auth.js +76 -0
  70. package/dist/core/auth.js.map +1 -0
  71. package/dist/core/codemod.d.ts +20 -0
  72. package/dist/core/codemod.d.ts.map +1 -0
  73. package/dist/core/codemod.js +150 -0
  74. package/dist/core/codemod.js.map +1 -0
  75. package/dist/core/fsx.d.ts +12 -0
  76. package/dist/core/fsx.d.ts.map +1 -0
  77. package/dist/core/fsx.js +70 -0
  78. package/dist/core/fsx.js.map +1 -0
  79. package/dist/core/http.d.ts +30 -0
  80. package/dist/core/http.d.ts.map +1 -0
  81. package/dist/core/http.js +95 -0
  82. package/dist/core/http.js.map +1 -0
  83. package/dist/core/journal.d.ts +18 -0
  84. package/dist/core/journal.d.ts.map +1 -0
  85. package/dist/core/journal.js +34 -0
  86. package/dist/core/journal.js.map +1 -0
  87. package/dist/core/log.d.ts +8 -0
  88. package/dist/core/log.d.ts.map +1 -0
  89. package/dist/core/log.js +9 -0
  90. package/dist/core/log.js.map +1 -0
  91. package/dist/core/pathGuard.d.ts +3 -0
  92. package/dist/core/pathGuard.d.ts.map +1 -0
  93. package/dist/core/pathGuard.js +18 -0
  94. package/dist/core/pathGuard.js.map +1 -0
  95. package/dist/core/paths.d.ts +11 -0
  96. package/dist/core/paths.d.ts.map +1 -0
  97. package/dist/core/paths.js +22 -0
  98. package/dist/core/paths.js.map +1 -0
  99. package/dist/core/validate.d.ts +8 -0
  100. package/dist/core/validate.d.ts.map +1 -0
  101. package/dist/core/validate.js +27 -0
  102. package/dist/core/validate.js.map +1 -0
  103. package/dist/index.d.ts +3 -0
  104. package/dist/index.d.ts.map +1 -0
  105. package/dist/index.js +23 -0
  106. package/dist/index.js.map +1 -0
  107. package/docs/decisions.md +55 -0
  108. package/package.json +39 -0
  109. package/recipes/audio-recorder/apps/native/src/app/audio-recorder/index.tsx +5 -0
  110. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-player.tsx +301 -0
  111. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +373 -0
  112. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +270 -0
  113. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/index.ts +4 -0
  114. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/recording-list.tsx +89 -0
  115. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +66 -0
  116. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +68 -0
  117. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +102 -0
  118. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/basic.tsx +27 -0
  119. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/index.ts +5 -0
  120. package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +82 -0
  121. package/recipes/audio-recorder/recipe.json +22 -0
  122. package/recipes/audio-recorder@latest.zip +0 -0
  123. package/recipes/charts/apps/native/src/app/charts/index.tsx +3 -0
  124. package/recipes/charts/apps/native/src/features/charts/README.md +185 -0
  125. package/recipes/charts/apps/native/src/features/charts/app/preview.tsx +223 -0
  126. package/recipes/charts/apps/native/src/features/charts/components/area-chart.tsx +40 -0
  127. package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +143 -0
  128. package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +196 -0
  129. package/recipes/charts/apps/native/src/features/charts/components/chart-card.tsx +65 -0
  130. package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +143 -0
  131. package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +246 -0
  132. package/recipes/charts/apps/native/src/features/charts/components/index.ts +10 -0
  133. package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +308 -0
  134. package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +180 -0
  135. package/recipes/charts/apps/native/src/features/charts/components/radial-bar-chart.tsx +188 -0
  136. package/recipes/charts/apps/native/src/features/charts/components/stacked-area-chart.tsx +265 -0
  137. package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +322 -0
  138. package/recipes/charts/apps/native/src/features/charts/data/mock-data.ts +183 -0
  139. package/recipes/charts/apps/native/src/features/charts/types/index.ts +66 -0
  140. package/recipes/charts/recipe.json +22 -0
  141. package/recipes/charts@latest.zip +0 -0
  142. package/recipes/chatbot/apps/native/src/app/chatbot/index.tsx +1 -0
  143. package/recipes/chatbot/apps/native/src/features/chatbot/app/index.tsx +302 -0
  144. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +59 -0
  145. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-input-bar.tsx +469 -0
  146. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +575 -0
  147. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +246 -0
  148. package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +161 -0
  149. package/recipes/chatbot/apps/native/src/features/chatbot/components/image-preview-list.tsx +115 -0
  150. package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +165 -0
  151. package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/index.ts +10 -0
  152. package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +129 -0
  153. package/recipes/chatbot/apps/native/src/features/chatbot/components/message-error-boundary.tsx +78 -0
  154. package/recipes/chatbot/apps/native/src/features/chatbot/components/message-list.tsx +173 -0
  155. package/recipes/chatbot/apps/native/src/features/chatbot/components/model-selector.tsx +283 -0
  156. package/recipes/chatbot/apps/native/src/features/chatbot/components/report-content-modal.tsx +188 -0
  157. package/recipes/chatbot/apps/native/src/features/chatbot/components/suggested-messages.tsx +67 -0
  158. package/recipes/chatbot/apps/native/src/features/chatbot/constants/models.ts +20 -0
  159. package/recipes/chatbot/apps/native/src/features/chatbot/constants/report-reasons.ts +9 -0
  160. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +143 -0
  161. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chat-config.ts +664 -0
  162. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +359 -0
  163. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +89 -0
  164. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-conversation.ts +79 -0
  165. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-image-picker.ts +122 -0
  166. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +161 -0
  167. package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +207 -0
  168. package/recipes/chatbot/apps/native/src/features/chatbot/models/index.ts +86 -0
  169. package/recipes/chatbot/apps/native/src/features/chatbot/models/models.ts +162 -0
  170. package/recipes/chatbot/apps/native/src/features/chatbot/models/providers.ts +62 -0
  171. package/recipes/chatbot/apps/native/src/features/chatbot/models/types.ts +40 -0
  172. package/recipes/chatbot/apps/native/src/features/chatbot/services/file-uploader.ts +238 -0
  173. package/recipes/chatbot/apps/native/src/features/chatbot/services/message-handler-service.ts +180 -0
  174. package/recipes/chatbot/apps/native/src/features/chatbot/types/index.ts +60 -0
  175. package/recipes/chatbot/apps/native/src/features/chatbot/utils/chat-telemetry.ts +91 -0
  176. package/recipes/chatbot/recipe.json +22 -0
  177. package/recipes/chatbot@latest.zip +0 -0
  178. package/recipes/image-generator/apps/native/src/app/image-generator/gallery.tsx +3 -0
  179. package/recipes/image-generator/apps/native/src/app/image-generator/index.tsx +3 -0
  180. package/recipes/image-generator/apps/native/src/features/image-generator/app/_layout.tsx +25 -0
  181. package/recipes/image-generator/apps/native/src/features/image-generator/app/gallery.tsx +217 -0
  182. package/recipes/image-generator/apps/native/src/features/image-generator/app/index.tsx +237 -0
  183. package/recipes/image-generator/apps/native/src/features/image-generator/components/gallery-image.tsx +26 -0
  184. package/recipes/image-generator/apps/native/src/features/image-generator/components/image-detail-modal.tsx +215 -0
  185. package/recipes/image-generator/apps/native/src/features/image-generator/components/image-model-selector.tsx +210 -0
  186. package/recipes/image-generator/apps/native/src/features/image-generator/components/image-placeholder.tsx +26 -0
  187. package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +71 -0
  188. package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +152 -0
  189. package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator.ts +93 -0
  190. package/recipes/image-generator/apps/native/src/features/image-generator/models/models.ts +66 -0
  191. package/recipes/image-generator/apps/native/src/features/image-generator/services/image-gallery-service.ts +98 -0
  192. package/recipes/image-generator/apps/native/src/features/image-generator/services/image-save-service.ts +121 -0
  193. package/recipes/image-generator/recipe.json +22 -0
  194. package/recipes/image-generator@latest.zip +0 -0
  195. package/recipes/quiz/apps/native/src/app/quiz/index.tsx +47 -0
  196. package/recipes/quiz/apps/native/src/features/quiz/components/question.tsx +67 -0
  197. package/recipes/quiz/apps/native/src/features/quiz/config.ts +11 -0
  198. package/recipes/quiz/apps/native/src/features/quiz/index.tsx +133 -0
  199. package/recipes/quiz/recipe.json +22 -0
  200. package/recipes/quiz@latest.zip +0 -0
  201. package/recipes/tracker-app/apps/native/src/app/tracker-app/index.tsx +1 -0
  202. package/recipes/tracker-app/apps/native/src/features/tracker-app/app/index.tsx +108 -0
  203. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/animated-number.tsx +102 -0
  204. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/calorie-card.tsx +66 -0
  205. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/circular-progress.tsx +97 -0
  206. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/floating-add-button.tsx +27 -0
  207. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/macro-card.tsx +80 -0
  208. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/promo-banner.tsx +98 -0
  209. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/recently-logged.tsx +64 -0
  210. package/recipes/tracker-app/apps/native/src/features/tracker-app/components/week-calendar.tsx +68 -0
  211. package/recipes/tracker-app/recipe.json +22 -0
  212. package/recipes/tracker-app@latest.zip +0 -0
  213. package/recipes/upload-all.sh +32 -0
  214. package/recipes/voice-bot/apps/native/src/app/voice-bot/index.tsx +27 -0
  215. package/recipes/voice-bot/apps/native/src/features/voice-bot/README.md +185 -0
  216. package/recipes/voice-bot/apps/native/src/features/voice-bot/components/conversation-status.tsx +76 -0
  217. package/recipes/voice-bot/apps/native/src/features/voice-bot/components/index.ts +4 -0
  218. package/recipes/voice-bot/apps/native/src/features/voice-bot/components/message-input.tsx +98 -0
  219. package/recipes/voice-bot/apps/native/src/features/voice-bot/components/voice-bot-screen.tsx +173 -0
  220. package/recipes/voice-bot/apps/native/src/features/voice-bot/components/voice-controls.tsx +73 -0
  221. package/recipes/voice-bot/apps/native/src/features/voice-bot/index.ts +3 -0
  222. package/recipes/voice-bot/apps/native/src/features/voice-bot/services/index.ts +1 -0
  223. package/recipes/voice-bot/apps/native/src/features/voice-bot/services/use-voice-bot.ts +161 -0
  224. package/recipes/voice-bot/apps/native/src/features/voice-bot/types.ts +29 -0
  225. package/recipes/voice-bot/recipe.json +22 -0
  226. package/recipes/voice-bot@latest.zip +0 -0
  227. package/scripts/create-recipes.mjs +189 -0
  228. package/src/commands/add.ts +183 -0
  229. package/src/commands/devices.ts +38 -0
  230. package/src/commands/doctor.ts +67 -0
  231. package/src/commands/list.ts +45 -0
  232. package/src/commands/login.ts +24 -0
  233. package/src/commands/logout.ts +15 -0
  234. package/src/commands/remove.ts +78 -0
  235. package/src/core/__tests__/journal.test.ts +119 -0
  236. package/src/core/__tests__/validate.test.ts +64 -0
  237. package/src/core/archive.ts +69 -0
  238. package/src/core/auth.ts +103 -0
  239. package/src/core/codemod.ts +211 -0
  240. package/src/core/fsx.ts +80 -0
  241. package/src/core/http.ts +136 -0
  242. package/src/core/journal.ts +64 -0
  243. package/src/core/log.ts +9 -0
  244. package/src/core/pathGuard.ts +22 -0
  245. package/src/core/paths.ts +33 -0
  246. package/src/core/validate.ts +44 -0
  247. package/src/index.ts +27 -0
  248. package/test-critical-cases.mjs +258 -0
  249. package/tsconfig.json +21 -0
  250. package/vitest.config.mts +12 -0
@@ -0,0 +1,258 @@
1
+ #!/usr/bin/env node
2
+ import { execSync } from 'child_process';
3
+ import { writeFileSync, readFileSync, existsSync } from 'fs';
4
+ import { join } from 'path';
5
+
6
+ const WORKER_URL = 'https://vibefast-cli-worker.mzafar611.workers.dev';
7
+ const CLI_PATH = '../vibefast-cli/dist/index.js';
8
+ const MONOREPO_PATH = '../vibefast-monorepo';
9
+
10
+ let testsPassed = 0;
11
+ let testsFailed = 0;
12
+
13
+ function log(message, type = 'info') {
14
+ const colors = {
15
+ info: '\x1b[36m', // cyan
16
+ success: '\x1b[32m', // green
17
+ error: '\x1b[31m', // red
18
+ warn: '\x1b[33m', // yellow
19
+ reset: '\x1b[0m'
20
+ };
21
+ console.log(`${colors[type]}${message}${colors.reset}`);
22
+ }
23
+
24
+ function runCommand(cmd, expectError = false) {
25
+ try {
26
+ const result = execSync(cmd, {
27
+ cwd: MONOREPO_PATH,
28
+ env: {
29
+ ...process.env,
30
+ VIBEFAST_WORKER_URL: WORKER_URL,
31
+ VIBEFAST_CONFIG_DIR: join(MONOREPO_PATH, '.vibefast'),
32
+ },
33
+ encoding: 'utf8',
34
+ stdio: 'pipe'
35
+ });
36
+ if (expectError) {
37
+ throw new Error(`Expected command to fail but it succeeded: ${cmd}`);
38
+ }
39
+ return { success: true, output: result };
40
+ } catch (error) {
41
+ if (expectError) {
42
+ return { success: true, output: error.stderr || error.stdout || error.message };
43
+ }
44
+ return { success: false, output: error.stderr || error.stdout || error.message };
45
+ }
46
+ }
47
+
48
+ function test(name, testFn) {
49
+ try {
50
+ log(`\n🧪 Testing: ${name}`, 'info');
51
+ testFn();
52
+ log(`āœ… PASS: ${name}`, 'success');
53
+ testsPassed++;
54
+ } catch (error) {
55
+ log(`āŒ FAIL: ${name}`, 'error');
56
+ log(` Error: ${error.message}`, 'error');
57
+ testsFailed++;
58
+ }
59
+ }
60
+
61
+ function cleanup() {
62
+ // Clean up test artifacts
63
+ runCommand('rm -rf "apps/native/src/app/(root)/(protected)/charts" "apps/native/src/features/charts"');
64
+ runCommand('echo \'{"entries":[]}\' > .vibefast/journal.json');
65
+
66
+ // Reset vibefast-features.ts
67
+ const cleanFeatures = `/**
68
+ * VibeFast CLI Managed Features
69
+ *
70
+ * āš ļø DO NOT EDIT THIS FILE MANUALLY
71
+ * This file is automatically managed by the VibeFast CLI.
72
+ *
73
+ * Features are added/removed via:
74
+ * - vf add <feature-name>
75
+ * - vf remove <feature-name>
76
+ */
77
+
78
+ export interface VibeFastFeature {
79
+ id: string;
80
+ title: string;
81
+ icon: string;
82
+ color: string;
83
+ description: string;
84
+ route: string;
85
+ testID: string;
86
+ }
87
+
88
+ export const vibefastFeatures: VibeFastFeature[] = [
89
+ // --- @vibefast:features:start ---
90
+ // CLI will inject features here
91
+ // --- @vibefast:features:end ---
92
+ ];
93
+ `;
94
+ writeFileSync(join(MONOREPO_PATH, 'apps/native/src/features/vibefast-features.ts'), cleanFeatures);
95
+ }
96
+
97
+ // ============================================================================
98
+ // CRITICAL EDGE CASE TESTS
99
+ // ============================================================================
100
+
101
+ log('šŸš€ Starting Critical Edge Case Tests\n', 'info');
102
+
103
+ // Test 1: Authentication Tests
104
+ test('Invalid token should be saved locally', () => {
105
+ const result = runCommand(`node ${CLI_PATH} login --token INVALID_TOKEN`);
106
+ if (!result.success) throw new Error('Login command should succeed');
107
+ });
108
+
109
+ test('Empty token should show error', () => {
110
+ const result = runCommand(`node ${CLI_PATH} login --token ""`, true);
111
+ if (!result.output.includes('Invalid token') && !result.output.includes('required')) {
112
+ throw new Error('Should show invalid token error');
113
+ }
114
+ });
115
+
116
+ test('Login without token should show error', () => {
117
+ const result = runCommand(`node ${CLI_PATH} login`, true);
118
+ if (!result.output.includes('required')) {
119
+ throw new Error('Should show required option error');
120
+ }
121
+ });
122
+
123
+ // Test 2: Setup Validation
124
+ test('Doctor in VibeFast repo should pass', () => {
125
+ const result = runCommand(`node ${CLI_PATH} doctor`);
126
+ if (!result.success || !result.output.includes('All checks passed')) {
127
+ throw new Error('Doctor should pass in VibeFast repo');
128
+ }
129
+ });
130
+
131
+ test('Commands without login should fail gracefully', () => {
132
+ // Logout first
133
+ runCommand(`node ${CLI_PATH} logout`);
134
+ const result = runCommand(`node ${CLI_PATH} list`, true);
135
+ if (!result.output.includes('Not logged in') && !result.output.includes('login')) {
136
+ throw new Error('Should show not logged in error');
137
+ }
138
+ // Login back
139
+ runCommand(`node ${CLI_PATH} login --token TEST_TOKEN_12345`);
140
+ });
141
+
142
+ // Test 3: Installation Tests
143
+ test('Install valid feature should work', () => {
144
+ cleanup();
145
+ const result = runCommand(`node ${CLI_PATH} add charts`);
146
+ if (!result.success || !result.output.includes('installed successfully')) {
147
+ throw new Error('Should install charts successfully');
148
+ }
149
+ });
150
+
151
+ test('Re-install same feature should show already installed', () => {
152
+ const result = runCommand(`node ${CLI_PATH} add charts`);
153
+ if (!result.success || !result.output.includes('already installed')) {
154
+ throw new Error('Should show already installed message');
155
+ }
156
+ });
157
+
158
+ test('Install with --force should overwrite', () => {
159
+ const result = runCommand(`node ${CLI_PATH} add charts --force`);
160
+ if (!result.success || !result.output.includes('installed successfully')) {
161
+ throw new Error('Should reinstall with --force');
162
+ }
163
+ });
164
+
165
+ test('Install non-existent feature should fail', () => {
166
+ const result = runCommand(`node ${CLI_PATH} add nonexistent-feature-xyz`, true);
167
+ if (!result.output.includes('not found') && !result.output.includes('404') && !result.output.includes('failed')) {
168
+ throw new Error('Should show feature not found error');
169
+ }
170
+ });
171
+
172
+ test('Dry-run should not make changes', () => {
173
+ cleanup();
174
+ const result = runCommand(`node ${CLI_PATH} add charts --dry-run`);
175
+ if (!result.success || !result.output.includes('dry run')) {
176
+ throw new Error('Should show dry run message');
177
+ }
178
+ // Check that files weren't actually created
179
+ const chartExists = existsSync(join(MONOREPO_PATH, 'apps/native/src/app/(root)/(protected)/charts'));
180
+ if (chartExists) {
181
+ throw new Error('Dry run should not create files');
182
+ }
183
+ });
184
+
185
+ // Test 4: Removal Tests
186
+ test('Remove installed feature should work', () => {
187
+ // First install
188
+ runCommand(`node ${CLI_PATH} add charts`);
189
+ // Then remove
190
+ const result = runCommand(`node ${CLI_PATH} remove charts`);
191
+ if (!result.success || !result.output.includes('removed successfully')) {
192
+ throw new Error('Should remove charts successfully');
193
+ }
194
+ // Check that navigation was cleaned
195
+ const featuresContent = readFileSync(join(MONOREPO_PATH, 'apps/native/src/features/vibefast-features.ts'), 'utf8');
196
+ if (featuresContent.includes("id: 'charts'")) {
197
+ throw new Error('Navigation should be cleaned after removal');
198
+ }
199
+ });
200
+
201
+ test('Remove non-installed feature should show message', () => {
202
+ const result = runCommand(`node ${CLI_PATH} remove nonexistent`);
203
+ if (!result.success || !result.output.includes('not installed')) {
204
+ throw new Error('Should show not installed message');
205
+ }
206
+ });
207
+
208
+ // Test 5: File System Tests
209
+ test('Navigation injection should work correctly', () => {
210
+ cleanup();
211
+ runCommand(`node ${CLI_PATH} add charts`);
212
+ const featuresContent = readFileSync(join(MONOREPO_PATH, 'apps/native/src/features/vibefast-features.ts'), 'utf8');
213
+ if (!featuresContent.includes("id: 'charts'") || !featuresContent.includes('Charts')) {
214
+ throw new Error('Navigation should be injected correctly');
215
+ }
216
+ });
217
+
218
+ test('Watermarking should work', () => {
219
+ cleanup();
220
+ runCommand(`node ${CLI_PATH} add charts`);
221
+ const indexContent = readFileSync(join(MONOREPO_PATH, 'apps/native/src/app/(root)/(protected)/charts/index.tsx'), 'utf8');
222
+ if (!indexContent.includes('// vibefast license:')) {
223
+ throw new Error('Watermark should be added to files');
224
+ }
225
+ });
226
+
227
+ test('Journal should track installations', () => {
228
+ cleanup();
229
+ runCommand(`node ${CLI_PATH} add charts`);
230
+ const journalContent = readFileSync(join(MONOREPO_PATH, '.vibefast/journal.json'), 'utf8');
231
+ const journal = JSON.parse(journalContent);
232
+ if (!journal.entries || journal.entries.length === 0) {
233
+ throw new Error('Journal should track installations');
234
+ }
235
+ const entry = journal.entries[0];
236
+ if (entry.feature !== 'charts' || entry.files.length === 0) {
237
+ throw new Error('Journal entry should have correct data');
238
+ }
239
+ });
240
+
241
+ // ============================================================================
242
+ // RESULTS
243
+ // ============================================================================
244
+
245
+ cleanup();
246
+
247
+ log('\nšŸ“Š Test Results:', 'info');
248
+ log(`āœ… Passed: ${testsPassed}`, 'success');
249
+ log(`āŒ Failed: ${testsFailed}`, testsFailed > 0 ? 'error' : 'success');
250
+ log(`šŸ“ˆ Success Rate: ${Math.round((testsPassed / (testsPassed + testsFailed)) * 100)}%`, 'info');
251
+
252
+ if (testsFailed === 0) {
253
+ log('\nšŸŽ‰ All critical tests passed! CLI is ready for production.', 'success');
254
+ process.exit(0);
255
+ } else {
256
+ log('\nāš ļø Some tests failed. Please fix before shipping.', 'warn');
257
+ process.exit(1);
258
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "lib": ["ES2022"],
6
+ "moduleResolution": "bundler",
7
+ "resolveJsonModule": true,
8
+ "allowJs": true,
9
+ "outDir": "./dist",
10
+ "rootDir": "./src",
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "declaration": true,
16
+ "declarationMap": true,
17
+ "sourceMap": true
18
+ },
19
+ "include": ["src/**/*"],
20
+ "exclude": ["node_modules", "dist"]
21
+ }
@@ -0,0 +1,12 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ environment: 'node',
7
+ coverage: {
8
+ provider: 'v8',
9
+ reporter: ['text', 'json', 'html'],
10
+ },
11
+ },
12
+ });