CLI Reference
The worm CLI is the command-line interface for S3WORM. It handles schema initialization, data import, validation, local development, code generation, and LLM content output.
Quick Reference Cheat Sheet
| Command | Description | Key Flags |
|---|---|---|
worm init | Initialize a .worm/ project | — |
worm import | Scan files and infer schema | --no-ai, --model <id> |
worm lint | Validate schema definition | — |
worm dev [path] | Start local dev mode (filesystem) | [path] (default: .worm) |
worm codegen | Generate TypeScript + Zod from schema | --zod, --output <dir> / -o |
worm llms | Generate llms.txt for AI consumption | --output <path> |
worm version | Print CLI version | — |
worm push | Push local data to S3 bucket | Coming soon |
worm pull | Pull S3 bucket data to local | Coming soon |
worm diff | Diff local vs remote | Coming soon |
worm status | Show sync status | Coming soon |
worm serve | Local S3-compatible HTTP server | Coming soon |
Installation
pnpm add -g @decoperations/s3worm
The CLI is available as the worm command after installation.
Commands
worm init
Initialize a new S3WORM project in the current directory. Creates the .worm/ directory structure with a starter schema and example data.
worm init
What It Creates
.worm/
schema.json # Schema definition with example models
import.prompt.md # AI import prompt template
data/ # Local data directory (filesystem transport root)
generated/ # Output directory for codegen
examples/ # Example data files
The generated schema.json includes sensible defaults: symbols, common dynamic types (uuid, evm), operators (auto, seq), and a "root" storage layout.
worm import
Scan the .worm/data/ directory, discover existing files, and infer schema paths from the file structure. Can use AI or heuristic mode for schema inference.
worm import [options]
Options
| Flag | Description |
|---|---|
--no-ai | Disable AI inference; use heuristic mode only |
--model <id> | OpenAI model to use for AI inference (default: gpt-4.1-mini) |
Behavior
- Recursively scans
.worm/data/for all files - Groups files by directory structure
- Infers path DSL patterns from file paths
- In AI mode: sends discovered paths and file samples to OpenAI for schema generation
- In heuristic mode: applies rule-based inference (directory depth, naming conventions)
- Writes inferred paths and models to
schema.json
Example
# AI-powered import (requires OPENAI_API_KEY)
worm import
# Heuristic-only import
worm import --no-ai
# Use a specific OpenAI model
worm import --model gpt-4.1
worm lint
Validate the schema definition. Checks for structural correctness, symbol consistency, path validity, dynamic type references, rule conflicts, and model integrity.
worm lint
What It Validates
| Check | Description |
|---|---|
| Symbols | All symbol keys (namespace, collection, dynamic, requiredFile) are defined |
| Paths | Path patterns use valid symbols and reference declared dynamic types |
| Dynamic types | Regex patterns are valid; referenced types exist |
| Models | Field types are valid; ref targets exist; idType matches a dynamic type |
| Rules | applyTo paths are valid; ACL and scope expressions are well-formed |
| ACL conflicts | Detects conflicting ACL declarations between rules and model-level ACLs |
| Views | Referenced models exist; filter fields exist on the target model |
| Storage | Layout values are valid ("inline", "collection", or "root") |
Output
$ worm lint
Linting .worm/schema.json...
ERROR [MODEL_REF_MISSING] Invoice.customerId refs "Customer" but model "Customer" not found
WARN [RULE_ACL_OVERLAP] Rule "admin-only" overlaps with model ACL on "Invoice"
1 error, 1 warning
Exits with code 1 if any errors are found. Warnings do not affect the exit code.
worm dev
Start local development mode. Uses the filesystem transport to read and write entities from .worm/data/. Watches for file changes and reports mutations in real time.
worm dev [path]
Arguments
| Argument | Default | Description |
|---|---|---|
path | .worm | Path to the .worm/ directory |
Behavior
- Loads
schema.jsonfrom the specified directory - Creates a
LocalFsTransportpointing at thedata/subdirectory - Validates the schema on startup
- Watches the
data/directory for file changes - On change: detects the affected model and entity, logs the mutation
Example
# Start dev mode with default path
worm dev
# Point to a custom .worm directory
worm dev ./my-project/.worm
The dev server provides a live feedback loop: edit JSON files in .worm/data/ and see changes reflected immediately. This is the foundation for local-first development with S3WORM.
worm codegen
Generate TypeScript interfaces and optional Zod validation schemas from your schema.json models. The output gives you type-safe entity types, repository aliases, and a model map for generic helpers.
worm codegen [options]
Options
| Flag | Alias | Description |
|---|---|---|
--zod | — | Also generate Zod validation schemas (models.zod.ts) |
--output <dir> | -o <dir> | Override output directory (default: schema.generatedDir or .worm/generated) |
Output Files
| File | When | Contents |
|---|---|---|
models.ts | Always | TypeScript interfaces extending SchemaEntity, repository type aliases, ModelName union, ModelMap |
models.zod.ts | With --zod | Zod schema objects (z.object), z.infer type exports |
Output Directory Resolution
The output directory is determined in this order:
--output/-oCLI flaggeneratedDirfield in yourschema.json.worm/generated(default fallback)
Type Mapping
| Schema Field Type | TypeScript Type | Zod Type |
|---|---|---|
string | string | z.string() |
number | number | z.number() |
boolean | boolean | z.boolean() |
datetime | string | z.string() |
object | Record<string, unknown> | z.record(z.unknown()) |
string[] | string[] | z.array(z.string()) |
number[] | number[] | z.array(z.number()) |
object[] | Record<string, unknown>[] | z.array(z.record(z.unknown())) |
| Enum field | "val1" | "val2" | z.enum(["val1", "val2"]) |
ref field | EntityRef | z.object({ $model: z.string(), $id: z.string() }) |
Auto-fields (createdAt, updatedAt) are inherited from SchemaEntity in the TypeScript output but included explicitly in Zod schemas. Optional fields get ? in TypeScript and .optional() in Zod. Default values are preserved in Zod via .default().
Example
# Generate TypeScript interfaces only
worm codegen
# Generate TypeScript + Zod schemas
worm codegen --zod
# Custom output directory
worm codegen --zod --output src/generated
Generated TypeScript (Example)
Given a schema with a Customer model:
// Auto-generated by `worm codegen` — do not edit
import type { SchemaEntity, EntityRef, SchemaRepository } from "@decoperations/s3worm";
/** Customer entity */
export interface Customer extends SchemaEntity {
name: string;
email: string;
company?: string;
status?: "active" | "inactive" | "churned";
tags?: string[];
}
export type CustomerRepository = SchemaRepository;
/** Union of all model names */
export type ModelName = "Customer";
/** Map from model name to entity type */
export interface ModelMap {
Customer: Customer;
}
Generated Zod Schema (Example)
With --zod:
// Auto-generated by `worm codegen` — do not edit
import { z } from "zod";
export const CustomerSchema = z.object({
id: z.string(),
name: z.string(),
email: z.string(),
company: z.string().optional(),
status: z.enum(["active", "inactive", "churned"]).default("active"),
tags: z.array(z.string()).optional(),
createdAt: z.string(),
updatedAt: z.string(),
});
export type Customer = z.infer<typeof CustomerSchema>;
worm llms
Generate an llms.txt file for AI and LLM consumption. Outputs a structured text representation of the schema that can be used as context for AI assistants.
worm llms [options]
Options
| Flag | Description |
|---|---|
--output <path> | Output file path (default: stdout) |
Example
# Print to stdout
worm llms
# Write to a file
worm llms --output llms.txt
The output includes the full schema definition, model descriptions, field types, path patterns, and relationship information in a format optimized for LLM context windows.
worm version
Print the current CLI version.
worm version
$ worm version
worm v0.5.1
Environment Variables
| Variable | Description | Required |
|---|---|---|
WORM_ROOT | Override the default .worm/ directory location | No |
OPENAI_API_KEY | OpenAI API key for AI-powered import | For worm import with AI |
WORM_OPENAI_MODEL | Override the default OpenAI model for import | No |
WORM_ROOT
By default, the CLI looks for .worm/ in the current working directory. Set WORM_ROOT to override:
export WORM_ROOT=/path/to/project/.worm
worm lint # uses /path/to/project/.worm/schema.json
OPENAI_API_KEY
Required when running worm import in AI mode. The CLI uses this key to call the OpenAI API for schema inference.
export OPENAI_API_KEY=sk-...
worm import
WORM_OPENAI_MODEL
Override the default OpenAI model used for AI import. Defaults to gpt-4.1-mini.
export WORM_OPENAI_MODEL=gpt-4.1
worm import
Directory Structure
After worm init, your project has this structure:
project/
.worm/
schema.json # Schema definition
import.prompt.md # AI import prompt
data/ # Local entity data (filesystem transport)
org/
customers/
abc-123/
profile.json
settings/
config.json
generated/ # Codegen output
models.ts # Generated TypeScript interfaces
examples/ # Example files
The data/ directory mirrors the S3 bucket structure. Paths in schema.json map directly to directory paths under data/:
Path: #org/@customers/(id:uuid)/[profile].json
Local: .worm/data/org/customers/{uuid}/profile.json
S3 key: org/customers/{uuid}/profile.json
Coming Soon
These commands are planned for upcoming releases. See the Roadmap for details.
| Command | Description |
|---|---|
worm push | Push .worm/data/ to a live S3 bucket |
worm pull | Pull a live S3 bucket into .worm/data/ |
worm diff | Show differences between local and remote data |
worm status | Display sync status (local vs remote) |
worm serve | Start a local S3-compatible HTTP endpoint (MinIO-lite) |
Exit Codes
| Code | Meaning |
|---|---|
0 | Success |
1 | Validation errors (lint), missing schema, or runtime error |
2 | Missing required configuration (e.g., no OPENAI_API_KEY for AI import) |