@melodicdev/cli
v3.0.0
Published
Scaffolding and code generation for Melodic apps and monorepos.
Maintainers
Readme
Melodic CLI
A lightweight scaffolding and code generation tool for Melodic apps and monorepos.
Install
npm install -g @melodicdev/cli
melodic --helpLocal dev build:
npm --workspace @melodicdev/cli run build
node packages/cli/dist/index.js --helpQuick Start
melodic init my-app
cd my-app
npm install
npm run devName rules
Every name the CLI accepts (project, app, lib, and generate names) is
kebab-cased and must then match ^[a-z][a-z0-9-]*$. Names containing path
separators, .., quotes, or other special characters are rejected — they
would otherwise escape the project directory or break generated source.
PascalCase input is fine: melodic g component UserCard generates user-card.
Commands
melodic init <directory> [--monorepo] [--app-name <name>]
Create a new Melodic project. melodic create is an alias.
Single app:
melodic init my-appMonorepo with
apps/andlibs/:melodic init my-repo --monorepo --app-name webThe monorepo uses npm workspaces: every folder in
libs/is a workspace package (e.g.@my-repo/config), linked intonode_modulesbynpm install. Apps import libraries by package name, so TypeScript and Vite resolve them identically — there are no tsconfig path aliases to keep in sync. A single roottsconfig.jsontypechecksapps/andlibs/in one pass (npm run typecheck).Monorepo layout:
my-repo/ ├── apps/ │ └── web/ # seeded app (index.html, src/, vite.config.ts) ├── libs/ │ ├── config/ # @my-repo/config — shared app configuration │ └── shared/ # @my-repo/shared — shared utilities ├── tsconfig.json └── package.json # workspaces: ["apps/*", "libs/*"]Apps generated by the CLI set
build.targettoes2022in Vite so top-level await works in production builds.
melodic add app <name> [--dir apps]
Add a new app to a monorepo (requires a root package.json with
workspaces). The app is seeded from the same template as the monorepo's
initial app, wired to the shared config library when libs/config exists, and
dev:<name> / build:<name> / preview:<name> scripts are added to the root
package.json.
melodic add app admin
npm run dev:adminmelodic add lib <name> [--dir libs]
Add a new shared workspace library (requires a monorepo root). The package is
scoped to your repo (@<repo>/<name>), never to @melodicdev. Run
npm install afterwards so the workspace link is created.
melodic add lib utils
npm install
# import { ... } from '@my-repo/utils';Using --dir with a directory not covered by the root workspaces globs adds
the glob (and the root tsconfig include entry) automatically.
melodic add config [--path .]
Add environment-aware configuration.
- In a monorepo root: creates the
libs/configshared config library (@<repo>/config) and prints wiring instructions for each app. - In a single app: creates
src/config/app.config.ts.
melodic add testing [--path .]
Add a basic Vitest + happy-dom test setup to an existing project.
melodic add testing --path apps/webmelodic generate <type> <name> [--path <dir>] [--dry-run] [--force]
melodic g is an alias for melodic generate. All generators:
- validate the name (see Name rules above);
- precheck all target files before writing anything, so a collision never leaves a half-generated result;
- refuse to overwrite existing files unless
--forceis passed; - support
--dry-runto print the files that would be created without writing.
Redundant type suffixes are deduped: melodic g component UserCardComponent
generates UserCardComponent, not UserCardComponentComponent.
melodic generate component <name> [--path src/components]
Creates a component directory following the framework convention:
src/components/user-card/
├── index.ts # barrel export
├── user-card.component.ts # @MelodicComponent class
├── user-card.template.ts # template function
└── user-card.styles.ts # css tagged templateCustom element selectors must contain a hyphen, so a single-word name is
automatically prefixed: melodic g component card produces
selector: 'app-card' (a note is printed when this happens).
melodic generate directive <name> [--path src/directives]
Create a template directive. The generated render function returns its state object on every render, as required by the directive contract.
melodic generate attribute-directive <name> [--path src/directives]
Create and register an attribute directive (registered under the camelCase
name, e.g. autoFocus).
melodic generate service <name> [--path src/services]
Create an injectable service.
melodic generate interceptor <name> [--path src/http/interceptors]
Create HTTP request/response interceptors matching the v2 @melodicdev/core
API (the response error handler receives an IHttpResponseErrorContext with
retry()).
melodic generate guard <name> [--path src/guards]
Create a route guard via createGuard. Return true to allow navigation,
false to cancel, or a path string to redirect.
melodic generate guard authmelodic generate resolver <name> [--path src/resolvers]
Create a route resolver via createResolver.
melodic generate resolver usermelodic generate class <name> [--path src]
Create a plain TypeScript class.
melodic version
Print the CLI version (also -v / --version).
Templates
The CLI uses built-in templates and replaces placeholders automatically:
app-basic: single app scaffoldmonorepo-basic: workspace root withlibs/config+libs/sharedmonorepo-app: the app scaffold seeded into monorepos byinit --monorepoandadd applib-basic: minimal workspace library scaffold used byadd lib
Template notes:
- App templates include
vite-plugin-melodic-styles.ts, asrc/styles/global.csssample, and a<link melodic-styles>entry inindex.html. - Dependencies are pinned to ranges (
@melodicdev/core: ^2.0.0) — neverlatest.
Placeholders:
__APP_NAME____REPO_NAME____LIB_NAME__
Behavior Notes
initrequires the target directory to be empty (or missing).- Existing files are never overwritten without
--force. --pathand--dirmust be relative paths inside the project; absolute paths and..segments are rejected.- Unknown flags are rejected with a usage message.
Deferred / not yet implemented
- Interactive prompts (
melodic generatewith no arguments) melodic add components(scaffold @melodicdev/components usage)
