Conversation
- Add docker-compose.dev.yml running only Postgres + Redis under an isolated Compose project "packmind-dev", so app processes no longer run in containers over a bind mount - Add mise.toml pinning Node 24.15.0 and pnpm 11.5.0 via corepack - Add .env.example documenting optional local overrides - Add LOCAL_DEV_REVAMP_PLAN.md describing the migration Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add pnpm dev / dev:infra / dev:infra:down / dev:reset / dev:setup / migrate scripts to package.json - Add scripts/dev-serve.sh: bake deterministic localhost wiring (an optional .env overrides it) and serve api, mcp-server and frontend natively via nx run-many - Add scripts/prepare-local-dev.mjs: select the effective tsconfig and seed the local JS playground directory (idempotent) - Native processes restore real fs events: no Nx daemon socket, no file-watch polling Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Rewrite CLAUDE.md and CONTRIBUTING.md "Starting the stack" sections for the hybrid setup: infra in Docker, apps native via pnpm dev - Recommend mise for toolchain pinning; keep nvm + corepack as alternative - Note the legacy in-container stack as a transitional fallback and the port conflict between the two Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Greptile SummaryThis PR replaces the all-in-container dev stack with a hybrid model: only Postgres and Redis run in Docker (
Confidence Score: 5/5Safe to merge. All changes are additive — new scripts and compose file — with the legacy docker-compose.yml left intact as a fallback. The hybrid dev setup is well-structured: infra healthchecks gate migrations, WATCH_POLLING correctly activates legacy polling only in the old container stack, and the exec-replace pattern in dev-serve.sh cleanly hands off to nx. The only gap is that DATABASE_URL overrides in .env are not forwarded to the migration step, but this only affects the edge case documented in .env.example as optional. package.json — the migrate script does not source .env, so DATABASE_URL overrides are not propagated to migrations. Important Files Changed
Sequence Diagram%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Dev as Developer
participant PJ as package.json (pnpm dev)
participant DC as docker-compose.dev.yml
participant DS as dev-serve.sh
participant NX as nx run-many
Dev->>PJ: pnpm dev
PJ->>DC: docker compose up -d --wait (dev:infra)
DC-->>PJ: postgres + redis healthy ✓
PJ->>PJ: node scripts/prepare-local-dev.mjs (dev:setup)
Note over PJ: tsconfig select + js-playground seed
PJ->>PJ: pnpm typeorm migration:run (migrate)
Note over PJ: datasource.ts hardcoded → localhost:5432
PJ->>DS: bash scripts/dev-serve.sh
DS->>DS: source .env (overrides)
DS->>DS: "apply localhost defaults (:= syntax)"
DS->>NX: exec nx run-many -t serve -p api mcp-server frontend
NX-->>Dev: api :3000 · mcp-server :3001 · frontend :4200
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Dev as Developer
participant PJ as package.json (pnpm dev)
participant DC as docker-compose.dev.yml
participant DS as dev-serve.sh
participant NX as nx run-many
Dev->>PJ: pnpm dev
PJ->>DC: docker compose up -d --wait (dev:infra)
DC-->>PJ: postgres + redis healthy ✓
PJ->>PJ: node scripts/prepare-local-dev.mjs (dev:setup)
Note over PJ: tsconfig select + js-playground seed
PJ->>PJ: pnpm typeorm migration:run (migrate)
Note over PJ: datasource.ts hardcoded → localhost:5432
PJ->>DS: bash scripts/dev-serve.sh
DS->>DS: source .env (overrides)
DS->>DS: "apply localhost defaults (:= syntax)"
DS->>NX: exec nx run-many -t serve -p api mcp-server frontend
NX-->>Dev: api :3000 · mcp-server :3001 · frontend :4200
Reviews (2): Last reviewed commit: "⚡️ perf(api): use native file watching f..." | Re-trigger Greptile |
| pgadmin: | ||
| profiles: | ||
| - tools | ||
| image: dpage/pgadmin4:latest |
There was a problem hiding this comment.
The
pgadmin service uses the unpinned latest tag while postgres and redis are both version-pinned. On a fresh pull, different developers could get different pgAdmin versions, breaking the consistency goal this PR sets out to achieve. Pinning to a specific version avoids unexpected breakage when pgAdmin ships a breaking UI or config-schema change.
| image: dpage/pgadmin4:latest | |
| image: dpage/pgadmin4:9.4 |
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
- Gate nodemon's --legacy-watch/--polling-interval behind WATCH_POLLING, expanded only when the var is set, so native `pnpm dev` uses real fs events (~3s reload) instead of 500ms polling - Remove "legacyWatch": true from apps/api/nodemon.json (default native) - Set WATCH_POLLING=1 on the legacy docker-compose.yml backend service, which still needs polling over the bind mount Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|



Why
The legacy
docker-compose.ymldev stack runs the watched Node apps (api, frontend, mcp-server) inside containers over a bind-mounted source tree. File-system events don't cross the container/VM boundary, so the setup forces polling everywhere (NX_WATCHER: polling,CHOKIDAR_USEPOLLING, …) — laggy HMR, CPU burn — plus a fragile shared Nx-daemon socket. A year of friction.Insight: Docker is great for stateful infra, bad for hot-reloading Node. This PR splits them.
What
Hybrid setup — infra in Docker, apps native, toolchain pinned by
mise:docker-compose.dev.yml— Postgres + Redis only, isolated Compose projectpackmind-devmise.toml— pins Node 24.15.0 + pnpm 11.5.0 (corepack)scripts/dev-serve.sh— bakes deterministic localhost wiring;.envoverrides winscripts/prepare-local-dev.mjs— tsconfig select + JS-playground seed (idempotent)package.json—dev,dev:infra,dev:infra:down,dev:reset,dev:setup,migrateResult: real fs events, fast HMR, no daemon socket, no polling.
Validated locally
Native stack on Node 24:
frontend=200 · api=200 · mcp up · frontend→api proxy=200 · 0 DB-connection failures · MCP "started successfully".Scope / transition
docker-compose.ymlleft intact as a fallback. Don't run both at once (ports 5432/6379).LOCAL_DEV_REVAMP_PLAN.md, phase 4).🤖 Generated with Claude Code