-
Notifications
You must be signed in to change notification settings - Fork 18
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
P2 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.
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>
Quality Gate Passed Quality Gate passed
Issues
0 New issues
0 Accepted issues
Measures
0 Security Hotspots
0.0% Coverage on New Code
0.0% Duplication on New Code
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