[FEATURE] Workflow scripts: a journaled run() hook so a deterministic command needs no agent

Status Open
Maintainer reply None cached
Activity 0 comments · opened Oct 8, 2026

Feature request: let a workflow script run a command without spawning an agent

Problem

A dynamic workflow script has "no direct filesystem or shell access from the workflow itself". Agents read, write and run commands, and the script only coordinates them. So when a stage only needs a deterministic command's output (git diff --name-only, a repo CLI that prints JSON, gh pr view --json …), the script has to spawn an agent() whose whole job is to run that one command and echo its stdout back as structured output.

In our repo that pattern accounts for a large share of all workflow agent spawns. Each one:

  • Costs a model session. Even a lean subagent definition costs about 4.8K prompt tokens before it reads its brief, and a default subagent about 49K.
  • Adds latency. A cold agent boot sits in front of a command that takes milliseconds.
  • Can be wrong. The model may reformat, summarize, truncate or skip the output, or act on text in it. We had to build per-stage fidelity checks that diff each agent's return against the command's own stdout in the transcript, just to trust these stages.

What we do today

We run what we can before launch and pass the output in through args, and split workflows at mid-run commands. That works for preflight commands, but a command that depends on an earlier stage's result still needs an agent or a second workflow.

Proposal

Add a script hook, for example:

const out = await run(['node', 'scripts/list.js', '--json'], { cwd, timeoutMs, stdin })
// → { exitCode, stdout, stderr }
  • Journaled like agent() returns, so a relaunch replays the recorded result rather than re-executing. That keeps resume deterministic, which we assume is why shell access was left out.
  • Permission-checked like a Bash tool call, with the session's allow and deny rules, PreToolUse hooks, sandboxing and auto-mode classifier applying exactly as they do to an agent's Bash call.
  • argv array only, with no shell string, so interpolated data cannot become shell syntax.

A read-only file read (readFile(path)) under the same rules would cover the other common echo stage.

Related

anthropics/claude-code#100380 asks for agent() to return a typed death cause instead of null.

View original on GitHub ↗