@rcrsr/rill-cli
v0.19.6
Published
CLI tools for the rill scripting language
Maintainers
Readme
@rcrsr/rill-cli
Command-line tools for running and validating rill scripts.
[!WARNING] This language is experimental. Breaking changes will occur before stabilization.
| Subcommand | Purpose |
|------------|---------|
| rill bootstrap | Initialize a new rill project (.rill/npm/, rill-config.json) |
| rill install <pkg> | Install an extension into .rill/npm/ and mount it |
| rill uninstall <mount> | Remove a mounted extension |
| rill upgrade <mount> | Update a mounted extension to a newer version |
| rill list | List installed extensions and their mount paths |
| rill build | Bundle the project for production |
| rill check | Validate rill-config.json and source files |
| rill describe | Print callable contracts (handler signatures) |
| rill eval <expr> | Evaluate a rill expression and print the result |
| rill exec <file> | Execute a rill script file or stdin input |
| rill run [project-dir] | Execute the project entry from rill-config.json |
Run rill help <command> or rill <command> --help for details.
Install
Requires Node.js >= 22.16.0. The CLI checks process.versions.node at entry and exits with a clear error on older runtimes.
npm install -g @rcrsr/rill-cliOr as a project dependency (@rcrsr/rill and @rcrsr/rill-config are declared as both runtime and peer dependencies, and will deduplicate with your project's installed versions):
npm install @rcrsr/rill-cliQuickstart
rill bootstrap # initialize project + .rill/npm/
rill install @rcrsr/rill-ext-datetime # add an extension
rill list # show installed extensions
rill build # bundle for production
rill run # execute the projectSubcommands
rill bootstrap
Initialize a new rill project. Creates .rill/npm/, .rill/tsconfig.rill.json, and a starter rill-config.json in the current directory.
rill bootstrap
rill bootstrap --force # rewrite rill-config.json (preserves .rill/npm/)
rill bootstrap --reset # wipe .rill/npm/ and rewrite all scaffolded filesOptions:
| Flag | Description |
|------|-------------|
| --force | Overwrite existing rill-config.json. .rill/npm/ and installed extensions are preserved. |
| --reset | Wipe .rill/npm/ and rewrite all scaffolded files. Deletes installed extensions; re-run rill install for each. |
TypeScript types for custom extensions. Bootstrap writes .rill/tsconfig.rill.json with a paths mapping into .rill/npm/node_modules/. Add this line to your tsconfig.json so editors and tsc --noEmit resolve extension imports:
{ "extends": "./.rill/tsconfig.rill.json" }Or use rill check --types (see below) to typecheck without managing tsconfig directly.
rill install
Install an extension into .rill/npm/ and register it as a mount in rill-config.json.
rill install @rcrsr/rill-ext-datetime # install from npm
rill install @rcrsr/rill-ext-datetime --as dt # custom mount name
rill install ./local-ext # install from a local directory
rill install ./extensions/crawler.ts --as crawler # single-file source
rill install --dry-run @rcrsr/rill-ext-anthropic # preview without writingOptions:
| Flag | Description |
|------|-------------|
| --as <mount> | Mount name to use (default: derived from package name; required for single-file sources) |
| --pin | Pin to the exact installed version (no caret prefix). Registry installs only. |
| --exact | Deprecated alias for --pin. Will be removed in 0.20. |
| --range <semver> | Specify a custom semver range. Registry installs only. |
| --dry-run | Print what would be done without writing config or running npm. |
Mount name derivation. When --as is omitted, the mount name comes from:
- Local path (
./foo,/abs/path):path.basename(specifier). - Scoped rill-ext (
@scope/rill-ext-X):X. - Plain rill-ext (
rill-ext-X):X. - Scoped package (
@scope/name):name(last segment). - Plain package: the specifier verbatim.
Use rill install --dry-run <pkg> to preview the derived name before installing.
Source kinds:
- Registry —
@rcrsr/rill-ext-fooorpkg@^1.2.3. npm install into.rill/npm/. Eligible for--pin/--range. - Local directory —
./my-ext. npm symlinks the directory; source edits propagate without reinstalling. Cannot be upgraded withrill upgrade. - Single-file source —
./extensions/crawler.ts(.ts/.js/.mjs/.cjs/.tsx/.jsx). Path is recorded verbatim inrill-config.json; npm is not invoked.--asis required, version flags are rejected.rill listlabels itlocal-file.rill uninstallunregisters but leaves the file on disk.
rill uninstall
Remove a mounted extension from .rill/npm/ and unregister it from rill-config.json.
rill uninstall <mount>rill upgrade
Update a mounted extension to a newer version. Resolves the latest version matching the configured range and reinstalls.
rill upgrade <mount>Local-path mounts cannot be upgraded; they are symlinked, so edits to the source directory are picked up automatically.
Pinned mounts ([email protected] with no caret/range) are a no-op — the mount was pinned on purpose. To repin to a new version, run rill install <pkg>@latest --pin --as <mount>.
rill list
List all installed extensions and their mount paths.
rill list
rill list --json # machine-readable outputOptions:
| Flag | Description |
|------|-------------|
| --json | Emit results as JSON array |
The source column distinguishes:
registry— installed from npm into.rill/npm/.local— local directory, symlinked into.rill/npm/.local-file— single-file source (.ts/.js/.mjs/etc.) recorded verbatim inrill-config.json.
rill exec
Execute a rill script file.
rill exec script.rill [args...]
rill exec - # read from stdinPositional arguments pass to the script as $ (pipe value):
rill exec greet.rill alice bob
# Inside script: $ == ["alice", "bob"]Read from stdin with -:
echo '"Hello" -> log' | rill exec -Exit codes:
| Return Value | Exit Code |
|-------------|-----------|
| true or non-empty string | 0 |
| false or empty string | 1 |
| [0, "message"] | 0 (prints message) |
| [1, "message"] | 1 (prints message) |
rill eval
Evaluate a single rill expression. No file context or module loading.
rill eval '"hello".len' # 5
rill eval '5 + 3' # 8
rill eval '[1, 2, 3] -> map |x|($x * 2)' # [2, 4, 6]rill check
Lint and validate rill scripts. Or, with --types, run tsc --noEmit against the project's TypeScript extensions.
rill check script.rill # text output
rill check --format json script.rill
rill check --fix script.rill # auto-fix
rill check --types # TypeScript type-checkOptions:
| Flag | Description |
|------|-------------|
| --fix | Apply automatic fixes |
| --format text\|json | Output format (default: text) |
| --verbose | Include rule category in JSON output |
| --min-severity error\|warning\|info | Severity threshold for non-zero exit (default: error) |
| --types | Run tsc --noEmit against the project's tsconfig.json. Locates tsc from node_modules/.bin/ or .rill/npm/node_modules/.bin/. Requires the user's tsconfig.json to extend ./.rill/tsconfig.rill.json (written by rill bootstrap). |
Exit codes:
| Code | Meaning |
|------|---------|
| 0 | No diagnostics at or above --min-severity (default: error) |
| 1 | Diagnostics at or above --min-severity, or CLI usage error |
| 2 | File not found or path is a directory |
| 3 | Parse error in source |
Diagnostics below the threshold still print so the user sees them; only the exit code is gated. Example: a file with one info-level advisory exits 0 by default but exits 1 under --min-severity info.
Configuration: Place .rill-check.json in the project root:
{
"rules": {
"NAMING_SNAKE_CASE": "on",
"SPACING_OPERATOR": "off"
}
}Rule states: "on" (enabled), "off" (disabled), "warn" (downgrade to warning).
Lint rules: 40 rules across 11 categories (naming, flow, collections, loops, conditionals, closures, types, strings, anti-patterns, formatting, errors). Run rill check --help for the full list.
rill run
Config-driven execution. Loads extensions and settings from rill-config.json, then runs a script or named handler.
rill run [project-dir] [--config <path>] [handler-args...]Module mode: When main points to a script file, rill run executes it. Positional arguments forward as $.
Handler mode: When main names a handler (e.g., "script.rill:processOrder"), parameters come from --param_name value flags. Run rill run --help to print the parameter list.
See CLI Reference and Config Reference for details.
rill build
Compile a rill project into a self-contained output directory. Bundles extensions via esbuild, copies entry and module files, and writes an enriched rill-config.json with build metadata.
rill build [project-dir] [--output <dir>] [--flat]Options:
| Flag | Description |
|------|-------------|
| --output <dir> | Output directory (default: build/) |
| --flat | Write directly into <output> without a package-name subdirectory. |
Output structure (default):
build/<package-name>/
main.rill # entry script
rill-config.json # enriched with build section
extensions/ # bundled extension JS files
modules/ # copied module .rill files
runtime.js # bundled rill runtime
run.js # CLI wrapper
handler.js # handler export for harness consumptionOutput structure (--flat): identical contents written directly into <output> without the package-name level. Use when you control the output dir and don't need to compose multiple packages.
The build section in the output rill-config.json contains a SHA-256 checksum, rill runtime version, and config version.
rill describe
Describe rill callables as a JSON contract. Three subcommands cover the distinct surfaces a project exposes: extension surface (project), the project's own handler (handler), and the rill runtime itself (builtins).
rill describe project # all extension mounts (default)
rill describe project --mount <name> # restrict output to a single mount
rill describe handler # the project's published handler
rill describe builtins # rill runtime callables (no config needed)When no subcommand is given, project is assumed.
Subcommands:
| Subcommand | Purpose |
|------------|---------|
| project | Walk project.extTree and emit per-mount callable trees |
| handler | Resolve main: "file.rill:name", execute the script, and emit the handler signature |
| builtins | Walk ctx.functions and ctx.typeMethodDicts |
Options (project):
| Flag | Description |
|------|-------------|
| --mount <name> | Limit output to a single mount |
| --strict | Exit 1 if any callable has returnType: any |
| --stubs | Stub unset env vars referenced as ${env.X} in rill-config.json with literal "x" before constructing extensions. Use to enumerate callable surface before credentials are populated (e.g., for LLM-driven authoring tools). String-typed config only; numeric/bool config may still cause factory construction to fail. |
| --config <path> | Config file path (default: ./rill-config.json) |
Options (handler):
| Flag | Description |
|------|-------------|
| --strict | Exit 1 if any callable has returnType: any |
| --config <path> | Config file path (default: ./rill-config.json) |
Options (builtins):
| Flag | Description |
|------|-------------|
| --strict | Exit 1 if any callable has returnType: any |
Exit codes:
| Code | Meaning |
|------|---------|
| 0 | Contract emitted |
| 1 | Config error, unknown mount, missing handler, or --strict violation |
Documentation
| Document | Description | |----------|-------------| | CLI Reference | Full CLI documentation | | Language Reference | Language specification | | Conventions | Coding style and lint rationale |
License
MIT
