@clemrig/factory 0.21.0 → 0.22.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/README.md CHANGED
@@ -162,7 +162,19 @@ import ask from "./workflows/ask/index.ts";
162
162
 
163
163
  const minutes = 60_000;
164
164
  const opus = { runtime: "claude-code", model: "claude-opus-5-5", thinking: "high" } as const;
165
- const planner = { ...opus, tools: ["Read", "Grep", "Glob", "Agent"], timeoutMs: 30 * minutes } satisfies AgentProfile;
165
+ const planner = {
166
+ ...opus,
167
+ tools: ["Read", "Grep", "Glob", "Agent"],
168
+ agents: {
169
+ Explore: {
170
+ description: "Read-only explorer of one area of the code. Give it the area, the questions to answer about it and …",
171
+ prompt: "You explore one area of this repository for an agent that plans a change, …",
172
+ tools: ["Read", "Grep", "Glob"],
173
+ omitClaudeMd: true,
174
+ },
175
+ },
176
+ timeoutMs: 30 * minutes,
177
+ } satisfies AgentProfile;
166
178
  const checker = {
167
179
  ...opus,
168
180
  tools: ["Read", "Grep", "Glob", "Bash"],
@@ -191,7 +203,7 @@ export default defineFactory({
191
203
  - `verify`: the repository's checks, at least one: `{ name, command, timeoutMs }`, the command an executable and its arguments, run without a shell in the repository. They run in order and stop at the first failure: on the main branch before the run's agents, then after each implementation. A check may add `when`, globs of the files whose change makes it run (`when: ["scripts/*deploy*", "caddy/**"]`): it is for a long validation, such as a rehearsal, that only some changes call for; it never runs on the main branch, and after an implementation only if a file changed since the plan matches it.
192
204
  - `maxCostUsd`: the budget of an `implement` run, in USD; `factory run implement --issue <slug> --max-cost-usd 40` changes it for one run. Codex announces no cost, so the agents of `implement` and `tidy` (`plan`, `implement`, `review`, `describe`) cannot run with Codex.
193
205
  - `tidy` (optional): `{ maxCostUsd }`, the budget of a `tidy` run, that of `implement` when absent; `--max-cost-usd` changes it for one run.
194
- - `profiles`: the agents of `plan`, `implement` and `review`, and optionally `describe`, which writes the pull request (the review's profile without it; see Profiles below); `tidy` runs its scout with the `plan` profile. Each profile decides what its agent may do: here, `plan` only reads the repository, handing areas of a large spec to sub-agents (`Agent`); `implement` also edits it and runs commands, and `permissionMode: "dontAsk"` refuses any other tool instead of waiting for a permission prompt; `review` and `describe` read it and run commands, such as tests, reproductions or the application in a browser (they must not change the repository: the run puts back what they change). `Agent` in the review's tools lets it split the review of a large change between sub-agents. Without a way to start the application and a browser, `describe` takes no screenshot and says why.
206
+ - `profiles`: the agents of `plan`, `implement` and `review`, and optionally `describe`, which writes the pull request (the review's profile without it; see Profiles below); `tidy` runs its scout with the `plan` profile. Each profile decides what its agent may do: here, `plan` only reads the repository, handing areas of a large spec to sub-agents (`Agent`), its `Explore` in place of Claude Code's: read-only, reporting facts with their file and symbol and what it did not find, on the planner's model and effort; `implement` also edits it and runs commands, and `permissionMode: "dontAsk"` refuses any other tool instead of waiting for a permission prompt; `review` and `describe` read it and run commands, such as tests, reproductions or the application in a browser (they must not change the repository: the run puts back what they change). `Agent` in the review's tools lets it split the review of a large change between sub-agents. Without a way to start the application and a browser, `describe` takes no screenshot and says why.
195
207
  - `app` (optional): how to run the repository's application for the agents that check a change: `{ setup?, start, teardown?, ports?, url }`, `url` a function of its variables that gives its address (see The application above).
196
208
  - `workflows` (optional): the repository's own workflows.
197
209
 
@@ -302,10 +314,10 @@ Workflows are TypeScript run directly by Node: use erasable syntax only (no `enu
302
314
  | `model` | model name or alias | model name | model name |
303
315
  | `thinking` | effort: `low` … `max` | reasoning effort of the model (`low`, `medium`, `high`…) | `off` … `max` |
304
316
  | `tools` | optional: exact names (`Read`, `Grep`, `Bash`…) and `mcp__<server>__<tool>`; limits the built-in tools and lets the listed ones run | — | optional: exact names (`read`, `bash`…); `[]` for none |
305
- | other | `permissionMode` (a `--permission-mode` choice), `mcpServers: { name: { command, args? } }` | `sandbox`: `read-only`, `workspace-write` or `danger-full-access` | `skills`, `extensions` (paths) |
317
+ | other | `permissionMode` (a `--permission-mode` choice), `mcpServers: { name: { command, args? } }`, `agents: { name: { description, prompt, model?, thinking?, tools?, omitClaudeMd? } }` (sub-agents, see below) | `sandbox`: `read-only`, `workspace-write` or `danger-full-access` | `skills`, `extensions` (paths) |
306
318
  | `timeoutMs` | default 15 minutes, no maximum | default 15 minutes, no maximum | default 15 minutes, no maximum |
307
319
 
308
- Each agent runs with this machine's and this repository's configuration, as you would run it yourself: Claude Code with its settings, `CLAUDE.md`, plugins, hooks, skills, MCP servers and memory; Codex with its `config.toml`, `AGENTS.md` files, skills and MCP servers; Pi with its extensions, skills, context files and MCP servers. The profile only adds its settings; without `tools`, `permissionMode` or `sandbox`, the agent's own configuration decides. A Claude Code call waits for its agent's sub-agents until they end or the profile's timeout stops the call: print mode alone would stop them after 10 minutes without a turn. The agent's answer ends the call: Claude Code is stopped then, with any command the agent left running in the background, such as the application it started, and the stage's journal counts them; whatever a Claude Code agent's commands leave running, detached with `&` or `nohup` included, ends with the call too. The same workflow can therefore behave differently on another machine, and a repository's own hooks and MCP servers run with its agents. Relative skill, extension and MCP command paths are relative to `.factory/`; a bare command is looked up in the `PATH`. Runtimes are not sandboxes unless one is enabled: their tools act with your rights.
320
+ Each agent runs with this machine's and this repository's configuration, as you would run it yourself: Claude Code with its settings, `CLAUDE.md`, plugins, hooks, skills, MCP servers and memory; Codex with its `config.toml`, `AGENTS.md` files, skills and MCP servers; Pi with its extensions, skills, context files and MCP servers. The profile only adds its settings; without `tools`, `permissionMode` or `sandbox`, the agent's own configuration decides. A Claude Code profile's `agents` defines sub-agents for its sessions, in place of the machine's or the built-in ones of the same name: `Explore`, say, for the code exploration Claude Code would otherwise run at the agent's effort, on the agent's model or, when the agent runs on Fable with a Claude subscription, a Console account or a gateway, on Opus. Each runs on its `model` (the agent's model without one, Fable included) at its `thinking` effort (the agent's when it runs on the agent's model) with its `tools` (those of the agent without a list), and `omitClaudeMd: true` starts it without the user's and the repository's `CLAUDE.md`, as the built-in `Explore` does; the run records them by name. A Claude Code call waits for its agent's sub-agents until they end or the profile's timeout stops the call: print mode alone would stop them after 10 minutes without a turn. The agent's answer ends the call: Claude Code is stopped then, with any command the agent left running in the background, such as the application it started, and the stage's journal counts them; whatever a Claude Code agent's commands leave running, detached with `&` or `nohup` included, ends with the call too. The same workflow can therefore behave differently on another machine, and a repository's own hooks and MCP servers run with its agents. Relative skill, extension and MCP command paths are relative to `.factory/`; a bare command is looked up in the `PATH`. Runtimes are not sandboxes unless one is enabled: their tools act with your rights.
309
321
 
310
322
  **Prompts.** An agent's prompt is `.factory/workflows/<workflow>/prompts/<name>.md`, where the name is the stage's unless `agent({ prompt })` names another; the factory's own workflows read theirs from the package. It is appended to the runtime's system prompt (Codex receives it as the session's `developer_instructions`); the request (context and output JSON Schema) follows on standard input. Prompts are read when a run starts: an edit applies to the next run, without building anything.
311
323
 
@@ -333,7 +345,7 @@ The run executes in the foreground. The terminal first shows the launch (flow's
333
345
 
334
346
  ## Data
335
347
 
336
- Issues live in `.factory/issues/` and are committed: their specs and plans are part of the repository's history. Each run keeps `state.json`, `events.jsonl` and, for each agent call, a record in `calls/<n>.json` (the workflow's prompt, the request as the runtime read it, the command with the prompt and the MCP servers' configuration replaced by what names them, and the agent's final text) in `.factory/runs/<RUN_ID>/`, plus its Pi sessions and Claude Code and Codex session markers; Claude Code and Codex keep their transcripts in their own storage (`~/.claude/projects/…`, `~/.codex/sessions/…`). Runs hold inputs, what flow sent the agents, their outputs and the journal: they stay private and are ignored by Git. `.factory/.env` is loaded automatically, without overriding variables already set in the shell; runtimes, MCP servers and commands inherit the environment. `factory run` executes the code of `.factory/`: trust it as you trust `npm run`. The Kanban and the runs dashboard show the same data to any local process that can reach `127.0.0.1`.
348
+ Issues live in `.factory/issues/` and are committed: their specs and plans are part of the repository's history. Each run keeps `state.json`, `events.jsonl` and, for each agent call, a record in `calls/<n>.json` (the workflow's prompt, the request as the runtime read it, the command with the prompt, the sub-agents' definitions and the MCP servers' configuration replaced by what names them, and the agent's final text) in `.factory/runs/<RUN_ID>/`, plus its Pi sessions and Claude Code and Codex session markers; Claude Code and Codex keep their transcripts in their own storage (`~/.claude/projects/…`, `~/.codex/sessions/…`). Runs hold inputs, what flow sent the agents, their outputs and the journal: they stay private and are ignored by Git. `.factory/.env` is loaded automatically, without overriding variables already set in the shell; runtimes, MCP servers and commands inherit the environment. `factory run` executes the code of `.factory/`: trust it as you trust `npm run`. The Kanban and the runs dashboard show the same data to any local process that can reach `127.0.0.1`.
337
349
 
338
350
  Tokens and costs are the figures each runtime announces: Claude Code announces at the end of a call its session's total, earlier calls included, and its tokens during a call are provisional; Codex announces at the end of each turn its thread's total tokens, earlier turns included, without a cost (its input includes the cached tokens, which flow takes out so that input counts the same tokens for every runtime); Pi announces each response with its cost. A run's total is the sum of its sessions, with the cost they announced: a call without a cost makes the cost partial, unknown while no call announced one. The estimated cost is the runtime's public-price estimate, not a bill.
339
351
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clemrig/factory",
3
- "version": "0.21.0",
3
+ "version": "0.22.0",
4
4
  "description": "Take a repository's issues from spec to pull request with agents, watch them on a local Kanban, and run the repository's own workflows",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -40,7 +40,7 @@
40
40
  },
41
41
  "dependencies": {
42
42
  "@clemrig/factory-ui": "0.6.0",
43
- "@clemrig/flow": "0.11.0",
44
- "@clemrig/flow-ui": "0.12.0"
43
+ "@clemrig/flow": "0.12.0",
44
+ "@clemrig/flow-ui": "0.13.0"
45
45
  }
46
46
  }
package/prompts/plan.md CHANGED
@@ -33,9 +33,10 @@ such as an application, a layer or a feature, establish from the code itself, no
33
33
  - the tests and tools that prove such behavior in this repository.
34
34
 
35
35
  When the spec touches several areas and you can launch sub-agents, give each, five at most, one area: the spec, the
36
- request's `prototype` when it gives one, the questions above for that area, and the instruction to report facts with
37
- the file and symbol they come from, to change nothing and to launch no agent itself. Check against the code the
38
- facts the plan depends on.
36
+ request's `prototype` when it gives one, the questions above for that area and the areas the others take, so that
37
+ each reads its own. Tell each to report facts with the file and symbol they come from, and what it looked for without
38
+ finding it; to run the searches and reads that do not depend on each other together, in the same turn; to change
39
+ nothing and to launch no agent itself. Check against the code the facts the plan depends on.
39
40
 
40
41
  ## The plan
41
42
 
package/prompts/review.md CHANGED
@@ -58,7 +58,9 @@ application, a layer or a feature, with its checks in a browser when it shows in
58
58
  takes the paths that cross the parts: failures, interruptions, concurrent requests and recoveries. Give each the
59
59
  spec, its part, the files concerned, where to read the diff, and the request's `prototype`, `app` and `browser` when
60
60
  it gives them, with the rules above on servers and data, and tell it to report its findings with their evidence,
61
- established as above, to look for each defect's other occurrences, to change nothing and to launch no agent itself.
61
+ established as above, to look for each defect's other occurrences, to run the reads, searches and inspection commands
62
+ that do not depend on each other together, in the same turn, but tests and browser checks one at a time, to change
63
+ nothing and to launch no agent itself.
62
64
  Check their reports, then give one answer for the whole change.
63
65
 
64
66
  Answer with:
@@ -12,6 +12,24 @@ const opus = {
12
12
  const planner = {
13
13
  ...opus,
14
14
  tools: ["Read", "Grep", "Glob", "Agent"],
15
+ agents: {
16
+ // In place of Claude Code's: one area of the code, read only and reported
17
+ // as facts, on the planner's model and effort; `thinking` would give it
18
+ // its own effort.
19
+ Explore: {
20
+ description:
21
+ "Read-only explorer of one area of the code. Give it the area, the questions to answer about it and the areas other agents take; it answers with facts, each with the file and symbol it comes from.",
22
+ prompt: [
23
+ "You explore one area of this repository for an agent that plans a change, and answer the questions it asks about that area. You change nothing: you only search and read.",
24
+ "Establish each answer from the code itself, not from names or documentation alone: read the whole of what an answer depends on, not only the lines a search matches. Stay in your area; outside it, read only what an answer depends on, such as a function your area calls, and leave the areas other agents take to them.",
25
+ "Run the searches and reads that do not depend on each other together, in the same turn.",
26
+ "Answer with facts, each with the file and symbol it comes from, then what you looked for and did not find, and what you could not establish. Propose no design and no code: the planning agent decides.",
27
+ ].join("\n\n"),
28
+ tools: ["Read", "Grep", "Glob"],
29
+ // As Claude Code's Explore: the planner's request gives what it needs.
30
+ omitClaudeMd: true,
31
+ },
32
+ },
15
33
  timeoutMs: 30 * minutes,
16
34
  } satisfies AgentProfile;
17
35
  // Reads the change and runs what checks it: tests, the application in a