Manager Agents
A global script is the scratch form. It lives on your machine, you run it by path, and when it stops being useful you delete it.
When a workflow is worth keeping — worth publishing, deploying, or running on a schedule — it becomes an agent whose job is orchestrating other agents.
eslint-manager/
├── src/
│ ├── scripts/
│ │ ├── audit.ts # boots a fleet, runs the audit
│ │ └── fix.ts # boots a fleet, applies fixes
│ ├── prompts/ # its own prompts
│ └── boot.vue # who this manager is
└── axon.config.ts
// src/scripts/audit.ts
const { linter, reviewer } = await Fleet({
linter: "@arclabs/linter",
reviewer: "@arclabs/reviewer",
})
const findings = await linter.request("audit this repo against our ruleset")
const triage = await reviewer.request(`which of these matter?\n\n${findings.text}`)
await axon.request(`summarise for the team:\n\n${triage.text}`)
There is no separate workflow artifact, and there does not need to be. An agent already has scripts, prompts, config, routes, hooks, a policy, and a place in the registry. A manager is an ordinary agent that happens to delegate.
What you get for free
This is the reason the pattern is worth knowing. Everything already built for agents applies unchanged:
| How | |
|---|---|
| Publish | axon publish — it's an agent |
| Install | axon install @cody/eslint-manager |
| Version | pinned like any registry package |
| Deploy | axon deploy — routes, URL, API key |
| Schedule | cron against a script or a route |
| Trigger | HTTP routes, hooks, email, the TUI palette |
| Observe | its own session trace, like any agent |
A new artifact kind would inherit none of that and would have to grow all of it again.
The manager can think
A manager agent has an identity and a full agent loop of its own. That is not vestigial — it is what makes a manager more capable than a script.
A script routes work by whatever its author hardcoded. A manager can decide:
// src/scripts/handle.ts
const { issue } = defineArgs<{ issue: string }>()
const routing = await axon.request(
`Which specialist should handle this? Answer with one name: security, perf, docs.\n\n${issue}`,
)
const { specialist } = await Fleet({
specialist: `@arclabs/${routing.text.trim()}`,
})
const result = await specialist.request(issue)
The delegation target is chosen at runtime, by an agent, based on the work. That is the capability a plain script doesn't have — and the reason "an orchestrator is just an agent" is a feature rather than a compromise.
Managers that never call axon.request() are fine too. Delegation with no judgment is a
legitimate manager; it just doesn't need the loop.
Triggering it
The same manager runs from everywhere an agent does:
axon run audit # headless, from the terminal
// server/api/audit.post.ts — as a service
export default defineEventHandler(async (event) => {
const { stream } = axon.scripts.stream("audit")
return sendStream(event, stream)
})
// server/plugins/nightly.ts — on a hook
export default defineAxonPlugin(async (axon) => {
axon.hooks.hook("github:pull_request.opened", async ({ number }) => {
void axon.scripts.request("audit", { pr: String(number) })
})
})
Note the shape of that last one. The plugin subscribes to a hook its own agent's module emits, then delegates to a script that boots whatever fleet it needs. The manager never reaches into another agent's lifecycle — it handles its own events and talks to other agents through the protocol. See The Boundary.
Declaring what it needs
A published manager cannot use relative paths — the consumer has no ../linter. Refer
to fleet members by registry name, pinned:
const { linter } = await Fleet({ linter: "@arclabs/linter@^1.2" })
The first run resolves and installs them; later runs read the cache. Pre-install with
axon install if you would rather not pay for it at runtime. See
Resolving Agents.
Script or manager?
Write a global script when the work is yours, local, and disposable. No folder, no config, no ceremony — a file you run.
Write a manager agent when the work needs to outlive the file: to be shared across repos, installed by a teammate, deployed as a service, or run on a schedule.
The graduation path is short. A *.axon.ts script that has earned its keep becomes
axon init, and the script body moves into src/scripts/ mostly unchanged — the calls
are identical, and the manager gains an ambient axon it can use or ignore.
Next: The Running Fleet — agents live on your machine.