CLI Commands
The sage command-line tool compiles and runs Sage programs.
sage new
Create a new Sage project with scaffolding:
sage new my_project
This creates:
my_project/
├── grove.toml # Project manifest
└── src/
└── main.sg # Entry point with example code
Examples
# Create a new project
sage new my_agent
# Enter the project and run it
cd my_agent
sage run .
sage run
Compile and execute a Sage program:
sage run program.sg
Options
| Option | Description |
|---|---|
--release | Build with optimizations |
-q, --quiet | Minimal output |
--trace | Enable tracing (emit trace events to stderr) |
--trace-file <path> | Write trace events to a file (NDJSON format) |
Examples
# Run a program
sage run hello.sg
# Run with optimizations
sage run hello.sg --release
# Run quietly (only program output)
sage run hello.sg -q
# Run with tracing to stderr
sage run hello.sg --trace
# Run with tracing to a file
sage run hello.sg --trace-file trace.ndjson
sage build
Compile a Sage program to a native binary without running it:
sage build program.sg
Options
| Option | Description |
|---|---|
--release | Build with optimizations |
-o, --output <dir> | Output directory (default: hearth) |
--emit-rust | Only generate Rust code, don’t compile |
--target <target> | Compilation target: native (default), web, or wasm |
Examples
# Build a native binary
sage build hello.sg
# Build with optimizations
sage build hello.sg --release
# Custom output directory
sage build hello.sg -o ./out
# Generate Rust code only (for inspection)
sage build hello.sg --emit-rust
# Build for WebAssembly
sage build hello.sg --target web
Output Structure
After building a native target, you’ll find:
hearth/
hello/
main.rs # Generated Rust code
hello # Native binary (if not --emit-rust)
After building a WASM target (--target web):
pkg/
hello.js # JavaScript glue (wasm-bindgen)
hello_bg.wasm # WebAssembly binary
sage check
Type-check a Sage program without compiling or running:
sage check program.sg
This is useful for quick validation during development.
Examples
# Check for errors
sage check hello.sg
# Output on success:
# ✨ No errors in hello.sg
sage test
Run tests in a Sage project:
sage test .
This discovers all *_test.sg files, compiles them, and runs the tests.
Options
| Option | Description |
|---|---|
--filter <pattern> | Only run tests matching the pattern |
--file <path> | Run only tests in the specified file |
--serial | Run all tests sequentially (not in parallel) |
-v, --verbose | Show detailed failure output |
--no-colour | Disable colored output |
Examples
# Run all tests in the project
sage test .
# Run tests matching "auth"
sage test . --filter auth
# Run tests in a specific file
sage test . --file src/utils_test.sg
# Run tests sequentially (useful for debugging)
sage test . --serial
# Verbose output with failure details
sage test . --verbose
Output
🦉 Ward Running 3 tests from 2 files
PASS auth_test.sg::login succeeds with valid credentials
PASS auth_test.sg::login fails with invalid password
FAIL utils_test.sg::parse handles empty input
🦉 Ward test result: FAILED. 2 passed, 1 failed, 0 skipped [1.23s]
Exit Codes
| Code | Meaning |
|---|---|
| 0 | All tests passed |
| 1 | One or more tests failed |
sage add
Add a dependency to your project:
sage add package-name --git https://github.com/user/package
Options
| Option | Description |
|---|---|
--git <url> | Git repository URL |
--path <path> | Local path to the package (relative or absolute) |
--tag <tag> | Git tag to use |
--branch <branch> | Git branch to use |
--rev <rev> | Git revision (commit SHA) to use |
Examples
# Add a git dependency
sage add mylib --git https://github.com/user/mylib
# Add a specific version
sage add mylib --git https://github.com/user/mylib --tag v1.0.0
# Add a local path dependency (for development)
sage add mylib --path ./path/to/mylib
# Add a sibling directory
sage add shared --path ../shared-lib
Path Dependencies
Path dependencies are useful for:
- Monorepo setups where packages are in the same repository
- Local development of dependencies
- Testing changes before publishing
Path dependencies are resolved relative to the project root (where grove.toml is located).
sage update
Update dependencies to their latest versions:
sage update
This fetches the latest commits for git dependencies and updates grove.lock.
sage trace
Analyse trace files generated by sage run --trace-file:
sage trace <subcommand> <file>
Subcommands
| Subcommand | Description |
|---|---|
pretty | Pretty-print trace events in human-readable format |
summary | Show summary with agent timeline, totals, and durations |
filter --agent <name> | Filter trace events by agent name |
divine | Show all LLM inference calls with durations |
cost | Estimate token costs from inference calls (experimental) |
Examples
# Pretty-print all trace events
sage trace pretty trace.ndjson
# Get a summary of what happened
sage trace summary trace.ndjson
# Filter events for a specific agent
sage trace filter trace.ndjson --agent Researcher
# See all LLM calls
sage trace divine trace.ndjson
# Estimate costs (experimental)
sage trace cost trace.ndjson
Trace File Format
Trace files use NDJSON (newline-delimited JSON) format. Each line is a JSON object representing an event:
{"t":0,"kind":"agent_spawn","agent":"Main","id":"a1"}
{"t":1,"kind":"infer_start","agent":"Main","model":"gpt-4"}
{"t":150,"kind":"infer_end","agent":"Main","duration_ms":149}
{"t":151,"kind":"agent_emit","agent":"Main","value":"Hello"}
sage tools
Manage and inspect MCP tool servers configured in grove.toml:
sage tools <subcommand>
Subcommands
| Subcommand | Description |
|---|---|
list | List configured MCP tools from grove.toml |
inspect --stdio <cmd> | Inspect a stdio server’s tool manifest |
inspect --http <url> | Inspect an HTTP server’s tool manifest |
generate --stdio <cmd> -o <file> | Generate Sage tool declarations from a server |
generate --http <url> -o <file> | Generate from an HTTP server |
Examples
# List tools configured in grove.toml
sage tools list
# Inspect a server to see available tools
sage tools inspect --stdio "npx -y @modelcontextprotocol/server-github"
sage tools inspect --http "https://mcp.example.com/mcp"
# Generate Sage declarations from a server manifest
sage tools generate --stdio "npx -y @modelcontextprotocol/server-github" -o src/tools/github.sg
Verification
Use sage check --verify-tools to verify that declared tool signatures match the actual MCP server manifest:
sage check --verify-tools
sage sense
Start the Language Server Protocol (LSP) server for editor integration:
sage sense
This command starts the Sage language server on stdin/stdout. It’s typically invoked automatically by editor extensions (Zed, VS Code) rather than manually.
Features
The language server provides:
- Real-time parse error reporting
- Type checking diagnostics
- Undefined variable detection
- All compiler error codes
Manual Usage
For editors without a Sage extension, configure the LSP client to run sage sense as the language server command.
Example for generic LSP configuration:
{
"languageId": "sage",
"command": "sage",
"args": ["sense"],
"fileExtensions": [".sg"]
}
Global Options
| Option | Description |
|---|---|
-h, --help | Show help information |
-V, --version | Show version |
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Compilation error (parse, type, or codegen) |
| Other | Program exit code (when using sage run) |
Compilation Modes
Sage automatically selects the fastest compilation mode:
Pre-compiled Toolchain (Default)
When installed via the install script or release binaries, Sage includes a pre-compiled Rust toolchain. This provides fast compilation without requiring Rust to be installed.
Cargo Fallback
If no pre-compiled toolchain is found, Sage falls back to using cargo. This requires Rust to be installed but allows compilation on any platform.
The output will indicate which mode was used:
✨ Done Compiled hello.sg in 0.42s # Pre-compiled toolchain
✨ Done Compiled hello.sg (cargo) in 2.31s # Cargo fallback