|
| 1 | +# Copilot Instructions for create-polyglot |
| 2 | + |
| 3 | +Purpose: This repo is a CLI (`bin/index.js`) that scaffolds a polyglot monorepo (Node.js, Python/FastAPI, Go, Spring Boot Java, Next.js frontend) with optional Turborepo or Nx presets, docker assets, and a basic concurrent dev runner. |
| 4 | + |
| 5 | +## Core Architecture |
| 6 | +- Single entrypoint: `bin/index.js` (ESM). All behavior (prompting, parsing, filesystem generation, process execution) lives here—there is no internal module layering yet. |
| 7 | +- Templates live under `templates/<service>` (node, python, go, spring-boot, frontend). These are copied verbatim; only Spring Boot renames `application.properties.txt` to `application.properties` post-copy. |
| 8 | +- Service selection -> array of objects: `{ type, name, port }`. Ports have defaults: frontend 3000, node 3001, go 3002, java 3003, python 3004. Uniqueness is enforced; conflicts abort. |
| 9 | +- `--services` flag accepts comma separated specs: `type`, or `type:name`, or `type:name:port`. Example: `--services node api:python:5001 go:web:4000`. |
| 10 | +- Preset affects root `package.json` dev script + adds config file (`turbo.json` or `nx.json`). No preset => basic runner (`scripts/dev-basic.cjs`). |
| 11 | +- Docker + `compose.yaml` are generated after templates: each service gets a Dockerfile if missing; compose exposes the same internal and external port. |
| 12 | + |
| 13 | +## Key Flows |
| 14 | +1. Parse CLI args (commander) -> gather missing info via `prompts` (unless `--yes`). |
| 15 | +2. Build `services` list; validate names (reject reserved), ensure port uniqueness. |
| 16 | +3. Create directory skeleton: `<project>/apps/*`, `packages/shared`, optional preset config. |
| 17 | +4. Write root artifacts: `package.json`, `.eslintrc.cjs`, `.prettierrc`, README, optional git init. |
| 18 | +5. Conditionally run `create-next-app` if frontend + `--frontend-generator` (fallback to internal template on failure). |
| 19 | +6. Generate Dockerfiles + `compose.yaml` (simple internal YAML function, not an external lib). |
| 20 | +7. Install deps unless `--no-install`. |
| 21 | + |
| 22 | +## Project Conventions |
| 23 | +- ESM at root (`type: module`). Test runner: Vitest (`npm test` => `vitest run`). Keep tests in `tests/` with `.test.js` naming. |
| 24 | +- Single large CLI file is intentional for now; when adding features prefer extracting small helper modules under `bin/` (e.g. `lib/ports.js`) but update imports accordingly. |
| 25 | +- All user-visible output uses `chalk` with emoji prefixes; follow existing style for consistency (info cyan/yellow, success green, errors red with leading symbol). |
| 26 | +- Interactive defaults when `--yes`: projectName 'app', services ['node'], preset none, packageManager npm, git false. |
| 27 | + |
| 28 | +## Edge Case Handling Already Implemented |
| 29 | +- Aborts on invalid service type, duplicate service name, reserved names, invalid port range, or port collision. |
| 30 | +- Graceful fallback if `create-next-app` fails (logs warning then copies template). |
| 31 | +- Git init failure is non-fatal. |
| 32 | +- Dependency install failures log a warning but do not abort scaffold. |
| 33 | + |
| 34 | +## Adding / Modifying Behavior (Examples) |
| 35 | +- New service template: create `templates/<newtype>`; add to `allServiceChoices` + defaultPorts + (optional) Dockerfile generation switch + compose mapping. |
| 36 | +- Custom flags: Extend commander chain; ensure interactive question only added when flag absent. Add to summary + README if user-relevant. |
| 37 | +- Compose enhancements: modify the `composeServices` object; keep network name `app-net` unless a breaking change is intended. |
| 38 | + |
| 39 | +## Dev & Testing Workflow |
| 40 | +- Local development: `npm install`, then run CLI directly: `node bin/index.js demo --services node,python --no-install --yes`. |
| 41 | +- Run tests: `npm test` (non-watch). To add tests, mirror `tests/smoke.test.js` pattern; use `execa` to run the CLI inside a temp directory. Keep per-test timeout generous (≥30s) for create-next-app scenarios. |
| 42 | +- When editing templates, no build step—files are copied verbatim. Ensure new template files are included via `files` array in root `package.json` if adding new top-level folders. |
| 43 | + |
| 44 | +## External Tools & Commands |
| 45 | +- `execa` is used for: `create-next-app`, git commands, and root dependency installation. Maintain `stdio: 'inherit'` for scaffold steps that should stream output. |
| 46 | +- Avoid spawning raw `child_process` unless streaming multi-process dev tasks (already done in `scripts/dev-basic.cjs`). Prefer `execa` for promise-based control. |
| 47 | + |
| 48 | +## Common Pitfalls to Avoid |
| 49 | +- Forgetting to update defaultPorts or Dockerfile switch when adding a service causes incorrect compose or missing Dockerfile. |
| 50 | +- Mutating `services` after port uniqueness check without re-validating can introduce collisions—re-run validation if you add dynamic adjustments. |
| 51 | +- Adding large binary/template assets outside `templates/` may break packaging (root `files` whitelist). |
| 52 | + |
| 53 | +## Style & Error Messaging |
| 54 | +- Use concise, user-facing error messages followed by `process.exit(1)` for hard failures before writing scaffolded output. |
| 55 | +- Non-critical failures (git init, install, external generator) should warn and continue. |
| 56 | + |
| 57 | +## Quick Reference |
| 58 | +- Entry CLI: `bin/index.js` |
| 59 | +- Basic dev runner template: `scripts/dev-basic.cjs` |
| 60 | +- Templates root: `templates/` |
| 61 | +- Tests: `tests/` |
| 62 | +- Workflow pipeline (publish): `.github/workflows/npm-publish.yml` (runs `npm ci && npm test` on release creation, then publishes) |
| 63 | + |
| 64 | +If adding major refactors (e.g., splitting CLI), document new module boundaries here. |
| 65 | + |
| 66 | +--- |
| 67 | +Feedback: Let me know if any sections need more depth (e.g., Docker generation, prompt flow, adding new presets) or if emerging conventions should be captured. |
0 commit comments