Setting Up Projects
Prerequisites
Load engineering-principles before this skill. It provides the foundation:
invest early, pit of success, safety net, strict tooling, and explicit over
clever. This skill builds on those principles with concrete project-shape
decisions, layout patterns, and a bootstrap checklist.
For deeper architecture decisions about boundaries, layers, and framework
choices, load architecting-changes after this skill.
Choose the Shape First
Choose structure based on expected change axes and future callers, not
only conventions. The shape determines where code lives, how it is tested, and how
it grows.
| Situation |
Default shape |
| One-off helper or tiny automation |
Single-file script with inline dependencies. Do not force a full project layout. See writing-scripts. |
| Reusable library or composable tool |
Package with clean public API. Add a thin CLI only if needed. |
| CLI application |
Package with core/, cli/, utils/, wrappers/ layers. |
| Multi-interface application (GUI + CLI + API sharing logic) |
Shared domain layer + separate presentation adapters + one composition root. |
| Backend service / API / worker |
Service-specific layout (see setting-up-backends). Thin transport + separate domain/services/infrastructure. |
The decision is about what will change independently and who will call the
code. A library needs a stable public API. A CLI app needs testable commands.
A multi-interface app needs a reusable core that survives presentation
changes.
Project Layout Pattern
This is a starting point, not a mandate. Omit what you do not need. No GUI
→ no ui/. No CLI → no cli/. Add domain-specific directories when the
project demands them.
project/
├── src/ # Source code (or ecosystem-appropriate name)
│ └── appname/
│ ├── core/ # Business logic, pure domain rules
│ │ ├── models # Data types
│ │ └── services # Operations / use cases
│ ├── cli/ # CLI interface (if applicable)
│ ├── ui/ # GUI interface (if applicable)
│ ├── utils/ # Stateless shared utilities
│ ├── wrappers/ # Typed facades around third-party APIs
│ └── entrypoint # Thin main/entry
├── tests/
│ ├── unit/
│ ├── integration/
│ └── fixtures/
├── scripts/ # Dev utilities, automation
├── docs/ # Coding standards, philosophy, ADRs
├── project-manifest # Dependencies, tool config
├── linter-config # Language-appropriate linter setup
└── ci-config/ # CI pipeline definitions
wrappers/: Isolate third-party, platform-specific, or weakly-typed
boundaries behind typed interfaces. Wrap when typing, exception isolation,
portability, or replacement matters. Do not wrap every dependency
reflexively — wrap when the boundary is dynamic, risky, or likely to change.
Entrypoint: Keep it thin. Assemble the real presentation layer elsewhere
(core, CLI, GUI, API app factory, worker entrypoint) and let the entrypoint
do only the final handoff. The entrypoint bootstraps and delegates, it does
not own behavior.
Setup Checklist
Create directory structure — create the source, test, script, and doc
directories. Start with only what you need; add more as the project grows.
Copy baseline files — if you have them, promote templates into place:
project manifest, linter config, CI config, version-control ignore file,
editor settings. Copy shared building blocks if the ecosystem provides them.
Copy coding standards and philosophy docs into docs/.
Trim unused pieces — keep only the modules and directories you
actually need. Remove unused template dependencies, shared modules, and
config sections. The template is a starting point, not a straitjacket.
Create entry points — thin main/entrypoint that hands off to the real
presentation layer. Keep it minimal: bootstrap and delegate. If the app
has multiple interfaces sharing one core, use a dedicated multi-interface
pattern rather than an ad-hoc router in the entrypoint.
Create initial smoke test — one test that exercises the entrypoint
end-to-end. Verifies the wiring works, not business logic. For entrypoints
that read command-line arguments, set them explicitly in the test so it
does not depend on the test runner's own arguments.
Initialize environment — initialize version control, install
dependencies, run linter + type checker + tests. Use the project's task
runner for all commands rather than system-installed binaries.
Verify everything works — linter passes, type checker passes, tests
pass. This is the baseline safety net. Every future commit must pass the
same gates.
Graceful Shutdown
Design every app to be interruptible without corruption, hanging, or ugly
tracebacks. The shutdown strategy depends on what the app does.
| App type |
Strategy |
| Simple script/CLI |
Catch interrupt signal, exit with standard signal code |
| CLI wrapping a quick subtask |
Kill process group immediately on interrupt |
| CLI wrapping complex external tool |
Graceful signal → wait timeout → force kill escalation |
| Long-running event-loop app |
Handle signal in event loop (see platform-specific docs) |
Always use process groups when spawning subprocesses so you can kill the
entire tree, not just the parent. For async subprocesses, handle cancellation
with the same escalation pattern: terminate → wait → kill.
The goal is that Ctrl+C always works cleanly. No hung processes, no partial
writes, no stack traces in user output.
Adapt to Domain
After scaffolding, adapt everything to the specific project. Templates are a
starting point, not a straitjacket. Keep the philosophy and core safety model
intact, then adapt the surrounding structure to fit the project's domain and
constraints.
| Area |
How to adapt |
| Directory layout |
Add/remove/rename directories to match domain. A data pipeline might need pipelines/, schemas/. A web service might need routes/, middleware/. |
| Dependencies |
Add domain-specific libraries. Remove unused defaults. Research current best-in-class libraries for the domain. |
| Linter/type checker config |
Adjust rules for ecosystem gaps. Do not relax strict defaults by default; document every real exception. |
| Project orientation doc |
Fill in project-specific architecture, key decisions, domain vocabulary, workflows. Make it specific to THIS project. |
| Coding standards |
Extend or override rules for the domain. Add domain-specific conventions (migration rules, API versioning, validation requirements). |
| Test structure |
Adjust to what matters. CLI tool → heavy e2e. Library → heavy unit. Web service → API integration tests. |
| CI/CD |
Add domain-appropriate checks (schema validation, container builds, integration suites). |
Research before building: When in an unfamiliar domain, research domain
conventions, check library compatibility with your toolchain, and identify
domain-specific tooling. Look at how well-maintained projects in the same
space are structured.
Quick Customization Checklist
Related myai Skills
engineering-principles — Parent skill. Language-agnostic project setup
philosophy: invest early, pit of success, safety net.
architecting-changes — For architecture decisions about project shape,
boundaries, and framework choice.
writing-scripts — For single-file scripts and small automation instead
of full project layout.
building-backends — For backend architecture patterns after initial
bootstrap: thin transport, reusable core, transactions, auth, workers.
setting-up-backends — For backend service bootstrap when the project
shape is a service/API/worker.
ci-cd-and-automation — For CI/CD pipeline setup after bootstrap.
Language-Specific Extensions
After applying the patterns in this skill, load the appropriate
language-specific extension for concrete tool choices, library selections,
config templates, and code examples:
- Python:
setting-up-python-projects — uv, basedpyright, ruff, pytest,
pre-commit, pyproject.toml, src layout, bootstrap script (provided by coding_rules_python aux repository)
- Other ecosystems: if no language-specific skill exists, apply the
patterns above with
engineering-principles ecosystem examples as a
starting point, and record the gap for follow-up
When a language-specific extension is available, load this skill first for
the patterns and decision framework, then the extension for concrete tooling.
1---2name: setting-up-projects3description: ALWAYS LOAD THIS SKILL WHEN CREATING A NEW PROJECT, BOOTSTRAPPING A REPO, OR CHOOSING INITIAL PROJECT SHAPE FOR ANY LANGUAGE OR ECOSYSTEM. Do not scaffold projects directly — use this skill first. Project shape decisions, directory layout patterns, bootstrap checklist, graceful shutdown strategy, domain adaptation, and language-specific extension routing.4license: MIT5---67# Setting Up Projects89## Prerequisites1011Load `engineering-principles` before this skill. It provides the foundation:12invest early, pit of success, safety net, strict tooling, and explicit over13clever. This skill builds on those principles with concrete project-shape14decisions, layout patterns, and a bootstrap checklist.1516For deeper architecture decisions about boundaries, layers, and framework17choices, load `architecting-changes` after this skill.1819---2021## Choose the Shape First2223Choose structure based on expected change axes and future callers, not24only conventions. The shape determines where code lives, how it is tested, and how25it grows.2627| Situation | Default shape |28|-----------|---------------|29| One-off helper or tiny automation | Single-file script with inline dependencies. Do not force a full project layout. See `writing-scripts`. |30| Reusable library or composable tool | Package with clean public API. Add a thin CLI only if needed. |31| CLI application | Package with `core/`, `cli/`, `utils/`, `wrappers/` layers. |32| Multi-interface application (GUI + CLI + API sharing logic) | Shared domain layer + separate presentation adapters + one composition root. |33| Backend service / API / worker | Service-specific layout (see `setting-up-backends`). Thin transport + separate domain/services/infrastructure. |3435The decision is about what will change independently and who will call the36code. A library needs a stable public API. A CLI app needs testable commands.37A multi-interface app needs a reusable core that survives presentation38changes.3940---4142## Project Layout Pattern4344This is a starting point, not a mandate. Omit what you do not need. No GUI45→ no `ui/`. No CLI → no `cli/`. Add domain-specific directories when the46project demands them.4748```text49project/50├── src/ # Source code (or ecosystem-appropriate name)51│ └── appname/52│ ├── core/ # Business logic, pure domain rules53│ │ ├── models # Data types54│ │ └── services # Operations / use cases55│ ├── cli/ # CLI interface (if applicable)56│ ├── ui/ # GUI interface (if applicable)57│ ├── utils/ # Stateless shared utilities58│ ├── wrappers/ # Typed facades around third-party APIs59│ └── entrypoint # Thin main/entry60├── tests/61│ ├── unit/62│ ├── integration/63│ └── fixtures/64├── scripts/ # Dev utilities, automation65├── docs/ # Coding standards, philosophy, ADRs66├── project-manifest # Dependencies, tool config67├── linter-config # Language-appropriate linter setup68└── ci-config/ # CI pipeline definitions69```7071**`wrappers/`**: Isolate third-party, platform-specific, or weakly-typed72boundaries behind typed interfaces. Wrap when typing, exception isolation,73portability, or replacement matters. Do not wrap every dependency74reflexively — wrap when the boundary is dynamic, risky, or likely to change.7576**Entrypoint**: Keep it thin. Assemble the real presentation layer elsewhere77(core, CLI, GUI, API app factory, worker entrypoint) and let the entrypoint78do only the final handoff. The entrypoint bootstraps and delegates, it does79not own behavior.8081---8283## Setup Checklist84851. **Create directory structure** — create the source, test, script, and doc86 directories. Start with only what you need; add more as the project grows.87882. **Copy baseline files** — if you have them, promote templates into place: 89 project manifest, linter config, CI config, version-control ignore file,90 editor settings. Copy shared building blocks if the ecosystem provides them. 91 Copy coding standards and philosophy docs into `docs/`.92933. **Trim unused pieces** — keep only the modules and directories you94 actually need. Remove unused template dependencies, shared modules, and95 config sections. The template is a starting point, not a straitjacket.96974. **Create entry points** — thin main/entrypoint that hands off to the real98 presentation layer. Keep it minimal: bootstrap and delegate. If the app99 has multiple interfaces sharing one core, use a dedicated multi-interface100 pattern rather than an ad-hoc router in the entrypoint.1011025. **Create initial smoke test** — one test that exercises the entrypoint103 end-to-end. Verifies the wiring works, not business logic. For entrypoints104 that read command-line arguments, set them explicitly in the test so it105 does not depend on the test runner's own arguments.1061076. **Initialize environment** — initialize version control, install108 dependencies, run linter + type checker + tests. Use the project's task109 runner for all commands rather than system-installed binaries.1101117. **Verify everything works** — linter passes, type checker passes, tests112 pass. This is the baseline safety net. Every future commit must pass the113 same gates.114115---116117## Graceful Shutdown118119Design every app to be interruptible without corruption, hanging, or ugly120tracebacks. The shutdown strategy depends on what the app does.121122| App type | Strategy |123|----------|----------|124| Simple script/CLI | Catch interrupt signal, exit with standard signal code |125| CLI wrapping a quick subtask | Kill process group immediately on interrupt |126| CLI wrapping complex external tool | Graceful signal → wait timeout → force kill escalation |127| Long-running event-loop app | Handle signal in event loop (see platform-specific docs) |128129Always use process groups when spawning subprocesses so you can kill the130entire tree, not just the parent. For async subprocesses, handle cancellation131with the same escalation pattern: terminate → wait → kill.132133The goal is that Ctrl+C always works cleanly. No hung processes, no partial134writes, no stack traces in user output.135136---137138## Adapt to Domain139140After scaffolding, adapt everything to the specific project. Templates are a141starting point, not a straitjacket. Keep the philosophy and core safety model142intact, then adapt the surrounding structure to fit the project's domain and143constraints.144145| Area | How to adapt |146|------|--------------|147| Directory layout | Add/remove/rename directories to match domain. A data pipeline might need `pipelines/`, `schemas/`. A web service might need `routes/`, `middleware/`. |148| Dependencies | Add domain-specific libraries. Remove unused defaults. Research current best-in-class libraries for the domain. |149| Linter/type checker config | Adjust rules for ecosystem gaps. Do not relax strict defaults by default; document every real exception. |150| Project orientation doc | Fill in project-specific architecture, key decisions, domain vocabulary, workflows. Make it specific to THIS project. |151| Coding standards | Extend or override rules for the domain. Add domain-specific conventions (migration rules, API versioning, validation requirements). |152| Test structure | Adjust to what matters. CLI tool → heavy e2e. Library → heavy unit. Web service → API integration tests. |153| CI/CD | Add domain-appropriate checks (schema validation, container builds, integration suites). |154155**Research before building**: When in an unfamiliar domain, research domain156conventions, check library compatibility with your toolchain, and identify157domain-specific tooling. Look at how well-maintained projects in the same158space are structured.159160### Quick Customization Checklist161162- [ ] Directory layout matches the domain, not the generic template163- [ ] Dependencies are domain-appropriate (researched, not guessed)164- [ ] Project orientation doc describes THIS project specifically165- [ ] Coding standards have domain-specific additions if needed166- [ ] Test structure reflects what matters most for this project167- [ ] Tool config accounts for domain-specific quirks168169---170171## Related myai Skills172173- **`engineering-principles`** — Parent skill. Language-agnostic project setup174 philosophy: invest early, pit of success, safety net.175- **`architecting-changes`** — For architecture decisions about project shape,176 boundaries, and framework choice.177- **`writing-scripts`** — For single-file scripts and small automation instead178 of full project layout.179- **`building-backends`** — For backend architecture patterns after initial180 bootstrap: thin transport, reusable core, transactions, auth, workers.181- **`setting-up-backends`** — For backend service bootstrap when the project182 shape is a service/API/worker.183- **`ci-cd-and-automation`** — For CI/CD pipeline setup after bootstrap.184185---186187## Language-Specific Extensions188189After applying the patterns in this skill, load the appropriate190language-specific extension for concrete tool choices, library selections,191config templates, and code examples:192193- **Python**: `setting-up-python-projects` — uv, basedpyright, ruff, pytest,194 pre-commit, pyproject.toml, src layout, bootstrap script (provided by coding_rules_python aux repository)195- **Other ecosystems**: if no language-specific skill exists, apply the196 patterns above with `engineering-principles` ecosystem examples as a197 starting point, and record the gap for follow-up198199When a language-specific extension is available, load this skill first for200the patterns and decision framework, then the extension for concrete tooling.