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.
- package/FINAL-STATUS.md +144 -0
- package/HOW-IT-WORKS.md +559 -0
- package/PLAN.md +453 -0
- package/README.md +129 -0
- package/RECIPES-READY.md +172 -0
- package/STATUS.md +199 -0
- package/SUCCESS.md +259 -0
- package/TESTING-CHECKLIST.md +450 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/64907821e2634080acce34618d2f3d4c/blobs/11f2769953c717e188062bc644da97c1fd1e4d6d0813a226ce7567dba759afab0000019a736fb8d4 +1 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite +0 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite-shm +0 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite-wal +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite-shm +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite-wal +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/vibefast-recipes/blobs/620e8cf7c35d9806da25dee237e1d7e8b2432bd98f755b60e2c7f08a48d2c7b90000019a73736484 +0 -0
- package/cloudflare-worker/MIGRATION.md +160 -0
- package/cloudflare-worker/QUICKSTART.md +200 -0
- package/cloudflare-worker/README.md +242 -0
- package/cloudflare-worker/generate-token.js +32 -0
- package/cloudflare-worker/mini-native@latest.zip +0 -0
- package/cloudflare-worker/setup.sh +143 -0
- package/cloudflare-worker/test-recipe/apps/native/src/app/mini/index.tsx +15 -0
- package/cloudflare-worker/test-recipe/recipe.json +16 -0
- package/cloudflare-worker/worker.js +308 -0
- package/cloudflare-worker/wrangler.toml +13 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +149 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/devices.d.ts +3 -0
- package/dist/commands/devices.d.ts.map +1 -0
- package/dist/commands/devices.js +35 -0
- package/dist/commands/devices.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +67 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +40 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +23 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +16 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +67 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/core/__tests__/journal.test.d.ts +2 -0
- package/dist/core/__tests__/journal.test.d.ts.map +1 -0
- package/dist/core/__tests__/journal.test.js +101 -0
- package/dist/core/__tests__/journal.test.js.map +1 -0
- package/dist/core/__tests__/validate.test.d.ts +2 -0
- package/dist/core/__tests__/validate.test.d.ts.map +1 -0
- package/dist/core/__tests__/validate.test.js +53 -0
- package/dist/core/__tests__/validate.test.js.map +1 -0
- package/dist/core/archive.d.ts +2 -0
- package/dist/core/archive.d.ts.map +1 -0
- package/dist/core/archive.js +59 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/auth.d.ts +15 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +76 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/codemod.d.ts +20 -0
- package/dist/core/codemod.d.ts.map +1 -0
- package/dist/core/codemod.js +150 -0
- package/dist/core/codemod.js.map +1 -0
- package/dist/core/fsx.d.ts +12 -0
- package/dist/core/fsx.d.ts.map +1 -0
- package/dist/core/fsx.js +70 -0
- package/dist/core/fsx.js.map +1 -0
- package/dist/core/http.d.ts +30 -0
- package/dist/core/http.d.ts.map +1 -0
- package/dist/core/http.js +95 -0
- package/dist/core/http.js.map +1 -0
- package/dist/core/journal.d.ts +18 -0
- package/dist/core/journal.d.ts.map +1 -0
- package/dist/core/journal.js +34 -0
- package/dist/core/journal.js.map +1 -0
- package/dist/core/log.d.ts +8 -0
- package/dist/core/log.d.ts.map +1 -0
- package/dist/core/log.js +9 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/pathGuard.d.ts +3 -0
- package/dist/core/pathGuard.d.ts.map +1 -0
- package/dist/core/pathGuard.js +18 -0
- package/dist/core/pathGuard.js.map +1 -0
- package/dist/core/paths.d.ts +11 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +22 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/validate.d.ts +8 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +27 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/docs/decisions.md +55 -0
- package/package.json +39 -0
- package/recipes/audio-recorder/apps/native/src/app/audio-recorder/index.tsx +5 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-player.tsx +301 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +373 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +270 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/index.ts +4 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/recording-list.tsx +89 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +66 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +68 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +102 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/basic.tsx +27 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/index.ts +5 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +82 -0
- package/recipes/audio-recorder/recipe.json +22 -0
- package/recipes/audio-recorder@latest.zip +0 -0
- package/recipes/charts/apps/native/src/app/charts/index.tsx +3 -0
- package/recipes/charts/apps/native/src/features/charts/README.md +185 -0
- package/recipes/charts/apps/native/src/features/charts/app/preview.tsx +223 -0
- package/recipes/charts/apps/native/src/features/charts/components/area-chart.tsx +40 -0
- package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +143 -0
- package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +196 -0
- package/recipes/charts/apps/native/src/features/charts/components/chart-card.tsx +65 -0
- package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +143 -0
- package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +246 -0
- package/recipes/charts/apps/native/src/features/charts/components/index.ts +10 -0
- package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +308 -0
- package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +180 -0
- package/recipes/charts/apps/native/src/features/charts/components/radial-bar-chart.tsx +188 -0
- package/recipes/charts/apps/native/src/features/charts/components/stacked-area-chart.tsx +265 -0
- package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +322 -0
- package/recipes/charts/apps/native/src/features/charts/data/mock-data.ts +183 -0
- package/recipes/charts/apps/native/src/features/charts/types/index.ts +66 -0
- package/recipes/charts/recipe.json +22 -0
- package/recipes/charts@latest.zip +0 -0
- package/recipes/chatbot/apps/native/src/app/chatbot/index.tsx +1 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/app/index.tsx +302 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +59 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-input-bar.tsx +469 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +575 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +246 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +161 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/image-preview-list.tsx +115 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +165 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/index.ts +10 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +129 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/message-error-boundary.tsx +78 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/message-list.tsx +173 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/model-selector.tsx +283 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/report-content-modal.tsx +188 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/suggested-messages.tsx +67 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/constants/models.ts +20 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/constants/report-reasons.ts +9 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +143 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chat-config.ts +664 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +359 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +89 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-conversation.ts +79 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-image-picker.ts +122 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +161 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +207 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/index.ts +86 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/models.ts +162 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/providers.ts +62 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/types.ts +40 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/services/file-uploader.ts +238 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/services/message-handler-service.ts +180 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/types/index.ts +60 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/utils/chat-telemetry.ts +91 -0
- package/recipes/chatbot/recipe.json +22 -0
- package/recipes/chatbot@latest.zip +0 -0
- package/recipes/image-generator/apps/native/src/app/image-generator/gallery.tsx +3 -0
- package/recipes/image-generator/apps/native/src/app/image-generator/index.tsx +3 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/_layout.tsx +25 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/gallery.tsx +217 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/index.tsx +237 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/gallery-image.tsx +26 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-detail-modal.tsx +215 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-model-selector.tsx +210 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-placeholder.tsx +26 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +71 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +152 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator.ts +93 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/models/models.ts +66 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/services/image-gallery-service.ts +98 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/services/image-save-service.ts +121 -0
- package/recipes/image-generator/recipe.json +22 -0
- package/recipes/image-generator@latest.zip +0 -0
- package/recipes/quiz/apps/native/src/app/quiz/index.tsx +47 -0
- package/recipes/quiz/apps/native/src/features/quiz/components/question.tsx +67 -0
- package/recipes/quiz/apps/native/src/features/quiz/config.ts +11 -0
- package/recipes/quiz/apps/native/src/features/quiz/index.tsx +133 -0
- package/recipes/quiz/recipe.json +22 -0
- package/recipes/quiz@latest.zip +0 -0
- package/recipes/tracker-app/apps/native/src/app/tracker-app/index.tsx +1 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/app/index.tsx +108 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/animated-number.tsx +102 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/calorie-card.tsx +66 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/circular-progress.tsx +97 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/floating-add-button.tsx +27 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/macro-card.tsx +80 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/promo-banner.tsx +98 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/recently-logged.tsx +64 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/week-calendar.tsx +68 -0
- package/recipes/tracker-app/recipe.json +22 -0
- package/recipes/tracker-app@latest.zip +0 -0
- package/recipes/upload-all.sh +32 -0
- package/recipes/voice-bot/apps/native/src/app/voice-bot/index.tsx +27 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/README.md +185 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/conversation-status.tsx +76 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/index.ts +4 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/message-input.tsx +98 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/voice-bot-screen.tsx +173 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/voice-controls.tsx +73 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/index.ts +3 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/services/index.ts +1 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/services/use-voice-bot.ts +161 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/types.ts +29 -0
- package/recipes/voice-bot/recipe.json +22 -0
- package/recipes/voice-bot@latest.zip +0 -0
- package/scripts/create-recipes.mjs +189 -0
- package/src/commands/add.ts +183 -0
- package/src/commands/devices.ts +38 -0
- package/src/commands/doctor.ts +67 -0
- package/src/commands/list.ts +45 -0
- package/src/commands/login.ts +24 -0
- package/src/commands/logout.ts +15 -0
- package/src/commands/remove.ts +78 -0
- package/src/core/__tests__/journal.test.ts +119 -0
- package/src/core/__tests__/validate.test.ts +64 -0
- package/src/core/archive.ts +69 -0
- package/src/core/auth.ts +103 -0
- package/src/core/codemod.ts +211 -0
- package/src/core/fsx.ts +80 -0
- package/src/core/http.ts +136 -0
- package/src/core/journal.ts +64 -0
- package/src/core/log.ts +9 -0
- package/src/core/pathGuard.ts +22 -0
- package/src/core/paths.ts +33 -0
- package/src/core/validate.ts +44 -0
- package/src/index.ts +27 -0
- package/test-critical-cases.mjs +258 -0
- package/tsconfig.json +21 -0
- package/vitest.config.mts +12 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { readFileContent, writeFileContent } from './fsx.js';
|
|
2
|
+
const NATIVE_START = '// --- @vibefast:features:start ---';
|
|
3
|
+
const NATIVE_END = '// --- @vibefast:features:end ---';
|
|
4
|
+
const WEB_START = '{/* @vibefast:nav:start */}';
|
|
5
|
+
const WEB_END = '{/* @vibefast:nav:end */}';
|
|
6
|
+
function escapeTsLiteral(value) {
|
|
7
|
+
return value
|
|
8
|
+
.replace(/\\/g, '\\\\')
|
|
9
|
+
.replace(/'/g, "\\'")
|
|
10
|
+
.replace(/\r/g, '\\r')
|
|
11
|
+
.replace(/\n/g, '\\n')
|
|
12
|
+
.replace(/\u2028/g, '\\u2028')
|
|
13
|
+
.replace(/\u2029/g, '\\u2029');
|
|
14
|
+
}
|
|
15
|
+
function escapeHtmlAttribute(value) {
|
|
16
|
+
return value
|
|
17
|
+
.replace(/&/g, '&')
|
|
18
|
+
.replace(/"/g, '"')
|
|
19
|
+
.replace(/'/g, ''')
|
|
20
|
+
.replace(/</g, '<')
|
|
21
|
+
.replace(/>/g, '>');
|
|
22
|
+
}
|
|
23
|
+
function escapeForRegex(value) {
|
|
24
|
+
return value.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
25
|
+
}
|
|
26
|
+
function safeNavId(value) {
|
|
27
|
+
const sanitized = value.replace(/[^a-zA-Z0-9_-]/g, '');
|
|
28
|
+
return sanitized || 'feature';
|
|
29
|
+
}
|
|
30
|
+
export async function insertNavLinkNative(filePath, link, options) {
|
|
31
|
+
const content = await readFileContent(filePath);
|
|
32
|
+
if (!content.includes(NATIVE_START) || !content.includes(NATIVE_END)) {
|
|
33
|
+
throw new Error(`Missing navigation markers in ${filePath}`);
|
|
34
|
+
}
|
|
35
|
+
// Check if link already exists by route
|
|
36
|
+
const routeCheck = link.href.replace('/(root)/(protected)/', '/');
|
|
37
|
+
const safeRoute = escapeTsLiteral(routeCheck);
|
|
38
|
+
if (content.includes(`route: '${safeRoute}'`)) {
|
|
39
|
+
return false; // Already exists, idempotent
|
|
40
|
+
}
|
|
41
|
+
// Create feature object for the vibefast-features.ts file
|
|
42
|
+
const featureId = safeNavId(link.href.split('/').pop() || 'feature');
|
|
43
|
+
const navItem = ` {
|
|
44
|
+
id: '${featureId}',
|
|
45
|
+
title: '${escapeTsLiteral(link.label)}',
|
|
46
|
+
icon: '${escapeTsLiteral(link.icon || '📦')}',
|
|
47
|
+
color: '${escapeTsLiteral(link.color || '#6366F1')}',
|
|
48
|
+
description: '${escapeTsLiteral(`${link.label} feature`)}',
|
|
49
|
+
route: '${safeRoute}',
|
|
50
|
+
testID: '${featureId}-button',
|
|
51
|
+
}`;
|
|
52
|
+
const startIdx = content.indexOf(NATIVE_START) + NATIVE_START.length;
|
|
53
|
+
const endIdx = content.indexOf(NATIVE_END);
|
|
54
|
+
const before = content.slice(0, startIdx);
|
|
55
|
+
const after = content.slice(endIdx);
|
|
56
|
+
const between = content.slice(startIdx, endIdx);
|
|
57
|
+
// Check if there are existing features (look for opening brace)
|
|
58
|
+
const hasExistingFeatures = between.includes('{');
|
|
59
|
+
let newContent;
|
|
60
|
+
if (hasExistingFeatures) {
|
|
61
|
+
// Add comma after new item since there are more items
|
|
62
|
+
newContent = `${before}\n${navItem},${between}${after}`;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// First item, no comma needed
|
|
66
|
+
newContent = `${before}\n${navItem}\n ${after}`;
|
|
67
|
+
}
|
|
68
|
+
if (!options?.dryRun) {
|
|
69
|
+
await writeFileContent(filePath, newContent, { force: true });
|
|
70
|
+
}
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
export async function removeNavLinkNative(filePath, href, options) {
|
|
74
|
+
const content = await readFileContent(filePath);
|
|
75
|
+
const routeCheck = href.replace('/(root)/(protected)/', '/');
|
|
76
|
+
const safeRoute = escapeTsLiteral(routeCheck);
|
|
77
|
+
if (!content.includes(`route: '${safeRoute}'`)) {
|
|
78
|
+
return false; // Not found
|
|
79
|
+
}
|
|
80
|
+
// Use regex to remove the entire feature object including trailing comma
|
|
81
|
+
// Match: { ... route: '/charts' ... }, or { ... route: '/charts' ... }
|
|
82
|
+
const featureObjectRegex = new RegExp(`\\s*\\{[^}]*route:\\s*'${escapeForRegex(safeRoute)}'[^}]*\\},?\\s*`, 'gs');
|
|
83
|
+
const newContent = content.replace(featureObjectRegex, '');
|
|
84
|
+
if (!options?.dryRun) {
|
|
85
|
+
await writeFileContent(filePath, newContent, { force: true });
|
|
86
|
+
}
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
export async function insertNavLinkWeb(filePath, link, options) {
|
|
90
|
+
const content = await readFileContent(filePath);
|
|
91
|
+
if (!content.includes(WEB_START) || !content.includes(WEB_END)) {
|
|
92
|
+
throw new Error(`Missing navigation markers in ${filePath}`);
|
|
93
|
+
}
|
|
94
|
+
// Check if link already exists
|
|
95
|
+
const safeHref = escapeHtmlAttribute(link.href);
|
|
96
|
+
if (content.includes(`href="${safeHref}"`)) {
|
|
97
|
+
return false; // Already exists
|
|
98
|
+
}
|
|
99
|
+
const navCard = ` <Link href="${safeHref}" className="card">
|
|
100
|
+
<h3>{${JSON.stringify(link.label)}}</h3>
|
|
101
|
+
</Link>`;
|
|
102
|
+
const startIdx = content.indexOf(WEB_START) + WEB_START.length;
|
|
103
|
+
const endIdx = content.indexOf(WEB_END);
|
|
104
|
+
const before = content.slice(0, startIdx);
|
|
105
|
+
const after = content.slice(endIdx);
|
|
106
|
+
const existing = content.slice(startIdx, endIdx).trim();
|
|
107
|
+
const newContent = existing
|
|
108
|
+
? `${before}\n${existing}\n${navCard}\n${after}`
|
|
109
|
+
: `${before}\n${navCard}\n${after}`;
|
|
110
|
+
if (!options?.dryRun) {
|
|
111
|
+
await writeFileContent(filePath, newContent, { force: true });
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
export async function removeNavLinkWeb(filePath, href, options) {
|
|
116
|
+
const content = await readFileContent(filePath);
|
|
117
|
+
const safeHref = escapeHtmlAttribute(href);
|
|
118
|
+
if (!content.includes(`href="${safeHref}"`)) {
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
const lines = content.split('\n');
|
|
122
|
+
const filtered = [];
|
|
123
|
+
let skipCount = 0;
|
|
124
|
+
for (let i = 0; i < lines.length; i++) {
|
|
125
|
+
const line = lines[i];
|
|
126
|
+
if (line.includes(`href="${safeHref}"`)) {
|
|
127
|
+
let start = i;
|
|
128
|
+
while (start > 0 && !lines[start].trim().startsWith('<Link')) {
|
|
129
|
+
start--;
|
|
130
|
+
}
|
|
131
|
+
let end = i;
|
|
132
|
+
while (end < lines.length && !lines[end].trim().startsWith('</Link>')) {
|
|
133
|
+
end++;
|
|
134
|
+
}
|
|
135
|
+
skipCount = end - start + 1;
|
|
136
|
+
i = end;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (skipCount > 0) {
|
|
140
|
+
skipCount--;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
filtered.push(line);
|
|
144
|
+
}
|
|
145
|
+
if (!options?.dryRun) {
|
|
146
|
+
await writeFileContent(filePath, filtered.join('\n'), { force: true });
|
|
147
|
+
}
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=codemod.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codemod.js","sourceRoot":"","sources":["../../src/core/codemod.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function ensureDir(path: string): Promise<void>;
|
|
2
|
+
export declare function exists(path: string): Promise<boolean>;
|
|
3
|
+
export declare function readFileContent(path: string): Promise<string>;
|
|
4
|
+
export declare function writeFileContent(path: string, content: string, options?: {
|
|
5
|
+
force?: boolean;
|
|
6
|
+
}): Promise<void>;
|
|
7
|
+
export declare function deleteFile(path: string): Promise<void>;
|
|
8
|
+
export declare function copyTree(src: string, dest: string, options?: {
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
force?: boolean;
|
|
11
|
+
}): Promise<string[]>;
|
|
12
|
+
//# sourceMappingURL=fsx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fsx.d.ts","sourceRoot":"","sources":["../../src/core/fsx.ts"],"names":[],"mappings":"AAIA,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM3D;AAED,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO3D;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAEnE;AAED,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5B,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5D;AAED,wBAAsB,QAAQ,CAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9C,OAAO,CAAC,MAAM,EAAE,CAAC,CA6BnB"}
|
package/dist/core/fsx.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { mkdir, writeFile, readFile, rm, access, readdir, stat, copyFile } from 'fs/promises';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { constants } from 'fs';
|
|
4
|
+
export async function ensureDir(path) {
|
|
5
|
+
try {
|
|
6
|
+
await mkdir(path, { recursive: true });
|
|
7
|
+
}
|
|
8
|
+
catch (err) {
|
|
9
|
+
if (err.code !== 'EEXIST')
|
|
10
|
+
throw err;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export async function exists(path) {
|
|
14
|
+
try {
|
|
15
|
+
await access(path, constants.F_OK);
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export async function readFileContent(path) {
|
|
23
|
+
return readFile(path, 'utf-8');
|
|
24
|
+
}
|
|
25
|
+
export async function writeFileContent(path, content, options) {
|
|
26
|
+
const fileExists = await exists(path);
|
|
27
|
+
if (fileExists && !options?.force) {
|
|
28
|
+
throw new Error(`File already exists: ${path}. Use --force to overwrite.`);
|
|
29
|
+
}
|
|
30
|
+
await ensureDir(dirname(path));
|
|
31
|
+
await writeFile(path, content, 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
export async function deleteFile(path) {
|
|
34
|
+
try {
|
|
35
|
+
await rm(path, { recursive: true, force: true });
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
if (err.code !== 'ENOENT')
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function copyTree(src, dest, options) {
|
|
43
|
+
const copied = [];
|
|
44
|
+
async function copyRecursive(srcPath, destPath) {
|
|
45
|
+
const stats = await stat(srcPath);
|
|
46
|
+
if (stats.isDirectory()) {
|
|
47
|
+
if (!options?.dryRun) {
|
|
48
|
+
await ensureDir(destPath);
|
|
49
|
+
}
|
|
50
|
+
const entries = await readdir(srcPath);
|
|
51
|
+
for (const entry of entries) {
|
|
52
|
+
await copyRecursive(join(srcPath, entry), join(destPath, entry));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const destExists = await exists(destPath);
|
|
57
|
+
if (destExists && !options?.force) {
|
|
58
|
+
throw new Error(`File exists: ${destPath}. Use --force to overwrite.`);
|
|
59
|
+
}
|
|
60
|
+
if (!options?.dryRun) {
|
|
61
|
+
await ensureDir(dirname(destPath));
|
|
62
|
+
await copyFile(srcPath, destPath);
|
|
63
|
+
}
|
|
64
|
+
copied.push(destPath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
await copyRecursive(src, dest);
|
|
68
|
+
return copied;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=fsx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fsx.js","sourceRoot":"","sources":["../../src/core/fsx.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export interface RecipeFetchRequest {
|
|
2
|
+
token: string;
|
|
3
|
+
device: {
|
|
4
|
+
id: string;
|
|
5
|
+
os: string;
|
|
6
|
+
arch: string;
|
|
7
|
+
version: string;
|
|
8
|
+
};
|
|
9
|
+
feature: string;
|
|
10
|
+
target: string;
|
|
11
|
+
starter: {
|
|
12
|
+
name: string;
|
|
13
|
+
version: string;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export interface RecipeFetchResponse {
|
|
17
|
+
ok: boolean;
|
|
18
|
+
signedUrl?: string;
|
|
19
|
+
zipData?: string;
|
|
20
|
+
expiresIn?: number;
|
|
21
|
+
watermark?: string;
|
|
22
|
+
error?: string;
|
|
23
|
+
message?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function fetchRecipe(request: RecipeFetchRequest): Promise<RecipeFetchResponse>;
|
|
26
|
+
export declare function downloadZip(signedUrlOrBase64: string, isBase64?: boolean): Promise<string>;
|
|
27
|
+
export declare function listRecipes(token: string): Promise<any>;
|
|
28
|
+
export declare function listDevices(token: string): Promise<any>;
|
|
29
|
+
export declare function deactivateDevice(token: string, deviceId: string): Promise<void>;
|
|
30
|
+
//# sourceMappingURL=http.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/core/http.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAID,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA0B3F;AAED,wBAAsB,WAAW,CAAC,iBAAiB,EAAE,MAAM,EAAE,QAAQ,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAyB9F;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAiB7D;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAa7D;AAED,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAarF"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { writeFile, mkdir } from 'fs/promises';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { tmpdir } from 'os';
|
|
4
|
+
import { randomUUID } from 'crypto';
|
|
5
|
+
const WORKER_URL = process.env.VIBEFAST_WORKER_URL || 'https://vibefast-cli-worker.mzafar611.workers.dev';
|
|
6
|
+
export async function fetchRecipe(request) {
|
|
7
|
+
try {
|
|
8
|
+
const response = await fetch(`${WORKER_URL}/api/recipe/fetch`, {
|
|
9
|
+
method: 'POST',
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
},
|
|
13
|
+
body: JSON.stringify(request),
|
|
14
|
+
});
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
const error = await response.json().catch(() => ({ message: response.statusText }));
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
error: error.message || `HTTP ${response.status}`,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
return response.json();
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
return {
|
|
26
|
+
ok: false,
|
|
27
|
+
error: 'Network error',
|
|
28
|
+
message: `Failed to connect to ${WORKER_URL}: ${err.message}`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export async function downloadZip(signedUrlOrBase64, isBase64 = false) {
|
|
33
|
+
let buffer;
|
|
34
|
+
if (isBase64) {
|
|
35
|
+
// Decode base64 data
|
|
36
|
+
buffer = Buffer.from(signedUrlOrBase64, 'base64');
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Download from URL
|
|
40
|
+
const response = await fetch(signedUrlOrBase64);
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error(`Failed to download recipe: ${response.statusText}`);
|
|
43
|
+
}
|
|
44
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
45
|
+
buffer = Buffer.from(arrayBuffer);
|
|
46
|
+
}
|
|
47
|
+
const tempDir = join(tmpdir(), 'vibefast', randomUUID());
|
|
48
|
+
await mkdir(tempDir, { recursive: true });
|
|
49
|
+
const zipPath = join(tempDir, 'recipe.zip');
|
|
50
|
+
await writeFile(zipPath, buffer);
|
|
51
|
+
return zipPath;
|
|
52
|
+
}
|
|
53
|
+
export async function listRecipes(token) {
|
|
54
|
+
try {
|
|
55
|
+
const response = await fetch(`${WORKER_URL}/api/recipes/list`, {
|
|
56
|
+
method: 'GET',
|
|
57
|
+
headers: {
|
|
58
|
+
'Authorization': `Bearer ${token}`,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
if (!response.ok) {
|
|
62
|
+
throw new Error(`Failed to fetch recipes: ${response.statusText}`);
|
|
63
|
+
}
|
|
64
|
+
return response.json();
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
throw new Error(`Failed to connect to ${WORKER_URL}: ${err.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export async function listDevices(token) {
|
|
71
|
+
const response = await fetch(`${WORKER_URL}/api/devices/list`, {
|
|
72
|
+
method: 'GET',
|
|
73
|
+
headers: {
|
|
74
|
+
'Authorization': `Bearer ${token}`,
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
if (!response.ok) {
|
|
78
|
+
throw new Error(`Failed to fetch devices: ${response.statusText}`);
|
|
79
|
+
}
|
|
80
|
+
return response.json();
|
|
81
|
+
}
|
|
82
|
+
export async function deactivateDevice(token, deviceId) {
|
|
83
|
+
const response = await fetch(`${WORKER_URL}/api/devices/deactivate`, {
|
|
84
|
+
method: 'POST',
|
|
85
|
+
headers: {
|
|
86
|
+
'Authorization': `Bearer ${token}`,
|
|
87
|
+
'Content-Type': 'application/json',
|
|
88
|
+
},
|
|
89
|
+
body: JSON.stringify({ deviceId }),
|
|
90
|
+
});
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
throw new Error(`Failed to deactivate device: ${response.statusText}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=http.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/core/http.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface JournalEntry {
|
|
2
|
+
feature: string;
|
|
3
|
+
target: 'native' | 'web';
|
|
4
|
+
files: string[];
|
|
5
|
+
insertedNav: boolean;
|
|
6
|
+
ts: number;
|
|
7
|
+
navHref?: string;
|
|
8
|
+
navLabel?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Journal {
|
|
11
|
+
entries: JournalEntry[];
|
|
12
|
+
}
|
|
13
|
+
export declare function readJournal(journalPath: string): Promise<Journal>;
|
|
14
|
+
export declare function writeJournal(journalPath: string, journal: Journal): Promise<void>;
|
|
15
|
+
export declare function addEntry(journalPath: string, entry: JournalEntry): Promise<void>;
|
|
16
|
+
export declare function removeEntry(journalPath: string, feature: string, target: 'native' | 'web'): Promise<JournalEntry | null>;
|
|
17
|
+
export declare function getEntry(journalPath: string, feature: string, target: 'native' | 'web'): Promise<JournalEntry | null>;
|
|
18
|
+
//# sourceMappingURL=journal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../../src/core/journal.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,QAAQ,GAAG,KAAK,CAAC;IACzB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,OAAO;IACtB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,wBAAsB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMvE;AAED,wBAAsB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAGvF;AAED,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtF;AAED,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,QAAQ,GAAG,KAAK,GACvB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAU9B;AAED,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,QAAQ,GAAG,KAAK,GACvB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAG9B"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFileContent, writeFileContent, exists, ensureDir } from './fsx.js';
|
|
2
|
+
import { dirname } from 'path';
|
|
3
|
+
export async function readJournal(journalPath) {
|
|
4
|
+
if (!(await exists(journalPath))) {
|
|
5
|
+
return { entries: [] };
|
|
6
|
+
}
|
|
7
|
+
const content = await readFileContent(journalPath);
|
|
8
|
+
return JSON.parse(content);
|
|
9
|
+
}
|
|
10
|
+
export async function writeJournal(journalPath, journal) {
|
|
11
|
+
await ensureDir(dirname(journalPath));
|
|
12
|
+
await writeFileContent(journalPath, JSON.stringify(journal, null, 2), { force: true });
|
|
13
|
+
}
|
|
14
|
+
export async function addEntry(journalPath, entry) {
|
|
15
|
+
const journal = await readJournal(journalPath);
|
|
16
|
+
// Remove existing entry for same feature+target
|
|
17
|
+
journal.entries = journal.entries.filter(e => !(e.feature === entry.feature && e.target === entry.target));
|
|
18
|
+
journal.entries.push(entry);
|
|
19
|
+
await writeJournal(journalPath, journal);
|
|
20
|
+
}
|
|
21
|
+
export async function removeEntry(journalPath, feature, target) {
|
|
22
|
+
const journal = await readJournal(journalPath);
|
|
23
|
+
const entry = journal.entries.find(e => e.feature === feature && e.target === target);
|
|
24
|
+
if (!entry)
|
|
25
|
+
return null;
|
|
26
|
+
journal.entries = journal.entries.filter(e => !(e.feature === feature && e.target === target));
|
|
27
|
+
await writeJournal(journalPath, journal);
|
|
28
|
+
return entry;
|
|
29
|
+
}
|
|
30
|
+
export async function getEntry(journalPath, feature, target) {
|
|
31
|
+
const journal = await readJournal(journalPath);
|
|
32
|
+
return journal.entries.find(e => e.feature === feature && e.target === target) || null;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=journal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.js","sourceRoot":"","sources":["../../src/core/journal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAgB/B,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,WAAmB;IACnD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACzB,CAAC;IACD,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,WAAW,CAAC,CAAC;IACnD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,WAAmB,EAAE,OAAgB;IACtE,MAAM,SAAS,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;IACtC,MAAM,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACzF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,WAAmB,EAAE,KAAmB;IACrE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;IAC/C,gDAAgD;IAChD,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC,CACjE,CAAC;IACF,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,WAAmB,EACnB,OAAe,EACf,MAAwB;IAExB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IACtF,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CACtC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CACrD,CAAC;IACF,MAAM,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACzC,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,WAAmB,EACnB,OAAe,EACf,MAAwB;IAExB,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;IAC/C,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC;AACzF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/core/log.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG;mBACC,MAAM;gBACT,MAAM;gBACN,MAAM;iBACL,MAAM;iBACN,MAAM;CACpB,CAAC"}
|
package/dist/core/log.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
export const log = {
|
|
3
|
+
success: (msg) => console.log(pc.green('✓'), msg),
|
|
4
|
+
info: (msg) => console.log(pc.blue('ℹ'), msg),
|
|
5
|
+
warn: (msg) => console.log(pc.yellow('⚠'), msg),
|
|
6
|
+
error: (msg) => console.error(pc.red('✗'), msg),
|
|
7
|
+
plain: (msg) => console.log(msg),
|
|
8
|
+
};
|
|
9
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/core/log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAE5B,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACzD,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACrD,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACvD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC;IACvD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;CACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathGuard.d.ts","sourceRoot":"","sources":["../../src/core/pathGuard.ts"],"names":[],"mappings":"AAMA,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAIvE;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAS5F"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { resolve, sep } from 'path';
|
|
2
|
+
function withTrailingSep(path) {
|
|
3
|
+
return path.endsWith(sep) ? path : `${path}${sep}`;
|
|
4
|
+
}
|
|
5
|
+
export function isSubPath(basePath, targetPath) {
|
|
6
|
+
const base = withTrailingSep(resolve(basePath));
|
|
7
|
+
const target = resolve(targetPath);
|
|
8
|
+
return target === base.slice(0, -1) || target.startsWith(base);
|
|
9
|
+
}
|
|
10
|
+
export function ensureWithinBase(basePath, targetPath, label) {
|
|
11
|
+
const base = resolve(basePath);
|
|
12
|
+
const target = resolve(targetPath);
|
|
13
|
+
if (!isSubPath(base, target)) {
|
|
14
|
+
throw new Error(`${label} must stay within ${base}`);
|
|
15
|
+
}
|
|
16
|
+
return target;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=pathGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pathGuard.js","sourceRoot":"","sources":["../../src/core/pathGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,MAAM,CAAC;AAEpC,SAAS,eAAe,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,EAAE,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,UAAkB;IAC5D,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACnC,OAAO,MAAM,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,UAAkB,EAAE,KAAa;IAClF,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAEnC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,qBAAqB,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface PathsConfig {
|
|
2
|
+
cwd: string;
|
|
3
|
+
signatureFile: string;
|
|
4
|
+
journalFile: string;
|
|
5
|
+
configDir: string;
|
|
6
|
+
nativeNavFile: string;
|
|
7
|
+
webNavFile: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function getPaths(cwd?: string): PathsConfig;
|
|
10
|
+
export declare function getConfigPath(): string;
|
|
11
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,QAAQ,CAAC,GAAG,GAAE,MAAsB,GAAG,WAAW,CASjE;AAED,wBAAgB,aAAa,IAAI,MAAM,CAStC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { join, resolve } from 'path';
|
|
2
|
+
import { homedir } from 'os';
|
|
3
|
+
export function getPaths(cwd = process.cwd()) {
|
|
4
|
+
return {
|
|
5
|
+
cwd,
|
|
6
|
+
signatureFile: join(cwd, '.vibefast', 'starter.json'),
|
|
7
|
+
journalFile: join(cwd, '.vibefast', 'journal.json'),
|
|
8
|
+
configDir: join(homedir(), '.vibefast'),
|
|
9
|
+
nativeNavFile: join(cwd, 'apps', 'native', 'src', 'features', 'vibefast-features.ts'),
|
|
10
|
+
webNavFile: join(cwd, 'apps', 'web', 'app', 'page.tsx'),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
export function getConfigPath() {
|
|
14
|
+
const directPath = process.env.VIBEFAST_CONFIG_PATH;
|
|
15
|
+
if (directPath) {
|
|
16
|
+
return resolve(directPath);
|
|
17
|
+
}
|
|
18
|
+
const customDir = process.env.VIBEFAST_CONFIG_DIR;
|
|
19
|
+
const baseDir = customDir ? resolve(customDir) : join(homedir(), '.vibefast');
|
|
20
|
+
return join(baseDir, 'config.json');
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAW7B,MAAM,UAAU,QAAQ,CAAC,MAAc,OAAO,CAAC,GAAG,EAAE;IAClD,OAAO;QACL,GAAG;QACH,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,cAAc,CAAC;QACrD,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,WAAW,EAAE,cAAc,CAAC;QACnD,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC;QACvC,aAAa,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,sBAAsB,CAAC;QACrF,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IACpD,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7B,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAClD,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface StarterConfig {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
targets: string[];
|
|
5
|
+
}
|
|
6
|
+
export declare function validateSignature(signaturePath: string): Promise<StarterConfig>;
|
|
7
|
+
export declare function validateTarget(target: string, availableTargets: string[]): void;
|
|
8
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAsB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA2BrF;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,EAAE,GAAG,IAAI,CAM/E"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { readFileContent, exists } from './fsx.js';
|
|
2
|
+
export async function validateSignature(signaturePath) {
|
|
3
|
+
if (!(await exists(signaturePath))) {
|
|
4
|
+
throw new Error('Not a VibeFast repo. Missing .vibefast/starter.json. Run this command from your VibeFast monorepo root.');
|
|
5
|
+
}
|
|
6
|
+
const content = await readFileContent(signaturePath);
|
|
7
|
+
let config;
|
|
8
|
+
try {
|
|
9
|
+
config = JSON.parse(content);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new Error('Invalid .vibefast/starter.json: not valid JSON');
|
|
13
|
+
}
|
|
14
|
+
if (config.name !== 'vibefast') {
|
|
15
|
+
throw new Error(`Invalid starter name: expected "vibefast", got "${config.name}"`);
|
|
16
|
+
}
|
|
17
|
+
if (!Array.isArray(config.targets) || config.targets.length === 0) {
|
|
18
|
+
throw new Error('Invalid .vibefast/starter.json: targets must be a non-empty array');
|
|
19
|
+
}
|
|
20
|
+
return config;
|
|
21
|
+
}
|
|
22
|
+
export function validateTarget(target, availableTargets) {
|
|
23
|
+
if (!availableTargets.includes(target)) {
|
|
24
|
+
throw new Error(`Invalid target "${target}". Available: ${availableTargets.join(', ')}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/core/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAQnD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,aAAqB;IAC3D,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,yGAAyG,CAC1G,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,CAAC;IACrD,IAAI,MAAqB,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CACb,mDAAmD,MAAM,CAAC,IAAI,GAAG,CAClE,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClE,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAC;IACvF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,gBAA0B;IACvE,IAAI,CAAC,gBAAgB,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,KAAK,CACb,mBAAmB,MAAM,iBAAiB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACxE,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|