CLI Commands

The foundry CLI communicates with a running foundryd daemon over gRPC.

Global Options

OptionDefaultDescription
--addr <url>http://127.0.0.1:50051Daemon address

foundry emit

Emit an event into the system. May trigger a workflow chain.

foundry emit <event_type> --project <project> [--throttle <level>] [--payload <json>] [--wait]
ArgumentRequiredDescription
event_typeYesEvent type name (positional)
--projectYesTarget project
--throttleNofull, audit_only, or dry_run (default: full)
--payloadNoJSON string with event-specific data
--waitNoBlock until processing completes, then display the trace

By default, emit returns immediately after the daemon accepts the event. Use --wait to block until the full event chain finishes and then display the trace output (equivalent to running foundry trace after completion).

Output (default):

Event emitted: evt_47fcb603e1b18c8435b8cc3b

Output (with --wait):

Event emitted: evt_47fcb603e1b18c8435b8cc3b
Waiting for processing to complete...
greet_requested (evt_47fcb603e1b18c8435b8cc3b) project=hello
  → Compose Greeting (1ms): ok — composed greeting for Stacey
    greeting_composed (evt_a1b2c3d4e5f6) project=hello
      → Deliver Greeting (0ms): ok — delivered greeting: Hello, Stacey!
---
Total: 2ms (blocks: 1ms)

foundry status

Show status of active workflows. Queries the daemon for workflows that are currently being processed in the background. The daemon tracks these via an in-memory WorkflowTracker that is populated when each Emit request spawns a background task and cleared on completion.

foundry status [workflow_id]

Without an argument, shows all active workflows. With a workflow ID, shows details for that specific workflow.

Output example:

evt_47fcb603e1b18c8435b8cc3b [iteration_requested] foundry — running

If no workflows are currently running:

No active workflows.

foundry watch

Stream live events as they are emitted in real time.

foundry watch [--project <project>]
OptionRequiredDescription
--projectNoFilter by project name; omit to see all projects

Server-side streaming — stays open until interrupted (Ctrl-C). Each line shows the event type, event ID, project, and payload (when non-empty).

Output example:

maintenance_run_started evt_abc project=my-tool
project_validation_completed evt_def project=my-tool
  payload: {"status":"ok","has_gates":true}
project_iteration_completed evt_ghi project=my-tool

foundry run

Trigger a maintenance run for all active projects or a single named project.

foundry run [--project <project>] [--throttle <level>]
OptionRequiredDescription
--projectNoLimit run to a single project by name; omit to run all projects
--throttleNofull, audit_only, or dry_run (default: full)

foundry run emits a maintenance_run_started event which triggers the maintenance workflow chain: validate → iterate (if enabled) → maintain (if enabled) → commit and push → post-push audit.

The command streams progress events in real time and exits automatically when the daemon broadcasts a maintenance_run_completed event at the end of the processing chain. This differs from foundry watch, which streams indefinitely.

When --project is omitted, the project name sent to the daemon is "system", which causes all active (non-skipped) projects to be processed.

Output:

Triggered maintenance run for my-tool
Event: evt_47fcb603e1b18c8435b8cc3b

[my-tool] maintenance_run_started
[my-tool] project_validation_completed (ok)
[my-tool] maintenance_run_completed (ok)

Use foundry trace <event_id> to inspect the full trace after the run completes.

foundry validate

Validate quality gates for one or more projects without running iterate or maintain workflows. This is a read-only operation — no code changes are made.

foundry validate <project>...
foundry validate --all
ArgumentRequiredDescription
projectYes (unless --all)One or more project names (positional)
--allNoValidate all active projects in the registry

For each project, emits a validation_requested event which triggers: Resolve GatesRun Preflight GatesRoute Validation Resultvalidation_completed. No Mutator blocks are involved, so throttle level is irrelevant.

Output example:

Validating mojentic-ts...
  mojentic-ts: PASS
    lint: ok (required)
    format: ok (required)
    test: ok (required)
    build: ok (required)
    security: ok (optional)
validation_requested (evt_007572156d627d7b1211d76f) project=mojentic-ts
  → Resolve Gates (0ms): ok — mojentic-ts: resolved 5 gates for validate workflow
    gate_resolution_completed (evt_92531a666649d6464e569dc2) project=mojentic-ts
      → Run Preflight Gates (6931ms): ok — mojentic-ts: preflight gates passed
        preflight_completed (evt_08b0f626599a23ee8c648a8c) project=mojentic-ts
          → Route Validation Result (3ms): ok — mojentic-ts: validation passed
            validation_completed (evt_e60a246dfa9072414890fa24) project=mojentic-ts
---

Exits with code 0 if all projects pass, non-zero if any required gate fails. Optional gate failures are reported but do not affect the exit code.

foundry trace

View the trace of a completed event chain.

foundry trace <event_id> [--verbose]
ArgumentRequiredDescription
event_idYesRoot event ID returned by foundry emit (positional)
--verboseNoShow trigger payloads, emitted payloads, raw shell output, and audit artifact paths

Displays the full event propagation tree with block execution results. Traces are stored on disk indefinitely under ~/.foundry/traces/YYYY-MM-DD/ and survive daemon restarts.

Output (default):

greet_requested (evt_47fcb603e1b18c8435b8cc3b) project=hello
  → ComposeGreeting: ok — composed greeting for Stacey
    greeting_composed (evt_a1b2c3d4e5f6) project=hello
      → DeliverGreeting: ok — delivered greeting: Hello, Stacey!
        greeting_delivered (evt_f6e5d4c3b2a1) project=hello
---
Total: 2ms (blocks: 1ms)

Output (with --verbose):

greet_requested (evt_47fcb603e1b18c8435b8cc3b) project=hello
  → ComposeGreeting (1ms): ok — composed greeting for Stacey
    trigger: {"name":"Stacey"}
    emitted[0]: {"greeting":"Hello, Stacey!"}
    greeting_composed (evt_a1b2c3d4e5f6) project=hello
      → DeliverGreeting (0ms): ok — delivered greeting: Hello, Stacey!
---
Total: 2ms (blocks: 1ms)

If the trace is unknown:

No trace found for evt_unknown (expired or unknown).

foundry history

Browse completed traces stored on disk.

foundry history [<date>] [--project <project>]
ArgumentRequiredDescription
dateNoDate in YYYY-MM-DD format; omit to show the last 7 days
--projectNoFilter results by project name

Traces are read from ~/.foundry/traces/ (or FOUNDRY_TRACES_DIR). Each row shows the event ID, success status, duration, event type, and project. Dates with no traces are omitted.

Output example:

2026-03-22
┌──────────────────────────────┬────────┬──────────┬──────────────────────────┬───────────┐
│ Event ID                     │ Status │ Duration │ Type                     │ Project   │
╞══════════════════════════════╪════════╪══════════╪══════════════════════════╪═══════════╡
│ evt_47fcb603e1b18c8435b8cc3b │ ok     │ 312ms    │ maintenance_run_started  │ my-tool   │
│ evt_a1b2c3d4e5f6789012345678 │ ok     │ 48ms     │ greet_requested          │ hello     │
└──────────────────────────────┴────────┴──────────┴──────────────────────────┴───────────┘

If no traces are found:

No traces found in the last 7 days.

foundry registry

Manage the project registry without editing the JSON file directly.

foundry registry <subcommand>

foundry registry init

Create an empty registry file at the default path (~/.foundry/registry.json). Does nothing if the file already exists.

foundry registry init

foundry registry list

List all projects in the registry as a table.

foundry registry list

Output example:

┌──────────┬────────────┬──────┬──────────────────────────┬───────┐
│ Name     │ Stack      │ Skip │ Actions                  │ Skill │
╞══════════╪════════════╪══════╪══════════════════════════╪═══════╡
│ my-tool  │ rust       │ no   │ iterate, maintain, push  │ auto  │
│ frontend │ typescript │ yes  │ maintain, push           │       │
└──────────┴────────────┴──────┴──────────────────────────┴───────┘

The Skill column shows auto (default derived command), cmd (custom command), off (explicitly disabled), or blank (not configured).

foundry registry show <name>

Show all details for a single project.

foundry registry show my-tool

Output example:

Name:      my-tool
Path:      /Users/alice/projects/my-tool
Stack:     rust
Agent:     claude
Repo:      alice/my-tool
Branch:    main
Skip:      no
Actions:   iterate, maintain, push
Install:   brew: my-tool
Installs skill: yes (default -- runs my-tool init --global --force)
Timeout:   3600s (default)

foundry registry add

Add a new project to the registry. If the registry file does not exist, it is created automatically.

foundry registry add \
  --name my-tool \
  --path /Users/alice/projects/my-tool \
  --stack rust \
  --agent claude \
  --repo alice/my-tool \
  --branch main \
  [--iterate] [--maintain] [--push] [--audit] [--release] \
  [--install-command "cargo install --path ."] \
  [--install-brew my-formula] \
  [--notes "Human-readable notes about the project"] \
  [--timeout-secs 3600]
OptionRequiredDescription
--nameYesUnique project name
--pathYesAbsolute path to the project
--stackYesTechnology stack: rust, python, typescript, elixir, cpp
--agentYesAI agent name (e.g. claude)
--repoYesGitHub slug (owner/repo)
--branchNoDefault branch (default: main)
--iterateNoEnable iterate action
--maintainNoEnable maintain action
--pushNoEnable push action
--auditNoEnable audit action
--releaseNoEnable release action
--install-commandNoShell command to run for local install
--install-brewNoHomebrew formula name
--notesNoHuman-readable notes
--timeout-secsNoCommand timeout in seconds (default: 1800)

foundry registry remove <name>

Remove a project from the registry. Errors if the project is not found.

foundry registry remove my-tool

foundry registry edit <name>

Update settings for an existing project. Only the fields you pass are changed; all others are left as-is.

foundry registry edit my-tool \
  --skip "Waiting for CI to stabilise" \
  --timeout-secs 3600
OptionDescription
--pathUpdate the project path
--stackUpdate the technology stack
--agentUpdate the agent name
--repoUpdate the GitHub slug
--branchUpdate the default branch
--skipSet a skip reason (pass empty string "" to clear the skip)
--iterateSet iterate action (true/false)
--maintainSet maintain action
--pushSet push action
--auditSet audit action
--releaseSet release action
--install-commandSet install command
--install-brewSet Homebrew formula
--notesSet notes (pass empty string "" to clear)
--timeout-secsSet command timeout in seconds