@shobman/strata-cli
v0.1.1
Published
Contract engine and CLI for the Strata layout protocol
Maintainers
Readme
@shobman/strata-cli
CLI toolchain and contract engine for the Strata layout protocol. Validates YAML contracts, generates TypeScript types, and scaffolds routes and components.
Installation
npm install @shobman/strata-cliCommands
strata init
Initialise a project with Strata contracts and AI skill file. Idempotent — safe to run multiple times.
npx strata initCreates:
.claude/skills/STRATA-SKILL.md # AI agent skill file
components/atoms/_contract.yml # atom level contract
components/molecules/_contract.yml # molecule level contract
components/organisms/_contract.yml # organism level contract
routes/_contract.yml # root route contractAlso adds strata:check and strata:build scripts to your package.json.
strata check
Validate all contracts (YAML only, no source code). Fast — runs in CI.
npx strata checkExit code 1 if errors are found. Output format:
error fills-reference-real-slots routes/funds/index/_contract.yml
Fill "nonexistent" does not match any slot in ancestors or self
warn route-level-consistency routes/funds/_contract.yml
Route-level contract should use level: route, rank: 3Validation rules:
| Rule | Severity | Description |
|------|----------|-------------|
| fills-reference-real-slots | error | All fills must reference slots declared by ancestors or self |
| required-slots-satisfied | error | Required slots must be filled through the default/redirect chain |
| default-redirect-mutual-exclusivity | error | A route cannot have both default and redirect |
| default-redirect-target-exists | error | Named child must exist as a subfolder |
| param-route-excluded-from-default-redirect | error | Dynamic routes ([param]) cannot be defaults or redirects |
| route-level-consistency | warn | Routes should be level: route, rank: 3 |
| component-level-consistency | warn | Components should match their directory level |
strata build
Generate TypeScript types from YAML contracts.
npx strata buildCreates .strata.types.ts next to each _contract.yml:
// AUTO-GENERATED by strata build — do not edit
export type FundsFundIdSlots = "tabs" | "contextPanel";
export type FundsFundIdRequiredSlots = "tabs";
export type FundsFundIdInheritedSlots = "breadcrumb" | "actions";
export type FundsFundIdAllSlots = FundsFundIdSlots | FundsFundIdInheritedSlots;Type naming convention: path segments are PascalCased and joined. routes/funds/[fundId] becomes FundsFundId.
strata add route <path>
Scaffold a new route with contract, page stub, and optional layout.
npx strata add route funds/[fundId]/compliance
npx strata add route funds --fills menu --slots listActions --default index| Flag | Description |
|------|-------------|
| --fills <slots> | Comma-separated slot names this route fills |
| --slots <slots> | Comma-separated slot names this layout declares (generates _layout.tsx) |
| --default <child> | Child that renders at this route's URL (index route) |
| --redirect <child> | Child that this route redirects to |
| --param <name> | Route parameter name (auto-detected from brackets) |
Creates _contract.yml and index.tsx. If --slots is provided, also creates _layout.tsx with SlotProvider/SlotTarget boilerplate. Runs strata build automatically after scaffolding.
strata add <level> <name>
Scaffold a component at the specified level.
npx strata add atom Button
npx strata add molecule SearchBar
npx strata add organism FundPanelCreates components/<level>s/<Name>/index.tsx and the level's _contract.yml if missing.
Contract Format
Every route directory contains a _contract.yml:
param: fundId # route parameter name (optional)
level:
name: route # atom | molecule | organism | route
rank: 3 # 0 | 1 | 2 | 3
fills: [breadcrumb, actions] # ancestor slots this route fills
layout:
slots:
tabs: required # slot declarations (required or null)
contextPanel:
default: overview # child renders at this URL (index route)
redirect: performance # parent URL redirects to child URLProgrammatic API
The contract engine is available as a library:
import {
buildContractTree,
validateContracts,
resolveAvailableSlots,
} from "@shobman/strata-cli";| Export | Description |
|--------|-------------|
| buildContractTree(rootDir) | Build hierarchical contract tree from filesystem |
| validateContracts(tree) | Run all validation rules, returns diagnostics |
| resolveAvailableSlots(node) | Get all slots available to a node (own + ancestor) |
| resolveAncestorSlots(node) | Get ancestor slots only |
| isSlotFilledInChain(node, name) | Check if slot is filled through default/redirect chain |
| parseContractFile(path) | Parse a single _contract.yml |
Tips
YAML bracket quoting
[fundId] is valid YAML array syntax. All _contract.yml references to parameterised folders must use quotes:
# Correct
default: "[fundId]"
# Wrong — YAML parses this as an array
default: [fundId]The strata add command handles this automatically when generating contracts for bracket segments.
