@solid-stack/mason
v1.0.24
Published
An interactive, type-safe CLI generator for scaffolding Solid Stack Clean Architecture features, usecases, domain entities, infrastructure, interfaces, httpHandlers, and injectables.
Readme
🧱 Mason (@solid-stack/mason)
The CLI Generator & Registry Engine for Solid Stack Clean Architecture
Mason is a type-safe CLI scaffolding tool and code-registry manager purpose-built for the Solid Stack Clean Architecture ecosystem (@solid-stack/agnos, @solid-stack/agnos-express, and @solid-stack/di).
Mason enables you to:
- Scaffold production-grade vertical slices: Generate features, use cases, domain models, runtime abstract interfaces, infrastructure adapters/stubs, HTTP endpoints, and DI providers via the CLI.
- Scaffold reusable shared modules: Generate encapsulated ports, adapters, and domain utilities with test stubs.
- Import from remote code registries: Download and link verified, pre-built modules from the Solid Stack Registry with topological dependency graph resolution, SHA-256 cryptographic drift detection, intelligent conflict resolution, import aliasing, and test file distribution.
- Enforce clean boundaries: Strictly decouple domain logic from presentation and database frameworks with zero runtime boilerplate.
📑 Table of Contents
- Architectural Blueprint
- Installation & Quick Start
- Configuration (
mason.config.json) - CLI Architecture & Execution Modes
- Global CLI Flags
- Command Reference: Scaffolding (
create) - Command Reference: Registry Import (
import) - Programmatic TypeScript API
- Docker, Testing & Makefiles
- License
- 🎯 CLI Cookbook: Real-World Examples & Complex Cases
🏗️ Architectural Blueprint
Mason scaffolds code according to strict Clean Architecture and Domain-Driven Design (DDD) vertical slice boundaries:
src/
├── features/
│ └── <feature>/
│ ├── domain/ # Pure domain models, entities, and runtime abstract interfaces
│ │ ├── <Entity>.ts # Pure domain model / value object (Zero DI dependencies!)
│ │ └── I<Entity>Repo.ts # Runtime abstract class (Serves as both type & DI token)
│ ├── infrastructure/ # Implementations of domain interfaces
│ │ ├── Stub<Entity>Repo.ts # In-memory test stub with helpers (clear, setError, getAll)
│ │ └── <Db><Entity>Repo.ts # Production adapter (@MakeInjectable)
│ ├── useCases/ # Application business logic
│ │ ├── <UseCase>.ts # Single-responsibility use case class (@MakeInjectable)
│ │ └── <UseCase>.test.ts # Vitest unit test exercising use case with test stubs
│ ├── pxExpress/ # Presentation layer (@solid-stack/agnos-express)
│ │ ├── index.ts # Route prefix (e.g. export const path = "/<feature>")
│ │ └── handlers/
│ │ └── <Handler>Http.ts # Endpoint extending ExpressRoute with Zod validation
│ └── diProvider.ts # Feature DI module registering interface -> infrastructure bindings
└── shared/
└── <module>/ # Reusable cross-cutting utility or port (e.g. hasher, time, uuid, jwt)
├── ports/ # Abstract classes defining ports (e.g. IHashEngine.ts)
├── infrastructure/ # Test stubs (StubHashEngine.ts) & concrete engines (ScryptHashEngine.ts)
├── <Module>.ts # Primary @MakeInjectable service facade
├── domain/ # Value objects or custom domain error types
├── <Module>.test.ts # Vitest unit tests
└── diProvider.ts # Shared DI provider moduleCore Architecture Rules Enforced by Mason:
- Zero DI in Domain: Entities and Value Objects never import
@solid-stack/dior framework decorators. - Abstract Classes as DI Tokens: Abstract classes are used for repositories and ports instead of plain TypeScript interfaces because abstract classes preserve runtime identity in JavaScript, eliminating string-token DI collisions.
- Dedicated In-Memory Stubs: Every domain interface and shared port receives an in-memory stub implementation with test manipulation methods (
clear(),setError(),setNextToken(),advance()), making use case tests fast, deterministic, and dependency-free. - Strict Import Portability: Modules use TypeScript path aliases (
@/shared/*,@/features/*), enabling automatic import rewriting when dependencies are aliased or relocated.
🚀 Installation & Quick Start
Mason can be executed directly on-demand or installed as a project dev dependency:
# Execute on-demand via pnpm dlx or npx
pnpm dlx @solid-stack/mason --help
# or
npx @solid-stack/mason --help
# Or install locally as a development dependency
pnpm add -D @solid-stack/mason
# Run directly via pnpm
pnpm mason --help⚙️ Configuration (mason.config.json)
Mason works out of the box with sensible defaults (src/features and src/shared), but custom destination paths can be configured using a mason.config.json file in your project root:
{
"$schema": "https://raw.githubusercontent.com/solid-stack-digital/mason/main/schema.json",
"paths": {
"features": "src/features",
"shared": "src/shared"
}
}[!NOTE] The schema definition exists in the Mason repository root as
schema.jsonand is distributed directly inside the@solid-stack/masonpackage (@solid-stack/mason/schema.json), providing full IDE auto-completion and validation.
Configuration Options
| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| $schema | string | — | URI or local path pointing to the Mason JSON validation schema. |
| paths.features | string | "src/features" | Destination directory for feature slices. |
| paths.shared | string | "src/shared" | Destination directory for reusable shared modules. |
🔄 CLI Architecture & Execution Modes
Mason provides a dual-interface CLI designed for both developer terminal usage and automated shell scripts / CI pipelines:
- Direct CLI Mode (Recommended for workflows & automation):
Pass subcommands, arguments, and flags directly. Use
-yor--yesto bypass prompts and accept intelligent defaults.pnpm mason create feature billing --yes pnpm mason create usecase ProcessInvoice -f billing --yes - Interactive Wizard Mode:
Running
masonormason createwithout arguments launches an interactive wizard with guided selections and codebase discovery. - Application Mode vs. Registry Mode:
- Application Mode (Default): Generates application code inside your project. Does not emit
registry.jsonmanifests. - Registry Mode (
--registry): Used by module authors maintaining code registries (e.g.mason-registry). Emits stampedregistry.jsonmanifests containing version, dependency metadata, and file lists.
- Application Mode (Default): Generates application code inside your project. Does not emit
🌐 Global CLI Flags
The following flags are supported across all Mason commands:
| Flag | Shorthand | Type | Description |
| :--- | :--- | :--- | :--- |
| --help | -h | boolean | Display help message and options for any command. |
| --version | -v | boolean | Display the current version of @solid-stack/mason. |
| --dry-run | -d | boolean | Preview file operations and transformations without writing to disk. |
| --overwrite | -o | boolean | Overwrite existing files if destination collisions are detected. |
| --yes | -y | boolean | Accept all recommended defaults and bypass interactive prompts for scripting. |
| --target <dir> | -t | string | Override the destination directory for the generated component. |
| --dest <dir> | | string | Alias for --target <dir>. |
| --registry | | boolean | Run or scaffold in registry mode (creates registry.json manifests). |
🔨 Command Reference: Scaffolding (create)
All scaffolding subcommands can be invoked via the canonical syntax mason create <type> [name] [options] or using flat top-level aliases (mason <type> [name] [options]).
1. mason create feature [name]
(Shorthand: mason feature [name])
Scaffolds a complete, self-contained Clean Architecture vertical slice with domain models, repository interfaces, in-memory stubs, use cases, Express route handlers, and a DI provider module.
mason create feature <name> [options]Arguments
[name](string, optional): Name of the feature (e.g.,users,billing,orders). Automatically converted to camelCase for directories and PascalCase for entities. Defaults to"feature"if omitted with--yes.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| --yes | -y | boolean | false | Non-interactive mode; accepts all recommended defaults. |
| --dry-run | -d | boolean | false | Preview generated files and paths without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing files if the feature directory already exists. |
| --target <dir> | -t | string | src/features/<name> | Custom destination directory for the feature slice. |
| --dest <dir> | | string | src/features/<name> | Alias for --target. |
| --express | | boolean | true | Include the Express presentation layer (pxExpress/index.ts and handlers). |
| --no-express | | boolean | false | Exclude Express presentation layer (creates a headless core feature slice). |
| --domainNames <names> | | string | Singular feature name | Comma-separated list of domain entity names to bootstrap (e.g. Product,Category). |
| --registry | | boolean | false | Scaffold in registry mode (generates registry.json manifest). |
| --description <text> | | string | "<name> feature module" | Module description for registry.json in registry mode. |
Generated Vertical Slice Structure
src/features/billing/
├── domain/
│ ├── Invoice.ts # Pure domain entity
│ └── IInvoiceRepo.ts # Abstract class serving as DI token & contract
├── infrastructure/
│ └── StubInvoiceRepo.ts # In-memory test stub with manipulation helpers
├── useCases/
│ ├── CreateInvoice.ts # Business logic class with @MakeInjectable
│ ├── CreateInvoice.test.ts # Vitest unit test pre-wired with StubInvoiceRepo
│ ├── GetInvoice.ts
│ ├── ListInvoices.ts
│ ├── UpdateInvoice.ts
│ └── DeleteInvoice.ts
├── pxExpress/
│ ├── index.ts # Route prefix export (e.g. path = "/billing")
│ └── handlers/
│ ├── CreateInvoiceHttp.ts # ExpressRoute endpoint with Zod validation
│ ├── GetInvoiceHttp.ts
│ ├── ListInvoicesHttp.ts
│ ├── UpdateInvoiceHttp.ts
│ └── DeleteInvoiceHttp.ts
└── diProvider.ts # DI module binding IInvoiceRepo -> StubInvoiceRepo2. mason create shared [name]
(Shorthand: mason shared [name])
Scaffolds a reusable shared utility module with abstract ports, in-memory stubs, facade classes, and DI registration.
mason create shared <name> [options]Arguments
[name](string, optional): Shared module name (e.g.,hasher,time,uuid,cache,logger). Converted to kebab-case. Defaults to"shared"if omitted with--yes.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| --yes | -y | boolean | false | Non-interactive mode; accepts all recommended defaults. |
| --dry-run | -d | boolean | false | Preview generated files without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing files if module directory exists. |
| --target <dir> | -t | string | src/shared/<name> | Custom destination directory for the shared module. |
| --dest <dir> | | string | src/shared/<name> | Alias for --target. |
| --description <text> | | string | "" | Description of the shared module. |
| --registry | | boolean | false | Scaffold in registry mode (generates registry.json manifest). |
Generated Structure
src/shared/cache/
├── ports/
│ └── ICacheEngine.ts # Abstract class defining the port contract
├── infrastructure/
│ └── StubCacheEngine.ts # In-memory test stub for deterministic tests
├── Cache.ts # Primary injectable facade service
├── Cache.test.ts # Vitest unit tests
└── diProvider.ts # DI module registering ICacheEngine -> StubCacheEngine3. mason create usecase [name]
(Shorthand: mason usecase [name])
Scaffolds a single-responsibility application use case class decorated with @MakeInjectable, typed input/output DTOs, and an accompanying Vitest unit test.
mason create usecase <name> [options]Arguments
[name](string, optional): Name of the use case (e.g.,PlaceOrder,ResetPassword,VerifyEmail). Converted to PascalCase.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| -f, --feature <feature> | -f | string | None | Target feature slice (required in non-interactive CLI mode). |
| --yes | -y | boolean | false | Accept defaults; skips interactive input/output property prompts. |
| --dry-run | -d | boolean | false | Preview changes without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing use case files. |
Generated Files
src/features/<feature>/useCases/<UseCase>.ts: Contains input DTO, output DTO, static dependencies injection mapping, andexecute()method.src/features/<feature>/useCases/<UseCase>.test.ts: Vitest test skeleton pre-wired with feature test stubs.
4. mason create domain [name]
(Shorthand: mason domain [name])
Scaffolds a pure domain model, entity class, or value object without framework dependencies.
mason create domain <name> [options]Arguments
[name](string, optional): Domain entity name (e.g.,User,Order,Money). Converted to PascalCase.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| -f, --feature <feature> | -f | string | None | Target feature slice (required in non-interactive CLI mode). |
| --yes | -y | boolean | false | Accept defaults (generates TypeScript interface with id, createdAt, updatedAt). |
| --dry-run | -d | boolean | false | Preview generated file without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing domain file. |
Supported Domain Models
- TypeScript Interface: Pure data contract for lightweight domain models.
- Entity Class: Class with constructor, properties, and encapsulation methods.
- Value Object: Immutable model with private constructor, static factory
create(), andequals()equality method.
5. mason create interface [name]
(Shorthand: mason interface [name])
Scaffolds a domain repository or service interface abstract class, auto-generates an in-memory test stub in infrastructure/, and updates diProvider.ts.
mason create interface <name> [options]Arguments
[name](string, optional): Interface name (e.g.,IUserRepository,IOrderRepo). Automatically prefixed withIif omitted.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| -f, --feature <feature> | -f | string | None | Target feature slice (required in non-interactive CLI mode). |
| --entity <entity> | | string | Inferred | Associated domain entity name for method signature generation. |
| --yes | -y | boolean | false | Non-interactive mode (creates abstract class, CRUD signatures, stub, and DI provider entry). |
| --dry-run | -d | boolean | false | Preview generated files without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing interface or stub files. |
6. mason create infrastructure [name]
(Shorthand: mason infrastructure [name])
Scaffolds an infrastructure adapter (e.g. database repository, cloud client) or an in-memory test stub implementing a domain interface.
mason create infrastructure <name> [options]Arguments
[name](string, optional): Class name (e.g.,PostgresUserRepository,StubOrderRepo,S3StorageAdapter). Converted to PascalCase.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| -f, --feature <feature> | -f | string | None | Target feature slice (when scoped to a feature). |
| -g, --global | -g | boolean | false | Place in global src/infrastructure/ instead of inside a feature slice. |
| -i, --interface <iface> | -i | string | Inferred | Domain interface or abstract class implemented by this class. |
| -k, --kind <kind> | -k | "stub" \| "concrete" | Inferred | Implementation kind (stub with test helpers or concrete with @MakeInjectable). Inferred from Stub prefix. |
| --no-provider | | boolean | false | Skip automatic registration in feature diProvider.ts when using -y. |
| --yes | -y | boolean | false | Non-interactive mode; accepts defaults. |
| --dry-run | -d | boolean | false | Preview generated files without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing implementation files. |
7. mason create httpHandler [name]
(Shorthand: mason httpHandler [name])
Scaffolds an Express endpoint handler extending ExpressRoute for @solid-stack/agnos-express, configured with dependency injection, use case execution, and Zod input validation.
mason create httpHandler <name> [options]Arguments
[name](string, optional): HTTP Route Handler class name (e.g.,CreateUserHttp,GetUserHttp). Automatically appendsHttpsuffix if omitted.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| -f, --feature <feature> | -f | string | None | Target feature slice (required in non-interactive CLI mode). |
| -m, --method <method> | -m | "get" \| "post" \| "put" \| "patch" \| "delete" | "get" | HTTP method for the route. |
| -p, --path <path> | -p | string | "/" | Route subpath relative to feature route prefix (e.g. /, /:id, /search). |
| -u, --usecase <usecase> | -u | string | None | Name of the domain use case class to inject and execute. |
| --message <message> | | string | None | Custom success message returned in the standard HTTP response JSON. |
| --yes | -y | boolean | false | Non-interactive mode; accepts defaults. |
| --dry-run | -d | boolean | false | Preview generated files without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing handler files. |
8. mason create injectable [name]
(Shorthand: mason injectable [name])
Scaffolds a general-purpose class decorated with @MakeInjectable for services, transformers, or utilities.
mason create injectable <name> [options]Arguments
[name](string, optional): Injectable class name (e.g.,PasswordHasher,TokenService,UserTransformer). Converted to PascalCase.
Options & Flags
| Flag | Shorthand | Type | Default | Description |
| :--- | :--- | :--- | :--- | :--- |
| -f, --feature <feature> | -f | string | None | Target feature to scope the service into (features/<feature>/services/). |
| -t, --target <dir> | -t | string | None | Custom destination directory path. |
| --dest <dir> | | string | None | Alias for --target. |
| --yes | -y | boolean | false | Non-interactive mode; accepts defaults. |
| --dry-run | -d | boolean | false | Preview generated file without writing to disk. |
| --overwrite | -o | boolean | false | Overwrite existing injectable files. |
📦 Command Reference: Registry Import (import)
Mason includes a package and module registry client that downloads verified pre-built modules from the Solid Stack Registry into your project, automatically resolving recursive dependency graphs, handling cryptographic drift, rewriting import paths, and installing required npm packages.
Import Command Syntax
mason import [type] [name] [options][type]: Module type to import:sharedorfeature(orfeatures).[name]: Name of the module from the registry (e.g.,hasher,authn,jwt,time,uuid).
Import Options & Flags
| Flag | Shorthand | Type | Description |
| :--- | :--- | :--- | :--- |
| --registry <url \| path> | | string | Override the registry URL or specify a local directory path (e.g. ../mason-registry). |
| --tests | | boolean | Include unit test files from the registry (default: true). |
| --no-tests | | boolean | Exclude unit test files during import, leaving only production code. |
| --alias <mapping> | | string | Programmatically import a conflicting dependency under a new alias name (e.g. --alias time:time-mason). |
| --point-to <mapping> | | string | Point a dependency to an existing local module without downloading duplicates (e.g. --point-to time:mytime). |
| --use-existing <mapping> | | string | Alias for --point-to <mapping>. |
| -o, --overwrite | -o | boolean | Overwrite existing local files with registry copies without prompting. |
| --skip-install | | boolean | Skip automatic detection and installation of missing npm packages via package manager. |
| -y, --yes | -y | boolean | Accept all defaults non-interactively; keeps existing local versions on conflict and skips prompts. |
| -d, --dry-run | -d | boolean | Preview files to be downloaded and import rewrites without writing to disk. |
Cryptographic Drift Detection & Resolution Flags
Mason calculates composite SHA-256 hashes of local source code (normalizing line endings) and compares them against remote registry integrity hashes.
When local modules have drifted or differ from registry versions, CLI flags provide deterministic, non-interactive control:
- Keep Existing Local Version (Default in
-ymode): Keeps your customized local files intact. Incoming dependent modules are linked to your local module. - Import Fresh Copy Under an Alias (
--alias <dep>:<new-name>): Downloads the registry dependency intosrc/shared/<new-name>. Mason automatically rewrites all TypeScript import paths across all dependent files to point to the new alias.pnpm mason import feature authn --alias time:time-mason -y - Point to Another Existing Module (
--point-to <dep>:<existing-name>): Re-links the dependency to a different local module. Zero duplicate files are downloaded, and Mason rewrites all import paths to point to@/shared/<existing-name>.pnpm mason import feature authn --point-to time:mytime -y - Overwrite Local Version (
--overwrite/-o): Replaces the local diverged files with clean registry copies.pnpm mason import feature authn --overwrite -y
Test Files Management
Every registry module includes full unit test suites (e.g. Hasher.test.ts, Login.test.ts).
- Include Tests (Default /
--tests): Downloads test files and rewrites all path aliases so tests pass immediately in Vitest. - Exclude Tests (
--no-tests): Omits test files for a minimal production footprint. - Integrity Invariance: Registry integrity hashes are calculated exclusively on non-test source files. Module hashes remain 100% valid whether tests are included or excluded.
💻 Programmatic TypeScript API
Mason can be used programmatically in custom generators, node scripts, or CI automation:
import {
generateFeature,
generateShared,
generateUseCase,
generateDomain,
generateInterface,
generateInfrastructure,
generateHttpHandler,
generateInjectable,
rewriteImports,
computeDirectoryHash,
isTestFile,
} from "@solid-stack/mason";
// 1. Programmatically scaffold a feature
const files = generateFeature({
name: "notifications",
projectRoot: process.cwd(),
includeExpress: true,
includeTests: true,
});
// 2. Programmatically rewrite import strings
const rewritten = rewriteImports(
`import { Clock } from "@/shared/time/Clock.js";`,
new Map([["@/shared/time", "@/shared/custom-time"]])
);
// Output: 'import { Clock } from "@/shared/custom-time/Clock.js";'
// 3. Compute deterministic directory hash (invariant to line endings & test files)
const hash = computeDirectoryHash("./src/shared/hasher");
console.log(hash); // 'sha256-09ebf144dd06...'🐳 Docker, Testing & Makefiles
Mason is verified with Docker, Docker Compose, and Makefiles for hermetic reliability.
Available Makefile Targets
| Target | Command | Description |
| :--- | :--- | :--- |
| make test | docker compose up --build test | Runs the full test suite in an isolated Linux container with a fresh build. |
| make test/cache | docker compose up test | Runs the test suite in Docker using cached image layers for maximum speed. |
| make dev | docker compose up dev | Runs the watcher in a container with mounted source volumes. |
| make build | docker compose up --build build | Builds the production distribution packages inside Docker. |
| make clean | docker compose down -v --remove-orphans | Tears down all containers, volumes, and temporary networks. |
Local Development Commands
pnpm dev # Start tsup watcher
pnpm build # Compile ESM/CJS bundles to dist/
pnpm test # Run Vitest unit tests
pnpm typecheck # Typecheck TypeScript without emitting (tsc --noEmit)
pnpm check # Run typecheck, tests, and build in sequence📄 License
UNLICENSED © Solid Stack Digital. All rights reserved.
Strictly confidential and proprietary. No part of this software may be used, copied, modified, distributed, sublicensed, or sold in any form or by any means without the prior written permission of the copyright owner. See LICENSE for full details.
🎯 CLI Cookbook: Real-World Examples & Complex Cases
Below is an exhaustive collection of real-world use cases mapping specific developer objectives directly to Mason CLI commands.
Basic Scaffolding Examples
1. Scaffold a standard feature slice with default CRUD and Express routes
# Goal: Create a full 'users' feature slice non-interactively
pnpm mason create feature users --yes2. Scaffold a headless / backend-only feature slice (no Express presentation layer)
# Goal: Create an 'analytics' slice with domain and usecases only, omitting pxExpress/
pnpm mason create feature analytics --no-express --yes3. Scaffold a feature slice with multiple domain entities
# Goal: Create an 'inventory' feature with multiple domain entities (Product, Warehouse, StockLevel)
pnpm mason create feature inventory --domainNames Product,Warehouse,StockLevel --yes4. Scaffold a feature slice into a custom directory path
# Goal: Place the feature in a custom path or monorepo package
pnpm mason create feature billing --target packages/billing-service/src/features/billing --yes5. Preview feature generation without writing anything to disk (dry-run)
# Goal: Inspect generated files and directory paths without creating files
pnpm mason create feature orders --dry-run6. Force overwrite an existing feature slice with clean defaults
# Goal: Re-scaffold the 'auth' feature, replacing any colliding files
pnpm mason create feature auth --overwrite --yesDomain & Infrastructure Scaffolding
7. Scaffold a domain entity model into a feature
# Goal: Add a 'Customer' domain entity to the 'customers' feature
pnpm mason create domain Customer -f customers --yes8. Scaffold a domain repository interface with automatic stub and DI binding
# Goal: Create ICustomerRepo, generate StubCustomerRepo, and wire them in diProvider.ts
pnpm mason create interface ICustomerRepo -f customers --entity Customer --yes9. Scaffold a concrete production database adapter implementing a domain interface
# Goal: Create PostgresCustomerRepo implementing ICustomerRepo with @MakeInjectable
pnpm mason create infrastructure PostgresCustomerRepo -f customers -i ICustomerRepo -k concrete --yes10. Scaffold an in-memory test stub for an existing domain interface
# Goal: Explicitly generate a test stub with in-memory map and test helper methods
pnpm mason create infrastructure StubCustomerRepo -f customers -i ICustomerRepo -k stub --yes11. Scaffold a global infrastructure service outside of feature slices
# Goal: Create a cross-cutting S3ObjectStorage adapter placed in src/infrastructure/
pnpm mason create infrastructure S3ObjectStorage --global -k concrete --yesUse Cases & HTTP Handler Scaffolding
12. Add a new business logic use case to an existing feature
# Goal: Add a 'ChangePassword' use case class and test skeleton to 'auth'
pnpm mason create usecase ChangePassword -f auth --yes13. Scaffold a POST HTTP endpoint handler bound to a use case with a custom path and response message
# Goal: Create endpoint POST /billing/checkout executing ProcessCheckout usecase
pnpm mason create httpHandler ProcessCheckoutHttp -f billing -m post -p /checkout -u ProcessCheckout --message "Checkout processed successfully" --yes14. Scaffold a GET HTTP endpoint handler with route parameter
# Goal: Create endpoint GET /users/:id executing GetUser usecase
pnpm mason create httpHandler GetUserHttp -f users -m get -p /:id -u GetUser --yes15. Scaffold a general-purpose injectable service in a feature
# Goal: Create TokenGenerator service inside features/auth/services/
pnpm mason create injectable TokenGenerator -f auth --yesEnd-to-End Vertical Slice Construction Pipeline
The following scripted CLI pipeline demonstrates building a production-ready vertical slice from scratch with zero manual prompts:
#!/usr/bin/env bash
set -e
# Step 1: Scaffold feature slice without express routes initially
pnpm mason create feature subscriptions --no-express --yes
# Step 2: Add additional domain entity
pnpm mason create domain Plan -f subscriptions --yes
# Step 3: Create domain repository interface (auto-creates StubSubscriptionRepo & binds in diProvider.ts)
pnpm mason create interface ISubscriptionRepo -f subscriptions --entity Subscription --yes
# Step 4: Create concrete production adapter (e.g. Postgres repository)
pnpm mason create infrastructure PostgresSubscriptionRepo -f subscriptions -i ISubscriptionRepo -k concrete --yes
# Step 5: Create application use cases
pnpm mason create usecase ActivateSubscription -f subscriptions --yes
pnpm mason create usecase CancelSubscription -f subscriptions --yes
# Step 6: Create presentation HTTP endpoints extending ExpressRoute
pnpm mason create httpHandler ActivateSubscriptionHttp -f subscriptions -m post -p /activate -u ActivateSubscription --message "Subscription activated" --yes
pnpm mason create httpHandler CancelSubscriptionHttp -f subscriptions -m post -p /cancel -u CancelSubscription --message "Subscription cancelled" --yes
# Step 7: Run tests to verify generated code passes immediately
pnpm testShared Module & Registry Authoring Examples
16. Scaffold a reusable shared module with description
# Goal: Create a shared cache module with ports, stubs, and facade
pnpm mason create shared cache --description "Multi-tier memory and Redis caching abstraction" --yes17. Scaffold a shared module in Registry Mode (registry.json)
# Goal: Scaffold shared module with an author manifest for publishing to mason-registry
pnpm mason create shared logger --description "Structured Pino logger port and stub" --registry --yes18. Scaffold a feature slice in Registry Mode
# Goal: Scaffold a complete reusable feature with registry.json manifest
pnpm mason create feature payments --description "Stripe and PayPal payment processing slice" --registry --yesRegistry Import: Simple to Highly Complex Scenarios
19. Import a shared utility module from the official registry
# Goal: Download pre-built 'hasher' module (Argon2/Scrypt port and stubs) into src/shared/hasher
pnpm mason import shared hasher --yes20. Import a complete feature slice with all transitive dependencies
# Goal: Import 'authn' feature; automatically imports dependencies (hasher, jwt, time, uuid, otp)
pnpm mason import feature authn --yes21. Import a module excluding unit tests for lean production deployments
# Goal: Download only runtime code, omitting *.test.ts and test fixtures
pnpm mason import feature authn --no-tests --yes22. Import without running the package manager (skip npm/pnpm install)
# Goal: Defer package installation in CI or scripted environments
pnpm mason import feature authn --skip-install --yes23. Import from a local directory registry (Monorepo or local development)
# Goal: Import directly from a local repository clone rather than remote GitHub
pnpm mason import shared hasher --registry ../mason-registry --yes24. Complex Case: Resolving drift by aliasing a dependency to a clean copy (--alias)
# Scenario:
# Your project already contains a customized 'src/shared/time' module.
# The incoming 'authn' feature requires the official registry version of 'time'.
#
# Goal: Download registry 'time' under 'time-mason' and automatically rewrite all imports
# in 'authn' and 'jwt' from '@/shared/time/*' to '@/shared/time-mason/*' without touching local 'time'.
pnpm mason import feature authn --alias time:time-mason --yes25. Complex Case: Resolving drift by pointing a dependency to an existing module (--point-to)
# Scenario:
# Your project has an existing custom module at 'src/shared/myhasher'.
# The incoming 'authn' feature depends on 'shared/hasher'.
#
# Goal: Reuse 'myhasher' with zero duplicate downloads and rewrite all imports
# in 'authn' from '@/shared/hasher/*' to '@/shared/myhasher/*'.
pnpm mason import feature authn --point-to hasher:myhasher --yes26. Complex Case: Multi-dependency resolution in a single automated command
# Scenario:
# Importing 'authn' which depends on 'time', 'hasher', and 'uuid'.
# - 'time' has local drift -> alias to fresh copy 'time-upstream'
# - 'hasher' exists locally as 'custom-hasher' -> point to 'custom-hasher'
# - Exclude test files to keep project lean
# - Skip package manager installation
# - Fully non-interactive execution
pnpm mason import feature authn \
--alias time:time-upstream \
--point-to hasher:custom-hasher \
--no-tests \
--skip-install \
--yes27. Complex Case: Force complete upstream overwrite in CI/CD pipelines
# Scenario:
# Automated nightly update job synchronizing core features against upstream registry.
# Overwrite any local modifications with canonical registry versions.
pnpm mason import feature authn --overwrite --yes28. Complex Case: Dry-run previewing topological resolution and import rewrites
# Scenario:
# Inspecting what modules, files, and import rewrites will occur without modifying the workspace.
pnpm mason import feature authn --alias time:time-v2 --dry-run