diff --git a/docs/devops/vercel/CODEX_AGENT_PROMPTS.md b/docs/devops/vercel/CODEX_AGENT_PROMPTS.md deleted file mode 100644 index 96981072..00000000 --- a/docs/devops/vercel/CODEX_AGENT_PROMPTS.md +++ /dev/null @@ -1,408 +0,0 @@ -# Codex Agent Prompts — Vercel Deployment Readiness - -> **Purpose:** Ready-to-paste prompts for Codex agents to complete all remaining work items from the Vercel deployment audit. -> **Dependency order:** Run prompts 1→2 first (infra), then 3→4→5 (code fixes) in any order, then 6 (`.npmrc` updates) last. -> **Reference:** See [`ECOSYSTEM_WEB_APPS_INVENTORY.md`](./ECOSYSTEM_WEB_APPS_INVENTORY.md) for full audit context. - ---- - -## Prompt 1: Caddy Gateway — Replace Traefik with Caddy on Azure VM - -> **Runs on:** Azure VM -> **Depends on:** Nothing -> **Blocks:** Prompt 2, Prompt 6 - -``` -You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. - -TASK: Replace the existing Traefik gateway container with Caddy to provide HTTPS termination and path-based routing for all backend services. - -CONTEXT: -- The decision doc is at docs/devops/single_azure_vm/docker/SECURE_API_EXPOSURE.md in the learning_ai_common_plat repo -- The domain is bytelyst.com -- API hostname: api.bytelyst.com -- Currently 13 backend services are healthy on ports 4003, 4005, 4007, 4010-4019 -- Traefik is running but only as a passthrough — no TLS, no path routing hardened -- All backend containers are on a Docker network - -DELIVERABLES: -1. Create a Caddyfile with: - - api.bytelyst.com as the main host (automatic Let's Encrypt TLS) - - Path-based routing to all 13 backends: - /platform/* → platform-service:4003 - /extraction/* → extraction-service:4005 - /mcp/* → mcp-server:4007 - /peakpulse/* → peakpulse:4010 - /chronomind/* → chronomind:4011 - /jarvisjr/* → jarvisjr:4012 - /nomgap/* → nomgap:4013 - /mindlyst/* → mindlyst:4014 - /lysnrai/* → lysnrai:4015 - /notelett/* → notelett:4016 - /flowmonk/* → flowmonk:4017 - /actiontrail/* → actiontrail:4018 - /localmemgpt/* → localmemgpt:4019 - - Strip the path prefix before forwarding (backends expect / not /platform/) -2. Add a caddy service to docker-compose replacing or alongside the gateway service -3. Stop publishing backend ports (4003, 4005, 4007, 4010-4019) publicly — only expose 80/443 -4. Verify all 13 backends respond via https://api.bytelyst.com//health -5. Update docs/devops/single_azure_vm/docker/README.md with the new access model - -DO NOT: -- Delete the existing Traefik config — just stop using it -- Expose any backend port publicly -- Hardcode IP addresses in the Caddyfile - -COMMIT: Use conventional commits: feat(gateway): replace Traefik with Caddy for HTTPS path routing -``` - ---- - -## Prompt 2: Gitea HTTPS Exposure via Caddy - -> **Runs on:** Azure VM -> **Depends on:** Prompt 1 (Caddy must be running) -> **Blocks:** Prompt 6 - -``` -You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. - -TASK: Expose the Gitea npm registry over HTTPS via the Caddy gateway so that external build systems (Vercel) can install @bytelyst/* packages. - -CONTEXT: -- Gitea is running on port 3300 inside the Docker network -- Caddy is already configured for api.bytelyst.com (from the previous task) -- The Gitea npm registry URL pattern is: /api/packages/ByteLyst/npm/ -- Gitea needs its own subdomain because its internal routing expects to be at root -- Target URL: https://gitea.bytelyst.com - -DELIVERABLES: -1. Add a gitea.bytelyst.com block to the Caddyfile: - gitea.bytelyst.com { - reverse_proxy gitea:3300 - } -2. Ensure Gitea's ROOT_URL / SERVER__ROOT_URL is updated to https://gitea.bytelyst.com -3. Verify https://gitea.bytelyst.com loads the Gitea web UI -4. Verify npm registry is accessible: - curl -s https://gitea.bytelyst.com/api/packages/ByteLyst/npm/@bytelyst%2ferrors | head -5. Remove port 3300 from public NSG rules (Gitea only accessible via Caddy now) -6. Lock down other operational ports from public access where possible: - - 8025 (Mailpit) - - 8080 (Traefik dashboard — no longer needed) - - 10000 (Azurite) - -DO NOT: -- Break existing Docker-internal Gitea access (other containers still use gitea:3300) -- Remove the Gitea container or change its internal port - -COMMIT: feat(gateway): expose Gitea npm registry via HTTPS at gitea.bytelyst.com -``` - ---- - -## Prompt 3: Fix `file:` References Across 7 Repos - -> **Runs on:** Any agent with repo access (can be local or cloud) -> **Depends on:** Nothing (packages are already published to Gitea) -> **Blocks:** Nothing directly - -``` -TASK: Convert all file: references to @bytelyst/* packages into semver ^0.1.0 references across 7 web app repos. - -CONTEXT: -- 7 repos have web/package.json files that use file: references to ../../learning_ai_common_plat/packages/* -- These fail on Vercel because the sibling repo doesn't exist -- The packages are already published to the Gitea npm registry -- Each fix is: change "file:../../learning_ai_common_plat/packages/X" to "^0.1.0" -- After changing, run pnpm install to update the lockfile, then verify pnpm build passes - -REPOS AND FILES TO FIX: - -1. learning_ai_clock/web/package.json - - "@bytelyst/design-tokens": "file:..." → "^0.1.0" - - "@bytelyst/ui": "file:..." → "^0.1.0" - -2. learning_ai_jarvis_jr/web/package.json - - "@bytelyst/ui": "file:..." → "^0.1.0" - -3. learning_ai_fastgap/web/package.json - - "@bytelyst/ui": "file:..." → "^0.1.0" - -4. learning_ai_flowmonk/web/package.json - - "@bytelyst/ui": "file:..." → "^0.1.0" - -5. learning_ai_notes/web/package.json - - "@bytelyst/ui": "file:..." → "^0.1.0" - -6. learning_ai_local_memory_gpt/web/package.json - - "@bytelyst/ui": "file:..." → "^0.1.0" - -7. learning_ai_local_llms/dashboard/package.json - - "@bytelyst/design-tokens": "file:..." → "^0.1.0" - - "@bytelyst/ui": "file:..." → "^0.1.0" - -FOR EACH REPO: -1. Edit the package.json — replace file: refs with ^0.1.0 -2. Run: cd web && pnpm install (or cd dashboard for LLM Lab) -3. Run: pnpm build -4. If build passes, commit: fix(web): convert file: refs to registry semver for Vercel compatibility -5. Push to origin main - -DO NOT: -- Change any other dependencies -- Modify any source code -- Skip the build verification step -``` - ---- - -## Prompt 4: Fix Hardcoded `output: standalone` in 4 Repos - -> **Runs on:** Any agent with repo access -> **Depends on:** Nothing -> **Blocks:** Nothing directly - -``` -TASK: Make the Next.js output mode Vercel-aware in 4 repos that currently hardcode output: 'standalone'. - -CONTEXT: -- Vercel manages its own output mode — hardcoded standalone breaks Vercel builds -- The fix is: wrap standalone output in a process.env.VERCEL conditional -- Docker builds (which don't set VERCEL env var) will still get standalone mode -- 4 repos need this fix - -REPOS AND FILES: - -1. learning_ai_fastgap/web/next.config.ts - Change: - output: "standalone", - outputFileTracingRoot: path.join(process.cwd(), ".."), - To: - ...(process.env.VERCEL ? {} : { - output: "standalone", - outputFileTracingRoot: path.join(process.cwd(), ".."), - }), - -2. learning_ai_notes/web/next.config.ts - Same pattern as above. - -3. learning_ai_trails/web/next.config.ts - Change: - output: 'standalone', - To: - ...(process.env.VERCEL ? {} : { output: 'standalone' }), - -4. learning_ai_local_memory_gpt/web/next.config.ts - Same pattern as #3. - -NOTE: learning_ai_local_llms/dashboard/next.config.ts also has this but LLM Lab is NOT viable on Vercel (needs local Ollama), so skip it. - -FOR EACH REPO: -1. Edit next.config.ts with the conditional -2. Verify Docker build still works: pnpm build (standalone should still activate without VERCEL env) -3. Verify VERCEL=1 pnpm build also works (output should be default, not standalone) -4. Commit: fix(web): make output mode Vercel-aware — conditional standalone -5. Push to origin main - -DO NOT: -- Change any other config options in next.config.ts -- Remove the standalone output entirely — Docker builds still need it -- Touch the LLM Lab dashboard (not viable on Vercel) -``` - ---- - -## Prompt 5: Create vercel.json for EffoRise (Vite SPA) - -> **Runs on:** Any agent with repo access to learning_ai_efforise -> **Depends on:** Nothing -> **Blocks:** Nothing - -``` -TASK: Create a vercel.json file for the EffoRise Vite SPA to handle client-side routing and API proxy configuration. - -CONTEXT: -- EffoRise is a Vite + React 19 SPA (not Next.js) in the learning_ai_efforise repo -- The Vite config is at the repo root (vite.config.ts) -- Build output goes to dist/public/ (custom, not default dist/) -- Uses wouter for client-side routing — all routes must serve index.html -- The backend API is at https://api.bytelyst.com/efforise -- Currently uses a dev proxy /api → localhost:4020 - -DELIVERABLES: -1. Create vercel.json at the repo root with: - { - "$schema": "https://openapi.vercel.sh/vercel.json", - "framework": "vite", - "buildCommand": "pnpm build", - "outputDirectory": "dist/public", - "rewrites": [ - { "source": "/api/(.*)", "destination": "https://api.bytelyst.com/efforise/$1" }, - { "source": "/(.*)", "destination": "/index.html" } - ] - } - -2. Verify pnpm build still works locally -3. Commit: feat(web): add vercel.json for Vite SPA deployment -4. Push to origin main - -DO NOT: -- Modify vite.config.ts -- Change any source code -- Add Vercel-specific code to the application -``` - ---- - -## Prompt 6: Update .npmrc Across All Product Repos - -> **Runs on:** Any agent with repo access -> **Depends on:** Prompt 2 (gitea.bytelyst.com must be live and accessible) -> **Blocks:** Vercel deployment - -``` -TASK: Update .npmrc files in all product repos to point to the public Gitea npm registry at gitea.bytelyst.com. - -CONTEXT: -- All product repos currently have .npmrc pointing to http://localhost:3300 (local Gitea) -- Gitea is now accessible at https://gitea.bytelyst.com via Caddy reverse proxy -- The npm registry URL is: https://gitea.bytelyst.com/api/packages/ByteLyst/npm/ -- Auth token is passed via GITEA_NPM_TOKEN env var -- This change enables Vercel builds to install @bytelyst/* packages - -NEW .npmrc CONTENT (same for all repos): -@bytelyst:registry=https://gitea.bytelyst.com/api/packages/ByteLyst/npm/ -//gitea.bytelyst.com/api/packages/ByteLyst/npm/:_authToken=${GITEA_NPM_TOKEN} - -REPOS TO UPDATE (12 total): - -1. learning_voice_ai_agent (user-dashboard-web, backend) -2. learning_ai_clock (web, backend) -3. learning_ai_jarvis_jr (web, backend) -4. learning_ai_fastgap (web, backend) -5. learning_ai_flowmonk (web, backend, mobile) -6. learning_ai_notes (web, backend, mobile) -7. learning_ai_trails (web, backend, sdk) -8. learning_multimodal_memory_agents (mindlyst-native/web, backend) -9. learning_ai_local_memory_gpt (web, backend) -10. learning_ai_efforise (root, backend, mobile) -11. learning_ai_local_llms (dashboard) -12. learning_ai_peakpulse (backend) - -FOR EACH REPO: -1. Find all .npmrc files (there may be multiple — root, web/, backend/, mobile/) -2. Update the @bytelyst registry line to use gitea.bytelyst.com -3. Add the auth token line if not present -4. Run: GITEA_NPM_TOKEN= pnpm install (verify packages resolve) -5. Commit: chore: update .npmrc to public Gitea registry at gitea.bytelyst.com -6. Push to origin main - -VERIFICATION: -After updating all repos, verify one end-to-end: - cd learning_ai_clock/web - GITEA_NPM_TOKEN= pnpm install - pnpm build - -DO NOT: -- Change any package versions -- Remove any other registry configurations (e.g., npmjs.org for non-@bytelyst packages) -- Hardcode the auth token — always use ${GITEA_NPM_TOKEN} -``` - ---- - -## Prompt 7: Complete admin-web and tracker-web on Azure VM - -> **Runs on:** Azure VM -> **Depends on:** Prompt 1 (Caddy gateway) -> **Blocks:** Nothing (independent of Vercel work) - -``` -You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. - -TASK: Resolve the remaining admin-web and tracker-web containers so they are running and healthy. - -CONTEXT: -- Per DEPLOYMENT_STATUS_2026-03-29.md, all 13 backend services are healthy -- admin-web and tracker-web are the two remaining unresolved containers -- Both are Next.js 16 apps from the learning_ai_common_plat repo under dashboards/ -- Both use workspace:* dependencies resolved by pnpm -- Both use the --webpack build flag -- admin-web runs on port 3001, tracker-web on port 3003 -- The Docker build context is dashboards/admin-web/ and dashboards/tracker-web/ - -DELIVERABLES: -1. Diagnose why admin-web and tracker-web builds failed -2. Fix the build issues (likely @bytelyst/* package resolution or standalone entrypoint) -3. Rebuild and start both containers -4. Verify health: - curl -s http://127.0.0.1:3001 | head - curl -s http://127.0.0.1:3003 | head -5. Add Caddy routes for the dashboards: - - https://admin.bytelyst.com → admin-web:3001 - - https://tracker.bytelyst.com → tracker-web:3003 -6. Update DEPLOYMENT_STATUS_2026-03-29.md to reflect the fix -7. Mark Phase 7 as DONE if all services are now healthy - -COMMIT: fix(deployment): resolve admin-web and tracker-web containers -``` - ---- - -## Prompt 8: NSG Lockdown — Reduce Public Port Exposure - -> **Runs on:** Azure VM (or Azure CLI from anywhere) -> **Depends on:** Prompts 1 + 2 (Caddy handling all traffic) -> **Blocks:** Nothing - -``` -TASK: Reduce the Azure NSG (Network Security Group) rules so only ports 80, 443, and 22 are publicly accessible. - -CONTEXT: -- The Azure VM currently exposes many service ports publicly (3000-3300, 4003-4019, 8025, 8080, 10000, 11434) -- Caddy now handles all public HTTPS traffic on 80/443 -- Backend services, Gitea, Grafana, Mailpit, and Azurite are all accessed through Caddy -- Only SSH (22) and HTTP/HTTPS (80/443) should remain publicly open -- This follows the recommendation in SECURE_API_EXPOSURE.md - -DELIVERABLES: -1. List current NSG rules: az network nsg rule list --resource-group --nsg-name -o table -2. Remove or deny inbound rules for all ports except 22, 80, 443 -3. Verify Caddy still serves all routes correctly -4. Verify SSH access still works -5. Document the changes in DEPLOYMENT_STATUS_2026-03-29.md - -DO NOT: -- Remove the SSH (22) rule -- Remove the HTTP (80) or HTTPS (443) rules -- Make changes without first listing the current rules - -COMMIT: chore(security): lock down Azure NSG to 22/80/443 only -``` - ---- - -## Execution Order - -``` -Phase 1 — Infrastructure (Azure VM agent) - ├── Prompt 1: Caddy Gateway Setup - ├── Prompt 2: Gitea HTTPS Exposure (after Prompt 1) - └── Prompt 7: Fix admin-web + tracker-web (after Prompt 1) - -Phase 2 — Code Fixes (any agent with repo access, all independent) - ├── Prompt 3: Fix file: refs (7 repos) - ├── Prompt 4: Fix output: standalone (4 repos) - └── Prompt 5: EffoRise vercel.json - -Phase 3 — Registry Migration (after Prompt 2 is verified) - └── Prompt 6: Update .npmrc (12 repos) - -Phase 4 — Security Hardening (after all Caddy routes confirmed) - └── Prompt 8: NSG Lockdown - -After all prompts complete: - → Vercel project creation (manual — Vercel UI) - → Set GITEA_NPM_TOKEN + other env vars per project (manual — Vercel UI) - → Trigger first deploys and verify -``` diff --git a/docs/devops/vercel/CODEX_PROMPTS_TRACK_A_AZURE_VM.md b/docs/devops/vercel/CODEX_PROMPTS_TRACK_A_AZURE_VM.md new file mode 100644 index 00000000..c815e9f0 --- /dev/null +++ b/docs/devops/vercel/CODEX_PROMPTS_TRACK_A_AZURE_VM.md @@ -0,0 +1,177 @@ +# Track A: Azure VM — Gateway, Dashboards & Security + +> **Agent:** Codex on Azure VM (`/opt/bytelyst/`) +> **Prompts:** 4 (run in order) +> **Dependency:** None — this track runs first, unblocks Track B Prompt 4 + +--- + +## A1: Caddy Gateway — Replace Traefik with Caddy + +> **Depends on:** Nothing +> **Blocks:** A2, A3, A4 + +``` +You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. + +TASK: Replace the existing Traefik gateway container with Caddy to provide HTTPS termination and path-based routing for all backend services. + +CONTEXT: +- The decision doc is at docs/devops/single_azure_vm/docker/SECURE_API_EXPOSURE.md in the learning_ai_common_plat repo +- The domain is bytelyst.com +- API hostname: api.bytelyst.com +- Currently 13 backend services are healthy on ports 4003, 4005, 4007, 4010-4019 +- Traefik is running but only as a passthrough — no TLS, no path routing hardened +- All backend containers are on a Docker network + +DELIVERABLES: +1. Create a Caddyfile with: + - api.bytelyst.com as the main host (automatic Let's Encrypt TLS) + - Path-based routing to all 13 backends: + /platform/* → platform-service:4003 + /extraction/* → extraction-service:4005 + /mcp/* → mcp-server:4007 + /peakpulse/* → peakpulse:4010 + /chronomind/* → chronomind:4011 + /jarvisjr/* → jarvisjr:4012 + /nomgap/* → nomgap:4013 + /mindlyst/* → mindlyst:4014 + /lysnrai/* → lysnrai:4015 + /notelett/* → notelett:4016 + /flowmonk/* → flowmonk:4017 + /actiontrail/* → actiontrail:4018 + /localmemgpt/* → localmemgpt:4019 + - Strip the path prefix before forwarding (backends expect / not /platform/) +2. Add a caddy service to docker-compose replacing or alongside the gateway service +3. Stop publishing backend ports (4003, 4005, 4007, 4010-4019) publicly — only expose 80/443 +4. Verify all 13 backends respond via https://api.bytelyst.com//health +5. Update docs/devops/single_azure_vm/docker/README.md with the new access model + +DO NOT: +- Delete the existing Traefik config — just stop using it +- Expose any backend port publicly +- Hardcode IP addresses in the Caddyfile + +COMMIT: feat(gateway): replace Traefik with Caddy for HTTPS path routing +``` + +--- + +## A2: Gitea HTTPS Exposure via Caddy + +> **Depends on:** A1 (Caddy must be running) +> **Blocks:** Track B Prompt B4 + +``` +You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. + +TASK: Expose the Gitea npm registry over HTTPS via the Caddy gateway so that external build systems (Vercel) can install @bytelyst/* packages. + +CONTEXT: +- Gitea is running on port 3300 inside the Docker network +- Caddy is already configured for api.bytelyst.com (from A1) +- The Gitea npm registry URL pattern is: /api/packages/ByteLyst/npm/ +- Gitea needs its own subdomain because its internal routing expects to be at root +- Target URL: https://gitea.bytelyst.com + +DELIVERABLES: +1. Add a gitea.bytelyst.com block to the Caddyfile: + gitea.bytelyst.com { + reverse_proxy gitea:3300 + } +2. Ensure Gitea's ROOT_URL / SERVER__ROOT_URL is updated to https://gitea.bytelyst.com +3. Verify https://gitea.bytelyst.com loads the Gitea web UI +4. Verify npm registry is accessible: + curl -s https://gitea.bytelyst.com/api/packages/ByteLyst/npm/@bytelyst%2ferrors | head +5. Remove port 3300 from public NSG rules (Gitea only accessible via Caddy now) +6. Lock down other operational ports from public access where possible: + - 8025 (Mailpit) + - 8080 (Traefik dashboard — no longer needed) + - 10000 (Azurite) + +DO NOT: +- Break existing Docker-internal Gitea access (other containers still use gitea:3300) +- Remove the Gitea container or change its internal port + +COMMIT: feat(gateway): expose Gitea npm registry via HTTPS at gitea.bytelyst.com +``` + +--- + +## A3: Fix admin-web and tracker-web Containers + +> **Depends on:** A1 (Caddy gateway for subdomain routing) +> **Blocks:** Nothing + +``` +You are working on the ByteLyst single-Azure-VM Docker deployment at /opt/bytelyst/. + +TASK: Resolve the remaining admin-web and tracker-web containers so they are running and healthy. + +CONTEXT: +- Per DEPLOYMENT_STATUS_2026-03-29.md, all 13 backend services are healthy +- admin-web and tracker-web are the two remaining unresolved containers +- Both are Next.js 16 apps from the learning_ai_common_plat repo under dashboards/ +- Both use workspace:* dependencies resolved by pnpm +- Both use the --webpack build flag +- admin-web runs on port 3001, tracker-web on port 3003 +- The Docker build context is dashboards/admin-web/ and dashboards/tracker-web/ + +DELIVERABLES: +1. Diagnose why admin-web and tracker-web builds failed +2. Fix the build issues (likely @bytelyst/* package resolution or standalone entrypoint) +3. Rebuild and start both containers +4. Verify health: + curl -s http://127.0.0.1:3001 | head + curl -s http://127.0.0.1:3003 | head +5. Add Caddy routes for the dashboards: + - https://admin.bytelyst.com → admin-web:3001 + - https://tracker.bytelyst.com → tracker-web:3003 +6. Update DEPLOYMENT_STATUS_2026-03-29.md to reflect the fix +7. Mark Phase 7 as DONE if all services are now healthy + +COMMIT: fix(deployment): resolve admin-web and tracker-web containers +``` + +--- + +## A4: NSG Lockdown — Reduce Public Port Exposure + +> **Depends on:** A1 + A2 (Caddy handling all traffic) +> **Blocks:** Nothing + +``` +TASK: Reduce the Azure NSG (Network Security Group) rules so only ports 80, 443, and 22 are publicly accessible. + +CONTEXT: +- The Azure VM currently exposes many service ports publicly (3000-3300, 4003-4019, 8025, 8080, 10000, 11434) +- Caddy now handles all public HTTPS traffic on 80/443 +- Backend services, Gitea, Grafana, Mailpit, and Azurite are all accessed through Caddy +- Only SSH (22) and HTTP/HTTPS (80/443) should remain publicly open +- This follows the recommendation in SECURE_API_EXPOSURE.md + +DELIVERABLES: +1. List current NSG rules: az network nsg rule list --resource-group --nsg-name -o table +2. Remove or deny inbound rules for all ports except 22, 80, 443 +3. Verify Caddy still serves all routes correctly +4. Verify SSH access still works +5. Document the changes in DEPLOYMENT_STATUS_2026-03-29.md + +DO NOT: +- Remove the SSH (22) rule +- Remove the HTTP (80) or HTTPS (443) rules +- Make changes without first listing the current rules + +COMMIT: chore(security): lock down Azure NSG to 22/80/443 only +``` + +--- + +## Track A Execution Order + +``` +A1: Caddy Gateway ──→ A2: Gitea HTTPS ──→ A4: NSG Lockdown + └──→ A3: Dashboards Fix +``` + +A3 can run in parallel with A2. A4 runs last after everything is routed through Caddy. diff --git a/docs/devops/vercel/CODEX_PROMPTS_TRACK_B_VERCEL_CODE.md b/docs/devops/vercel/CODEX_PROMPTS_TRACK_B_VERCEL_CODE.md new file mode 100644 index 00000000..8081bc54 --- /dev/null +++ b/docs/devops/vercel/CODEX_PROMPTS_TRACK_B_VERCEL_CODE.md @@ -0,0 +1,237 @@ +# Track B: Vercel Code Readiness — Fix Repos for Deployment + +> **Agent:** Any Codex agent with repo access (local or cloud) +> **Prompts:** 4 (B1–B3 run in parallel, B4 runs last after Track A completes A2) + +--- + +## B1: Fix `file:` References Across 7 Repos + +> **Depends on:** Nothing (packages are already published to Gitea) +> **Blocks:** Nothing + +``` +TASK: Convert all file: references to @bytelyst/* packages into semver ^0.1.0 references across 7 web app repos. + +CONTEXT: +- 7 repos have web/package.json files that use file: references to ../../learning_ai_common_plat/packages/* +- These fail on Vercel because the sibling repo doesn't exist +- The packages are already published to the Gitea npm registry +- Each fix is: change "file:../../learning_ai_common_plat/packages/X" to "^0.1.0" +- After changing, run pnpm install to update the lockfile, then verify pnpm build passes + +REPOS AND FILES TO FIX: + +1. learning_ai_clock/web/package.json + - "@bytelyst/design-tokens": "file:..." → "^0.1.0" + - "@bytelyst/ui": "file:..." → "^0.1.0" + +2. learning_ai_jarvis_jr/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +3. learning_ai_fastgap/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +4. learning_ai_flowmonk/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +5. learning_ai_notes/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +6. learning_ai_local_memory_gpt/web/package.json + - "@bytelyst/ui": "file:..." → "^0.1.0" + +7. learning_ai_local_llms/dashboard/package.json + - "@bytelyst/design-tokens": "file:..." → "^0.1.0" + - "@bytelyst/ui": "file:..." → "^0.1.0" + +FOR EACH REPO: +1. Edit the package.json — replace file: refs with ^0.1.0 +2. Run: cd web && pnpm install (or cd dashboard for LLM Lab) +3. Run: pnpm build +4. If build passes, commit: fix(web): convert file: refs to registry semver for Vercel compatibility +5. Push to origin main + +DO NOT: +- Change any other dependencies +- Modify any source code +- Skip the build verification step +``` + +--- + +## B2: Fix Hardcoded `output: standalone` in 4 Repos + +> **Depends on:** Nothing +> **Blocks:** Nothing + +``` +TASK: Make the Next.js output mode Vercel-aware in 4 repos that currently hardcode output: 'standalone'. + +CONTEXT: +- Vercel manages its own output mode — hardcoded standalone breaks Vercel builds +- The fix is: wrap standalone output in a process.env.VERCEL conditional +- Docker builds (which don't set VERCEL env var) will still get standalone mode +- 4 repos need this fix + +REPOS AND FILES: + +1. learning_ai_fastgap/web/next.config.ts + Change: + output: "standalone", + outputFileTracingRoot: path.join(process.cwd(), ".."), + To: + ...(process.env.VERCEL ? {} : { + output: "standalone", + outputFileTracingRoot: path.join(process.cwd(), ".."), + }), + +2. learning_ai_notes/web/next.config.ts + Same pattern as above. + +3. learning_ai_trails/web/next.config.ts + Change: + output: 'standalone', + To: + ...(process.env.VERCEL ? {} : { output: 'standalone' }), + +4. learning_ai_local_memory_gpt/web/next.config.ts + Same pattern as #3. + +NOTE: learning_ai_local_llms/dashboard/next.config.ts also has this but LLM Lab is NOT viable on Vercel (needs local Ollama), so skip it. + +FOR EACH REPO: +1. Edit next.config.ts with the conditional +2. Verify Docker build still works: pnpm build (standalone should still activate without VERCEL env) +3. Verify VERCEL=1 pnpm build also works (output should be default, not standalone) +4. Commit: fix(web): make output mode Vercel-aware — conditional standalone +5. Push to origin main + +DO NOT: +- Change any other config options in next.config.ts +- Remove the standalone output entirely — Docker builds still need it +- Touch the LLM Lab dashboard (not viable on Vercel) +``` + +--- + +## B3: Create vercel.json for EffoRise (Vite SPA) + +> **Depends on:** Nothing +> **Blocks:** Nothing + +``` +TASK: Create a vercel.json file for the EffoRise Vite SPA to handle client-side routing and API proxy configuration. + +CONTEXT: +- EffoRise is a Vite + React 19 SPA (not Next.js) in the learning_ai_efforise repo +- The Vite config is at the repo root (vite.config.ts) +- Build output goes to dist/public/ (custom, not default dist/) +- Uses wouter for client-side routing — all routes must serve index.html +- The backend API is at https://api.bytelyst.com/efforise +- Currently uses a dev proxy /api → localhost:4020 + +DELIVERABLES: +1. Create vercel.json at the repo root with: + { + "$schema": "https://openapi.vercel.sh/vercel.json", + "framework": "vite", + "buildCommand": "pnpm build", + "outputDirectory": "dist/public", + "rewrites": [ + { "source": "/api/(.*)", "destination": "https://api.bytelyst.com/efforise/$1" }, + { "source": "/(.*)", "destination": "/index.html" } + ] + } + +2. Verify pnpm build still works locally +3. Commit: feat(web): add vercel.json for Vite SPA deployment +4. Push to origin main + +DO NOT: +- Modify vite.config.ts +- Change any source code +- Add Vercel-specific code to the application +``` + +--- + +## B4: Update .npmrc Across All Product Repos + +> **Depends on:** Track A Prompt A2 (gitea.bytelyst.com must be live and accessible) +> **Blocks:** Vercel deployment + +``` +TASK: Update .npmrc files in all product repos to point to the public Gitea npm registry at gitea.bytelyst.com. + +CONTEXT: +- All product repos currently have .npmrc pointing to http://localhost:3300 (local Gitea) +- Gitea is now accessible at https://gitea.bytelyst.com via Caddy reverse proxy +- The npm registry URL is: https://gitea.bytelyst.com/api/packages/ByteLyst/npm/ +- Auth token is passed via GITEA_NPM_TOKEN env var +- This change enables Vercel builds to install @bytelyst/* packages + +NEW .npmrc CONTENT (same for all repos): +@bytelyst:registry=https://gitea.bytelyst.com/api/packages/ByteLyst/npm/ +//gitea.bytelyst.com/api/packages/ByteLyst/npm/:_authToken=${GITEA_NPM_TOKEN} + +REPOS TO UPDATE (12 total): + +1. learning_voice_ai_agent (user-dashboard-web, backend) +2. learning_ai_clock (web, backend) +3. learning_ai_jarvis_jr (web, backend) +4. learning_ai_fastgap (web, backend) +5. learning_ai_flowmonk (web, backend, mobile) +6. learning_ai_notes (web, backend, mobile) +7. learning_ai_trails (web, backend, sdk) +8. learning_multimodal_memory_agents (mindlyst-native/web, backend) +9. learning_ai_local_memory_gpt (web, backend) +10. learning_ai_efforise (root, backend, mobile) +11. learning_ai_local_llms (dashboard) +12. learning_ai_peakpulse (backend) + +FOR EACH REPO: +1. Find all .npmrc files (there may be multiple — root, web/, backend/, mobile/) +2. Update the @bytelyst registry line to use gitea.bytelyst.com +3. Add the auth token line if not present +4. Run: GITEA_NPM_TOKEN= pnpm install (verify packages resolve) +5. Commit: chore: update .npmrc to public Gitea registry at gitea.bytelyst.com +6. Push to origin main + +VERIFICATION: +After updating all repos, verify one end-to-end: + cd learning_ai_clock/web + GITEA_NPM_TOKEN= pnpm install + pnpm build + +DO NOT: +- Change any package versions +- Remove any other registry configurations (e.g., npmjs.org for non-@bytelyst packages) +- Hardcode the auth token — always use ${GITEA_NPM_TOKEN} +``` + +--- + +## Track B Execution Order + +``` +B1: Fix file: refs ──────┐ +B2: Fix standalone ──────┼──→ B4: Update .npmrc (waits for Track A → A2) +B3: EffoRise vercel.json ┘ +``` + +B1, B2, B3 can all run in parallel immediately. B4 must wait until `gitea.bytelyst.com` is live (Track A, Prompt A2). + +--- + +## After Both Tracks Complete + +``` +Manual steps (Vercel UI): + → Create Vercel projects for each app + → Set GITEA_NPM_TOKEN + other env vars per project + → Trigger first deploys and verify +``` + +See [`ECOSYSTEM_WEB_APPS_INVENTORY.md`](./ECOSYSTEM_WEB_APPS_INVENTORY.md) for the full app list and per-app environment variables. +See individual `ROADMAP_*.md` files for per-app Vercel project setup details.