Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .agents/skills/workflow/onboard-new-developer/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Comprehensive onboarding process to get a new developer up and running quickly.
4. **Start local Postgres**: `pnpm --filter @repo/api db:start` (`setup` does not start Supabase)
5. **Reset and seed**: `pnpm reset` from repo root (Supabase reset + Drizzle migrate + seed). See `apps/api/README.md` and ADR 008
6. **Run web/API**: `pnpm dev` (API + Next.js)
7. **First login**: Magic link, or `ALLOW_TEST=true` + `test@test.ai`. Signed-in home is `/`
7. **First login**: Copied env has `ALLOW_TEST=true`. Use `test@test.ai`. Signed-in home is `/`. Resend is optional.
8. **Run mobile (optional)**: `pnpm --filter @repo/mobile start` (or `start:localhost` / `start:tunnel` for remote). See `apps/docu/content/docs/development/dev-environments.mdx`
9. **Verify**: Web loads, API `GET /health` succeeds, simulator/device can reach the API if running mobile
10. **Project familiarization**: Review `_first/basilic/PRODUCT.md` and architecture MDX; run tests when changing code; submit first PR
3 changes: 2 additions & 1 deletion .cursor/rules/frontend/e2e-playwright.mdc
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ alwaysApply: false
- Confirm dialogs use `getByRole('alertdialog')` (shadcn AlertDialog), not `dialog`

## Projects (dependency graph)
`public` → `auth` → `setup` → `{chromium, security, passkey-login}`; `chromium` → `chat`
`public` → `auth` → `setup` → `{chromium, security, passkey-login}`; `chromium` → `chat` (chat omitted without a real Anthropic key)

- **public**: no storageState
- **auth**: empty storageState; numbered `01-`…`06-` specs (file-name order is the convention — `testMatch` only selects files, it does not impose execution order)
- **setup**: `auth.setup.ts` writes `test-results/.auth/user.json` (depends on auth)
- **chromium** / **security** / **chat**: `storageState` from setup file
- **passkey-login**: empty storageState; dedicated `e2e-passkey@test.ai`
- **chat**: omitted when `hasRealAnthropicKey()` is false (`e2e/anthropic-key.ts`; empty, `sk-ant-xxx`, `sk-ant-dummy*`)

## Session model
- Setup project logs in once; authed projects reuse `user.json` with a **new context per test**
Expand Down
10 changes: 0 additions & 10 deletions .github/workflows/web-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,6 @@ jobs:
- name: Build
run: pnpm turbo run build --filter=@repo/web...
- uses: ./.github/actions/setup-playwright
- name: Verify ANTHROPIC_API_KEY for E2E (AI_PROVIDER=anthropic)
shell: bash
env:
AI_PROVIDER: ${{ env.AI_PROVIDER }}
ANTHROPIC_API_KEY: ${{ env.ANTHROPIC_API_KEY }}
run: |
if [[ "${AI_PROVIDER}" == "anthropic" && -z "${ANTHROPIC_API_KEY}" ]]; then
echo "::error::AI_PROVIDER is anthropic but ANTHROPIC_API_KEY is empty or unset. Set the ANTHROPIC_API_KEY repository secret; required before E2E tests (local)." >&2
exit 1
fi
- name: E2E tests (local)
env:
SKIP_BUILD: '1'
Expand Down
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Gabo Esquivel

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Fork-and-run developer starter: typed SDKs, self-hosted auth, a portable architecture, Cursor-first workflow, and a thin web demo. Fastify • OpenAPI • Next.js • Expo scaffold — one stack, multiple clients.

> 🚧 **Active development** — Explore, fork, and contribute. 🏗️
MIT licensed. Start a product with GitHub **Use this template**, or fork to contribute back. First successful use is [Product Ready](https://basilic-docs.vercel.app/docs/testing/product-ready) (`pnpm setup`, `db:start`, `pnpm reset`, `pnpm dev`, `test@test.ai`). After you own the copy: [After fork](https://basilic-docs.vercel.app/docs/development/after-fork).

## Features

Expand Down Expand Up @@ -95,8 +95,9 @@ Run with `pnpm <script>`.

Full docs: [basilic-docs.vercel.app](https://basilic-docs.vercel.app/docs)

- [Getting Started](https://basilic-docs.vercel.app/docs/development) — clone, `pnpm setup`, `db:start`, `pnpm reset`, `pnpm dev`
- [Getting Started](https://basilic-docs.vercel.app/docs/development) — clone or Use this template, `pnpm setup`, `db:start`, `pnpm reset`, `pnpm dev`
- [Product Ready](https://basilic-docs.vercel.app/docs/testing/product-ready) — fork-and-run bar (not CI green)
- [After fork](https://basilic-docs.vercel.app/docs/development/after-fork) — template vs fork, what to replace, CI secrets
- Maintainers: [`_first/basilic/PRODUCT.md`](_first/basilic/PRODUCT.md) — intent, feature map, roadmap
- [Dev Environments](https://basilic-docs.vercel.app/docs/development/dev-environments) — Local vs remote (ports 3000, 3001, 8081; `start:localhost`, `start:tunnel`)
- FIRST factory (stations, overlays): [`_first/`](_first/README.md) — load `_first/AGENTS.md` then `_first/ABOUT.md` then `_first/FIRST.md`. See [AI Workflow](https://basilic-docs.vercel.app/docs/development/ai-workflow)
Expand Down
2 changes: 1 addition & 1 deletion _first/basilic/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Meaningful boundaries have explicit inputs, outputs, errors, and references to a
- **Fact:** `createClient` modes: no-auth, JWT (`getAuthToken` / refresh), apiKey (`bask_…`)
- **Fact:** Drift check: `pnpm generate && git diff --exit-code -- apps/api/openapi/openapi.json packages/core/src/gen` (also `api-e2e.yml`)
- **Fact:** Generation how-to: [openapi-generation.mdx](../../apps/docu/content/docs/development/openapi-generation.mdx)
- **Drift:** Architecture index “API as source of truth” vs routes/TypeBox generate OpenAPI. Follow TypeBox. ADR 009 already says Fastify routes are the source.
- **Fact:** Architecture index matches this overlay: TypeBox on Fastify routes generate OpenAPI. ADR 009: Fastify routes are the source.
- **Unresolved:** public versioning/idempotency policy beyond regenerate-on-change; MCP server as a shipped app; GraphQL secondary interface (ADR 009 optional)

Who may call is Security. This station owns how credentials and denial appear on the contract.
Expand Down
6 changes: 3 additions & 3 deletions _first/basilic/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ The system has an inspectable structural model at the level its scale requires.
- **Fact:** Apps depend on packages, never the reverse. `react` depends on `core`. Clients call Fastify over HTTP.
- **Fact:** Store: PostgreSQL via `DATABASE_URL`. PGLite when `PGLITE=true`. Supabase is the managed host, not the auth SDK.
- **Fact:** Externals: Vercel, Resend, OAuth IdPs, AI providers, Sentry/GlitchTip, EAS, scanners
- **Drift:** Architecture index says “API as source of truth.” [api.mdx](../../apps/docu/content/docs/architecture/api.mdx) and [ADR 009](../../apps/docu/content/docs/adrs/009-api-architecture.mdx) say Fastify routes / TypeBox generate OpenAPI. Follow TypeBox/routes.
- **Drift:** [portability.mdx](../../apps/docu/content/docs/architecture/portability.mdx) describes host-anywhere. Shipped path is Vercel + Supabase.
- **Fact:** Contract source is TypeBox on Fastify routes; OpenAPI is generated ([api.mdx](../../apps/docu/content/docs/architecture/api.mdx), [ADR 009](../../apps/docu/content/docs/adrs/009-api-architecture.mdx))
- **Fact:** Shipped deploy path is Vercel + Supabase ([portability.mdx](../../apps/docu/content/docs/architecture/portability.mdx))
- **Unresolved:** GCP/AWS as first-class deploy targets; mobile as an API consumer

```mermaid
Expand Down Expand Up @@ -64,7 +64,7 @@ flowchart LR
## Validation

- A new contributor can name apps, packages, responsibilities, and dependency direction from architecture MDX.
- Diagrams match code and deployment, or discrepancies are named (mobile, PostHog, portability).
- Diagrams match code and deployment, or discrepancies are named (mobile, PostHog).
- New dependencies follow apps → packages; generated client from OpenAPI; no app-to-app imports.
- Consequential choices have ADRs, not only a technology name.
- Architecture stays proportional to a starter toolkit.
Expand Down
2 changes: 1 addition & 1 deletion _first/basilic/DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Consequential decisions, conventions, setup steps, and domain context live in di
- **Fact:** Portable factory: vendored `../AGENTS.md`, `../ABOUT.md`, `../templates/`. Station specs: `/f-*` from `npx skills add blockmatic/first`. This folder is the Basilic adoption pack, not a second docs site. Essays live in [`blockmatic/first`](https://github.com/blockmatic/first/tree/main/_first/articles).
- **Fact:** Same-change rule: update matching MDX when behavior, commands, or conventions change; update [PRODUCT.md](PRODUCT.md) when goals, feature map, or horizons change
- **Fact:** `__dev/` is gitignored scratch. Do not treat it as Fact or as the backlog. Remembered technical decisions go in `apps/docu` or ADRs. Product decisions go in [PRODUCT.md](PRODUCT.md).
- **Drift:** named in sibling instances (PostHog, “API as source of truth”, portability vs Vercel). Fix MDX in the same work when you change the fact; do not leave load-bearing drift only in chat.
- **Fact:** Architecture MDX matches this overlay: TypeBox on Fastify generates OpenAPI; shipped path is Vercel + Supabase; PostHog is chosen not installed. Named remaining drift: mobile vs web, PostHog not in the runtime.

## Minimum Useful Artifact

Expand Down
2 changes: 1 addition & 1 deletion _first/basilic/JOURNEYS.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Actors, entry points, happy paths, alternates, error paths, permission gates, an

- **Fact:** [authentication.mdx](../../apps/docu/content/docs/architecture/authentication.mdx), [account-linking.mdx](../../apps/docu/content/docs/architecture/account-linking.mdx)
- **Fact:** Web gate: [`../../apps/web/proxy.ts`](../../apps/web/proxy.ts). Public: `/auth/login`, `/auth/callback/*`, `/auth/logout`, `/auth/session/revoke`, `/terms`, `/privacy`, `/images/auth-login-hero.webp`. Unauthenticated → login. Authenticated on login → `/`. Token refresh on navigation.
- **Fact:** Adopter first-success: [product-ready.mdx](../../apps/docu/content/docs/testing/product-ready.mdx) (`db:start` + `pnpm reset` + `pnpm dev` + first login). Not CI green.
- **Fact:** Adopter first-success: [product-ready.mdx](../../apps/docu/content/docs/testing/product-ready.mdx) (`db:start` + `pnpm reset` + `pnpm dev` + `ALLOW_TEST` + `test@test.ai`). Not CI green. After they own the copy: [after-fork.mdx](../../apps/docu/content/docs/development/after-fork.mdx).
- **Fact:** Actors: web end user; adopting developer; CLI/agent with API key; CI/CodeRabbit/DeepSec; mobile user (**deferred**)
- **Fact:** Login methods: magic link (`token`+`verificationId` or `token`+`email`); OAuth GitHub/Google/Facebook/Twitter; passkey; Web3 EIP-155/Solana on the API. TOTP is 2FA only.
- **Fact:** E2E magic link: `test@test.ai` when `ALLOW_TEST=true`
Expand Down
2 changes: 1 addition & 1 deletion _first/basilic/PIPELINES.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Changes flow through an automated path: format → lint → typecheck → test
- **Fact:** Mobile: `mobile-build.yml`, `mobile-preview.yml`, `mobile-pr-preview.yml` ([mobile-cicd.mdx](../../apps/docu/content/docs/deployment/mobile-cicd.mdx))
- **Fact:** Local: `pnpm qa` via [`../../scripts/run-qa.mjs`](../../scripts/run-qa.mjs) — checktypes → lint → generate + drift → build → unit → e2e (`SKIP_BUILD=1`)
- **Fact:** Vercel git deploys web/api/docu ([vercel.mdx](../../apps/docu/content/docs/deployment/vercel.mdx)). CI does **not** deploy. Preview migrate gated unless `RUN_PG_MIGRATE=true`.
- **Fact:** `web-e2e` needs `ANTHROPIC_API_KEY`
- **Fact:** `web-e2e` chat project runs only when `ANTHROPIC_API_KEY` is set; auth/dashboard E2E still run on forks
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
- **Fact:** R0 is documentation alignment. It does not require a GitHub Release or a version bump. Preview deploys still run from git as usual.
- **Unresolved:** commit-stage artifact identity and promote-without-rebuild (hosts rebuild from git)

Expand Down
15 changes: 8 additions & 7 deletions _first/basilic/PRODUCT.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ The project has an inspectable answer to what, why, and how we will know. Non-go
## Artifacts

- **Fact:** This file is the canonical product brief (Brief, Feature map, Roadmap below). Do not put Basilic intent, feature map, or horizons in `apps/docu`
- **Fact:** [`../../README.md`](../../README.md) — fork-and-run TypeScript fullstack starter (Fastify, OpenAPI, Next, Expo scaffold). No Wagmi, no first-class OpenAI SDK, no web wallet UI
- **Fact:** [`../../README.md`](../../README.md) — MIT fork-and-run TypeScript fullstack starter (Fastify, OpenAPI, Next, Expo scaffold). No Wagmi, no first-class OpenAI SDK, no web wallet UI
- **Fact:** [`../../apps/docu/content/docs/`](../../apps/docu/content/docs/) — adopter technical docs (architecture, ADRs, development, testing, deployment). Not a product site
- **Fact:** Two audiences: **adopters** (developers using the starter) and **demo users** (web markets `/`, headlines strip, settings, in-shell assistant; auth is the shipped job)
- **Fact:** GTM: clone + [Getting Started](../../apps/docu/content/docs/development/index.mdx) (`db:start`, `pnpm reset`) + first local login. Bar: [Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx). Finance **N/A** (toolkit)
- **Fact:** GTM: clone or GitHub **Use this template** + [Getting Started](../../apps/docu/content/docs/development/index.mdx) (`db:start`, `pnpm reset`) + first local login (`ALLOW_TEST` + `test@test.ai`). Bar: [Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx). After you own the copy: [After fork](../../apps/docu/content/docs/development/after-fork.mdx). Finance **N/A** (toolkit)
- **Fact:** Owner: Gabo Esquivel
- **Fact:** New-device sign-in alerts are transactional email via Fastify `emailProvider` + `@repo/email`, not a notification product
- **Fact:** Not a billed SaaS in files. Do not invent TAM/LTV
Expand All @@ -36,7 +36,7 @@ The project has an inspectable answer to what, why, and how we will know. Non-go
- users: adopting developers; demo end users on web auth and dashboard
- goal: portable starter with self-hosted Web2 auth and Cursor-first workflow (Web3 on API only)
- non-goals: Brief → Non-goals (R0) in this file
- audience/channel/first use: clone + Getting Started (`db:start`, `pnpm reset`) + first local login ([Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx))
- audience/channel/first use: clone or Use this template + Getting Started (`db:start`, `pnpm reset`) + first local login (`ALLOW_TEST` + `test@test.ai`) ([Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx))
- metrics: auth and assistant jobs **instrumented, not collected**
- events: `auth_succeeded`, `auth_failed`, `assistant_turn` — specified + instrumented, no sink
- owners: Gabo Esquivel
Expand All @@ -56,7 +56,7 @@ The project has an inspectable answer to what, why, and how we will know. Non-go

- A new maintainer can answer what we are building from this file + README without `__dev/` or Fumadocs Product pages
- Success metrics can fail. They are not CI green. Auth/assistant remain unmeasured (no sink)
- GTM is clone + Getting Started. Product Ready is that path, not CI green. Finance N/A
- GTM is clone or Use this template + Getting Started. Product Ready is that path, not CI green. Finance N/A
- No silent product decisions in code without a note or open question

## Definition of Done
Expand Down Expand Up @@ -93,7 +93,7 @@ Owner until this file says otherwise: **Gabo Esquivel**.

### Two audiences

**Adopters** clone the repo, run the stack locally, and copy patterns. First successful use is [Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx): clone → [Getting Started](../../apps/docu/content/docs/development/index.mdx) (`db:start`, `pnpm reset`, `pnpm dev`) → magic-link (or `ALLOW_TEST` + `test@test.ai`) to `/`.
**Adopters** clone the repo or use GitHub **Use this template**, run the stack locally, and copy patterns. First successful use is [Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx): clone → [Getting Started](../../apps/docu/content/docs/development/index.mdx) (`db:start`, `pnpm reset`, `pnpm dev`) → `ALLOW_TEST` + `test@test.ai` to `/`. After they own the copy: [After fork](../../apps/docu/content/docs/development/after-fork.mdx).

**Demo users** sign in to the web app. The shipped job is auth (sessions, API keys, settings). Markets, a headlines strip, and the in-shell assistant are demo chrome. See Feature map below.

Expand Down Expand Up @@ -129,7 +129,7 @@ Status is what the tree does today, not a wish list. Horizons: Roadmap below.
Must work after clone → `pnpm setup` → `db:start` → `pnpm reset` → `pnpm dev`.

- Fastify TypeBox API → generated OpenAPI → `@repo/core` / handwritten `@repo/react`
- Auth: magic link (Resend **or** `ALLOW_TEST` + `test@test.ai`) → cookies → `/`
- Auth: magic link (Resend **or** copied local `ALLOW_TEST=true` + `test@test.ai`) → cookies → `/`
- Optional OAuth (unconfigured = disabled / 503)
- Passkeys, sessions, API keys `bask_`, Settings profile and security
- Next 16 web app gated by `apps/web/proxy.ts`
Expand Down Expand Up @@ -171,7 +171,8 @@ R0 is **documentation alignment**. It does not need a semver bump or a GitHub Re

- This file: what Basilic is, feature map, this roadmap
- Honesty in README and auth docs (starter, not wallet/OpenAI template)
- [Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx): `db:start` + `pnpm reset` before `pnpm dev`
- MIT `LICENSE`; GitHub Template; [After fork](../../apps/docu/content/docs/development/after-fork.mdx)
- [Product Ready](../../apps/docu/content/docs/testing/product-ready.mdx): `db:start` + `pnpm reset` before `pnpm dev`; copied env `ALLOW_TEST=true`

### R-demo — Markets + GenAI artifacts

Expand Down
11 changes: 7 additions & 4 deletions apps/api/.env.defaults.example
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
# SENTRY_ENVIRONMENT=

# -----------------------------------------------------------------------------
# AI (at least one provider path for chat features)
# AI (assistant is optional — paid key or local Ollama, not a placeholder)
# -----------------------------------------------------------------------------
ANTHROPIC_API_KEY=sk-ant-xxx
# Unset so the resolver can fall through to Ollama when it is running.
# A truthy placeholder (sk-ant-xxx) selects Anthropic and the chat job fails.
# ANTHROPIC_API_KEY=
# OPEN_ROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxx
# OLLAMA_BASE_URL=http://localhost:11434
# AI_PROVIDER=anthropic
# AI_PROVIDER=ollama
# AI_DEFAULT_MODEL=claude-haiku-4-5
# AI_UPSTREAM_TIMEOUT_MS=120000
# AI_TOOL_MAX_STEPS=5
Expand Down Expand Up @@ -70,7 +72,8 @@ ENCRYPTION_KEY=0000000000000000000000000000000000000000000000000000000000000000
# -----------------------------------------------------------------------------
# Testing / features
# -----------------------------------------------------------------------------
# ALLOW_TEST=false
# Local Product Ready: test@test.ai without Resend. Production refuses this.
ALLOW_TEST=true

# -----------------------------------------------------------------------------
# OAuth — optional (routes return 503 when unset)
Expand Down
2 changes: 1 addition & 1 deletion apps/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
},
"keywords": [],
"author": "",
"license": "ISC",
"license": "MIT",
"dependencies": {
"@ai-sdk/anthropic": "^4.0.45",
"@faker-js/faker": "^10.6.0",
Expand Down
Loading
Loading