@ai-outfitter/outfitter 1.10.0 → 1.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.outfitter/skills/outfitter/SKILL.md +4 -0
- package/README.md +5 -1
- package/dist/agents/PiCredentialPersistence.d.ts +3 -3
- package/dist/agents/PiCredentialPersistence.js +9 -4
- package/dist/agents/PiCredentialPersistence.js.map +1 -1
- package/dist/cli/OutfitterCli.js +2 -0
- package/dist/cli/OutfitterCli.js.map +1 -1
- package/dist/cli/commands/RunAgentCommand.d.ts +5 -0
- package/dist/cli/commands/RunAgentCommand.js +21 -4
- package/dist/cli/commands/RunAgentCommand.js.map +1 -1
- package/dist/cli/commands/SetupCommand.d.ts +2 -1
- package/dist/cli/commands/SetupCommand.js +1 -0
- package/dist/cli/commands/SetupCommand.js.map +1 -1
- package/dist/cli/commands/SourcesCommand.d.ts +19 -0
- package/dist/cli/commands/SourcesCommand.js +85 -0
- package/dist/cli/commands/SourcesCommand.js.map +1 -0
- package/dist/cli/commands/SyncCommand.js +8 -0
- package/dist/cli/commands/SyncCommand.js.map +1 -1
- package/dist/composer/Composer.js +3 -0
- package/dist/composer/Composer.js.map +1 -1
- package/dist/composer/Composition.d.ts +3 -0
- package/dist/composer/Models.d.ts +20 -0
- package/dist/composer/Models.js +160 -0
- package/dist/composer/Models.js.map +1 -0
- package/dist/projection/Materialize.js +3 -0
- package/dist/projection/Materialize.js.map +1 -1
- package/dist/projection/ModelProjection.d.ts +8 -0
- package/dist/projection/ModelProjection.js +127 -0
- package/dist/projection/ModelProjection.js.map +1 -0
- package/dist/projection/ProjectHarness.js +13 -15
- package/dist/projection/ProjectHarness.js.map +1 -1
- package/dist/projection/Projection.d.ts +2 -0
- package/dist/schemas/settings.schema.json +5 -0
- package/dist/settings/Settings.d.ts +6 -0
- package/dist/settings/Settings.js +1 -0
- package/dist/settings/Settings.js.map +1 -1
- package/dist/settings/SettingsLoader.js +1 -0
- package/dist/settings/SettingsLoader.js.map +1 -1
- package/dist/settings/SettingsMerger.js +3 -0
- package/dist/settings/SettingsMerger.js.map +1 -1
- package/dist/setup/DefaultCatalog.js +18 -2
- package/dist/setup/DefaultCatalog.js.map +1 -1
- package/dist/sources/SourceCachePolicy.d.ts +11 -0
- package/dist/sources/SourceCachePolicy.js +48 -0
- package/dist/sources/SourceCachePolicy.js.map +1 -0
- package/dist/sources/SourceState.d.ts +32 -0
- package/dist/sources/SourceState.js +90 -0
- package/dist/sources/SourceState.js.map +1 -0
- package/docs/documentation/README.md +5 -3
- package/docs/documentation/agents.md +36 -0
- package/docs/documentation/ai-outfitter.md +259 -0
- package/docs/documentation/assets/feature-to-pr.svg +70 -0
- package/docs/documentation/cli.md +8 -0
- package/docs/documentation/containers.md +3 -80
- package/docs/documentation/settings.md +5 -0
- package/docs/documentation/support-matrix.md +25 -23
- package/package.json +1 -1
- package/src/schemas/settings.schema.json +5 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# How AI Outfitter fits together
|
|
2
|
+
|
|
3
|
+
Open, vendor-neutral tooling for configuring and operating agents: ramp a
|
|
4
|
+
user, a team, or an organization from AI-assisted coding to an autonomous
|
|
5
|
+
software development lifecycle.
|
|
6
|
+
|
|
7
|
+
Everything here builds on one convention: an agent's context, tools, skills,
|
|
8
|
+
and permissions are plain files in a `.agents/` directory — committed,
|
|
9
|
+
reviewed, and shared like the rest of your code. The same plain-file definition
|
|
10
|
+
can be shared across environments and model vendors; runtime support varies by
|
|
11
|
+
harness, as shown in the
|
|
12
|
+
[support matrix](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/support-matrix.md).
|
|
13
|
+
The core is open source under MIT.
|
|
14
|
+
|
|
15
|
+
## Why we built AI Outfitter
|
|
16
|
+
|
|
17
|
+
We built AI Outfitter to give teams a shared path from local agent use to
|
|
18
|
+
automated and governed workflows. Its defaults are customizable, so teams can
|
|
19
|
+
begin at the rung that matches their current process.
|
|
20
|
+
|
|
21
|
+
## The adoption ramp
|
|
22
|
+
|
|
23
|
+
Five rungs, from AI-assisted coding to an autonomous lifecycle
|
|
24
|
+
([full definition](https://github.com/ai-outfitter/outfitter/blob/main/docs/philosophy.md)).
|
|
25
|
+
Each Outfitter component targets a rung, so you climb without rebuilding what
|
|
26
|
+
got you here — and without adopting complexity too early. Rungs 2, 3, and 4
|
|
27
|
+
each open with the **runbook** that gets you there: the concrete steps, and a
|
|
28
|
+
success check you run rather than judge.
|
|
29
|
+
|
|
30
|
+
1. **Assisted** — autocomplete and chat; a human's hands stay on the
|
|
31
|
+
keyboard. _You are here if_ you use autocomplete in an IDE.
|
|
32
|
+
There is nothing to govern yet — but the habit that matters starts here:
|
|
33
|
+
document what works and what doesn't in `AGENTS.md`/`CLAUDE.md`, and
|
|
34
|
+
keep it in the repo.
|
|
35
|
+
- [First-time CLI agent users](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/first-time-cli-agent-users.md#context-engineering)
|
|
36
|
+
— what belongs in a first `AGENTS.md`, and how to ask an agent to use
|
|
37
|
+
it.
|
|
38
|
+
|
|
39
|
+
2. **Delegated** — a local agent does the task; you define the idea and
|
|
40
|
+
review the PR. _You are here if_ engineers run a coding agent in a
|
|
41
|
+
terminal and push the result. This is where configuration starts to
|
|
42
|
+
matter.
|
|
43
|
+
- **Runbook: [Share one catalog](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/share-one-catalog.md)**
|
|
44
|
+
— one pinned catalog the organization shares, instead of per-laptop
|
|
45
|
+
configuration.
|
|
46
|
+
- [outfitter](https://github.com/ai-outfitter/outfitter) — composes what
|
|
47
|
+
an agent knows and may do into a **profile**: plain files in your
|
|
48
|
+
`.agents/` folder, reviewed like code and portable across environments
|
|
49
|
+
and **harnesses** (the CLI that runs an agent: Claude Code, Pi, Codex).
|
|
50
|
+
- [deepwork](https://github.com/ai-outfitter/deepwork) — step-by-step
|
|
51
|
+
quality gates so the agent checks its own work.
|
|
52
|
+
|
|
53
|
+
3. **Automated** — a workflow runs without your laptop: an issue, a message,
|
|
54
|
+
or a schedule triggers agents in CI, on a cluster, or on a remote server
|
|
55
|
+
you never sit at; adversarial review is part of the pipeline; session
|
|
56
|
+
logs are captured before merge. _You are here when_ you close your laptop
|
|
57
|
+
and the work keeps going. What promotes you is the trigger, not the
|
|
58
|
+
hardware: an agent you drive over SSH is rung 2 on a bigger machine.
|
|
59
|
+
- **Runbook: [Run it without your laptop](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/run-without-your-laptop.md)**
|
|
60
|
+
— an event triggers the workflow, its output lands through review, and
|
|
61
|
+
the session is captured.
|
|
62
|
+
- [actions](https://github.com/ai-outfitter/actions) — runs any profile
|
|
63
|
+
headless in GitHub Actions, on any trigger.
|
|
64
|
+
- [channels](https://github.com/ai-outfitter/channels) — pushes email,
|
|
65
|
+
Slack, Signal, and forge events (GitHub or GitLab activity) into an
|
|
66
|
+
agent session, so one message can start the same workflow.
|
|
67
|
+
- [agent-operator](https://github.com/ai-outfitter/agent-operator) —
|
|
68
|
+
hosts the same profiles on your own infrastructure, well before you
|
|
69
|
+
need its resident-agent story on the next rung.
|
|
70
|
+
|
|
71
|
+
4. **Governed** — the organization shares one version-pinned catalog of
|
|
72
|
+
agents, skills, and policy; every agent action lands in an auditable
|
|
73
|
+
record; **[resident agents](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/in-cluster.md)**
|
|
74
|
+
— long-lived agents onboarded like teammates,
|
|
75
|
+
with their own accounts and boundaries — take on standing jobs. _You are
|
|
76
|
+
here when_ agents work across many teams, and the organization needs
|
|
77
|
+
shared policy — and proof of what every agent did.
|
|
78
|
+
- **Runbook: [Give the agent a residence](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/give-the-agent-a-residence.md)**
|
|
79
|
+
— a named, assignable agent with an account and somewhere to live.
|
|
80
|
+
- **Build your agent catalog: [Share one catalog](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/share-one-catalog.md)**
|
|
81
|
+
— the rung 2 runbook creates it and links to guidance on its layout,
|
|
82
|
+
version pinning, and governance. Our own
|
|
83
|
+
[.agents](https://github.com/ai-outfitter/.agents) is a worked example
|
|
84
|
+
you can read end to end.
|
|
85
|
+
- [agent-operator](https://github.com/ai-outfitter/agent-operator) —
|
|
86
|
+
provisions and supervises resident agents on your own infrastructure.
|
|
87
|
+
- [pensieve](https://github.com/ai-outfitter/pensieve) — designed to retain
|
|
88
|
+
evidence from agent sessions, including environments, agents, tools,
|
|
89
|
+
artifacts, and costs. That record can support audits, compliance reviews,
|
|
90
|
+
and evaluation workflows.
|
|
91
|
+
|
|
92
|
+
5. **Self-improving** — the audit record feeds evals and improvement; humans
|
|
93
|
+
set goals and acceptance gates, agents own the middle. Rung 5 is where
|
|
94
|
+
the stack is thinnest today.
|
|
95
|
+
- [evals](https://github.com/ai-outfitter/evals) — evaluates changes to a
|
|
96
|
+
profile, model, or workflow with reproducible, attested benchmarks.
|
|
97
|
+
- [autoimprove](https://github.com/ai-outfitter/autoimprove) — improves
|
|
98
|
+
portable skills against measured outcomes.
|
|
99
|
+
|
|
100
|
+
## Start with one workflow end to end
|
|
101
|
+
|
|
102
|
+
One useful first workflow takes **a feature idea to a merged PR**, automated
|
|
103
|
+
end to end, with every step leaving evidence. This is what rung 3 looks like
|
|
104
|
+
up close.
|
|
105
|
+
|
|
106
|
+

|
|
107
|
+
|
|
108
|
+
1. **Entry point.** Someone files an issue and assigns it to an agent — from
|
|
109
|
+
the forge, from chat, or from a planning session at a desk. Different
|
|
110
|
+
doors, same workflow.
|
|
111
|
+
2. **Plan.** A planner profile with read-only tools turns the issue into a
|
|
112
|
+
spec artifact and posts it back to the issue, where a human can approve
|
|
113
|
+
it (we recommend an enforced spec system, like
|
|
114
|
+
[2119](https://github.com/Unsupervisedcom/2119), for more autonomous
|
|
115
|
+
workflows).
|
|
116
|
+
3. **Implement.** An implementer profile picks up the approved spec in a
|
|
117
|
+
fresh container with exactly the tools the work needs — a different
|
|
118
|
+
agent, a clean context window, the same shared catalog.
|
|
119
|
+
4. **Review.** An adversarial reviewer profile, which shares none of the
|
|
120
|
+
implementer's context, tries to break the change before any human reads
|
|
121
|
+
it.
|
|
122
|
+
5. **Merge.** The PR arrives with its history attached: session transcripts,
|
|
123
|
+
tool calls, and diffs captured as artifacts before the environment that
|
|
124
|
+
produced them is torn down.
|
|
125
|
+
|
|
126
|
+
The same shape handles other starting workflows. A vulnerability report
|
|
127
|
+
instead of a feature idea turns the pipeline into governed security
|
|
128
|
+
remediation: the scanner files the issue (most scanners already can), the
|
|
129
|
+
planner scopes the fix, and the same steps carry it to a tested, approved
|
|
130
|
+
PR. Bug reports run the same way with a triage step in front: an agent
|
|
131
|
+
reproduces and prioritizes each report, and only the ones that clear triage
|
|
132
|
+
enter the pipeline.
|
|
133
|
+
|
|
134
|
+
Teams adopt the system through the same composition process: an engineer
|
|
135
|
+
refines a skill in their own
|
|
136
|
+
[`~/.agents`](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/local-development.md)
|
|
137
|
+
against real work; the team mines
|
|
138
|
+
[pensieve](https://github.com/ai-outfitter/pensieve) for the patterns behind
|
|
139
|
+
successful and failing runs. When a change earns trust it moves by pull
|
|
140
|
+
request into the org catalog, where every agent composes it by name. One
|
|
141
|
+
person's improvement becomes everyone's default at the next pin bump — no
|
|
142
|
+
one else reconfigures anything.
|
|
143
|
+
|
|
144
|
+
## Start this afternoon
|
|
145
|
+
|
|
146
|
+
You can begin with a local assessment and CLI trial before committing to an
|
|
147
|
+
organization-wide rollout or additional infrastructure.
|
|
148
|
+
|
|
149
|
+
### 1. See where you are
|
|
150
|
+
|
|
151
|
+
The read-only assessment takes one afternoon. The
|
|
152
|
+
[org-onboarding runbook](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/usecases/org-onboarding-sdlc-report.md)
|
|
153
|
+
produces a baseline **SDLC report**: where your organization sits on the
|
|
154
|
+
ramp, with evidence, gaps, and next-rung recommendations. Concretely: one
|
|
155
|
+
engineer runs the `sdlc-report` skill from their own local agent with a
|
|
156
|
+
read-only forge token. It reads through the API — never clones, never
|
|
157
|
+
writes — and produces two local files you review before anyone else sees
|
|
158
|
+
them. We ran it on this organization the day we wrote this page; the output
|
|
159
|
+
is committed at
|
|
160
|
+
[.agents/reports/sdlc](https://github.com/ai-outfitter/.agents/tree/main/reports/sdlc),
|
|
161
|
+
so you can see exactly what you would get.
|
|
162
|
+
|
|
163
|
+
### 2. Try the toolchain
|
|
164
|
+
|
|
165
|
+
The first run takes about ten minutes.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
npx @ai-outfitter/outfitter
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
This launches the Outfitter CLI with the
|
|
172
|
+
[Pi](https://github.com/earendil-works/pi) harness bundled and walks you
|
|
173
|
+
through composing your first agent profile from a starter catalog. You end
|
|
174
|
+
in a working agent session, and everything it created is plain files under
|
|
175
|
+
`~/.agents` — which you can read, edit, or delete afterward.
|
|
176
|
+
|
|
177
|
+
### 3. Automate one workflow
|
|
178
|
+
|
|
179
|
+
Pick feature-to-PR or bug-to-PR, keep it to
|
|
180
|
+
one repository, and promote the profiles you already trust at a desk into
|
|
181
|
+
[CI](https://github.com/ai-outfitter/actions). Work the runbooks in order —
|
|
182
|
+
[share one catalog](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/share-one-catalog.md),
|
|
183
|
+
[run it without your laptop](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/run-without-your-laptop.md),
|
|
184
|
+
then [give the agent a residence](https://github.com/ai-outfitter/outfitter/blob/main/docs/runbooks/give-the-agent-a-residence.md).
|
|
185
|
+
Each ends with the one concrete step that starts the next.
|
|
186
|
+
|
|
187
|
+
Every runbook closes with a **Done when** section naming the signals the report
|
|
188
|
+
above checks — for this one, `triggered-agents`, `protected-landing`, and
|
|
189
|
+
`session-capture`. Re-run the report and it names whichever is still unmet.
|
|
190
|
+
|
|
191
|
+
## Agent configuration as code
|
|
192
|
+
|
|
193
|
+
Your agent setup is already configuration: system prompts, skills, MCP
|
|
194
|
+
servers, model choices, permissions. Today that configuration lives per tool
|
|
195
|
+
and per laptop, gets pasted between repositories, and drifts. Every other
|
|
196
|
+
kind of configuration your organization depends on graduated from that stage
|
|
197
|
+
years ago — into files, in a repository, behind review.
|
|
198
|
+
|
|
199
|
+
The [`.agents` convention](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/concepts.md#the-agents-protocol)
|
|
200
|
+
is an open standard for doing the same for agents:
|
|
201
|
+
|
|
202
|
+
```text
|
|
203
|
+
.agents/
|
|
204
|
+
agents.md # shared operating context
|
|
205
|
+
system-prompt.md # base system prompt
|
|
206
|
+
mcp.json # MCP servers
|
|
207
|
+
models.json # model configuration
|
|
208
|
+
agents/<id>/agent.md # agent identities + loadouts
|
|
209
|
+
skills/<id>/... # capability packages
|
|
210
|
+
knowledge/ # reference documents
|
|
211
|
+
commands/ # slash commands
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Because the configuration is Markdown and JSON, you can read, review, and
|
|
215
|
+
audit it with ordinary repository tools. Layers merge by name — a project's
|
|
216
|
+
`.agents/` over an engineer's `~/.agents/` over the organization's
|
|
217
|
+
**[catalog](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/catalogs.md)**,
|
|
218
|
+
a shared collection pinned by version — so individuals keep their preferences and
|
|
219
|
+
organizations keep their policy
|
|
220
|
+
([conventions](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/conventions.md)).
|
|
221
|
+
|
|
222
|
+
Composition beats accumulation. A profile is a selection from those files,
|
|
223
|
+
and profiles stack: a personal baseline, a team convention, a project role,
|
|
224
|
+
switched as the work changes. That keeps each profile tight, and tight
|
|
225
|
+
profiles preserve the context headroom that turns into faster, better
|
|
226
|
+
sessions.
|
|
227
|
+
|
|
228
|
+
The directory is also the exit door. It is the source of truth, and it is
|
|
229
|
+
useful without Outfitter. Vendor-neutral cuts in every direction — models,
|
|
230
|
+
harnesses, and us. Swap model vendors freely. Run the catalog through any
|
|
231
|
+
harness: Pi has the deepest runtime support today, with Claude Code tracked
|
|
232
|
+
component by component in the
|
|
233
|
+
[support matrix](https://github.com/ai-outfitter/outfitter/blob/main/docs/documentation/support-matrix.md)
|
|
234
|
+
— a Claude Code team starts on Claude Code, and the matrix shows the gaps
|
|
235
|
+
before you hit them. And if you drop Outfitter itself, the catalog you
|
|
236
|
+
built is still yours — plain files, still working.
|
|
237
|
+
|
|
238
|
+
## Where this is today
|
|
239
|
+
|
|
240
|
+
Outfitter and several supporting projects are in active development. Actions
|
|
241
|
+
and the catalogs run AI Outfitter's own workloads today; rung 5 remains the
|
|
242
|
+
least developed part of the stack. Check each linked repository for its current
|
|
243
|
+
implementation status.
|
|
244
|
+
|
|
245
|
+
The model is open core: the convention, the toolchain, and the defaults are
|
|
246
|
+
MIT — modules you can rip out and replace — while some advanced capabilities
|
|
247
|
+
ship under an enterprise license. If you are evaluating this for an
|
|
248
|
+
organization, [open an issue](https://github.com/ai-outfitter/outfitter/issues)
|
|
249
|
+
with what you found. The gaps you hit are the roadmap we want.
|
|
250
|
+
|
|
251
|
+
## As you climb
|
|
252
|
+
|
|
253
|
+
Two suggestions we make strongly, and follow ourselves:
|
|
254
|
+
|
|
255
|
+
1. **Automate nothing you have not first done manually.**
|
|
256
|
+
2. **Hand over control one layer at a time.**
|
|
257
|
+
|
|
258
|
+
You never skip a step you don't understand, and nothing you build on one
|
|
259
|
+
rung is thrown away on the next.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 980 284" font-family="-apple-system, 'Segoe UI', Helvetica, Arial, sans-serif">
|
|
2
|
+
<defs>
|
|
3
|
+
<marker id="arr" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse">
|
|
4
|
+
<path d="M 0 1 L 8 5 L 0 9 z" fill="#57606a"/>
|
|
5
|
+
</marker>
|
|
6
|
+
<marker id="arrdim" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
|
7
|
+
<path d="M 0 1 L 8 5 L 0 9 z" fill="#d4a72c"/>
|
|
8
|
+
</marker>
|
|
9
|
+
</defs>
|
|
10
|
+
|
|
11
|
+
<rect x="0.5" y="0.5" width="979" height="283" rx="12" fill="#ffffff" stroke="#d0d7de"/>
|
|
12
|
+
|
|
13
|
+
<!-- step boxes -->
|
|
14
|
+
<g>
|
|
15
|
+
<rect x="28" y="36" width="168" height="88" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
16
|
+
<text x="112" y="58" text-anchor="middle" font-size="10.5" fill="#0969da" font-weight="600" letter-spacing="0.5">1 · ENTRY POINT</text>
|
|
17
|
+
<text x="112" y="78" text-anchor="middle" font-size="14" fill="#1f2328" font-weight="600">Issue assigned</text>
|
|
18
|
+
<text x="112" y="96" text-anchor="middle" font-size="11" fill="#57606a">from the forge, chat,</text>
|
|
19
|
+
<text x="112" y="110" text-anchor="middle" font-size="11" fill="#57606a">or a desk session</text>
|
|
20
|
+
</g>
|
|
21
|
+
<g>
|
|
22
|
+
<rect x="217" y="36" width="168" height="88" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
23
|
+
<text x="301" y="58" text-anchor="middle" font-size="10.5" fill="#0969da" font-weight="600" letter-spacing="0.5">2 · PLAN</text>
|
|
24
|
+
<text x="301" y="78" text-anchor="middle" font-size="14" fill="#1f2328" font-weight="600">Planner agent</text>
|
|
25
|
+
<text x="301" y="96" text-anchor="middle" font-size="11" fill="#57606a">read-only tools →</text>
|
|
26
|
+
<text x="301" y="110" text-anchor="middle" font-size="11" fill="#57606a">spec posted for approval</text>
|
|
27
|
+
</g>
|
|
28
|
+
<g>
|
|
29
|
+
<rect x="406" y="36" width="168" height="88" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
30
|
+
<text x="490" y="58" text-anchor="middle" font-size="10.5" fill="#0969da" font-weight="600" letter-spacing="0.5">3 · IMPLEMENT</text>
|
|
31
|
+
<text x="490" y="78" text-anchor="middle" font-size="14" fill="#1f2328" font-weight="600">Implementer agent</text>
|
|
32
|
+
<text x="490" y="96" text-anchor="middle" font-size="11" fill="#57606a">fresh container,</text>
|
|
33
|
+
<text x="490" y="110" text-anchor="middle" font-size="11" fill="#57606a">scoped tools, clean context</text>
|
|
34
|
+
</g>
|
|
35
|
+
<g>
|
|
36
|
+
<rect x="595" y="36" width="168" height="88" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
37
|
+
<text x="679" y="58" text-anchor="middle" font-size="10.5" fill="#0969da" font-weight="600" letter-spacing="0.5">4 · REVIEW</text>
|
|
38
|
+
<text x="679" y="78" text-anchor="middle" font-size="14" fill="#1f2328" font-weight="600">Adversarial reviewer</text>
|
|
39
|
+
<text x="679" y="96" text-anchor="middle" font-size="11" fill="#57606a">shares no context,</text>
|
|
40
|
+
<text x="679" y="110" text-anchor="middle" font-size="11" fill="#57606a">tries to break the change</text>
|
|
41
|
+
</g>
|
|
42
|
+
<g>
|
|
43
|
+
<rect x="784" y="36" width="168" height="88" rx="8" fill="#f6f8fa" stroke="#d0d7de"/>
|
|
44
|
+
<text x="868" y="58" text-anchor="middle" font-size="10.5" fill="#0969da" font-weight="600" letter-spacing="0.5">5 · MERGE</text>
|
|
45
|
+
<text x="868" y="78" text-anchor="middle" font-size="14" fill="#1f2328" font-weight="600">PR, with history</text>
|
|
46
|
+
<text x="868" y="96" text-anchor="middle" font-size="11" fill="#57606a">transcripts & diffs attached</text>
|
|
47
|
+
<text x="868" y="110" text-anchor="middle" font-size="11" fill="#57606a">before teardown</text>
|
|
48
|
+
</g>
|
|
49
|
+
|
|
50
|
+
<!-- horizontal arrows -->
|
|
51
|
+
<line x1="198" y1="80" x2="213" y2="80" stroke="#57606a" stroke-width="1.5" marker-end="url(#arr)"/>
|
|
52
|
+
<line x1="387" y1="80" x2="402" y2="80" stroke="#57606a" stroke-width="1.5" marker-end="url(#arr)"/>
|
|
53
|
+
<line x1="576" y1="80" x2="591" y2="80" stroke="#57606a" stroke-width="1.5" marker-end="url(#arr)"/>
|
|
54
|
+
<line x1="765" y1="80" x2="780" y2="80" stroke="#57606a" stroke-width="1.5" marker-end="url(#arr)"/>
|
|
55
|
+
|
|
56
|
+
<!-- drop lines to the record -->
|
|
57
|
+
<line x1="112" y1="124" x2="112" y2="162" stroke="#d4a72c" stroke-width="1.2" stroke-dasharray="3 3" marker-end="url(#arrdim)"/>
|
|
58
|
+
<line x1="301" y1="124" x2="301" y2="162" stroke="#d4a72c" stroke-width="1.2" stroke-dasharray="3 3" marker-end="url(#arrdim)"/>
|
|
59
|
+
<line x1="490" y1="124" x2="490" y2="162" stroke="#d4a72c" stroke-width="1.2" stroke-dasharray="3 3" marker-end="url(#arrdim)"/>
|
|
60
|
+
<line x1="679" y1="124" x2="679" y2="162" stroke="#d4a72c" stroke-width="1.2" stroke-dasharray="3 3" marker-end="url(#arrdim)"/>
|
|
61
|
+
<line x1="868" y1="124" x2="868" y2="162" stroke="#d4a72c" stroke-width="1.2" stroke-dasharray="3 3" marker-end="url(#arrdim)"/>
|
|
62
|
+
|
|
63
|
+
<!-- evidence record band -->
|
|
64
|
+
<rect x="28" y="166" width="924" height="52" rx="8" fill="#fff8c5" stroke="#d4a72c" stroke-dasharray="5 4"/>
|
|
65
|
+
<text x="490" y="188" text-anchor="middle" font-size="11" fill="#7d4e00" font-weight="600" letter-spacing="1">THE RECORD</text>
|
|
66
|
+
<text x="490" y="206" text-anchor="middle" font-size="12" fill="#7d4e00">session transcripts · tool calls · diffs · approvals — written at every transition</text>
|
|
67
|
+
|
|
68
|
+
<!-- footer caption -->
|
|
69
|
+
<text x="490" y="252" text-anchor="middle" font-size="12" fill="#57606a" font-style="italic">Each step is an agent profile from a shared catalog — designed to run the same at a desk, in CI, or in a cluster.</text>
|
|
70
|
+
</svg>
|
|
@@ -94,3 +94,11 @@ Write the composed resource tree as a self-contained `.agents/` directory for re
|
|
|
94
94
|
| `--out <dir>` | Destination directory (default `./.agents`). |
|
|
95
95
|
|
|
96
96
|
> **Tasks and `outfitter task bake`** — baking a task and its inputs into an immutable execution artifact — are the subject of a separate upcoming RFC and are not part of this command surface yet. See [Tasks](./tasks.md).
|
|
97
|
+
|
|
98
|
+
`outfitter run` verifies these caches before composition. Use
|
|
99
|
+
`--source-cache-policy <repair|locked|offline>` to override the configured startup policy.
|
|
100
|
+
|
|
101
|
+
## `outfitter sources`
|
|
102
|
+
|
|
103
|
+
Report local and remote source precedence, requested and resolved revisions, origins, and cache
|
|
104
|
+
health. `outfitter sources --json` emits stable credential-redacted machine-readable output.
|
|
@@ -13,9 +13,6 @@ servers, or other use-case behavior. The default runtime user and group are
|
|
|
13
13
|
both `1000` (named `outfitter`), with `/tmp` as the home directory and
|
|
14
14
|
`/workspace` as the working directory.
|
|
15
15
|
|
|
16
|
-
A Nix closure variant of the image is also published under the `-nix` suffix;
|
|
17
|
-
see [the `-nix` variant](#the--nix-variant) below.
|
|
18
|
-
|
|
19
16
|
## Run a resident agent
|
|
20
17
|
|
|
21
18
|
A resident container is an ordinary `outfitter run` whose harness stays in RPC
|
|
@@ -47,7 +44,7 @@ spec:
|
|
|
47
44
|
fsGroup: 1000
|
|
48
45
|
containers:
|
|
49
46
|
- name: agent
|
|
50
|
-
# The
|
|
47
|
+
# The published Debian-based image.
|
|
51
48
|
image: ghcr.io/ai-outfitter/outfitter:<version>
|
|
52
49
|
stdin: true
|
|
53
50
|
workingDir: /workspace
|
|
@@ -85,8 +82,8 @@ The image is a normal Debian base: extend it with an ordinary Dockerfile.
|
|
|
85
82
|
`apt-get` works, and so does `COPY`ing binaries. A dynamically linked binary
|
|
86
83
|
runs when it matches the image — same architecture, glibc-linked, and its
|
|
87
84
|
shared-library dependencies present. The standard ELF interpreter is where
|
|
88
|
-
tools expect it
|
|
89
|
-
|
|
85
|
+
tools expect it, but the slim base ships a small library set. Use `apt-get
|
|
86
|
+
install` when a binary needs more runtime libraries.
|
|
90
87
|
Switch to `root` for the layers that install, then drop back to `1000`:
|
|
91
88
|
|
|
92
89
|
```dockerfile
|
|
@@ -111,77 +108,3 @@ docker run --rm --entrypoint /bin/sh example-agent \
|
|
|
111
108
|
|
|
112
109
|
The entrypoint stays `outfitter`; override `ENTRYPOINT` only when the derived
|
|
113
110
|
image wraps the launch itself.
|
|
114
|
-
|
|
115
|
-
## The `-nix` variant
|
|
116
|
-
|
|
117
|
-
The Nix closure image that was previously the primary tag remains published
|
|
118
|
-
for `lib.mkContainer` consumers:
|
|
119
|
-
|
|
120
|
-
```text
|
|
121
|
-
ghcr.io/ai-outfitter/outfitter:<version>-nix
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
It is built by the flake, includes the Nix CLI, Bash, core utilities, Git,
|
|
125
|
-
SSH, and CA certificates, and its entrypoint is an absolute `/nix/store` path.
|
|
126
|
-
It is not conventionally extensible — there is no apt, and foreign dynamic
|
|
127
|
-
binaries do not run — so extend it through Nix instead: the flake exports
|
|
128
|
-
`lib.mkContainer` for reproducible derivative images:
|
|
129
|
-
|
|
130
|
-
```nix
|
|
131
|
-
{
|
|
132
|
-
inputs = {
|
|
133
|
-
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
134
|
-
outfitter = {
|
|
135
|
-
url = "github:ai-outfitter/outfitter/v1.4.0";
|
|
136
|
-
inputs.nixpkgs.follows = "nixpkgs";
|
|
137
|
-
};
|
|
138
|
-
};
|
|
139
|
-
|
|
140
|
-
outputs =
|
|
141
|
-
{ nixpkgs, outfitter, ... }:
|
|
142
|
-
let
|
|
143
|
-
system = "x86_64-linux";
|
|
144
|
-
pkgs = nixpkgs.legacyPackages.${system};
|
|
145
|
-
in
|
|
146
|
-
{
|
|
147
|
-
packages.${system}.default = outfitter.lib.mkContainer {
|
|
148
|
-
inherit pkgs;
|
|
149
|
-
outfitterPackage = outfitter.packages.${system}.outfitter;
|
|
150
|
-
name = "example-agent";
|
|
151
|
-
extraPackages = [
|
|
152
|
-
pkgs.jq
|
|
153
|
-
pkgs.ripgrep
|
|
154
|
-
];
|
|
155
|
-
};
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
Build and exercise the exact image:
|
|
161
|
-
|
|
162
|
-
```sh
|
|
163
|
-
nix build
|
|
164
|
-
docker load < result
|
|
165
|
-
docker run --rm example-agent:latest --version
|
|
166
|
-
docker run --rm --entrypoint /bin/sh example-agent:latest \
|
|
167
|
-
-c 'nix --version && jq --version && rg --version'
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Prefer adding known runtime packages through `extraPackages`. The resulting
|
|
171
|
-
image stays reproducible, and it avoids the trap below.
|
|
172
|
-
|
|
173
|
-
**Do not mount an empty volume over `/nix` of the `-nix` variant.** That image
|
|
174
|
-
_is_ its Nix store: the entrypoint is an absolute store path and every binary
|
|
175
|
-
in `/bin` is a symlink into `/nix/store`. Mounting a fresh volume there hides
|
|
176
|
-
all of it, so the container cannot start — it fails before it could initialize
|
|
177
|
-
the very store you mounted the volume to populate. (The primary Debian image
|
|
178
|
-
has no `/nix` and is not affected.)
|
|
179
|
-
|
|
180
|
-
Runtime installation in the `-nix` variant therefore needs one of:
|
|
181
|
-
|
|
182
|
-
- a volume **pre-populated** with the image's closure, seeded from the image
|
|
183
|
-
before the agent starts (an init container copying `/nix` into the volume);
|
|
184
|
-
- an **overlay** whose lower layer is the image's `/nix`, so the closure stays
|
|
185
|
-
visible while writes land in the upper layer; or
|
|
186
|
-
- writable Nix **state** only — `/nix/var` and a per-user profile — leaving the
|
|
187
|
-
store itself as the image shipped it.
|
|
@@ -41,6 +41,8 @@ remote_settings:
|
|
|
41
41
|
ref: 9c47d1e2b8a05f36c4d7e90a12b3f8c5d6e71a04
|
|
42
42
|
|
|
43
43
|
cache_directory: ./cache # optional; relative to this settings file
|
|
44
|
+
source_cache:
|
|
45
|
+
policy: repair # repair (default), locked, or offline
|
|
44
46
|
|
|
45
47
|
# Pseudonymous product analytics consent; defaults to true when absent.
|
|
46
48
|
telemetry:
|
|
@@ -53,6 +55,9 @@ telemetry:
|
|
|
53
55
|
- `remote_settings` — shared settings a repository distributes; cached locally and merged below your project and user settings, so anything you set locally wins.
|
|
54
56
|
- `cache_directory` — the repository cache root used consistently by sync, remote settings, remote
|
|
55
57
|
source resolution, and default-catalog setup. It defaults to `~/.agents/cache`; repositories live
|
|
58
|
+
- `source_cache.policy` — verifies remote caches before `run`: `repair` reuses healthy caches and
|
|
59
|
+
atomically repairs unhealthy ones, `locked` also requires full commit pins, and `offline` never
|
|
60
|
+
accesses the network.
|
|
56
61
|
below its `repos/` directory.
|
|
57
62
|
- `telemetry.enabled` — the primary and sole persistent control for pseudonymous product analytics. Edit it directly to enable or disable telemetry. See [Telemetry](./telemetry.md) for consent precedence, automatic identifier cleanup, the event contract, and the current inert-build status.
|
|
58
63
|
|
|
@@ -12,33 +12,35 @@ When a composition requests something an adapter cannot project, Outfitter warns
|
|
|
12
12
|
|
|
13
13
|
Tasks and bake are not in this matrix — they are the subject of a [separate upcoming RFC](./tasks.md).
|
|
14
14
|
|
|
15
|
-
| What Outfitter projects | Pi | Claude Code | Codex CLI
|
|
16
|
-
| ------------------------------------------------------------------------ | --------- | ----------- |
|
|
17
|
-
| Agent config directory | Supported | Supported | Roadmap
|
|
18
|
-
| Session directory | Supported | Supported | Roadmap
|
|
19
|
-
| Agent identity (`system-prompt.md`, `agents.md`, `agents/<id>/agent.md`) | Supported | Supported | Roadmap
|
|
20
|
-
| Subagents (`agents/<id>` as harness delegates) | Supported | Supported | Roadmap
|
|
21
|
-
| Skills (`skills/<id>`) | Supported | Partial | Roadmap
|
|
22
|
-
| Commands (`commands/`) | Supported | Partial | Roadmap
|
|
23
|
-
| Knowledge (`knowledge/`) | Supported | Partial | Roadmap
|
|
24
|
-
| Model selection (`models.json`) | Supported |
|
|
25
|
-
| MCP servers (`mcp.json`) | Supported | Supported | Partial
|
|
26
|
-
| Extensions (agent `extensions:` loadout) | Supported | Pi only | Pi only
|
|
27
|
-
| Plugins (agent `plugins:` loadout) | Supported | Roadmap | Roadmap
|
|
28
|
-
| Credentials and environment | Supported | Supported | Roadmap
|
|
29
|
-
| DeepWork job selection | Supported | Roadmap | Roadmap
|
|
30
|
-
| Hooks | Partial | Partial | Roadmap
|
|
31
|
-
| Tool availability (agent `tools:` loadout) | Supported | Supported | Roadmap
|
|
32
|
-
| Theme / UI presentation | Roadmap | Roadmap | Roadmap
|
|
33
|
-
| Working directory | Roadmap | Roadmap | Roadmap
|
|
34
|
-
| Pass-through arguments | Supported | Supported | Supported
|
|
35
|
-
| Bootstrap hook | Supported | Roadmap | Roadmap
|
|
15
|
+
| What Outfitter projects | Pi | Claude Code | Codex CLI |
|
|
16
|
+
| ------------------------------------------------------------------------ | --------- | ----------- | ---------- |
|
|
17
|
+
| Agent config directory | Supported | Supported | Roadmap |
|
|
18
|
+
| Session directory | Supported | Supported | Roadmap |
|
|
19
|
+
| Agent identity (`system-prompt.md`, `agents.md`, `agents/<id>/agent.md`) | Supported | Supported | Roadmap |
|
|
20
|
+
| Subagents (`agents/<id>` as harness delegates) | Supported | Supported | Roadmap |
|
|
21
|
+
| Skills (`skills/<id>`) | Supported | Partial | Roadmap |
|
|
22
|
+
| Commands (`commands/`) | Supported | Partial | Roadmap |
|
|
23
|
+
| Knowledge (`knowledge/`) | Supported | Partial | Roadmap |
|
|
24
|
+
| Model selection (`models.json`) | Supported | Supported¹ | Supported² |
|
|
25
|
+
| MCP servers (`mcp.json`) | Supported | Supported | Partial |
|
|
26
|
+
| Extensions (agent `extensions:` loadout) | Supported | Pi only | Pi only |
|
|
27
|
+
| Plugins (agent `plugins:` loadout) | Supported | Roadmap | Roadmap |
|
|
28
|
+
| Credentials and environment | Supported | Supported | Roadmap |
|
|
29
|
+
| DeepWork job selection | Supported | Roadmap | Roadmap |
|
|
30
|
+
| Hooks | Partial | Partial | Roadmap |
|
|
31
|
+
| Tool availability (agent `tools:` loadout) | Supported | Supported | Roadmap |
|
|
32
|
+
| Theme / UI presentation | Roadmap | Roadmap | Roadmap |
|
|
33
|
+
| Working directory | Roadmap | Roadmap | Roadmap |
|
|
34
|
+
| Pass-through arguments | Supported | Supported | Supported |
|
|
35
|
+
| Bootstrap hook | Supported | Roadmap | Roadmap |
|
|
36
|
+
|
|
37
|
+
¹ Canonical `anthropic-messages` providers. ² Canonical `openai-responses` providers. Other dialects warn and fail under `--strict` rather than changing endpoints.
|
|
36
38
|
|
|
37
39
|
## Codex CLI notes
|
|
38
40
|
|
|
39
41
|
- **Launch mode** — Outfitter launches `codex` directly. Pass-through arguments choose the native mode: no subcommand keeps the interactive CLI shape, while `-- exec ...` selects non-interactive `codex exec`.
|
|
40
42
|
- **Agent identity and appended prompts** — Codex has no native identity projection yet: launches drop the composed identity/system prompt and any `--append-prompt` documents, supplied documents produce a separate warning, and `--strict` aborts before execution.
|
|
41
|
-
- **Model selection
|
|
43
|
+
- **Model selection** — an agent's `provider/model` selection resolves from layered `models.json`. OpenAI Responses providers map to native `model_provider`, `base_url`, `env_key`, header, wire API, and `-m` overrides. Unsupported dialects warn and omit the target instead of reusing its model ID against Codex's default endpoint. Thinking, tools, skills, subagents, plugins, and prompt templates remain unsupported and warn when selected.
|
|
42
44
|
- **Extensions (Pi only)** — `extensions:` names pi extension packages, so a Codex or Claude Code launch installs none of them. This is a property of the element, not a gap a user can close, so it produces no warning and does not fail under `--strict`.
|
|
43
45
|
- **MCP servers (Partial)** — selected stdio fields (`command`, `args`, `env`, `cwd`) and streamable HTTP fields (`url`, `headers`) become repeated TOML-valued `-c mcp_servers.<id>.<key>=...` overrides. Server ids must contain only letters, digits, `_`, or `-`; other ids cannot be expressed by Codex `-c` key paths and are skipped with a warning. Legacy SSE and other HTTP transport types are also skipped with a warning. User and project `config.toml` servers remain active because Codex has no strict MCP isolation mode, so every launch warns that projection is additive, even when no servers are selected.
|
|
44
46
|
- **Stdio environment safety** — `${ENV_NAME}` becomes an `env_vars` reference only when the stdio `env` key is also `ENV_NAME`; a reference that would rename the variable is dropped with a warning. Literal values pass through `env` and are visible in process arguments.
|
|
@@ -52,7 +54,7 @@ Tasks and bake are not in this matrix — they are the subject of a [separate up
|
|
|
52
54
|
- **MCP servers** — every Claude launch passes the generated `mcp.json` through `--mcp-config`. An inherited run stops there, so the composition's servers merge with the ones already configured on the machine: selecting a server says what the profile needs, not what the user may not have. An isolated run adds `--strict-mcp-config`, which excludes MCP servers from user or project configuration, `.claude.json`, and plugins so only the composition's servers are active.
|
|
53
55
|
- **Subagents** — selected `agents/<id>` definitions are materialized into the composition's agents directory. An inherited run loads them under the plugin's name (`<profile>:<subagent>`); an isolated run finds them natively under `CLAUDE_CONFIG_DIR`.
|
|
54
56
|
- **Skills (Partial)** — selected skills are materialized into the config directory's skills surface; remaining gaps are tracked per release. The bundled Outfitter skill ships through the plugin channel.
|
|
55
|
-
- **Model selection
|
|
57
|
+
- **Model selection** — an agent's `provider/model` selection resolves from layered `models.json`. Anthropic Messages providers map to native `--model`, `ANTHROPIC_BASE_URL`, `ANTHROPIC_AUTH_TOKEN`, and custom-header controls. Unsupported dialects warn and omit the target instead of reusing its model ID against Claude's default endpoint. Thinking level maps to `--effort`.
|
|
56
58
|
- **Hooks** — Outfitter does not project hook configuration for Claude, and there is no portable protocol hooks resource yet. An inherited run keeps the hooks in your own `~/.claude/settings.json`; an isolated run has none. See [Hooks](./hooks.md).
|
|
57
59
|
- **Tool availability** — `tools.allow` (after `tools.deny` removes entries) maps to both `--tools` (_availability_: an unlisted builtin is not in the session) and `--allowedTools` (_permission_: the granted tools are pre-approved, so a headless session is not stopped by a prompt); `tools.deny` always maps to `--disallowedTools`, including when both are declared, and a bare denied name removes the tool from context per Claude's docs. An allowlist that `tools.deny` empties maps to `--tools ""`, Claude's documented "disable all tools" form. Caveat: per the CLI reference, `--tools` governs the built-in set only — MCP tools (`mcp__server__*`) are unaffected and are governed by which MCP servers the loadout selects, so `--tools ""` is not exactly pi's zero-tool session when MCP servers are present. Claude's behavior here comes from `claude --help` and the CLI reference, not local measurement.
|
|
58
60
|
- **DeepWork jobs** — job selection is Pi-only today and warns on Claude.
|
package/package.json
CHANGED
|
@@ -11,6 +11,11 @@
|
|
|
11
11
|
"description": "Whether a run stands on the machine's native harness configuration (inherit, the default) or on the projection alone (isolated). Honored only from home-scope settings."
|
|
12
12
|
},
|
|
13
13
|
"cache_directory": { "type": "string", "minLength": 1 },
|
|
14
|
+
"source_cache": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": { "policy": { "enum": ["repair", "locked", "offline"] } },
|
|
17
|
+
"additionalProperties": false
|
|
18
|
+
},
|
|
14
19
|
"state_persistence": {
|
|
15
20
|
"type": "object",
|
|
16
21
|
"description": "Maps adapter-declared state paths to a persistence strategy.",
|