This document is the single source of truth for Cursor Automations working on the Vacation repo. Read AGENTS.md at the start of every run.
Paradise Planner is an AI vacation concierge that collects trip details via chat and converts conversations into leads for human travel specialists. The product is lead generation, not booking.
- Production URL: https://vacation-app-21706.firebaseapp.com
- Admin CRM: https://vacation-app-21706.firebaseapp.com/admin
- Firebase project:
vacation-app-21706 - GitHub repo:
ether314/Vacation(branchmain)
| Slack channel | Agent | Responsibility |
|---|---|---|
#vacation-hq |
Chief of Staff | Triage, prioritize, auto-post delegated tasks to department channels + ack in thread — no repo checkout, no code, no PRs |
#vacation-product |
Product | Prompts, UX, lead fields — auto commit, push, Firebase deploy on every change |
#vacation-engineering |
Engineering | Flutter + Firebase — auto commit, push, Firebase deploy on every change |
#vacation-qa |
QA | Run tests — auto deploy when tests pass |
#vacation-deploy |
DevOps | Always runs full release pipeline (build + Firebase deploy) |
#vacation-ops |
Operations | Lead pipeline, Twilio SMS — auto deploy when functions/ or hosting changes |
Escalate to @vacation-leads when blocked, when secrets are needed, or for business decisions.
All new feature requests, product ideas, bugs, and cross-team work start in #vacation-hq.
| Where you post | What happens |
|---|---|
#vacation-hq |
Chief of Staff triages, delegates to department channels, acks in thread |
#vacation-product, #vacation-engineering, #vacation-qa, #vacation-deploy, #vacation-ops |
Do not start new work here. Department agents only run tasks delegated from HQ (or Phase 2 orchestrator handoffs). If a human posts a new request in a department channel, agents reply once: post it in #vacation-hq. |
Phase 2 orchestrator listens on department channels for direct runs — misrouted human posts get a redirect to HQ instead of starting an agent.
flutter_app/
lib/main_customer.dart # Customer web/mobile entry
lib/main_admin.dart # Admin CRM entry
lib/chat/ # AI agent layer (primary dev surface)
agent_prompts.dart # System prompt + extraction schema
agent_model.dart # Gemini model name
chat_controller.dart # State machine, handoff, submit flow
vacation_agent_service.dart # Gemini streaming + lead extraction
lead_extraction_heuristic.dart # When to hand off / save partial
lead_submit_validation.dart
lib/admin/ # Admin CRM screens + Firestore streams
functions/src/index.ts # submitLead, submitPartialLead, Twilio SMS triggers
scripts/
build-web.ps1 # Flutter web build → public/ (always run before Firebase deploy)
test-chat-flow.mjs # End-to-end chat flow test
test-submit-lead.mjs # Lead submission test
public/ # Deployed static web (customer + admin)
firebase.json # Hosting, Firestore, Functions config
- User chats with Gemini (
gemini-2.5-flash-lite) via Firebase AI Logic. - Agent collects one field at a time: destination, dates, budget, activities, party size, phone.
- Handoff triggers (
lead_extraction_heuristic.dart): phone in message, phone in transcript after 2+ turns, or 4+ user turns. - Second Gemini call extracts structured JSON →
submitLeadorsubmitPartialLeadCloud Function. - Full leads land in Firestore
leads; partial inpartialLeads. New leads trigger Twilio SMS.
- Prompt/heuristic change is justified against handoff and lead quality goals
- No recap/permission language in customer-facing copy (see
agent_prompts.dartrules) - Done = committed, pushed to
main, and Firebase hosting deployed (automatic — never ask)
- Small, focused diffs matching existing patterns
- No secrets in code or commits
- Commit directly to
main, push, and automatically Firebase deploy — see Release pipeline (no PRs unless the task asks for one)
- After any
functions/or customer-facing change: automatic Firebase deploy (hosting + functions as needed)
cd flutter_app && flutter analyze
node scripts/test-chat-flow.mjs
node scripts/test-submit-lead.mjsOwner policy: every agent run that changes repo files must automatically commit, push to main, build, and Firebase deploy in the same run. Do not prompt, pause, wait for confirmation, or skip deploy. A task is not done until hosting deploy completes (or you report a credential blocker).
# 1. Commit (include public/ when flutter web build output changed)
git add -A
git commit -m "<concise message>"
# 2. Push
git push origin main
# 3. Build + deploy (ALWAYS — not optional)
# Linux / Cloud Agent:
./scripts/deploy-hosting.sh
npx firebase-tools@latest deploy --only firestore:rules,firestore:indexes --project vacation-app-21706 --non-interactive
cd functions && npm run deploy
# Windows (OneDrive-safe):
# .\scripts\deploy-hosting.ps1
# npx firebase-tools@latest deploy --only firestore:rules,firestore:indexes --project vacation-app-21706 --non-interactive
# cd functions; npm run deployPost in the Slack thread: commit hash, push result, Firebase deploy result, production URL (https://vacation-app-21706.web.app), and smoke-test pass/fail.
Who runs it (all automatic, no asking):
- Engineering, Product, Ops — full pipeline after any code change
- QA — after tests pass, run full pipeline (commit/build/deploy if needed)
- Deploy — always runs full pipeline on every trigger
- Chief of Staff — delegate
#vacation-deployon every swarm that touches shippable code; department agents still deploy their own changes when they commit
Never: stop after commit/push only, ask "should I deploy?", or defer deploy to a later manual step.
Credentials: FIREBASE_TOKEN or GOOGLE_APPLICATION_CREDENTIALS (see docs/deploy.md). Add FIREBASE_TOKEN as a Cloud Agent Runtime Secret and restart the agent. If missing, report the blocker — do not fake success.
- Reply in the Slack thread on the triggering message.
- Feature requests →
#vacation-hqonly. Department agents must not implement work from a human top-level message unless it is a Chief of Staff delegation (Delegated from #vacation-hq) or a:arrow_forward:reaction on that delegation. - Reference file paths when discussing code changes.
- Always automatically Firebase deploy after commit/push when the run produces or validates shippable code — never ask for permission, never skip deploy (see Release pipeline).
- Never print or request API keys, Twilio tokens, or Firebase service accounts.
Programmatic swarm via Cursor SDK + Slack Bolt — no bot-message trigger issues, no manual reactions.
| Component | Path |
|---|---|
| Service | slack-orchestrator/ |
| Setup | docs/slack-orchestrator-setup.md |
.\scripts\run-slack-orchestrator.ps1 -InstallPost in #vacation-hq → orchestrator plans, posts to department channels, runs cloud agents, replies in threads.
Disable overlapping Cursor Automations on the same channels to avoid duplicate runs.
| Doc | Purpose |
|---|---|
| docs/slack-workspace-setup.md | Slack workspace + channels |
| docs/cursor-integrations-setup.md | Cursor integrations |
| docs/slack-swarm-delegation.md | Reaction-trigger workaround |
| docs/automations/ | Automation prefills |
| docs/bootstrap-test.md | Validation checklist |
The startup update script already runs npm install --prefix functions and flutter pub get --directory flutter_app, so dependencies are ready when a session begins. flutter (3.44.x / Dart 3.12.x) and Node 22 are preinstalled and on PATH.
Services and how to run them in dev (commands documented in README.md / docs/deploy.md / scripts/):
- Customer web app (core product):
cd flutter_app && flutter run -d web-server --web-hostname=0.0.0.0 --web-port=5001 -t lib/main_customer.dart. First compile takes ~30–60s before it prints "is being served at"; use--web-hostname=0.0.0.0so the Cloud Agent browser can reach it. - Admin CRM: same
flutter runbut-t lib/main_admin.dart(e.g. port 5002). Unlike the customer app (anonymous auth), admin requires a real Firebase login (lib/admin/login_screen.dart). - Cloud Functions: local
npm run build(tsc) only.functions/package.jsonpinsengines.node: 20but the VM has Node 22 — fine for local build/tests; the mismatch only matters for the deploy runtime.
Non-obvious caveats:
- No emulator wiring. The Flutter app talks directly to the live Firebase project
vacation-app-21706(Firestore, Auth, Functions, Gemini AI Logic). There is no local backend; running the chat requires network access and the embedded API key. Messages/leads sent during testing hit production data stores and can trigger Twilio SMS. - e2e scripts hit live Firebase.
node scripts/test-*.mjs(e.g.test-chat-flow.mjs,test-submit-lead.mjs) call the live project and create real leads.scripts/has a committednode_modules/but nopackage.json, so its deps are not reproducible via the update script. - Lint/test:
cd flutter_app && flutter analyzeandflutter test. Analyze currently reports a few pre-existing info/warning lints (not errors).