fh run
Execute a workspace agent, or any standalone agent file, against a local Node runtime or a Temporal worker.
fabric-harness run <agent|file> [options]Runs the named agent. The CLI loads the agent module, validates the input payload, calls run({ init, input, payload }), and validates the output.
<agent> is either a workspace agent name (resolved from .fabricharness/jobs/) or a path to an agent file (see Single-file mode).
Single-file mode
When <agent> resolves to an existing .ts, .mts, .js, or .mjs file, fh run executes that file directly — no .fabricharness/ workspace, no config.ts, no credentials required:
fh run ./agent.ts --message "hello"- The file is transpiled on the fly. Package imports (including
@fabric-harness/sdk) resolve from the nearestnode_modulesto the file, falling back to the CLI's own install. - Every exported
defineAgent()/createAgent()value is discovered. With exactly one export it runs directly; with several, pass--agent <name>to select one (the error lists the exported names). PersistentcreateAgent()agents still require a workspace. - When no model credentials resolve (
--model,FABRIC_MODEL, or provider keys), the run falls back to the mock model and says so on stderr, so the command round-trips offline.--mockkeeps its explicit meaning. - The reply (and any structured output) prints on stdout; the session id prints on stderr as
[fabric-harness] session <id> completed (memory store — not persisted).— single-file runs use an in-memory store, so there is nothing to resume. - An explicit path that does not exist (
./missing.ts) is a hard error; a bare name still falls back to workspace agent resolution.
Options
| Flag | Description |
|---|---|
--agent <name> | Single-file mode: select one export when the file exports several agents. |
--id <id> | Session identifier. Reusing an existing id resumes that persisted session — new turns append to its history. If omitted, a session id is generated using ${idPrefix}-${uuid}. |
--resume <id> | Explicit alias for --id <id>: continue the persisted session <id>. |
--fork <id> | Fork persisted session <id> into a new session: copies its history into a fresh id (pass --id to name the fork), then continues the copy. Requires a persisted store. |
--target <node|temporal-worker> | Where the agent runs. Defaults to node. temporal-worker switches --runtime to temporal. |
--runtime <inline|temporal> | Equivalent lower-level flag. Usually set via --target. |
--model <provider/model-id> | Override the agent's default model, e.g. openai/gpt-5.5. |
--mock | Use the deterministic mock model provider — no credentials needed. |
--mock-script <path> | Scripted mock responses from a JSON fixture file (aimock-style { match, response } entries). Implies --mock; see Test Without Credentials. |
--cwd <dir> | Default sandbox/session working directory for this run. Relative paths stay scoped inside the sandbox workspace. |
--uid <uid> | Persistent agents: require an existing incarnation with this id. |
--new | Persistent agents: require creation of a new instance. |
--data <json> | Persistent agents: immutable initial data for a new instance. |
--tenant <id> | Tenant identifier for this run. |
--prompt <text> | Message text for persistent agents; also the prompt for --runtime temporal mode. |
--payload '<json>' | Pass an inline JSON payload. |
--payload-file <path> | Read JSON payload from a file. |
--stdin | Read JSON payload from stdin. |
--set key=value | Set a payload field. May be repeated. |
--<field> <value> | Shortcut for setting a payload field, e.g. --question "...". |
<field>=<value> | Positional shortcut for setting a payload field, e.g. question="...". |
--env <file> | Load .env-style variables. Repeatable; shell env wins. |
Resuming and forking sessions
Every successful workspace run prints its session id on stderr with a resume hint:
[fabric-harness] session sess-1 completed. Resume: fh run hello --resume sess-1With a durable store (store: { backend: 'file' }, the default), passing the same id again — via --id or the explicit --resume alias — continues the session: the model sees the prior history and new entries append to it. --fork <id> instead copies a persisted session into a new id and continues the copy, leaving the original untouched:
fh run hello --id sess-1 --message "first"
fh run hello --resume sess-1 --message "second" # continues sess-1
fh run hello --fork sess-1 --id sess-1-copy --message "third" # branches a copyWith store: { backend: 'memory' } nothing is persisted, and the run says so explicitly (session <id> completed (memory store — not persisted).) — fh sessions staying empty after a memory-store run is expected, not data loss. Resume and fork require a persisted store.
Payload precedence
When more than one source is given, fields merge in this order (later wins):
--payload → --payload-file → --stdin → --set / --<field> / key=valueExamples
Single file, no workspace
fh run ./agent.ts --message "hello"
fh run ./multi.ts --agent beta --message "hello"Inline JSON
fh run ask --payload '{"question":"What is Temporal?"}'Field shortcut
fh run ask --question "What is Temporal?"
fh run ask question="What is Temporal?"
fh run ask --set question="What is Temporal?"Working directory
fh run code --cwd /workspace/project --prompt "Run tests and summarize failures"
fh run code --cwd packages/core --payload '{"prompt":"Inspect this package"}'--cwd is a sandbox cwd, not a host directory switch. Use it to make file/shell tools default to a repository subdirectory.
From a file or stdin
fh run ask --payload-file input.json
echo '{"question":"hi"}' | fh run ask --stdinReal model
Put provider keys once in a repo/workspace .env.local; TechFabric Harness auto-loads it and shell env still wins.
cp .env.example .env.local
# edit .env.local and set OPENAI_API_KEY=...
fh run ask --model openai/gpt-5.5 --question "What is Temporal?"Use explicit --env <file> only for test/CI overrides.
Temporal worker target
# In a separate terminal:
fh temporal-worker
# Then:
fh run ask --target temporal-worker --id ask-001 --prompt "What is Temporal?"What happens during run
- Resolve workspace root by walking up to find
.fabricharness/. (Single-file mode skips this and the next step — the file is loaded directly with SDK defaults.) - Load
.fabricharness/config.tsand merge with env and CLI flags. - Resolve agent path, target, runtime, model, id, and sandbox cwd.
- Apply env model provider (e.g. set provider credentials).
- Validate input payload against the agent's input schema (metadata agents only).
- Call the agent's
run({ init, input, payload }). - Validate output against the output schema (metadata agents only).
- Persist session and print the session id on stderr (with a resume hint, or a
not persistednotice on the memory store).
See also
fh agents/fh describe— discover what's runnable.- Sessions — inspect what just happened.
- Configuration — defaults and precedence.