Global Scripts
A file ending .axon.ts is a global script. It is an ordinary TypeScript program that
happens to know how to boot agents, and it lives wherever you put it — a repo root, a
scratch directory, ~/bin.
// ~/scripts/standup.axon.ts
import { Fleet } from "@axon/core"
const { barry } = await Fleet({ barry: "~/agents/barry" })
const summary = await barry.request("summarise yesterday's commits")
console.log(summary.text)
axon run standup.axon.ts
No agent folder, no axon.config.ts, no project. The script names what it needs.
Imports, not globals
A script inside an agent gets axon, args, and its tools as globals, because the
runtime that injected them was already running when the script started. A global script
has no such runtime — it is the thing that starts one — so it imports what it uses:
import { Axon, Fleet } from "@axon/core"
That one line is the whole ceremony, and it buys real things: your editor types it with
no generation step, no tsconfig has to be in the right place, and the file works when
you move it. Magic globals need a project to hang off. A global script has no project by
design.
The two script kinds
Both are first-class. They differ on who owns the agent's lifetime:
// src/scripts/review.ts — inside an agent
const content = await axon.tools.fs.readFile(file)
const prompt = await axon.prompt("review", { file, content })
const { stream } = axon.stream({ prompt })
for await (const entry of stream) {
if (entry.type === "text") process.stdout.write(entry.content)
}
// review.axon.ts — a global script
import { Axon } from "@axon/core"
const { axon: barry } = await Axon("../barry")
const content = await barry.tools.fs.readFile(file)
const prompt = await barry.prompt("review", { file, content })
const { stream } = barry.stream({ prompt })
for await (const entry of stream) {
if (entry.type === "text") process.stdout.write(entry.content)
}
The bodies are identical. The only difference is where the handle came from — ambient in
one, constructed in the other. Everything you know about axon transfers directly;
barry is the same handle with a name you chose.
Arguments
Global scripts take arguments from the command line like any program:
axon run review.axon.ts --file src/index.ts
const file = process.argv[...]
There is no defineArgs here. That global belongs to agent-scoped scripts, where the
runtime parses arguments before invoking the script and the TUI palette builds a form
from the declaration. A global script is started by a shell, so it reads process.argv
like a shell program does.
Running one
axon run standup.axon.ts # by path
axon run ./deploy/nightly.axon.ts # anywhere on disk
The CLI runs the file, waits for it, and shuts down every agent the script booted before exiting — including when the script throws. See Lifecycle.
What runs it, and under what policy
A global script runs in your shell, as you, with your permissions. It is not sandboxed
and it is not policy-checked — the same trust model as any node or bun script you
run on your own machine.
The agents it boots are a different matter. Each one enforces its own declared policy on its own tool calls, in its own capsule. Booting an agent does not widen what that agent may do, and a script cannot grant an agent a permission its policy withholds.
So the rule is the ordinary one: run a global script you would run any script. The agents inside it stay bounded regardless.
When a script should become an agent
A global script is deliberately disposable. It has no identity, no version, no address, and nowhere to live but the path you saved it at — which is right for a tool you wrote this afternoon.
When it earns its keep — when a teammate wants it, or it should run nightly, or it needs
to be reachable over HTTP — it becomes a manager agent. The
script body moves into src/scripts/ mostly unchanged.
Next: Composing a Fleet — booting several at once.