Tee dev:auth stdout+stderr to services/mana-auth/dev.log and add a
logs:auth script (tail -f) so a developer can isolate auth output
without hunting through concurrently's multiplexed stream.
Follow-up to the 2026-04-23 incident where a missing DB column caused
mana-auth to return misleading 401s while the real Postgres error was
buried in concurrently-managed stderr. The HTTP layer fix (error-
classification + passkey end-to-end) deferred this dev-ergonomics
improvement explicitly.
https://claude.ai/code/session_01CDNt5FiUtXt5FYdFmpVyU6
Adds a "Local Login & Dev Users" section to docs/LOCAL_DEVELOPMENT.md
and a short pointer in services/mana-auth/CLAUDE.md so the next dev
finds the script without first hitting the "why can't I log in?" wall:
- Why it exists (no admin seed, requireEmailVerification + no SMTP)
- The 3 default accounts + password
- Single-account form + env overrides (TIER, AUTH_URL, …)
- Idempotency promise
- Prereqs (Postgres + mana-auth on :3001)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Local dev secrets like MANA_STT_API_KEY had no persistent home — they
lived only in the gitignored, generator-overwritten per-app .env files.
Every `pnpm setup:env` wiped them, so devs had to re-paste keys after
any env regeneration. Same recurring friction for MANA_LLM_API_KEY,
MANA_AUTH_KEK, OAuth keys, etc.
New layer: `.env.secrets` at the repo root.
- Gitignored, optional, never required for the build to pass
- Read by generate-env.mjs AFTER .env.development; non-empty values
override the matching key, so the merged result drives every per-app
.env the generator writes
- Empty values fall through to the .env.development defaults — a
freshly-copied .env.secrets.example is a no-op
- One source of truth for all dev secrets, propagated to every app
with one `pnpm setup:env`
Files:
- `.env.secrets.example` — committed template documenting all known
secret keys (mana-stt, mana-llm, auth KEK, sync JWT, MinIO, third-
party APIs). Devs `cp .env.secrets.example .env.secrets` and fill in.
- `.gitignore` — ignores .env.secrets, allows .env.secrets.example
- `scripts/generate-env.mjs` — loads .env.secrets if present, prints
"Loaded N secrets from .env.secrets" so devs see the override
taking effect
- `scripts/setup-secrets.mjs` + `pnpm setup:secrets` — convenience
script that SSHes to mana-server, greps the prod .env for the keys
defined in .env.secrets.example, and writes them locally. Confirms
before overwriting an existing .env.secrets unless --force is set;
reports which keys couldn't be found on the remote so devs know
what's left to fill manually
- `docs/LOCAL_DEVELOPMENT.md` + `docs/ENVIRONMENT_VARIABLES.md` —
walk-through and architecture diagram update
Verified end-to-end:
- `rm .env.secrets apps/mana/apps/web/.env && pnpm setup:env` →
STT key empty (no regression for devs who haven't opted in)
- `pnpm setup:secrets --force && pnpm setup:env` →
STT key propagated, "Loaded 3 secrets from .env.secrets" in output
- POST /api/v1/voice/transcribe with a real audio file →
full transcript back via gpu-stt.mana.how, end-to-end working
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add scripts/setup-databases.sh for automatic DB creation and schema push
- Add dev:*:full commands (chat, zitare, contacts, calendar, clock, todo, picture)
- Update docker/init-db to create all databases on first startup
- Add docs/LOCAL_DEVELOPMENT.md with comprehensive local dev guide
- Update CLAUDE.md with new quick start commands
Now developers can run `pnpm dev:chat:full` to automatically:
1. Create the database if missing
2. Push the latest schema
3. Start auth, backend, and web with colored output