Don't code? No problem! The easy install guide is available at bao.builders
____ ____ _ _ _ ____ _ _
| __ ) __ _ ___ | __ ) _ _(_) | __| | __ ) _ _ __| | __| |_ _
| _ \ / _` |/ _ \| _ \| | | | | |/ _` | _ \| | | |/ _` |/ _` | | | |
| |_) | (_| | (_) | |_) | |_| | | | (_| | |_) | |_| | (_| | (_| | |_| |
|____/ \__,_|\___/|____/ \__,_|_|_|\__,_|____/ \__,_|\__,_|\__,_|\__, |
|___/
Local Operations Manual
BaoBuildBuddy is a full-stack toolkit for game-industry job seekers. It aggregates job listings, helps you build resumes and cover letters, runs AI-powered mock interviews, automates job applications with browser RPA, and tracks your progress with a gamification system.
/------------------------------\
| BAO WORLD |
| Press START to begin! |
|------------------------------|
| 1) Prepare environment |
| 2) Configure services |
| 3) Start server and client |
| 4) Verify contracts |
| 5) Run your automation |
\------------------------------/
Not sure where to start? Choose the guide that matches your goal:
| I want to... | Go here |
|---|---|
| Understand the app in plain English | ELI5 System Walkthrough |
| Get BaoBuildBuddy running for the first time | First-Time Setup Guide |
| Set up local AI with Ollama | Local AI Setup Guide |
| Learn the automation and RPA flows | Automation Guide |
| Deploy to Railway | Railway Deployment Guide |
| Install a desktop app (no dev setup) | Non-Technical Install |
| Read the full technical reference | Keep reading this file |
| Resolve conflicting “audit” stack claims | Stack contract (Drizzle + Nuxt, not Prisma + htmx) |
- Nuxt is the screen you click on.
- Elysia is the traffic controller.
- SQLite is the notebook that remembers things.
- Playwright is the robot browser.
- Bun is the runtime, package manager, bundler, and test runner.
- Tauri is the desktop wrapper.
- Pick Your Guide
- Quick Start
- Local AI Quick Path
- Non-Technical Install
- Architecture
- Configuration
- Running the App
- Automation & RPA
- Job Provider Registry
- AI Integration
- Additional Services
- Internationalization
- Database Schema
- Project Structure
- Client Pages & Features
- Validation & Quality Gates
- Desktop Packaging (Tauri)
- Troubleshooting
- Final Checklist
- Documentation Index
| Required | Purpose |
|---|---|
| Bun (>=1.3.10) | Runtime, package manager, test runner |
| Git | Source control |
Optional: Rust + Cargo (for desktop builds), curl/jq (for diagnostics), at least one AI provider key.
Check your Bun version against the workspace manifest:
bun pm pkg get packageManager
# -> "bun@1.3.10"macOS / Linux:
git clone https://github.com/d4551/baobuildbuddy.git
cd baobuildbuddy
bash scripts/setup.shWindows (PowerShell):
git clone https://github.com/d4551/baobuildbuddy.git
cd baobuildbuddy
powershell -ExecutionPolicy Bypass -File scripts\setup.ps1The setup script installs dependencies, sets up Playwright Chromium, creates .env from .env.example, bootstraps the database, and runs validation checks.
| Flag | Bash | PowerShell | Effect |
|---|---|---|---|
| Skip verification | --skip-checks |
-SkipChecks |
Skip typecheck, lint, and test runs |
| Skip browser install | --skip-browser-install |
-SkipBrowserInstall |
Skip Playwright Chromium installation |
| Include build | --include-build |
-IncludeBuild |
Run bun run build after setup |
| Include desktop build | --include-desktop-build |
-IncludeDesktopBuild |
Run Tauri desktop build after setup |
| Help | --help |
-Help |
Print usage and exit |
git clone https://github.com/d4551/baobuildbuddy.git
cd baobuildbuddy
bun install
bun run automation:browsers:install
cp .env.example .env # Windows: copy .env.example .env
bun run db:generate
bun run db:pushbun run devThis starts the API server (port 3000) and Nuxt client (port 3001) together via scripts/dev-stack.ts.
Verify everything is working:
curl -fsS http://localhost:3000/api/health
curl -fsS http://localhost:3000/api/auth/status
curl -fsS http://localhost:3000/api/jobs?limit=1 | headThen open http://localhost:3001 in your browser.
Want BaoBuildBuddy to use AI on your own computer without cloud API keys?
- Install Ollama from ollama.com/download.
- Read the official Ollama Quickstart if you want the vendor walkthrough.
- Download a first model:
ollama pull llama3.2 - Open BaoBuildBuddy and go to Settings > AI Providers.
- Set the local endpoint to
http://localhost:11434/v1and leave the model blank for auto-detect.
For the full beginner walkthrough, see docs/LOCAL_AI_SETUP.md.
Use the packaged desktop installers in packages/desktop/releases when you want to skip the developer setup entirely.
A wild installer appeared. Choose your OS in
packages/desktop/releases.
| Operating System | Artifact Pattern |
|---|---|
| macOS (Apple Silicon) | <PRODUCT_NAME>_<VERSION>_aarch64.dmg |
| Windows (x64) | <PRODUCT_NAME>_<VERSION>_x64-setup.exe or <PRODUCT_NAME>_<VERSION>_x64-portable.zip |
| Linux (ARM64) | <PRODUCT_NAME>_<VERSION>_arm64.deb or <PRODUCT_NAME>-<VERSION>-1.aarch64.rpm |
Windows builds are 64-bit only. See packages/desktop/releases/README.md for the current artifact catalog.
_____
| |
| GLa | "The cake is a lie."
| D | But the architecture diagram is real.
| 0S |
|_____|
Browser ──> Nuxt SSR ──> Elysia API ──> SQLite
| | |
|── WebSocket ──> /ws/chat |── AI providers (5 adapters)
|── WebSocket ──> /ws/interview |── RPA subprocess (Bun.spawn)
|── WebSocket ──> /ws/automation |
|
Job provider registry
(ATS + gaming boards + company boards)
flowchart LR
subgraph Client["@bao/client"]
UI["Nuxt pages · components"]
Eden["Eden treaty client"]
WS["WebSocket clients"]
end
subgraph Server["@bao/server"]
API["17 route modules"]
WSHandlers["ws/chat · interview · automation"]
Svcs["Services layer"]
end
subgraph Data["Data & external"]
DB[("SQLite")]
AI["AI providers"]
Jobs["Job providers"]
RPA["Scraper/RPA"]
end
UI --> Eden
UI --> WS
Eden -->|HTTP /api/*| API
WS --> WSHandlers
API --> Svcs
Svcs --> DB
Svcs --> AI
Svcs --> Jobs
Svcs --> RPA
RPA -->|Bun.spawn| Scraper["@bao/scraper"]
External or legacy agent prompts sometimes mention Prisma, htmx, or files that are not in this repo. Treat this README, AGENTS.md, and docs/feature-trace-matrix.md as canonical: the UI is Nuxt 4 + Vue + daisyUI with Eden Treaty to an Elysia API, persistence via Drizzle ORM and SQLite (bun:sqlite), not htmx-driven partial HTML or Prisma.
| Package | Path | What it does |
|---|---|---|
@bao/server |
packages/server |
Bun + Elysia API, Drizzle ORM, WebSockets, orchestration |
@bao/client |
packages/client |
Nuxt 4 SSR frontend, Tailwind CSS v4, daisyUI v5 |
@bao/shared |
packages/shared |
Shared types, contracts, constants, schemas, validation |
@bao/scraper |
packages/scraper |
Bun + Playwright automation executables |
@bao/desktop |
packages/desktop |
Tauri desktop packaging and release staging |
flowchart TD
Browser["Browser"] --> Client["packages/client · Nuxt SSR"]
Client --> Pages["pages · layouts · components"]
Client --> Composables["typed composables · api-normalizers"]
Client --> EdenClient["plugins/eden"]
Client --> FlowEngine["flow-engine · ui-layout"]
ServerTypes["packages/server/dist-types"]
Shared["packages/shared contracts"]
EdenClient -->|"typed HTTP calls"| ApiPrefix["/api"]
EdenClient -->|"type import"| ServerTypes
ApiPrefix --> App["packages/server/src/app"]
App --> Middleware["cors · swagger · rate-limit · logger · errorHandler · authGuard"]
App --> Routes["17 route modules from route-modules"]
App --> WebSockets["ws: chat · interview · automation"]
App --> Shared
App --> ServerTypes
Routes --> AuthRoutes["auth · user · settings"]
Routes --> CareerRoutes["jobs · resume · cover-letter · portfolio · interview · studios"]
Routes --> AutomationRoutes["automation · scraper · automation-screenshots"]
Routes --> PlatformRoutes["ai · gamification · skill-mapping · search · stats"]
CareerRoutes --> JobsSvc["jobs service"]
JobsSvc --> JobAggregator["job-aggregator"]
JobAggregator --> ProviderRegistry["provider-registry"]
ProviderRegistry --> ATSProviders["greenhouse · lever · company-board"]
ProviderRegistry --> GamingProviders["gaming-providers"]
JobsSvc --> MatchingSvc["matching-service"]
JobsSvc --> DedupSvc["deduplication"]
CareerRoutes --> DomainServices["resume · cover-letter · portfolio · interview · studio services"]
PlatformRoutes --> PlatformServices["ai · gamification · skill-mapping · search · statistics"]
PlatformServices --> SkillExtractor["skill-extractor"]
PlatformServices --> AiProviders["local · openai · gemini · claude · huggingface"]
AiProviders --> ExternalAI["provider APIs and local model endpoint"]
AutomationRoutes --> AutomationSvc["application-automation-service"]
AutomationRoutes --> ScraperSvc["scraper-service"]
AutomationSvc --> Runner["automation/rpa-runner"]
AutomationSvc --> SmartFieldMapper["smart-field-mapper"]
AutomationSvc --> EmailDelivery["email-delivery-service"]
ScraperSvc --> Runner
Runner --> ScraperPkg["packages/scraper"]
ScraperPkg --> Scripts["src/scripts"]
Scripts --> Runtime["Playwright runtime · ATS adapters · provider extractors"]
JobsSvc --> DB[("SQLite via Bun SQLite and Drizzle")]
DomainServices --> DB
PlatformServices --> DB
AutomationSvc --> AutomationRuns["automation_runs"]
ScraperSvc --> JobsStudios["jobs · studios ingestion"]
AutomationRuns --> DB
JobsStudios --> DB
Each Elysia route module owns its service directly -- routes call services, services call the database or external providers. Typed contracts in packages/shared are the source of truth for request/response shapes. Bun automation executables run in isolated subprocesses with JSON/NDJSON over stdin/stdout.
Key conventions:
- Global flow decisions live in
packages/client/constants/flow-engine.tsand are consumed viauseFlowEngine.ts. - Layout is tokenized in
packages/client/constants/ui-layout.tsand rendered throughPageScaffold,PageHeaderBlock,SectionGrid, andAppModalFrame. - AI provider display uses locale-driven keys (
aiProviderCatalog.*) andAIProviderIcon-- no hardcoded provider labels. - Interview role selection is adaptive: profile role, readiness rankings, pathway scores, and live job signals drive recommendations.
- Skills readiness uses typed IDs (
feedbackId,improvementSuggestions,nextSteps) so all UI copy is locale-driven.
.---------.
| .-------. | ~~~ OPTIONS MENU ~~~
| | .env | |
| | | | Every configurable value lives
| '-------' | in .env or a source-of-truth
'----( )----' config file. Nothing is hardcoded.
| |
| | "Hey! Listen!" -- set your
'-' LOCAL_MODEL_ENDPOINT first.
| Key | Purpose | Details |
|---|---|---|
PORT |
API bind port | Validated in range 1..65535 |
HOST |
API bind host | Passed to Elysia listener |
DB_PATH |
SQLite database file location | Parent directory must be writable |
LOG_LEVEL |
Logging verbosity | info, debug, warn, error |
CORS_ORIGINS |
Comma-separated allowed origins | Defaults include localhost |
BAO_DISABLE_AUTH |
Disable auth explicitly | Set true or 1 for local-only dev |
BAO_AUTH_SETUP_TOKEN |
First-run API key bootstrap token | Required only when auth stays enabled during setup |
| Key | Purpose |
|---|---|
NUXT_PUBLIC_API_BASE |
API base URL for useFetch/$fetch |
NUXT_PUBLIC_WS_BASE |
WebSocket base URL |
NUXT_PUBLIC_API_PROXY |
Dev proxy target (defaults to http://localhost:${PORT}) |
NUXT_PUBLIC_QUERY_STALE_TIME_MS |
TanStack Query stale time |
NUXT_PUBLIC_QUERY_RETRY_COUNT |
TanStack Query retry budget |
NUXT_PUBLIC_QUERY_REFETCH_ON_FOCUS |
Refetch on window focus |
NUXT_PUBLIC_I18N_DEFAULT_LOCALE |
Initial locale (en-US default) |
NUXT_PUBLIC_I18N_FALLBACK_LOCALE |
Fallback when translations are missing |
NUXT_PUBLIC_I18N_LOCALE_COOKIE_KEY |
Cookie key for persisted locale |
Do NOT set
NUXT_PUBLIC_I18N_SUPPORTED_LOCALESin.env. Nuxt runtime config replaces the parsed array with a raw string, which breaks the i18n plugin. The default is handled innuxt.config.ts.
At least one provider is needed for AI features (chat, interviews, email drafts, resume review, cover letters). Keys can also be set via Settings > AI Providers in the UI.
| Key | Purpose |
|---|---|
LOCAL_MODEL_ENDPOINT |
Local inference server URL |
LOCAL_MODEL_NAME |
Local model identifier |
OPENAI_API_KEY |
OpenAI cloud provider |
GEMINI_API_KEY |
Google Gemini cloud provider |
CLAUDE_API_KEY |
Anthropic Claude cloud provider |
HUGGINGFACE_TOKEN |
HuggingFace Inference API (free tier requires a token) |
| Key | Purpose | Default |
|---|---|---|
AUTOMATION_STDIO_BUFFER_LIMIT |
Max stdout lines from scraper scripts | 200 (increase to 2000 for large outputs) |
AUTOMATION_SCRIPT_TIMEOUT_MS |
Max execution time per script | 30000 |
Install bundled Chromium: bun run automation:browsers:install
Provider configuration for job ingestion is stored in settings.automationSettings.jobProviders. Populate it via PUT /api/settings before running ingestion. Required keys include providerTimeoutMs, greenhouseBoards[], leverCompanies[], companyBoards[], gamingPortals[], and related defaults. See the settings schema for the full shape.
| File | Governs |
|---|---|
packages/server/src/config/env.ts |
Server environment validation |
packages/server/src/config/paths.ts |
File system paths used by server |
packages/client/nuxt.config.ts |
Client runtime config, proxy, modules |
packages/scraper/package.json |
Bun automation runtime dependencies |
.env.example |
Template for all env vars |
_____________
| ___ ___ |
| | 1 || 2 | | PLAYER SELECT
| |___||___| |
| ___ ___ | 1 = Full stack (bun run dev / scripts/dev-stack.ts)
| | 3 || 4 | | 2 = Server only (bun run dev:server)
| |___||___| | 3 = Client only (bun run dev:client)
|_____________| 4 = Split terminals
"Press START to begin"
bun run devStarts server + client via scripts/dev-stack.ts:
- API server on
PORT(default 3000) - Nuxt client on port 3001
Terminal 1:
bun run dev:serverTerminal 2:
bun run dev:client| Endpoint | Default URL | Config key |
|---|---|---|
| API server | http://localhost:3000 |
PORT |
| Client UI | http://localhost:3001 |
client nuxt dev |
| Chat WebSocket | ws://localhost:3000/api/ws/chat |
NUXT_PUBLIC_WS_BASE |
| Interview WebSocket | ws://localhost:3000/api/ws/interview |
NUXT_PUBLIC_WS_BASE |
| Automation WebSocket | ws://localhost:3000/api/ws/automation |
NUXT_PUBLIC_WS_BASE |
| Script | Command | Purpose |
|---|---|---|
| Dev (full) | bun run dev |
Start server + client via scripts/dev-stack.ts |
| Dev (stack) | bun run dev:stack |
Alias to scripts/dev-stack.ts |
| Dev server | bun run dev:server |
Start API server only |
| Dev client | bun run dev:client |
Start Nuxt client only |
| Dev desktop | bun run dev:desktop |
Start Tauri desktop wrapper |
| Build | bun run build |
Build server and client |
| Build desktop | bun run build:desktop |
Build Tauri installer for current host; merges into packages/desktop/releases without deleting other OS artifacts |
| Typecheck | bun run typecheck |
TypeScript checking across all packages |
| Test | bun run test |
Run all test suites |
| Lint | bun run lint |
All validators + Biome + ESLint + typecheck |
| Lint fix | bun run lint:fix |
Autofix with guardrails preserved |
| Format | bun run format |
Apply Biome formatter |
| Format check | bun run format:check |
Verify formatter output |
| DB generate | bun run db:generate |
Generate Drizzle migration files |
| DB push | bun run db:push |
Push schema changes to SQLite |
| DB studio | bun run db:studio |
Open Drizzle Studio GUI |
| Release desktop (macOS) | bun run release:desktop:macos |
Native macOS release artifacts |
| Release desktop (Windows) | bun run release:desktop:windows |
Native Windows release artifacts |
| Release desktop (Linux x64) | bun run release:desktop:linux-x64 |
Native Linux x64 release artifacts |
| Release desktop (Linux ARM) | bun run release:desktop:linux-arm64 |
Native Linux ARM64 release artifacts |
| Release refresh (all staged OSes) | bun run release:refresh:all-os |
Assemble staged release artifacts + checksums |
| Verify pages | bun run verify:pages |
Validate SSR routes return proper HTML |
| Server type contract | bun run --filter '@bao/server' build:types |
Generate dist-types for client typecheck |
| Validate ARIA | bun run validate:aria |
Interactive labeling + dialog semantics |
| Validate layout tokens | bun run validate:ui-layout-tokens |
Block hardcoded width/grid literals |
| Validate UI | bun run validate:ui |
WCAG contrast + hardcoded color checks |
| Validate page SEO | bun run validate:page-seo |
Require SSR useServerSeoMeta on core pages |
| Validate i18n | bun run validate:i18n-ui |
Reject static template copy / missing t() keys |
| Validate no try/catch | bun run validate:no-try-catch |
Enforce no-try/catch policy |
| ASCII validation | bun run scripts/validate-ascii-geometry.ts README.md |
Verify ASCII-art geometry |
| Audit official LLM docs | bun run audit:official-llms |
Check Elysia/Nuxt/Bun/daisyUI llms.txt reachability |
___
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ! | CAUTION: Entering RPA territory
|___|
/ \ Automation runs are persisted to
/ BAO \ automation_runs in SQLite for full
/_______\ audit trail and replay capability.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"Do a barrel roll!" -- but only after
Playwright Chromium is installed.
Automation execution flows from automationRoutes through application-automation-service.ts to rpa-runner.ts.
- API route receives a typed job-apply payload.
- Service resolves required entities from the database (resume, optional cover letter).
- A new
automation_runsrecord is created with a unique run ID. rpa-runner.tsspawns a Bun subprocess withBun.spawn.- The request payload goes to the script on
stdin. - The Playwright script navigates, fills forms, clicks, and captures screenshots.
- NDJSON/JSON protocol output is parsed and persisted.
- The run status is updated (
successorerror).
| Script ID | File | Purpose |
|---|---|---|
job-apply |
packages/scraper/src/scripts/job-apply.ts |
Job application form automation |
scraper-hitmarker |
packages/scraper/src/scripts/scraper-hitmarker.ts |
Scrape Hitmarker jobs |
scraper-grackle |
packages/scraper/src/scripts/scraper-grackle.ts |
Scrape GrackleHQ jobs |
scraper-workwithindies |
packages/scraper/src/scripts/scraper-workwithindies.ts |
Scrape Work With Indies |
scraper-remotegamejobs |
packages/scraper/src/scripts/scraper-remotegamejobs.ts |
Scrape RemoteGameJobs |
scraper-gamesjobsdirect |
packages/scraper/src/scripts/scraper-gamesjobsdirect.ts |
Scrape GamesJobsDirect |
scraper-pocketgamer |
packages/scraper/src/scripts/scraper-pocketgamer.ts |
Scrape PocketGamer.biz |
studio-scraper |
packages/scraper/src/scripts/studio-scraper.ts |
Curated studio directory |
Scripts read JSON from stdin, produce protocol-compliant JSON/NDJSON on stdout, and exit non-zero on hard failure.
Input:
{
"jobUrl": "https://example.com/job/application",
"resume": {
"personalInfo": {
"fullName": "Player One",
"email": "player@example.com",
"phone": "+1 555 0100",
"location": "Remote"
},
"education": ["..."],
"experience": ["..."],
"skills": ["..."]
},
"coverLetter": {
"company": "Acme",
"position": "Senior Game Designer",
"content": {}
},
"customAnswers": {
"q_salary": "120000",
"q_relocation": "No"
}
}Success:
{
"success": true,
"error": null,
"screenshots": ["step-01.png", "step-02.png"],
"steps": [
{ "action": "navigate", "status": "ok" },
{ "action": "fill_full_name", "status": "ok" },
{ "action": "submit", "status": "ok" }
]
}Failure:
{
"success": false,
"error": "No matching submit button",
"screenshots": [],
"steps": [{ "action": "click_submit", "status": "error" }]
}Screenshots are served through GET /api/automation/screenshots/:runId/:index.
rpa-runner.ts calls Bun.spawn with stdin: "pipe", stdout: "pipe", stderr: "pipe". It passes the payload to stdin, reads both streams, and returns structured context on non-zero exit.
All automation types support scheduling through one persisted model:
POST /api/automation/job-apply/schedulePOST /api/automation/email-response/schedulePOST /api/automation/scrape/schedule
Each writes a pending row to automation_runs with the requested time at input.schedule.runAt, then queues an in-memory timer. On restart, pending rows are reloaded and timers restored. No separate cron table.
AUTOMATION_RUNTIME_ERRORAUTOMATION_TIMEOUTAUTOMATION_CANCELLEDSCRIPT_PROTOCOL_ERRORSCRIPT_OUTPUT_INVALIDOUTPUT_PERSISTENCE_ERROROUTPUT_VALIDATION_ERROR
.-----------.
/ JOBS BOARD \ "War. War never changes."
| +-----------+ | But job boards do. The provider
| | Greenhouse| | registry normalizes provider behavior
| | Lever | | so the aggregator doesn't have to
| | Company | | care which ATS you're scraping.
| +-----------+ |
\ /
'------------'
The job system lives in packages/server/src/services/jobs/:
| File | What it does |
|---|---|
job-aggregator.ts |
Orchestrates fetching across all providers |
matching-service.ts |
Scores jobs against user profile and skills |
deduplication.ts |
Deduplicates listings from multiple boards |
providers/provider-interface.ts |
Common interface all providers implement |
providers/provider-registry.ts |
Add/remove providers at runtime |
providers/greenhouse.ts |
Greenhouse ATS integration |
providers/lever.ts |
Lever ATS integration |
providers/company-board.ts |
Direct company career page scraping |
providers/provider-settings.ts |
Settings-backed provider configuration |
providers/gaming-providers.ts |
Game-industry board aggregation |
The default set includes Greenhouse, Lever, Hitmarker, GrackleHQ, Work With Indies, RemoteGameJobs, GamesJobsDirect, PocketGamer.biz, plus configured SmartRecruiters/Workday/Ashby company boards.
The aggregator calls each provider, deduplicates results, scores them against your profile, and persists everything to SQLite.
.-------------.
/ CHOOSE \
/ YOUR CLASS \
/ \
| [1] Local Mage |
| [2] OpenAI Knight |
| [3] Gemini Ranger | "Would you kindly"
| [4] Claude Healer | configure at least
| [5] HF Summoner | one provider?
\ /
\_________________/
The AI subsystem is in packages/server/src/services/ai/:
| File | What it does |
|---|---|
ai-service.ts |
Routes requests to the active provider |
provider-interface.ts |
Common interface for all providers |
local-provider.ts |
Connects to Ollama, LM Studio, etc. |
openai-provider.ts |
OpenAI API adapter |
gemini-provider.ts |
Google Gemini API adapter |
claude-provider.ts |
Anthropic Claude API adapter |
huggingface-provider.ts |
HuggingFace Inference API adapter |
context-manager.ts |
Manages conversation history and context windows |
prompts.ts |
Prompt templates for resume review, interviews, cover letters |
- Local provider is used when
LOCAL_MODEL_ENDPOINTandLOCAL_MODEL_NAMEare set. - Cloud adapters are selected based on which API keys are configured.
- The context manager handles conversation state and prompt construction.
All AI calls are server-owned. The client communicates through API routes and WebSocket endpoints, never directly to providers.
____________________________
| SERVICE INVENTORY |
|____________________________|
| |
| "I used to be an |
| adventurer like you, |
| then I took a service |
| layer to the knee." |
|____________________________|
| Service | File | Purpose |
|---|---|---|
| CV Questionnaire | cv-questionnaire-service.ts |
Guided questionnaire flow for building resume data |
| Data Service | data-service.ts |
Shared data access patterns |
| Export Service | export-service.ts |
Export resumes, portfolios, cover letters to PDF/JSON |
| Email Delivery | email-delivery-service.ts |
SMTP delivery for automation email responses |
| Skill Extractor | skill-extractor.ts |
Extract and normalize skills from listings/resumes |
| Skill Mapping | skill-mapping-service.ts |
Map user skills to job requirements for scoring |
| Smart Field Mapper | automation/smart-field-mapper.ts |
AI-assisted form field mapping for job-apply RPA |
BaoBuildBuddy ships these locale packs:
| Locale | File |
|---|---|
en-US |
packages/client/locales/en-US.ts |
es-ES |
packages/client/locales/es-ES.ts |
fr-FR |
packages/client/locales/fr-FR.ts |
ja-JP |
packages/client/locales/ja-JP.ts |
Source of truth: packages/client/plugins/i18n.ts registers catalogs. nuxt.config.ts defines i18n runtime config. Locale files follow the schema in en-US.ts.
Resolution order: saved cookie locale -> Accept-Language header (q-weighted) -> browser locale -> configured default.
To add a language:
- Add a catalog file under
packages/client/locales. - Register it in
I18N_MESSAGE_CATALOG. - Add the locale to
NUXT_PUBLIC_I18N_SUPPORTED_LOCALES. - Add matching preference/voice mappings where needed.
.-----------.
/ \ "A man chooses. A slave obeys."
| 16 TABLES | But a schema migrates.
| IN SQLite |
\ / All tables are defined in
'-----------' packages/server/src/db/schema/
| Schema File | Tables | Purpose |
|---|---|---|
user.ts |
user_profile | User accounts and profiles |
auth.ts |
auth | Authentication sessions and tokens |
resumes.ts |
resumes | Resume data with structured sections |
cover-letters.ts |
cover_letters | Generated and custom cover letters |
portfolios.ts |
portfolios, portfolio_projects | Portfolio collections and projects |
interviews.ts |
interview_sessions | Mock interview sessions and transcripts |
studios.ts |
studios | Game studio directory |
jobs.ts |
jobs, saved_jobs, applications | Aggregated job listings, saves, applications |
skill-mappings.ts |
skill_mappings | User skill profiles and gap analysis |
gamification.ts |
gamification | XP, level, achievements, streaks |
settings.ts |
settings | User preferences and app configuration |
automation-runs.ts |
automation_runs | RPA execution audit trail |
chat-history.ts |
chat_messages | AI conversation history |
Migrations live in packages/server/src/db/migrations/. Seed data in packages/server/src/db/seed/ provides initial studio records and industry reference data.
"The right man in the wrong place
can make all the difference in the world."
-- But the right file in the wrong directory? Not so much.
baobuildbuddy/
+-- packages/
| +-- server/ Bun + Elysia API server
| | +-- src/
| | | +-- routes/ API route modules with route-level tests
| | | | +-- auth.routes.ts
| | | | +-- user.routes.ts
| | | | +-- settings.routes.ts
| | | | +-- jobs.routes.ts
| | | | +-- resume.routes.ts
| | | | +-- cover-letter.routes.ts
| | | | +-- portfolio.routes.ts
| | | | +-- interview.routes.ts
| | | | +-- studio.routes.ts
| | | | +-- scraper.routes.ts
| | | | +-- ai.routes.ts
| | | | +-- gamification.routes.ts
| | | | +-- skill-mapping.routes.ts
| | | | +-- search.routes.ts
| | | | +-- stats.routes.ts
| | | | +-- automation.routes.ts
| | | | +-- automation-screenshots.routes.ts
| | | +-- services/ Business logic layer
| | | | +-- ai/ 5 provider adapters + context manager + prompts
| | | | +-- automation/ application-automation-service.ts, rpa-runner.ts
| | | | +-- jobs/ Aggregator, matching, dedup, provider registry
| | | | | +-- providers/ greenhouse, lever, company-board, gaming-providers
| | | | +-- resume-service.ts
| | | | +-- cover-letter-service.ts
| | | | +-- portfolio-service.ts
| | | | +-- interview-service.ts
| | | | +-- gamification-service.ts
| | | | +-- scraper-service.ts
| | | | +-- search-service.ts
| | | | +-- statistics-service.ts
| | | | +-- export-service.ts
| | | | +-- data-service.ts
| | | | +-- cv-questionnaire-service.ts
| | | | +-- skill-extractor.ts
| | | | +-- skill-mapping-service.ts
| | | +-- db/
| | | | +-- schema/ Drizzle table modules + schema-modules.ts
| | | | | +-- user.ts, auth.ts, resumes.ts, cover-letters.ts
| | | | | +-- portfolios.ts, interviews.ts, studios.ts, jobs.ts
| | | | | +-- skill-mappings.ts, gamification.ts, settings.ts
| | | | | +-- automation-runs.ts, chat-history.ts
| | | | +-- migrations/
| | | | +-- seed/ Initial gaming data and studio records
| | | | +-- client.ts, init.ts
| | | +-- middleware/ auth.ts, error-handler.ts, logger.ts
| | | +-- ws/ chat.ws.ts, interview.ws.ts, automation.ws.ts
| | | +-- config/ env.ts (validation), paths.ts
| +-- client/ Nuxt 4 SSR application
| | +-- pages/ SSR routes for setup, jobs, studios, interview, AI, automation, docs
| | +-- components/ Shared UI and feature Vue components
| | | +-- ai/ AIChatBubble, AIStreamingResponse, BaoFairy
| | | +-- resume/ ResumePreview, ExperienceList, PersonalInfoForm,
| | | | SkillsEditor, EducationList
| | | +-- jobs/ JobCard, JobMatchScore, JobSearchBar
| | | +-- interview/ InterviewChat, ScoreCard, StudioSelector
| | | +-- gamification/ DailyChallenge, XPBar, AchievementBadge
| | | +-- portfolio/ PortfolioGrid, ProjectCard
| | | +-- layout/ AppNavbar, AppSidebar, AppDock
| | | +-- ui/ ConfirmDialog, LoadingSkeleton
| | +-- composables/ Typed data, websocket, speech, and view-state composables
| | | +-- useApi, useAuth, useUser, useSettings, useSettingsQuery
| | | +-- useTheme, useWebSocket, useSpeech, useTTS, useSTT
| | | +-- useJobs, useSearch, useResume, useCoverLetter
| | | +-- usePortfolio, useStudio, useInterview, useAI
| | | +-- useAutomation, useGamification, useSkillMapping, useStatistics
| | +-- plugins/ vue-query.ts, toast.client.ts, eden.ts
| | +-- middleware/ auth.ts (client-side auth guard)
| | +-- layouts/ default.vue, auth-shell.vue
| | +-- utils/ errors.ts
| | +-- types/ nuxt.d.ts, speech.d.ts
| | +-- assets/css/ main.css
| +-- shared/ Cross-package contracts
| | +-- src/
| | | +-- types/ Shared domain types
| | | | +-- user, ai, resume, interview, jobs, cover-letter
| | | | +-- portfolio, studio, gamification, skill-mapping
| | | | +-- settings, search
| | | +-- schemas/ Shared validation and protocol schemas
| | | | +-- user.schema, resume.schema, job.schema
| | | | +-- interview.schema, settings.schema
| | | | +-- portfolio.schema, skill-mapping.schema
| | | +-- constants/ Runtime, API, automation, AI, and UI contract constants
| | | +-- utils/ Shared parsing, validation, and formatting helpers
| | | +-- public-api.ts Package export surface
| +-- scraper/ Bun automation runtime
| +-- src/scripts/ Bun/TS automation entrypoints
| +-- src/providers/ Playwright scraper extractors
| +-- src/job-apply/ ATS adapter runtime
| +-- src/runtime/ IO/protocol/browser helpers
| +-- package.json
+-- scripts/
| +-- setup.sh Automated setup for macOS / Linux
| +-- setup.ps1 Automated setup for Windows (PowerShell)
| +-- validate-ascii-geometry.ts ASCII art geometry checker
| +-- validate-no-try-catch.ts Repository no-try/catch policy validator
| +-- validate-ui-accessibility.ts WCAG + hardcoded-color drift validator
+-- docs/
| +-- ELI5_SYSTEM_WALKTHROUGH.md Plain-English system overview
| +-- STARTER_GUIDE.md First-time setup guide
| +-- LOCAL_AI_SETUP.md Local AI with Ollama
| +-- AUTOMATION.md Automation contracts and runtime
| +-- RAILWAY.md Railway deployment guide
+-- .env.example
+-- package.json
+-- drizzle.config.ts
+-- biome.json
_____________________
| _______________ |
| | | | "All your base
| | WORLD MAP | | are belong to us."
| | | |
| | CORE ROUTES | | Navigate the SSR app across
| | + FEATURES | | the main product surfaces.
| |_______________| |
|_____________________|
| Feature Area | Pages | Key Composables |
|---|---|---|
| Home, Setup & Docs | index, setup, settings, docs/api |
useAuth, useSettings, useTheme |
| Resume | resume/index, resume/build, resume/preview |
useResume |
| Cover Letter | cover-letter/index, cover-letter/[id] |
useCoverLetter |
| Portfolio | portfolio/index, portfolio/preview |
usePortfolio |
| Interview | interview/index, interview/session, interview/history |
useInterview, useWebSocket |
| AI Chat | ai/dashboard, ai/chat |
useAI, useChatVoice, useSpeech |
| Studios | studios/index, studios/[id], studios/analytics |
useStudio |
| Jobs | jobs/index, jobs/[id] |
useJobs, useSearch |
| Automation | automation/index, automation/job-apply, automation/email, automation/scraper, automation/runs, automation/runs/[id] |
useAutomation |
| Skills & XP | skills/index, skills/pathways, gamification |
useSkillMapping, useGamification |
- SSR-first data loading by default; composables for client-side interactivity.
useFetchfor page-level data,$fetchfor user-triggered actions.- Async state (
idle,pending,success,error) mapped to daisyUI components. - The Eden client (
plugins/eden.ts) provides end-to-end type safety between Nuxt and the API. - Dynamic endpoints use Eden function-param invocation (e.g.
api.resumes({ id }).get()). - API payloads are normalized in
composables/api-normalizers.tsbefore binding to domain state. - Error handling follows Elysia centralized
onErrormiddleware and Eden{ data, error }branching. - TanStack Vue Query (
plugins/vue-query.ts) manages cache, stale time, and retry.
______
| | ~~~ SAVE POINT ~~~
| SAVE |
|______| Before you open the UI, run these
/ \ verification checks. Every check that
/ () \ passes is XP earned. Every check
/________\ skipped is a Boo that haunts you later.
bun run format:check
bun run typecheck
bun run lint
bun run test
bun run buildbun run validate:page-seo
bun run validate:i18n-ui
bun run validate:aria
bun run validate:ui-layout-tokens
bun run validate:ui
bun run verify:pagesThe UI validation pipeline enforces:
- WCAG AA color contrast for daisyUI theme pairs
- No hardcoded UI colors in client source
- No static user-facing copy or static ARIA/placeholder attributes in templates
- Core pages define SSR
useServerSeoMetawith localizedtitleanddescription - All
t('...')keys resolve in theen-USlocale schema - Form controls are programmatically labeled
- Clickable surfaces are keyboard-operable and focusable
- Modal surfaces use
AppModalFramewitharia-modalandaria-labelledby - Core pages use tokenized layout primitives (
PageScaffold/SectionGrid)
flowchart LR
Templates["Vue templates + shared UI primitives"] --> Alignment["bun run validate:alignment"]
Alignment --> UIValidate["validate:page-seo + validate:i18n-ui + validate:aria + validate:ui"]
UIValidate --> UIState{"Layout, daisyUI, and accessibility checks pass?"}
UIState -->|No| UIFixes["Fix theme token pairs or remove hardcoded colors"]
UIFixes --> Alignment
UIState -->|Yes| A11yLint["Client ESLint + vuejs-accessibility"]
A11yLint --> LintState{"A11y errors = 0?"}
LintState -->|No| Fixes["Fix labels, keyboard handlers, control semantics"]
Fixes --> A11yLint
LintState -->|Yes| BrowserQA["Manual browser QA: tab order, Enter/Space, CTA wiring"]
BrowserQA --> Ready["Release-ready UI"]
Context7 verification: bun run audit:official-llms fetches and validates llms.txt from official sources (Elysia, Nuxt, Bun, daisyUI). Each source is checked for required markers to ensure AI assistants receive up-to-date docs.
Verify stack alignment:
bun run ci:alignment
bun run audit:stack-versions
bun run verify:bun-baseline
bun run validate:alignmentFull local quality gate and desktop verification:
bun ci
bun run lint
bun run typecheck
bun run test
bun run build
bun run build:desktopPer-platform native release staging:
bun run release:desktop:macos -- --output-root .desktop-release-artifacts --release
bun run release:desktop:windows -- --output-root .desktop-release-artifacts --release
bun run release:desktop:linux-x64 -- --output-root .desktop-release-artifacts --release
bun run release:desktop:linux-arm64 -- --output-root .desktop-release-artifacts --releaseAssemble multi-platform release set:
bun run release:refresh:all-os| Command | Expected result |
|---|---|
bun run lint |
No warnings or errors |
bun run typecheck |
No TypeScript diagnostics |
bun run test |
All test suites pass |
bun run build |
All packages build successfully |
bun run build:desktop |
Current-host desktop packaging succeeds |
bun run verify:desktop-runtime |
Packaged runtime executes deterministic automation proof |
bun run verify:pages |
All SSR routes and content checks pass |
bun run ci:alignment |
Frozen-lockfile install + alignment gate passes |
bun run validate:alignment |
Bun + daisyUI alignment passes |
| Endpoint | Purpose | Expected Response |
|---|---|---|
/api/health |
Readiness probe | JSON with status and database |
/api/auth/status |
Auth state | Whether auth system is initialized |
/api/jobs |
Job search | Paginated job list |
/api/studios |
Studio data | Studio list |
/api/resumes |
Resume CRUD | Resume list |
/api/cover-letters |
Cover letter CRUD | Cover letter list |
/api/portfolio |
Portfolio CRUD | Portfolio project list |
/api/interview/sessions |
Interview sessions | Interview history |
/api/skills/mappings |
Skill mapping CRUD | Mapped skills list |
/api/skills/pathways |
Career pathways | Ranked pathways by match score |
/api/skills/readiness |
Career readiness | Readiness score and breakdown |
/api/automation/job-apply |
Start job automation | RpaRunExecutionEnvelope (status running) |
/api/automation/email-response |
Generate email response | { runId, status, reply, provider, model } |
/api/automation/scrape |
Run scraper now | RpaRunExecutionEnvelope |
/api/automation/runs |
Automation audit | Persisted run records |
/api/automation/screenshots/:runId/:index |
Run screenshot | PNG/JPEG/WebP image stream |
/api/gamification/progress |
XP and level progression | Gamification progress payload |
/api/stats/dashboard |
Usage statistics | Aggregate stat payload |
/api/ws/chat |
AI chat | WebSocket upgrade handshake |
/api/ws/interview |
Mock interview | WebSocket upgrade handshake |
/api/ws/automation |
Automation progress events | WebSocket event stream |
______________________
/| |\ Desktop packaging uses a native shell and
/ | TAURI | \ no separate Electron runtime.
/__|_____________________|__\ It launches the existing Bun stack and opens
| | | | it in a desktop window.
|__| .-.\ /.-. |__| This keeps one codebase for web + desktop.
| | |o| |o| | |
| | '-' '-' | |
| |_____________________| |
|___________________________|
Tauri is the default desktop path because it reuses your existing Bun stack with a thin native shell and no extra runtime overhead.
- Rust toolchain (
rustup+cargo) - macOS/Linux: system C/C++ build tools
- Windows: Visual C++ Build Tools
rustc --version
cargo --versionbun run dev:desktopThis auto-starts the server/client stack if needed and opens the app at http://127.0.0.1:3001 in a Tauri window.
Single-host build (current platform):
bun run build:desktopMatching-host release builds (run each on its target platform):
bun run release:desktop:macos -- --output-root .desktop-release-artifacts --release
bun run release:desktop:windows -- --output-root .desktop-release-artifacts --release
bun run release:desktop:linux-x64 -- --output-root .desktop-release-artifacts --release
bun run release:desktop:linux-arm64 -- --output-root .desktop-release-artifacts --releaseOptional installable variants (defaults are on; set false to omit):
DESKTOP_RELEASE_MACOS_ARCHITECTURES=aarch64,x86_64,universal bun run release:desktop:macos -- --output-root .desktop-release-artifacts --release
DESKTOP_RELEASE_WINDOWS_MSI=false bun run release:desktop:windows -- --output-root .desktop-release-artifacts --release
DESKTOP_RELEASE_LINUX_APPIMAGE=false DESKTOP_RELEASE_LINUX_SIGNATURES=false bun run release:desktop:linux-x64 -- --output-root .desktop-release-artifacts --releaseAssemble all platforms:
bun run release:refresh:all-osThis assembles previously built artifacts into packages/desktop/releases/, regenerates checksums, and verifies provenance. The GitHub Actions desktop workflow now gates every native packaging job behind bun ci, bun run lint, bun run typecheck, bun run test, and bun run build, then runs bun run verify:desktop-runtime and bun run verify:desktop-releases -- --release on each native host before artifact upload. MSI, AppImage, and Linux .sig outputs are on by default (unset env uses defaults); set workflow-dispatch inputs, repository variables, or DESKTOP_RELEASE_*=false to turn them off. Extra macOS architectures still use DESKTOP_RELEASE_MACOS_ARCHITECTURES.
--release on macOS always runs xcrun stapler validate on the staged DMG (notarization ticket). For a non-stapled tree (typical local ad-hoc sign), run bun run verify:desktop-releases without --release so payload and checksum checks still run; use --release only when the DMG is stapled like a shipping build.
Output locations:
- Raw build output:
packages/desktop/src-tauri/target/release/bundle - Release artifacts:
packages/desktop/releases/{macos,windows,linux-x64,linux-arm64} - Checksums:
packages/desktop/releases/sha256.txt
| Platform | Build target | Notes |
|---|---|---|
macOS (aarch64-apple-darwin) |
release:desktop:macos |
Split flow: bun tauri build --no-bundle then bun tauri bundle --bundles app,dmg; optional x86_64 and universal channels via DESKTOP_RELEASE_MACOS_ARCHITECTURES. |
Windows (x86_64-pc-windows-msvc) |
release:desktop:windows |
NSIS installer + portable zip + MSI by default. Omit MSI with DESKTOP_RELEASE_WINDOWS_MSI=false. |
Linux x64 (x86_64-unknown-linux-gnu) |
release:desktop:linux-x64 |
Deb + RPM + AppImage + detached .sig files by default (when GPG env is set for signing). Omit variants with DESKTOP_RELEASE_LINUX_APPIMAGE=false / DESKTOP_RELEASE_LINUX_SIGNATURES=false. |
Linux ARM64 (aarch64-unknown-linux-gnu) |
release:desktop:linux-arm64 |
Deb + RPM + detached .sig by default. Omit signatures with DESKTOP_RELEASE_LINUX_SIGNATURES=false. Requires ARM64 host or emulated runner. |
For macOS DMG packaging with non-UTF8 locale defaults:
LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 bun run build:desktop| Variable | Default | Purpose |
|---|---|---|
BAO_STACK_BOOTSTRAP_COMMAND |
bun |
Stack command override |
BAO_STACK_HOST |
127.0.0.1 |
Health-check host |
PORT |
3000 |
API port |
CLIENT_PORT |
3001 |
Client readiness check port |
BAO_DISABLE_AUTH |
- | Pass through to stack startup |
BAO_AUTH_SETUP_TOKEN |
- | One-time setup token for first API key bootstrap |
DESKTOP_RELEASE_MACOS_ARCHITECTURES |
aarch64 |
Optional macOS release channels: aarch64, x86_64, universal |
DESKTOP_RELEASE_WINDOWS_MSI |
true |
Include the MSI installable in Windows release builds (false to omit) |
DESKTOP_RELEASE_LINUX_APPIMAGE |
true |
Include the AppImage installable on Linux x64 (false to omit) |
DESKTOP_RELEASE_LINUX_SIGNATURES |
true |
Generate detached GPG signatures for Linux release artifacts (false to omit) |
APPLE_SIGNING_IDENTITY |
- | macOS code-sign identity used only for --release desktop builds |
WINDOWS_CERTIFICATE_THUMBPRINT |
- | Windows certificate thumbprint used only for --release desktop builds |
WINDOWS_DIGEST_ALGORITHM |
SHA256 |
Windows signing digest algorithm for --release desktop builds |
WINDOWS_TIMESTAMP_URL |
- | Windows timestamp server URL for --release desktop builds |
DESKTOP_RELEASE_GPG_KEY_ID |
- | GPG identity for Linux detached signatures |
DESKTOP_RELEASE_GPG_PASSPHRASE |
- | Optional passphrase for Linux detached signatures |
If desktop build fails with failed to run 'cargo metadata':
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh .--------.
/ YOU DIED \ Don't panic. Check the matrix below.
| ________ | Every problem has a save file.
| |CONTINUE| |
| |________| | "Had to be me. Someone else might
\__________/ have gotten it wrong." -- debug carefully.
| Check | Fix |
|---|---|
| Dependencies installed? | bun install |
| Port already in use? | lsof -i :3000 or change PORT in .env |
| DB path writable? | Verify parent directory of DB_PATH exists |
| Need more detail? | Set LOG_LEVEL=debug in .env and restart |
| Check | Fix |
|---|---|
| API base configured? | Verify NUXT_PUBLIC_API_BASE in .env |
| Proxy configured? | Set NUXT_PUBLIC_API_PROXY or ensure localhost:${PORT} is reachable |
| CORS issue? | Add client origin to CORS_ORIGINS |
| Server running? | curl http://localhost:3000/api/health |
| Check | Fix |
|---|---|
| WS base correct? | Verify NUXT_PUBLIC_WS_BASE |
| Routes registered? | Server logs should show /api/ws/chat, /api/ws/interview, /api/ws/automation |
| Firewall blocking? | wscat -c ws://localhost:3000/api/ws/chat |
| Check | Fix |
|---|---|
| Playwright browser installed? | bun run automation:browsers:install |
| Chrome available? | which google-chrome or which chromium |
| Script output? | Check server logs for stdout/stderr |
| Run record? | Query /api/automation/runs for the run ID |
| Check | Fix |
|---|---|
| Keys configured? | Verify API keys in .env |
| Local model running? | curl ${LOCAL_MODEL_ENDPOINT}/api/tags |
| Provider logs? | Set LOG_LEVEL=debug and check AI service output |
| Context overflow? | Check conversation length in context-manager.ts |
| Check | Fix |
|---|---|
| Providers registered? | Check server logs for provider registration |
| Network access? | Verify outbound HTTP to Greenhouse, Lever, etc. |
| DB seeded? | Run seed if studios table is empty |
| Dedup too aggressive? | Check thresholds in deduplication.ts |
========================================
| FINAL BOSS: DEPLOYMENT READINESS |
| |
| ,%%%, |
| ,%%%` %==-- HP: [==========] |
| ,%%`( '| |
| ,%%@ /\_/ Clear all checks |
| ,%.-"""--, to defeat this |
| %%/ | boss and go live.|
| %' \ / |
| | / | "Finish Him!" |
| | | | |
========================================
-
bun installcompleted successfully -
bun run automation:browsers:installcompleted successfully -
.envpopulated from.env.examplewith environment-specific values -
bun run typecheckpasses -
bun run validate:no-try-catchpasses -
bun run validate:page-seopasses -
bun run validate:i18n-uipasses -
bun run lintpasses -
bun run testpasses -
bun run db:generate+bun run db:pushcomplete -
bun run devstarts both server and client -
/api/healthreturns healthy status -
/api/auth/statusresponds -
/api/jobsreturns job list -
/api/automation/runsreturns run records -
/api/ws/chatWebSocket handshake succeeds -
/api/ws/interviewWebSocket handshake succeeds -
/api/ws/automationWebSocket handshake succeeds - AI provider responds (local or cloud)
-
bun run scripts/validate-ascii-geometry.ts README.mdpasses
+============================================================+
| |
| __ __ ___ ____ ____ ___ ___ _ _ |
| | \/ |_ _/ ___/ ___|_ _/ _ \| \ | | |
| | |\/| || |\___ \___ \| | | | | \| | |
| | | | || | ___) |__) | | |_| | |\ | |
| |_| |_|___|____/____/___\___/|_| \_| |
| |
| ____ ___ __ __ ____ _ _____ _____ _____ |
| / ___/ _ \| \/ | _ \| | | ____|_ _| ____| |
| | | | | | | |\/| | |_) | | | _| | | | _| |
| | |__| |_| | | | | __/| |___| |___ | | | |___ |
| \____\___/|_| |_|_| |_____|_____| |_| |_____| |
| |
| BaoBuildBuddy is ready. |
| |
| "Thank you Mario! |
| But our princess is in |
| another castle." |
| |
| Just kidding. You're done. |
| |
+============================================================+
| Document | Purpose |
|---|---|
| ELI5 System Walkthrough | Plain-English system overview |
| First-Time Setup Guide | Step-by-step first install |
| Local AI Setup Guide | Ollama setup for local AI |
| Automation Guide | RPA contracts and runtime behavior |
| Railway Deployment Guide | Deploy to Railway |
| Feature Trace Matrix | Route-to-service-to-UI traceability |
| Stack contract | Canonical stack (Drizzle, Nuxt, Eden) vs misleading audit prompts |
| Job Board Service Layer | Job aggregation API reference |
| Server routes | API route modules |