Architecture linter for the JavaScript ecosystem.
Monorepo using npm workspaces:
packages/cli/-@morando/cli, the core CLI toolwebsite/- Docusaurus documentation sitedecisions/- Architecture Decision Records (ADRs)
- Runtime: Node.js (ESM)
- Language: TypeScript (strict mode,
verbatimModuleSyntax) - CLI framework: yargs
- Validation: AJV (JSON Schema)
- FP utilities: ok-fp (
Either,Optionmonads) - Build: tsdown
- Test: vitest (with
@vitest/coverage-v8) - Lint: oxlint (config in
.oxlintrc.json)
npm run lint # Run oxlint
npm run typecheck # Run tsc --noEmit
npm run test # Run vitest
npm run build # Build with tsdownAll commands run from packages/cli/.
- Config file name:
.morandorc.json - Template files live in
packages/cli/templates/, named{name}-v{version}.json - Tests are co-located with source files using
.spec.tssuffix - Imports use
.jsextensions (ESM convention for TypeScript) - Use
vi.mock()for mocking in tests; mocks are declared at module level
Runs on every push: lint, typecheck, test, build - all in parallel after install-dependencies.
This project follows a functional style. ok-fp is the primary library for controlling computation flow using effect data types (Either, Option, etc.).
The ok-fp library is maintained by the same team. If its API could offer a better consumer experience for this project, flag it and suggest improvements.
- Allowed without asking: non-mutating npm scripts (
lint,typecheck,test,build), reading project files, creating commits. - Requires permission:
npm installor any command that modifies project dependencies, pushing to origin, reading or modifying files outside the project directory. - Strictly forbidden without permission: accessing or modifying files outside the project.
After a batch of code changes, verify that QA scripts pass (lint, typecheck, test) and that packages build correctly before considering the work done.
- Read existing code before modifying it. Understand the patterns in use.
- Keep changes minimal and focused. Do not refactor surrounding code unless asked.
- Follow existing conventions. Do not introduce new patterns without discussion.
- TypeScript strict mode. All compiler options in
packages/cli/tsconfig.jsonare intentional. - Use
ok-fpmonads (Either,Option) for error handling where the codebase already does. Do not mix with try/catch in the same flow. - ESM imports with
.jsextensions (e.g.,import foo from "./foo.js"). - No default exports except where already established (e.g.,
attachInitCommand,listTemplates,readConfig). - Prefer
constand functional patterns. Avoid classes unless modeling domain errors (seedefs.tsfiles).
- Be strict and concise. No filler, no fluff.
- Never use em dashes in docs, comments, or commit messages. Use commas, periods, or parentheses instead.
- Co-locate tests with source:
foo.ts->foo.spec.ts - Use vitest (
describe,it,expect,vi) - Mock at module level with
vi.mock(), thenvi.mocked()for type-safe access clearMocks: trueis set globally in vitest config. No need to manually reset mocks.- Test behavior, not implementation. Prefer testing public API surfaces.
- Domain types go in
defs.tsfiles within their feature directory - Error classes are defined alongside the types they relate to
- Utility functions go in
utils/directory
- Use conventional commits (e.g.,
feat:,fix:,refactor:,test:,docs:,chore:). - One logical change per commit.
- PR descriptions should explain the "why", not just the "what".
- CI must pass: lint, typecheck, test, build.