@clemrig/factory 0.1.0 → 0.2.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.
Files changed (105) hide show
  1. package/README.md +6 -17
  2. package/dist/app/doctor.d.ts +2 -4
  3. package/dist/app/doctor.js +6 -4
  4. package/dist/app/doctor.js.map +1 -1
  5. package/dist/app/factory.d.ts +2 -0
  6. package/dist/app/factory.js +13 -2
  7. package/dist/app/factory.js.map +1 -1
  8. package/dist/app/init.js +1 -1
  9. package/dist/app/init.js.map +1 -1
  10. package/dist/app/options.d.ts +17 -0
  11. package/dist/app/options.js +78 -0
  12. package/dist/app/options.js.map +1 -0
  13. package/dist/app/run.d.ts +4 -20
  14. package/dist/app/run.js +22 -93
  15. package/dist/app/run.js.map +1 -1
  16. package/dist/app/runs.d.ts +2 -34
  17. package/dist/app/runs.js +3 -63
  18. package/dist/app/runs.js.map +1 -1
  19. package/dist/cli/application.d.ts +1 -1
  20. package/dist/cli/application.js +1 -1
  21. package/dist/cli/args.js +2 -2
  22. package/dist/cli/args.js.map +1 -1
  23. package/dist/cli/doctor.d.ts +1 -1
  24. package/dist/cli/doctor.js +1 -1
  25. package/dist/cli/doctor.js.map +1 -1
  26. package/dist/cli/help.d.ts +1 -1
  27. package/dist/cli/help.js +1 -1
  28. package/dist/cli/init.d.ts +1 -1
  29. package/dist/cli/init.js +1 -1
  30. package/dist/cli/launcher.d.ts +1 -1
  31. package/dist/cli/launcher.js +4 -4
  32. package/dist/cli/launcher.js.map +1 -1
  33. package/dist/cli/reporter.d.ts +1 -1
  34. package/dist/cli/reporter.js +1 -2
  35. package/dist/cli/reporter.js.map +1 -1
  36. package/dist/cli/run.d.ts +1 -5
  37. package/dist/cli/run.js +24 -11
  38. package/dist/cli/run.js.map +1 -1
  39. package/dist/cli/status.js +3 -3
  40. package/dist/cli/status.js.map +1 -1
  41. package/dist/cli/ui.d.ts +1 -1
  42. package/dist/cli/ui.js +10 -3
  43. package/dist/cli/ui.js.map +1 -1
  44. package/dist/index.d.ts +3 -7
  45. package/dist/index.js +3 -5
  46. package/dist/index.js.map +1 -1
  47. package/dist/system/factory.d.ts +1 -1
  48. package/dist/system/factory.js +1 -1
  49. package/dist/system/factory.js.map +1 -1
  50. package/dist/system/templates.d.ts +1 -1
  51. package/dist/system/templates.js +1 -1
  52. package/package.json +7 -17
  53. package/dist/engine/metrics.d.ts +0 -45
  54. package/dist/engine/metrics.js +0 -60
  55. package/dist/engine/metrics.js.map +0 -1
  56. package/dist/engine/primitives.d.ts +0 -34
  57. package/dist/engine/primitives.js +0 -81
  58. package/dist/engine/primitives.js.map +0 -1
  59. package/dist/engine/profiles.d.ts +0 -53
  60. package/dist/engine/profiles.js +0 -117
  61. package/dist/engine/profiles.js.map +0 -1
  62. package/dist/engine/runner.d.ts +0 -13
  63. package/dist/engine/runner.js +0 -157
  64. package/dist/engine/runner.js.map +0 -1
  65. package/dist/engine/types.d.ts +0 -194
  66. package/dist/engine/types.js +0 -2
  67. package/dist/engine/types.js.map +0 -1
  68. package/dist/engine/workflow.d.ts +0 -18
  69. package/dist/engine/workflow.js +0 -196
  70. package/dist/engine/workflow.js.map +0 -1
  71. package/dist/system/process.d.ts +0 -21
  72. package/dist/system/process.js +0 -238
  73. package/dist/system/process.js.map +0 -1
  74. package/dist/system/runtimes/adapter.d.ts +0 -90
  75. package/dist/system/runtimes/adapter.js +0 -20
  76. package/dist/system/runtimes/adapter.js.map +0 -1
  77. package/dist/system/runtimes/agent-runtime.d.ts +0 -45
  78. package/dist/system/runtimes/agent-runtime.js +0 -184
  79. package/dist/system/runtimes/agent-runtime.js.map +0 -1
  80. package/dist/system/runtimes/claude-code.d.ts +0 -10
  81. package/dist/system/runtimes/claude-code.js +0 -383
  82. package/dist/system/runtimes/claude-code.js.map +0 -1
  83. package/dist/system/runtimes/inspect.d.ts +0 -25
  84. package/dist/system/runtimes/inspect.js +0 -129
  85. package/dist/system/runtimes/inspect.js.map +0 -1
  86. package/dist/system/runtimes/pi.d.ts +0 -7
  87. package/dist/system/runtimes/pi.js +0 -235
  88. package/dist/system/runtimes/pi.js.map +0 -1
  89. package/dist/system/runtimes/protocol.d.ts +0 -9
  90. package/dist/system/runtimes/protocol.js +0 -38
  91. package/dist/system/runtimes/protocol.js.map +0 -1
  92. package/dist/system/runtimes/registry.d.ts +0 -5
  93. package/dist/system/runtimes/registry.js +0 -5
  94. package/dist/system/runtimes/registry.js.map +0 -1
  95. package/dist/system/store.d.ts +0 -20
  96. package/dist/system/store.js +0 -126
  97. package/dist/system/store.js.map +0 -1
  98. package/dist/ui/server.d.ts +0 -8
  99. package/dist/ui/server.js +0 -111
  100. package/dist/ui/server.js.map +0 -1
  101. package/dist/ui/static/dashboard.js +0 -266
  102. package/dist/ui/static/follow.js +0 -67
  103. package/dist/ui/static/index.html +0 -20
  104. package/dist/ui/static/style.css +0 -166
  105. package/dist/ui/static/timeline.js +0 -180
package/README.md CHANGED
@@ -26,7 +26,7 @@ factory run ask --question "What changed recently?"
26
26
 
27
27
  ```
28
28
  .factory/
29
- package.json pins the exact core version
29
+ package.json pins the exact factory version
30
30
  factory.ts the repository's workflows
31
31
  workflows/ask/
32
32
  index.ts the example workflow
@@ -37,7 +37,7 @@ factory run ask --question "What changed recently?"
37
37
  .env optional secrets (ignored)
38
38
  ```
39
39
 
40
- The global `factory` command uses the nearest `.factory/` holding a `package.json`, in the current directory or a parent, and runs the core version installed there: every machine runs the version pinned in the repository. Only `factory init` and `factory help` run with the global version. Without `.factory/` the command asks for `factory init`; without installed dependencies it gives the `npm ci --prefix .factory` command to run.
40
+ The global `factory` command uses the nearest `.factory/` holding a `package.json`, in the current directory or a parent, and runs the factory version installed there: every machine runs the version pinned in the repository. Only `factory init` and `factory help` run with the global version. Without `.factory/` the command asks for `factory init`; without installed dependencies it gives the `npm ci --prefix .factory` command to run.
41
41
 
42
42
  The example workflow `ask` reads the last 10 commits with `git log` (a CODE stage), asks a read-only Claude Code agent (`claude-sonnet-5-5`, effort `low`, tools `Read`, `Grep`, `Glob`) to answer the question, and checks the answer with a gate that sends it back at most 3 times. Copy its folder to start a new workflow.
43
43
 
@@ -119,7 +119,7 @@ import changelog from "./workflows/changelog/index.ts";
119
119
  export default [ask, changelog];
120
120
  ```
121
121
 
122
- Workflows are TypeScript run directly by Node: use erasable syntax only (no `enum`, no parameter properties) and relative imports with their `.ts` extension. Import the core only from `@clemrig/factory`, which also exports `z` (Zod), so that workflows and the core share one Zod instance.
122
+ Workflows are TypeScript run directly by Node: use erasable syntax only (no `enum`, no parameter properties) and relative imports with their `.ts` extension. Import only from `@clemrig/factory`, which also exports `z` (Zod), so that workflows, the factory and its engine share one Zod instance.
123
123
 
124
124
  **Graph.** Each stage declares its outcomes and the node routes every outcome to a stage, to `END` or to `retry(stage, max)`. A stage receives `{ state, agent, log, dir }`: the run (read-only), the agent runtime, the run journal and the repository directory. Stages and agents work in the repository (the folder that contains `.factory/`), which is also the process's working directory during a run, wherever the command was started.
125
125
 
@@ -132,7 +132,7 @@ Workflows are TypeScript run directly by Node: use erasable syntax only (no `enu
132
132
  | `pick(...keys)` | agent context from `input` and data keys |
133
133
  | `runProcess(argv, cwd, timeoutMs)` | runs a command without a shell; Ctrl-C stops it |
134
134
 
135
- `defineWorkflow` refuses, when the workflow is loaded: a `.` in a stage or outcome name (a correction counter is named `<stage>.<outcome>`), an unrouted outcome, an unknown target, a retry maximum outside 1–100, a loop whose edges include no `retry` (with the loop's path), an invalid profile, a write tool in a read-only profile, a prompt or session name that cannot name a file, a `maxCostUsd` that is not a positive number, and an input that is not a `z.object` or uses the names `json`, `help` or `max-cost-usd`. Every run is therefore bounded.
135
+ `defineWorkflow` refuses, when the workflow is loaded: a `.` in a stage or outcome name (a correction counter is named `<stage>.<outcome>`), an unrouted outcome, an unknown target, a retry maximum outside 1–100, a loop whose edges include no `retry` (with the loop's path), an invalid profile, a write tool in a read-only profile, a prompt or session name that cannot name a file, a `maxCostUsd` that is not a positive number, and an input that is not a `z.object`. Loading `factory.ts` also refuses an input whose name cannot be an option (`json`, `help`, `max-cost-usd`, or other than letters, digits, `-` and `_` after a letter). Every run is therefore bounded.
136
136
 
137
137
  **Inputs.** Each field of `input` becomes a `--<name>` option of `factory run`; an option given without a value is `true` and only a boolean field accepts it: `z.boolean()`, possibly with `.optional()`, `.nullable()` or `.default(…)` (a transformed boolean or one with `.catch` takes no option alone). A missing, invalid or unknown option is refused with the list of problems, before any run is created. A workflow without `input` accepts no input option.
138
138
 
@@ -165,7 +165,7 @@ factory ui [--port 4321]
165
165
  factory doctor [--json]
166
166
  ```
167
167
 
168
- Before creating a run, `factory run` validates the input, reads the prompts and checks, for each runtime the workflow uses, that its executable is in the `PATH`, at least the supported version, and connected; a missing piece fails the command with the stage, runtime and reason. The terminal then shows each runtime's version and connection. A model the account cannot use fails the run at its first call, with the runtime's message.
168
+ Before creating a run, `factory run` validates the input, reads the prompts and checks from the repository, where the agents will work, for each runtime the workflow uses, that its executable is in the `PATH`, at least the supported version, and connected; a missing piece fails the command with the stage, runtime and reason. The terminal then shows each runtime's version and connection. A model the account cannot use fails the run at its first call, with the runtime's message.
169
169
 
170
170
  The run executes in the foreground. The terminal shows each stage's start and end, decisions and corrections with their counter (`[check.invalid 1/3]`), journal messages and, for an agent, the start and end of its call, each finished tool with its duration and isolation warnings; then the result, the duration, the agents' tokens and estimated cost, and the runtimes used. `--json` writes every event, then the result, as JSON lines on standard output. Exit codes: 0 completed, 1 error or failed run.
171
171
 
@@ -183,17 +183,6 @@ Tokens and costs are the figures each runtime announces, never recomputed: Claud
183
183
 
184
184
  Not in this version: resuming a run, detached runs, logs `--follow` and stop, local settings or profile overrides, actions or graph drawing in the dashboard, runs of several repositories, `factory new`, a shared stage library, a test harness for workflows, CI, cron or Git hook triggers, notifications, Windows.
185
185
 
186
- ## Develop the core
187
-
188
- ```sh
189
- npm ci
190
- npm run check # lint, format, typecheck, tests with coverage, build
191
- npm run build
192
- npm pack # then, in a test repository: npm install --no-save --prefix .factory /path/to/clemrig-factory-0.1.0.tgz
193
- ```
194
-
195
- `npm link` in this repository provides a global `factory` built from it; a test repository still runs the core installed in its `.factory/`. See [AGENTS.md](AGENTS.md), [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md), [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) and the [decisions](docs/decisions/README.md) (in French).
196
-
197
186
  ## License
198
187
 
199
- [MIT](LICENSE)
188
+ MIT
@@ -1,7 +1,5 @@
1
- import type { Runtime } from "../engine/profiles.js";
2
- import type { Workflow } from "../engine/types.js";
3
- import { type AgentProblem, type RuntimeStatus } from "../system/runtimes/inspect.js";
4
- export type { AgentProblem, RuntimeStatus, } from "../system/runtimes/inspect.js";
1
+ import { type AgentProblem, type Runtime, type RuntimeStatus, type Workflow } from "@clemrig/flow";
2
+ export type { RuntimeStatus } from "@clemrig/flow";
5
3
  /** What `factory doctor` found, without any provider request. */
6
4
  export interface Diagnosis {
7
5
  ok: boolean;
@@ -1,6 +1,7 @@
1
+ import { inspectNode, inspectRuntimes, } from "@clemrig/flow";
1
2
  import { loadLocalEnvironment } from "../system/environment.js";
2
- import { loadFactory, loadPrompts } from "../system/factory.js";
3
- import { inspectNode, inspectRuntimes, } from "../system/runtimes/inspect.js";
3
+ import { emptyFactory, loadPrompts } from "../system/factory.js";
4
+ import { loadWorkflows } from "./factory.js";
4
5
  const message = (error) => error instanceof Error ? error.message : String(error);
5
6
  /** Node, the factory and its workflows' prompts, then each runtime in use. */
6
7
  export async function diagnose(factoryDir) {
@@ -9,7 +10,7 @@ export async function diagnose(factoryDir) {
9
10
  let factory;
10
11
  let loaded;
11
12
  try {
12
- factory = await loadFactory(factoryDir);
13
+ factory = await loadWorkflows(factoryDir);
13
14
  loaded = { ok: true, detail: `Factory ${factoryDir}` };
14
15
  }
15
16
  catch (error) {
@@ -28,7 +29,8 @@ export async function diagnose(factoryDir) {
28
29
  for (const [stage, declared] of Object.entries(workflow.agents))
29
30
  agents[`${workflow.name}.${stage}`] = declared;
30
31
  }
31
- const { runtimes, problems } = await inspectRuntimes(agents);
32
+ // Where the agents will work: the repository.
33
+ const { runtimes, problems } = await inspectRuntimes(agents, factory?.dir ?? emptyFactory(factoryDir).dir);
32
34
  const ok = node.ok &&
33
35
  loaded.ok &&
34
36
  workflows.every(({ error }) => error === undefined) &&
@@ -1 +1 @@
1
- {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/app/doctor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAgB,WAAW,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC9E,OAAO,EAEL,WAAW,EACX,eAAe,GAEhB,MAAM,+BAA+B,CAAC;AAmBvC,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE,CACjC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,UAAkB;IAC/C,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,OAA4B,CAAC;IACjC,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,UAAU,EAAE,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IAC/D,CAAC;IACD,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,MAAM,MAAM,GAA+B,EAAE,CAAC;IAC9C,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC7D,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC;IACnD,CAAC;IACD,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,EAAE,GACN,IAAI,CAAC,EAAE;QACP,MAAM,CAAC,EAAE;QACT,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;QACnD,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACtE,CAAC"}
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/app/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,WAAW,EACX,eAAe,GAIhB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAgB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAgB7C,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE,CACjC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,UAAkB;IAC/C,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;IAC3B,IAAI,OAA4B,CAAC;IACjC,IAAI,MAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,aAAa,CAAC,UAAU,CAAC,CAAC;QAC1C,MAAM,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,UAAU,EAAE,EAAE,CAAC;IACzD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,OAAO,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;IAC/D,CAAC;IACD,MAAM,SAAS,GAA2B,EAAE,CAAC;IAC7C,MAAM,MAAM,GAA+B,EAAE,CAAC;IAC9C,KAAK,MAAM,QAAQ,IAAI,OAAO,EAAE,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;QACzD,IAAI,CAAC;YACH,MAAM,WAAW,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YACxC,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;YAC7D,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC,GAAG,QAAQ,CAAC;IACnD,CAAC;IACD,8CAA8C;IAC9C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,MAAM,eAAe,CAClD,MAAM,EACN,OAAO,EAAE,GAAG,IAAI,YAAY,CAAC,UAAU,CAAC,CAAC,GAAG,CAC7C,CAAC;IACF,MAAM,EAAE,GACN,IAAI,CAAC,EAAE;QACP,MAAM,CAAC,EAAE;QACT,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC;QACnD,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;IACxB,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACtE,CAAC"}
@@ -1,5 +1,7 @@
1
1
  import { type Factory } from "../system/factory.js";
2
2
  export type { Factory } from "../system/factory.js";
3
+ /** The repository's workflows, each of whose inputs can be given as options of `factory run`. */
4
+ export declare function loadWorkflows(factoryDir: string): Promise<Factory>;
3
5
  /** Loads `.factory/.env` without overriding the shell, then the repository's workflows. */
4
6
  export declare function openFactory(factoryDir: string): Promise<Factory>;
5
7
  /**
@@ -1,10 +1,21 @@
1
1
  import { loadLocalEnvironment } from "../system/environment.js";
2
2
  import { emptyFactory, loadFactory } from "../system/factory.js";
3
+ import { optionProblems } from "./options.js";
3
4
  const message = (error) => error instanceof Error ? error.message : String(error);
5
+ /** The repository's workflows, each of whose inputs can be given as options of `factory run`. */
6
+ export async function loadWorkflows(factoryDir) {
7
+ const factory = await loadFactory(factoryDir);
8
+ for (const workflow of factory.workflows.values()) {
9
+ const problems = optionProblems(workflow);
10
+ if (problems.length)
11
+ throw new Error(`Invalid workflow ${workflow.name}: ${problems.join("; ")}`);
12
+ }
13
+ return factory;
14
+ }
4
15
  /** Loads `.factory/.env` without overriding the shell, then the repository's workflows. */
5
16
  export async function openFactory(factoryDir) {
6
17
  loadLocalEnvironment(factoryDir);
7
- return loadFactory(factoryDir);
18
+ return loadWorkflows(factoryDir);
8
19
  }
9
20
  /**
10
21
  * The factory to read runs with: while `factory.ts` cannot load, its runs stay
@@ -13,7 +24,7 @@ export async function openFactory(factoryDir) {
13
24
  export async function openFactoryForReading(factoryDir) {
14
25
  loadLocalEnvironment(factoryDir);
15
26
  try {
16
- return { factory: await loadFactory(factoryDir) };
27
+ return { factory: await loadWorkflows(factoryDir) };
17
28
  }
18
29
  catch (error) {
19
30
  return { factory: emptyFactory(factoryDir), error: message(error) };
@@ -1 +1 @@
1
- {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/app/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAgB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAI/E,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE,CACjC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,WAAW,CAAC,UAAU,CAAC,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB;IAElB,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;IACpD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;IACtE,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/app/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,YAAY,EAAgB,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAI9C,MAAM,OAAO,GAAG,CAAC,KAAc,EAAE,EAAE,CACjC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEzD,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,UAAkB;IACpD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,UAAU,CAAC,CAAC;IAC9C,KAAK,MAAM,QAAQ,IAAI,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;QAClD,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,QAAQ,CAAC,MAAM;YACjB,MAAM,IAAI,KAAK,CACb,oBAAoB,QAAQ,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5D,CAAC;IACN,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,2FAA2F;AAC3F,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjC,OAAO,aAAa,CAAC,UAAU,CAAC,CAAC;AACnC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAkB;IAElB,oBAAoB,CAAC,UAAU,CAAC,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC,UAAU,CAAC,EAAE,CAAC;IACtD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;IACtE,CAAC;AACH,CAAC"}
package/dist/app/init.js CHANGED
@@ -1,4 +1,4 @@
1
- import { runProcess } from "../system/process.js";
1
+ import { runProcess } from "@clemrig/flow";
2
2
  export { createFromTemplates as createFactory } from "../system/templates.js";
3
3
  /** Installs `.factory/`'s dependencies; `output` explains a failure. */
4
4
  export async function installFactory(factoryDir) {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/app/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,OAAO,EAAE,mBAAmB,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE9E,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,UAAU,CAC9B,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,EAC7C,UAAU,EACV,OAAO,CACR,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC;QAC3B,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAC/D,CAAC,CAAC,CAAC;IACJ,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,QAAQ,KAAK,CAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;KACzC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/app/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,mBAAmB,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE9E,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,UAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,UAAU,CAC9B,CAAC,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,CAAC,EAC7C,UAAU,EACV,OAAO,CACR,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,CAAC;QAC3B,QAAQ,EAAE,CAAC;QACX,MAAM,EAAE,EAAE;QACV,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAC/D,CAAC,CAAC,CAAC;IACJ,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,QAAQ,KAAK,CAAC;QAC1B,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM;KACzC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type Workflow, type z } from "@clemrig/flow";
2
+ /** What an option may be called, after its `--`. */
3
+ export declare const OPTION_NAME: RegExp;
4
+ /** Why some inputs of the workflow cannot be given as `--<name>` options of `factory run`. */
5
+ export declare function optionProblems(workflow: Pick<Workflow, "input">): string[];
6
+ /** Whether a field takes an option given alone: a boolean, possibly optional or defaulted. */
7
+ export declare function isFlag(schema: z.ZodType): boolean;
8
+ /**
9
+ * The input that `factory run` options give the workflow. An option given
10
+ * without a value is `true`, accepted only by a boolean field: otherwise it is
11
+ * refused with every other problem, found by validating the input once.
12
+ */
13
+ export declare function inputFromOptions(workflow: Pick<Workflow, "name" | "input">, options: Record<string, string | boolean>): Record<string, string | boolean>;
14
+ /** A refused input of `factory run`, worded as options; any other error as it is. */
15
+ export declare function asOptionsError(workflow: Pick<Workflow, "name">, options: Record<string, string | boolean>, error: unknown): unknown;
16
+ /** `--max-cost-usd`: the run's budget instead of the workflow's. */
17
+ export declare function parseBudget(value: string | boolean): number;
@@ -0,0 +1,78 @@
1
+ import { InvalidInputError, parseInput, } from "@clemrig/flow";
2
+ /** Options of every `factory run`: no input may take their names. */
3
+ const GLOBAL_OPTIONS = ["json", "help", "max-cost-usd"];
4
+ /** What an option may be called, after its `--`. */
5
+ export const OPTION_NAME = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
6
+ /** Why some inputs of the workflow cannot be given as `--<name>` options of `factory run`. */
7
+ export function optionProblems(workflow) {
8
+ return Object.keys(workflow.input?.shape ?? {}).flatMap((name) => GLOBAL_OPTIONS.includes(name)
9
+ ? [`input ${name} conflicts with the global --${name} option`]
10
+ : OPTION_NAME.test(name)
11
+ ? []
12
+ : [`input ${name} is not a valid option name`]);
13
+ }
14
+ /** Whether a field takes an option given alone: a boolean, possibly optional or defaulted. */
15
+ export function isFlag(schema) {
16
+ let def = schema.def;
17
+ while (def.innerType &&
18
+ ["optional", "nullable", "default"].includes(def.type))
19
+ def = def.innerType.def;
20
+ return def.type === "boolean";
21
+ }
22
+ /** Options given without a value to a field that is not a boolean: they have no value to give. */
23
+ function valueless(workflow, options) {
24
+ const shape = workflow.input?.shape ?? {};
25
+ return Object.keys(options).filter((name) => {
26
+ const field = Object.hasOwn(shape, name) ? shape[name] : undefined;
27
+ return options[name] === true && field !== undefined && !isFlag(field);
28
+ });
29
+ }
30
+ /** Every problem of `factory run` options, worded as options. */
31
+ function optionsError(workflow, options, missingValues, problems) {
32
+ const found = missingValues.map((name) => `--${name}: missing value`);
33
+ for (const { kind, field, message } of problems) {
34
+ const name = field.split(".")[0] ?? "";
35
+ if (kind === "unknown")
36
+ found.push(`unknown option --${field}`);
37
+ else if (!missingValues.includes(name))
38
+ found.push(Object.hasOwn(options, name)
39
+ ? `--${name}: ${message}`
40
+ : `missing option --${name}`);
41
+ }
42
+ return new Error(`Invalid input for ${workflow.name}: ${found.join("; ")}`);
43
+ }
44
+ /**
45
+ * The input that `factory run` options give the workflow. An option given
46
+ * without a value is `true`, accepted only by a boolean field: otherwise it is
47
+ * refused with every other problem, found by validating the input once.
48
+ */
49
+ export function inputFromOptions(workflow, options) {
50
+ const missingValues = valueless(workflow, options);
51
+ const input = Object.fromEntries(Object.entries(options).filter(([name]) => !missingValues.includes(name)));
52
+ if (!missingValues.length)
53
+ return input;
54
+ let problems = [];
55
+ try {
56
+ parseInput(workflow, input);
57
+ }
58
+ catch (error) {
59
+ if (!(error instanceof InvalidInputError))
60
+ throw error;
61
+ problems = error.problems;
62
+ }
63
+ throw optionsError(workflow, options, missingValues, problems);
64
+ }
65
+ /** A refused input of `factory run`, worded as options; any other error as it is. */
66
+ export function asOptionsError(workflow, options, error) {
67
+ return error instanceof InvalidInputError
68
+ ? optionsError(workflow, options, [], error.problems)
69
+ : error;
70
+ }
71
+ /** `--max-cost-usd`: the run's budget instead of the workflow's. */
72
+ export function parseBudget(value) {
73
+ const budget = Number(value);
74
+ if (typeof value !== "string" || !Number.isFinite(budget) || budget <= 0)
75
+ throw new Error(`Invalid --max-cost-usd ${String(value)}: expected a positive number of USD`);
76
+ return budget;
77
+ }
78
+ //# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"options.js","sourceRoot":"","sources":["../../src/app/options.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,iBAAiB,EACjB,UAAU,GAGX,MAAM,eAAe,CAAC;AAEvB,qEAAqE;AACrE,MAAM,cAAc,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AAExD,oDAAoD;AACpD,MAAM,CAAC,MAAM,WAAW,GAAG,0BAA0B,CAAC;AAEtD,8FAA8F;AAC9F,MAAM,UAAU,cAAc,CAAC,QAAiC;IAC9D,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/D,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC;QAC3B,CAAC,CAAC,CAAC,SAAS,IAAI,gCAAgC,IAAI,SAAS,CAAC;QAC9D,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;YACtB,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,CAAC,SAAS,IAAI,6BAA6B,CAAC,CACnD,CAAC;AACJ,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,MAAM,CAAC,MAAiB;IACtC,IAAI,GAAG,GAAG,MAAM,CAAC,GAA8C,CAAC;IAChE,OACE,GAAG,CAAC,SAAS;QACb,CAAC,UAAU,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;QAEtD,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC,GAAiB,CAAC;IACxC,OAAO,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC;AAChC,CAAC;AAED,kGAAkG;AAClG,SAAS,SAAS,CAChB,QAAiC,EACjC,OAAyC;IAEzC,MAAM,KAAK,GAA8B,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC;IACrE,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnE,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iEAAiE;AACjE,SAAS,YAAY,CACnB,QAAgC,EAChC,OAAyC,EACzC,aAAuB,EACvB,QAAwB;IAExB,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,IAAI,iBAAiB,CAAC,CAAC;IACtE,KAAK,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,IAAI,IAAI,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,oBAAoB,KAAK,EAAE,CAAC,CAAC;aAC3D,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC;YACpC,KAAK,CAAC,IAAI,CACR,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;gBAC1B,CAAC,CAAC,KAAK,IAAI,KAAK,OAAO,EAAE;gBACzB,CAAC,CAAC,oBAAoB,IAAI,EAAE,CAC/B,CAAC;IACN,CAAC;IACD,OAAO,IAAI,KAAK,CAAC,qBAAqB,QAAQ,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAA0C,EAC1C,OAAyC;IAEzC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAC9B,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAC1E,CAAC;IACF,IAAI,CAAC,aAAa,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IACxC,IAAI,QAAQ,GAAmB,EAAE,CAAC;IAClC,IAAI,CAAC;QACH,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,iBAAiB,CAAC;YAAE,MAAM,KAAK,CAAC;QACvD,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC;IAC5B,CAAC;IACD,MAAM,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAC5B,QAAgC,EAChC,OAAyC,EACzC,KAAc;IAEd,OAAO,KAAK,YAAY,iBAAiB;QACvC,CAAC,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC;QACrD,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC;QACtE,MAAM,IAAI,KAAK,CACb,0BAA0B,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAC7E,CAAC;IACJ,OAAO,MAAM,CAAC;AAChB,CAAC"}
package/dist/app/run.d.ts CHANGED
@@ -1,24 +1,8 @@
1
- import type { RunEvent, RunState } from "../engine/types.js";
1
+ import { type RunHooks, type StartedRun } from "@clemrig/flow";
2
2
  import { type Factory } from "../system/factory.js";
3
- import { type RuntimeStatus } from "../system/runtimes/inspect.js";
4
- export interface RunHooks {
5
- /** Each stage, journal and agent event, once recorded. */
6
- onEvent(event: RunEvent): void;
7
- }
8
- /** A created run, executing in the foreground. */
9
- export interface StartedRun {
10
- state: Readonly<RunState>;
11
- /** Each runtime the run uses: version, executable and connection. */
12
- runtimes: RuntimeStatus[];
13
- /** Settles with the run once it completed or failed. */
14
- done: Promise<RunState>;
15
- /** Fails the run with `reason` before its next stage. */
16
- stop(reason: Error): void;
17
- /** Kills the child process groups still running, before quitting at once. */
18
- kill(): void;
19
- }
20
3
  /**
21
- * Checks input, budget, prompts and runtimes before creating the run, then runs
22
- * it in the repository that contains `.factory/`, whatever the working directory.
4
+ * Starts a workflow of the factory from `factory run` options, with its prompts
5
+ * from `.factory/`; the run works in the repository that contains `.factory/`
6
+ * and is kept in its `runs/`.
23
7
  */
24
8
  export declare function startRun(factory: Factory, name: string, options: Record<string, string | boolean>, hooks: RunHooks): Promise<StartedRun>;
package/dist/app/run.js CHANGED
@@ -1,100 +1,29 @@
1
- import { budgetProblem, emptyMetrics, recordUsage } from "../engine/metrics.js";
2
- import { executeWorkflow } from "../engine/runner.js";
3
- import { parseInput } from "../engine/workflow.js";
1
+ import { startRun as start, } from "@clemrig/flow";
4
2
  import { loadPrompts, workflowOf } from "../system/factory.js";
5
- import { inDirectory, killProcessGroups } from "../system/process.js";
6
- import { AgentRuntime } from "../system/runtimes/agent-runtime.js";
7
- import { inspectRuntimes, } from "../system/runtimes/inspect.js";
8
- import { FileRunStore, newRunId } from "../system/store.js";
9
- /** `--max-cost-usd`: the run's budget instead of the workflow's. */
10
- function parseBudget(value) {
11
- const budget = Number(value);
12
- if (typeof value !== "string" || !Number.isFinite(budget) || budget <= 0)
13
- throw new Error(`Invalid --max-cost-usd ${String(value)}: expected a positive number of USD`);
14
- return budget;
15
- }
3
+ import { asOptionsError, inputFromOptions, parseBudget } from "./options.js";
16
4
  /**
17
- * Checks input, budget, prompts and runtimes before creating the run, then runs
18
- * it in the repository that contains `.factory/`, whatever the working directory.
5
+ * Starts a workflow of the factory from `factory run` options, with its prompts
6
+ * from `.factory/`; the run works in the repository that contains `.factory/`
7
+ * and is kept in its `runs/`.
19
8
  */
20
9
  export async function startRun(factory, name, options, hooks) {
21
10
  const workflow = workflowOf(factory, name);
22
- const { "max-cost-usd": budget, ...inputOptions } = options;
23
- const maxCostUsd = budget === undefined ? workflow.maxCostUsd : parseBudget(budget);
24
- const input = parseInput(workflow, inputOptions);
25
- const prompts = await loadPrompts(factory.factoryDir, workflow);
26
- const { runtimes, problems, executables } = await inspectRuntimes(workflow.agents);
27
- if (problems.length)
28
- throw new Error(`Missing prerequisites: ${problems.map(({ stage, runtime, reason }) => `stage ${stage} (${runtime}): ${reason}`).join("; ")}`);
29
- const now = new Date().toISOString();
30
- const state = {
31
- version: 4,
32
- id: newRunId(),
33
- workflow: name,
34
- input,
35
- stage: workflow.initial,
36
- status: "running",
37
- data: {},
38
- createdAt: now,
39
- updatedAt: now,
40
- metrics: emptyMetrics(),
41
- runtimes: Object.fromEntries(Object.entries(runtimes).map(([runtime, { detail }]) => [
42
- runtime,
43
- detail,
44
- ])),
45
- };
46
- const store = new FileRunStore(factory.runsDir, state.id);
47
- const agent = new AgentRuntime({
48
- dir: factory.dir,
49
- factoryDir: factory.factoryDir,
50
- prompts,
51
- onUsage: async (report) => {
52
- if (state.metrics)
53
- recordUsage(state.metrics, report);
54
- await store.save(state);
55
- },
56
- run: { id: state.id, directory: store.directory },
57
- executables,
58
- });
59
- await store.save(state);
60
- const controller = new AbortController();
61
- /**
62
- * Past its budget, the run stops: the abort fails it at its next stage
63
- * boundary even if workflow code catches the error, and no call starts.
64
- */
65
- const overBudget = () => {
66
- const problem = maxCostUsd === undefined || !state.metrics
67
- ? undefined
68
- : budgetProblem(state.metrics, maxCostUsd);
69
- if (problem)
70
- controller.abort(new Error(problem));
71
- return problem;
72
- };
73
- // Checked before each agent call and after it, failed or not, on the figures its runtime announced.
74
- const budgeted = {
75
- async execute(request, record) {
76
- const refused = overBudget();
77
- if (refused)
78
- throw new Error(refused);
79
- const value = await agent
80
- .execute(request, record)
81
- .finally(() => overBudget());
82
- const exceeded = overBudget();
83
- if (exceeded)
84
- throw new Error(exceeded);
85
- return value;
86
- },
87
- };
88
- const done = inDirectory(factory.dir, () => executeWorkflow(workflow, state, { agent: budgeted, dir: factory.dir }, store, {
89
- onEvent: hooks.onEvent,
90
- signal: controller.signal,
91
- }));
92
- return {
93
- state,
94
- runtimes: Object.values(runtimes),
95
- done,
96
- stop: (reason) => controller.abort(reason),
97
- kill: killProcessGroups,
98
- };
11
+ const { "max-cost-usd": budget, ...given } = options;
12
+ const maxCostUsd = budget === undefined ? undefined : parseBudget(budget);
13
+ const input = inputFromOptions(workflow, given);
14
+ try {
15
+ return await start({
16
+ workflow,
17
+ input,
18
+ maxCostUsd,
19
+ prompts: () => loadPrompts(factory.factoryDir, workflow),
20
+ dir: factory.dir,
21
+ configDir: factory.factoryDir,
22
+ runsDir: factory.runsDir,
23
+ }, hooks);
24
+ }
25
+ catch (error) {
26
+ throw asOptionsError(workflow, given, error);
27
+ }
99
28
  }
100
29
  //# sourceMappingURL=run.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/app/run.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/app/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,QAAQ,IAAI,KAAK,GAClB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAgB,WAAW,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE7E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,OAAgB,EAChB,IAAY,EACZ,OAAyC,EACzC,KAAe;IAEf,MAAM,QAAQ,GAAG,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC3C,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1E,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAChB;YACE,QAAQ;YACR,KAAK;YACL,UAAU;YACV,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC;YACxD,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,SAAS,EAAE,OAAO,CAAC,UAAU;YAC7B,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,EACD,KAAK,CACN,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,cAAc,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;IAC/C,CAAC;AACH,CAAC"}
@@ -1,36 +1,4 @@
1
- import type { RunEvent, RunState } from "../engine/types.js";
1
+ import type { RunState } from "@clemrig/flow";
2
2
  import type { Factory } from "../system/factory.js";
3
- export { UnknownRunError } from "../system/store.js";
4
- /** A run, or why it cannot be read. */
5
- export type RunEntry = {
6
- id: string;
7
- state: RunState;
8
- } | {
9
- id: string;
10
- error: string;
11
- };
12
- /** The repository's runs in creation order; an unreadable run comes with its error. */
13
- export declare function listRuns(factory: Factory): Promise<RunEntry[]>;
14
- /** A run as a list shows it; a cost no agent announced is unknown (`null`), not zero. */
15
- export declare function summarizeRun(state: RunState): {
16
- id: string;
17
- workflow: string;
18
- status: "completed" | "failed" | "running";
19
- stage: string;
20
- durationMs: number | null;
21
- costUsd: number | null;
22
- /** Some agent call announced no usage. */
23
- partial: boolean;
24
- updatedAt: string;
25
- };
26
- /** One run's state; an unknown ID is refused. */
27
- export declare function loadRun(factory: Factory, id: string): Promise<RunState>;
28
- /** One run's stage and journal events, in order. */
29
- export declare function loadRunEvents(factory: Factory, id: string): Promise<RunEvent[]>;
30
- /**
31
- * A run's result lines: its workflow's rendering, or its validated data when the
32
- * workflow left `factory.ts`. A failing rendering becomes the explanation.
33
- */
3
+ /** A run's result lines: its workflow's rendering, or its validated data when the workflow left `factory.ts`. */
34
4
  export declare function presentResult(factory: Factory, state: Readonly<RunState>): string[];
35
- /** Each correction route's maximum, keyed `<stage>.<outcome>` like a run's counters. */
36
- export declare function retryMaximums(factory: Factory, workflow: string): Map<string, number>;
package/dist/app/runs.js CHANGED
@@ -1,66 +1,6 @@
1
- import { elapsedMs } from "../engine/metrics.js";
2
- import { presentData } from "../engine/workflow.js";
3
- import { FileRunStore } from "../system/store.js";
4
- export { UnknownRunError } from "../system/store.js";
5
- const message = (error) => error instanceof Error ? error.message : String(error);
6
- /** The repository's runs in creation order; an unreadable run comes with its error. */
7
- export async function listRuns(factory) {
8
- const entries = [];
9
- for (const id of await FileRunStore.list(factory.runsDir))
10
- try {
11
- entries.push({
12
- id,
13
- state: await new FileRunStore(factory.runsDir, id).load(),
14
- });
15
- }
16
- catch (error) {
17
- entries.push({ id, error: message(error) });
18
- }
19
- return entries;
20
- }
21
- /** A run as a list shows it; a cost no agent announced is unknown (`null`), not zero. */
22
- export function summarizeRun(state) {
23
- const usage = state.metrics?.usage;
24
- return {
25
- id: state.id,
26
- workflow: state.workflow,
27
- status: state.status,
28
- stage: state.stage,
29
- durationMs: elapsedMs(state),
30
- costUsd: usage?.responses ? usage.costUsd : null,
31
- /** Some agent call announced no usage. */
32
- partial: Boolean(usage?.missing),
33
- updatedAt: state.updatedAt,
34
- };
35
- }
36
- /** One run's state; an unknown ID is refused. */
37
- export async function loadRun(factory, id) {
38
- return new FileRunStore(factory.runsDir, id).load();
39
- }
40
- /** One run's stage and journal events, in order. */
41
- export async function loadRunEvents(factory, id) {
42
- return new FileRunStore(factory.runsDir, id).events();
43
- }
44
- /**
45
- * A run's result lines: its workflow's rendering, or its validated data when the
46
- * workflow left `factory.ts`. A failing rendering becomes the explanation.
47
- */
1
+ import * as flow from "@clemrig/flow";
2
+ /** A run's result lines: its workflow's rendering, or its validated data when the workflow left `factory.ts`. */
48
3
  export function presentResult(factory, state) {
49
- try {
50
- const workflow = factory.workflows.get(state.workflow);
51
- return workflow ? workflow.presentResult(state) : presentData(state);
52
- }
53
- catch (error) {
54
- return [`Result unavailable: ${message(error)}`];
55
- }
56
- }
57
- /** Each correction route's maximum, keyed `<stage>.<outcome>` like a run's counters. */
58
- export function retryMaximums(factory, workflow) {
59
- const found = new Map();
60
- for (const [name, node] of Object.entries(factory.workflows.get(workflow)?.nodes ?? {}))
61
- for (const [outcome, edge] of Object.entries(node.on))
62
- if (edge && typeof edge === "object")
63
- found.set(`${name}.${outcome}`, edge.max);
64
- return found;
4
+ return flow.presentResult(factory.workflows.get(state.workflow), state);
65
5
  }
66
6
  //# sourceMappingURL=runs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/app/runs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/app/runs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,eAAe,CAAC;AAItC,iHAAiH;AACjH,MAAM,UAAU,aAAa,CAC3B,OAAgB,EAChB,KAAyB;IAEzB,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;AAC1E,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The command run by the core installed in `.factory/`: the global `factory`
2
+ * The command run by the factory installed in `.factory/`: the global `factory`
3
3
  * calls it with the arguments it received and the `.factory/` it found. This
4
4
  * contract only changes with a major version.
5
5
  */
@@ -16,7 +16,7 @@ function parsePort(value) {
16
16
  return port;
17
17
  }
18
18
  /**
19
- * The command run by the core installed in `.factory/`: the global `factory`
19
+ * The command run by the factory installed in `.factory/`: the global `factory`
20
20
  * calls it with the arguments it received and the `.factory/` it found. This
21
21
  * contract only changes with a major version.
22
22
  */
package/dist/cli/args.js CHANGED
@@ -1,4 +1,4 @@
1
- const OPTION = /^[a-zA-Z][a-zA-Z0-9_-]*$/;
1
+ import { OPTION_NAME } from "../app/options.js";
2
2
  /** `--name value`, or `--name` alone for true; --json and --help never take a value. */
3
3
  export function parseArgs(argv) {
4
4
  const positional = [];
@@ -17,7 +17,7 @@ export function parseArgs(argv) {
17
17
  else if (name === "help")
18
18
  help = true;
19
19
  else {
20
- if (!OPTION.test(name))
20
+ if (!OPTION_NAME.test(name))
21
21
  throw new Error(`Invalid option ${arg}`);
22
22
  if (Object.hasOwn(options, name))
23
23
  throw new Error(`Duplicate option ${arg}`);
@@ -1 +1 @@
1
- {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AASA,MAAM,MAAM,GAAG,0BAA0B,CAAC;AAE1C,wFAAwF;AACxF,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,MAAM;YAAE,IAAI,GAAG,IAAI,CAAC;aAC5B,IAAI,IAAI,KAAK,MAAM;YAAE,IAAI,GAAG,IAAI,CAAC;aACjC,CAAC;YACJ,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;YACjE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;YAC/D,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,MAAM;QACrC,UAAU;QACV,OAAO;QACP,IAAI;QACJ,IAAI;KACL,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AAC5E,CAAC"}
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAWhD,wFAAwF;AACxF,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,IAAI,IAAI,GAAG,KAAK,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,MAAM;YAAE,IAAI,GAAG,IAAI,CAAC;aAC5B,IAAI,IAAI,KAAK,MAAM;YAAE,IAAI,GAAG,IAAI,CAAC;aACjC,CAAC;YACJ,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,kBAAkB,GAAG,EAAE,CAAC,CAAC;YACtE,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;YAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC1B,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC;YAC/D,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IACD,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,KAAK,EAAE,IAAI,MAAM;QACrC,UAAU;QACV,OAAO;QACP,IAAI;QACJ,IAAI;KACL,CAAC;AACJ,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,SAAS,CAAC,IAAe;IACvC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,IAAI,QAAQ,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AAC5E,CAAC"}