@usine/config 0.2.1 → 0.4.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 (74) hide show
  1. package/LICENSE +661 -21
  2. package/README.md +32 -18
  3. package/dist/agent.d.ts +2 -3
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +2 -3
  6. package/dist/agent.js.map +1 -1
  7. package/dist/board.d.ts +11 -6
  8. package/dist/board.d.ts.map +1 -1
  9. package/dist/board.js +11 -6
  10. package/dist/board.js.map +1 -1
  11. package/dist/checks.d.ts +3 -0
  12. package/dist/checks.d.ts.map +1 -1
  13. package/dist/checks.js +3 -0
  14. package/dist/checks.js.map +1 -1
  15. package/dist/factory.d.ts +258 -22
  16. package/dist/factory.d.ts.map +1 -1
  17. package/dist/factory.js +270 -30
  18. package/dist/factory.js.map +1 -1
  19. package/dist/file.d.ts +3 -3
  20. package/dist/file.d.ts.map +1 -1
  21. package/dist/file.js +3 -3
  22. package/dist/file.js.map +1 -1
  23. package/dist/frontmatter.d.ts +1 -1
  24. package/dist/frontmatter.d.ts.map +1 -1
  25. package/dist/frontmatter.js +1 -1
  26. package/dist/frontmatter.js.map +1 -1
  27. package/dist/instance/diagnostics.d.ts +1 -1
  28. package/dist/instance/diagnostics.d.ts.map +1 -1
  29. package/dist/instance/diagnostics.js +1 -1
  30. package/dist/instance/diagnostics.js.map +1 -1
  31. package/dist/instance/instance.d.ts +1 -1
  32. package/dist/instance/instance.d.ts.map +1 -1
  33. package/dist/instance/instance.js +2 -2
  34. package/dist/instance/instance.js.map +1 -1
  35. package/dist/instance/references.d.ts +5 -6
  36. package/dist/instance/references.d.ts.map +1 -1
  37. package/dist/instance/references.js +9 -9
  38. package/dist/instance/references.js.map +1 -1
  39. package/dist/instance-folder.d.ts +1 -1
  40. package/dist/instance-folder.d.ts.map +1 -1
  41. package/dist/instance-folder.js +13 -1
  42. package/dist/instance-folder.js.map +1 -1
  43. package/dist/label.d.ts +5 -5
  44. package/dist/label.d.ts.map +1 -1
  45. package/dist/label.js +5 -5
  46. package/dist/label.js.map +1 -1
  47. package/dist/loop.d.ts +12 -3
  48. package/dist/loop.d.ts.map +1 -1
  49. package/dist/loop.js +14 -6
  50. package/dist/loop.js.map +1 -1
  51. package/dist/parser.d.ts +6 -6
  52. package/dist/parser.d.ts.map +1 -1
  53. package/dist/parser.js +30 -11
  54. package/dist/parser.js.map +1 -1
  55. package/dist/payload-slices.d.ts +4 -7
  56. package/dist/payload-slices.d.ts.map +1 -1
  57. package/dist/payload-slices.js +30 -25
  58. package/dist/payload-slices.js.map +1 -1
  59. package/dist/selector.d.ts +6 -3
  60. package/dist/selector.d.ts.map +1 -1
  61. package/dist/selector.js +10 -6
  62. package/dist/selector.js.map +1 -1
  63. package/dist/trigger.d.ts +4 -7
  64. package/dist/trigger.d.ts.map +1 -1
  65. package/dist/trigger.js +6 -9
  66. package/dist/trigger.js.map +1 -1
  67. package/dist/yaml/document.d.ts +2 -2
  68. package/dist/yaml/document.js +3 -3
  69. package/dist/yaml/document.js.map +1 -1
  70. package/dist/yaml/writer.d.ts +4 -4
  71. package/dist/yaml/writer.d.ts.map +1 -1
  72. package/dist/yaml/writer.js +5 -6
  73. package/dist/yaml/writer.js.map +1 -1
  74. package/package.json +12 -11
package/README.md CHANGED
@@ -1,15 +1,16 @@
1
1
  # @usine/config
2
2
 
3
- Reads and edits the authored files in a [usine](https://github.com/basaltbytes/usine) instance folder:
3
+ Reads and edits the files of a [usine](https://github.com/basaltbytes/usine) instance folder. The [`usine.yaml`](https://docs.usine.dev/reference/configuration/usine-yaml/), [loop file](https://docs.usine.dev/reference/configuration/loop-files/), and [agent file](https://docs.usine.dev/reference/configuration/agent-files/) references describe every key.
4
4
 
5
- - `usine.yaml` defines the schema version, factory-wide GitHub labels, managed-repo registry, settings, workers, webhook mode, and operator login.
6
- - `loops/*.md` combines strict YAML frontmatter with a Markdown prompt. The parser type-checks the trigger and every `{{ CEL expression }}` against that trigger's payload.
7
- - `agents/*.md` records a named agent's harness, model, effort, optional parent model, optional parent effort, and persona.
8
- - `updateYaml` and `updateFrontmatter` change one path through the YAML document tree while retaining comments, key order, and the Markdown body.
5
+ - `usine.yaml`: schema version, factory-wide GitHub labels, the managed-repo registry, settings, workers, webhook mode, and operator login.
6
+ - `loops/*.md`: strict YAML frontmatter and a Markdown prompt. The parser type-checks the trigger and every `{{ CEL expression }}` against the trigger's payload.
7
+ - `agents/*.md`: harness, model, effort, optional parent model and parent effort, and persona.
9
8
 
10
- Authored keys are snake_case (`poll_interval`, `max_concurrent_attempts`); the decoded domain types expose camelCase fields (`pollInterval`, `maxConcurrentAttempts`). The rename is part of the schema, so edits encode back to the authored casing.
9
+ `updateYaml` and `updateFrontmatter` change one path in the YAML tree and keep comments, key order, and the Markdown body. Files use snake_case keys (`poll_interval`, `max_concurrent_attempts`); decoded types use camelCase (`pollInterval`, `maxConcurrentAttempts`). The schema does the rename, so edits keep snake_case.
11
10
 
12
- Declare the GitHub labels used by Loops and Board lanes once. Usine provisions missing declarations in every managed repository; existing definitions are never edited or deleted. `color` is an optional six-digit hexadecimal value without `#`:
11
+ ## Labels and lanes
12
+
13
+ Declare the labels that loops and lanes use once. usine creates missing labels in every managed repo and never edits or deletes labels:
13
14
 
14
15
  ```yaml
15
16
  labels:
@@ -19,11 +20,9 @@ labels:
19
20
  - name: ready-for-review
20
21
  ```
21
22
 
22
- Label names follow GitHub's contract: at most 50 characters, no surrounding whitespace, and unique without regard to case; descriptions are at most 100 characters. A lane source or trigger-expression string literal that refers to an undeclared label becomes a non-blocking entry in `LoadedInstance.warnings`; prose in prompt bodies is not inspected.
23
-
24
- Set `settings.max_children` to the number of child sessions one Attempt may spawn. The default is 4, and the count includes sequential and concurrent child sessions.
23
+ An undeclared label in a lane source or a trigger expression string literal adds a non-blocking entry to `LoadedInstance.warnings`. Prompt prose isn't checked.
25
24
 
26
- Each managed repository can define an exclusive Board lane map. A lane accepts one or more GitHub label or Item-state sources:
25
+ Each managed repo can define an exclusive board lane map of label and item state sources:
27
26
 
28
27
  ```yaml
29
28
  repos:
@@ -38,16 +37,31 @@ repos:
38
37
  - state: pr-open
39
38
  ```
40
39
 
41
- Valid state sources are `issue-open`, `issue-closed`, `pr-open`, `pr-closed`, and `pr-merged`. Lane names and sources must be unique within the repository. Repositories without an authored map receive proposed lanes from the labels observed during GitHub polling.
40
+ `isSettledItemState` reports the settled states, `issue-closed`, `pr-closed`, and `pr-merged`; the board places such an item by state alone, whatever its labels. A repo without a lane map gets proposed lanes from the labels that polling finds.
41
+
42
+ ## Settings and workers
43
+
44
+ `settings.max_children` (default 4) limits the child sessions, sequential and concurrent, that one attempt can start. Without a `workers` key, the parser adds a local worker named `local` that runs one attempt at a time. A worker's `kind` (`local`, `exe.dev`, or `ssh`) selects its executor. An SSH worker's `container` (`WorkerContainer`) sets the image and the `cpus`, `memory_mib`, and `pids` limits of each attempt container; each limit is optional, and the executor derives an unset one from the machine at preflight.
45
+
46
+ Issue and pull request loops accept `max_cycles`, a positive integer (default 3): the number of runs each loop can open on an item between operator resets. The first admission past it blocks runs from every loop on the item. Schedule loops are exempt. See [Write review and fix loops](https://docs.usine.dev/guides/review-fix-loops/).
47
+
48
+ A loop's optional `priority`, a positive integer (`LoopFile.priority`, `LoopPriority`), ranks its runs for a free worker slot before runs that lane order ranks, higher first. See [Loop files](https://docs.usine.dev/reference/configuration/loop-files/#priority).
49
+
50
+ ## Load an instance
51
+
52
+ `InstanceFolder.load` takes an `InstanceDirectory` (`@usine/core/instance`) and returns one atomic `LoadedInstance` snapshot:
42
53
 
43
- `workers` must contain at least one uniquely named worker. If the key is absent, the parser supplies one local worker named `local` with a concurrency limit of one. Set `kind` to `local` or `exe.dev` to select its executor, and set `max_concurrent_attempts` to control how many Attempts it can run at once.
54
+ - An invalid `usine.yaml` fails the load with `FactoryConfigError`.
55
+ - An invalid loop goes to `quarantinedLoops` with a `ConfigFileError` naming the file and stage. Valid loops still load.
56
+ - Invalid agents go to `invalidAgents`, and loops that use them are quarantined.
57
+ - Non-blocking reference diagnostics go to `warnings`.
44
58
 
45
- `InstanceFolder.load` takes an `InstanceDirectory` (from `@usine/core/instance`) and returns one atomic `LoadedInstance` snapshot. An invalid `usine.yaml` fails the load with a `FactoryConfigError`; an invalid loop enters `quarantinedLoops` with a `ConfigFileError` naming the file and stage, without blocking valid siblings. Invalid agents appear in `invalidAgents`, and loops that name them are quarantined. A `LoadedInstance` always satisfies its own reference rule: every loaded loop names a rostered agent and registered selector entries, enforced at construction. Non-blocking authored-reference diagnostics appear in `warnings`. The `ConfigError` union covers both failure types.
59
+ `ConfigError` is the union of both errors. The `LoadedInstance` constructor enforces that every loop references a rostered agent and registered selector entries.
46
60
 
47
- Import factory settings and registry types from `@usine/config/factory`, Board lanes from `@usine/config/board`, and label declarations from `@usine/config/label`. Authored loop, trigger, and agent schemas are available at `/loop`, `/trigger`, and `/agent`; `/selector` provides both the selector schema and matching operation. `/instance` provides `LoadedInstance` and its warnings, while `/file` provides file paths and typed loading failures. Shared identities and agent personas come from their owning `@usine/core` modules.
61
+ ## Imports
48
62
 
49
- The package exports Effect services and layers. Import `InstanceFolder` from `@usine/config/instance-folder` and `ConfigParser` from `@usine/config/parser`. Supply `FileSystem.FileSystem` and `Path.Path` implementations when composing `InstanceFolder.layer`; `ConfigParser.layer` requires `ExpressionEngine` from `@usine/expression/expression-engine`.
63
+ Subpaths: `/factory` (settings and registry), `/board` (lanes), `/label`, `/loop`, `/trigger`, `/agent`, `/selector` (schema and matching), `/instance` (`LoadedInstance` and warnings), and `/file` (file paths and loading failures). Shared identities and agent personas come from `@usine/core`.
50
64
 
51
- All APIs remain 0.x and can change between minor releases.
65
+ `InstanceFolder` (`/instance-folder`) and `ConfigParser` (`/parser`) are Effect services. `InstanceFolder.layer` needs `FileSystem.FileSystem` and `Path.Path`; `ConfigParser.layer` needs `ExpressionEngine` from `@usine/expression/expression-engine`.
52
66
 
53
- Issue and pull-request Loops accept `max_cycles`, a positive integer defaulting to three. Each Loop may open that many Runs on an Item between operator resets. The first excess admission blocks further Runs from every Loop on the Item. Schedule Loops are exempt. See the [review/fix guide](../../docs/guides/review-fix-loops.md) for authored examples.
67
+ The 0.x APIs can change between minor releases.
package/dist/agent.d.ts CHANGED
@@ -10,16 +10,15 @@ declare const AgentFile_base: Schema.Class<AgentFile, Schema.Struct<{
10
10
  readonly parentEffort: Schema.Option<Schema.Literals<readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"]>>;
11
11
  readonly persona: Schema.brand<Schema.String, "AgentPersona">;
12
12
  }>, {}>;
13
- /** An Agent's authored brain, parent overrides, and standing instructions, named by its Markdown filename. */
13
+ /** A parsed Agent Markdown file; `name` comes from the filename. */
14
14
  export declare class AgentFile extends AgentFile_base {
15
- /** The roster member represented by this file, including persona and parent overrides. */
16
15
  get agent(): Agent;
17
16
  }
18
17
  declare const InvalidAgent_base: Schema.Class<InvalidAgent, Schema.Struct<{
19
18
  readonly file: Schema.brand<Schema.NonEmptyString, "InstancePath">;
20
19
  readonly error: typeof ConfigFileError;
21
20
  }>, {}>;
22
- /** An Agent file excluded from the roster because it could not be loaded. */
21
+ /** An Agent file that failed to load and is left out of the roster. */
23
22
  export declare class InvalidAgent extends InvalidAgent_base {
24
23
  }
25
24
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA2B,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAC;;;;;;;;;;AAE1D,8GAA8G;AAC9G,qBAAa,SAAU,SAAQ,cAQ7B;IACA,0FAA0F;IAC1F,IAAI,KAAK,IAAI,KAAK,CAQjB;CACF;;;;;AAED,6EAA6E;AAC7E,qBAAa,YAAa,SAAQ,iBAGhC;CAAG"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAA2B,MAAM,mBAAmB,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAC;;;;;;;;;;AAE1D,oEAAoE;AACpE,qBAAa,SAAU,SAAQ,cAQ7B;IACA,IAAI,KAAK,IAAI,KAAK,CAQjB;CACF;;;;;AAED,uEAAuE;AACvE,qBAAa,YAAa,SAAQ,iBAGhC;CAAG"}
package/dist/agent.js CHANGED
@@ -2,7 +2,7 @@ import { Agent, AgentPersona, AgentName } from "@usine/core/agent";
2
2
  import { BrainSpec, Effort, Harness, ModelId } from "@usine/core/agent/brain";
3
3
  import { Schema } from "effect";
4
4
  import { InstancePath, ConfigFileError } from "./file.js";
5
- /** An Agent's authored brain, parent overrides, and standing instructions, named by its Markdown filename. */
5
+ /** A parsed Agent Markdown file; `name` comes from the filename. */
6
6
  export class AgentFile extends Schema.Class("@usine/config/AgentFile")({
7
7
  name: AgentName,
8
8
  harness: Harness,
@@ -12,7 +12,6 @@ export class AgentFile extends Schema.Class("@usine/config/AgentFile")({
12
12
  parentEffort: Schema.Option(Effort),
13
13
  persona: AgentPersona,
14
14
  }) {
15
- /** The roster member represented by this file, including persona and parent overrides. */
16
15
  get agent() {
17
16
  return new Agent({
18
17
  name: this.name,
@@ -23,7 +22,7 @@ export class AgentFile extends Schema.Class("@usine/config/AgentFile")({
23
22
  });
24
23
  }
25
24
  }
26
- /** An Agent file excluded from the roster because it could not be loaded. */
25
+ /** An Agent file that failed to load and is left out of the roster. */
27
26
  export class InvalidAgent extends Schema.Class("@usine/config/InvalidAgent")({
28
27
  file: InstancePath,
29
28
  error: ConfigFileError,
package/dist/agent.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE1D,8GAA8G;AAC9G,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,KAAK,CAAY,yBAAyB,CAAC,CAAC;IAChF,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,YAAY;CACtB,CAAC;IACA,0FAA0F;IAC1F,IAAI,KAAK;QACP,OAAO,IAAI,KAAK,CAAC;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YACvF,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC,CAAC;IACL,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,KAAK,CAAe,4BAA4B,CAAC,CAAC;IACzF,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,eAAe;CACvB,CAAC;CAAG"}
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE1D,oEAAoE;AACpE,MAAM,OAAO,SAAU,SAAQ,MAAM,CAAC,KAAK,CAAY,yBAAyB,CAAC,CAAC;IAChF,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,MAAM;IACd,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACnC,OAAO,EAAE,YAAY;CACtB,CAAC;IACA,IAAI,KAAK;QACP,OAAO,IAAI,KAAK,CAAC;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,KAAK,EAAE,IAAI,SAAS,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;YACvF,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,YAAY,EAAE,IAAI,CAAC,YAAY;SAChC,CAAC,CAAC;IACL,CAAC;CACF;AAED,uEAAuE;AACvE,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,KAAK,CAAe,4BAA4B,CAAC,CAAC;IACzF,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,eAAe;CACvB,CAAC;CAAG"}
package/dist/board.d.ts CHANGED
@@ -1,30 +1,35 @@
1
1
  import { Schema } from "effect";
2
- /** The operator-visible name of one lane on a Project's Board. */
3
2
  export declare const LaneName: Schema.brand<Schema.String, "LaneName">;
4
3
  export type LaneName = typeof LaneName.Type;
5
- /** An issue or pull-request state that can place an Item in a Board lane. */
6
4
  export declare const LaneItemState: Schema.Literals<readonly ["issue-open", "issue-closed", "pr-open", "pr-closed", "pr-merged"]>;
7
5
  export type LaneItemState = typeof LaneItemState.Type;
6
+ /** The state of a closed issue or a closed or merged pull request. */
7
+ export declare const SettledItemState: Schema.Literals<readonly ["issue-closed", "pr-closed", "pr-merged"]>;
8
+ export type SettledItemState = typeof SettledItemState.Type;
9
+ /**
10
+ * Returns whether `state` is a closed issue or a closed or merged pull request, which the Board
11
+ * places by state regardless of labels.
12
+ */
13
+ export declare const isSettledItemState: (state: LaneItemState) => state is SettledItemState;
8
14
  declare const LabelLaneSource_base: Schema.Class<LabelLaneSource, Schema.Struct<{
9
15
  readonly label: Schema.brand<Schema.String, "GitHubLabelName">;
10
16
  }>, {}>;
11
- /** Places Items with this GitHub label in the lane; Board moves can write the label. */
17
+ /** A lane source that matches Items with this GitHub label, which Board moves can set. */
12
18
  export declare class LabelLaneSource extends LabelLaneSource_base {
13
19
  }
14
20
  declare const StateLaneSource_base: Schema.Class<StateLaneSource, Schema.Struct<{
15
21
  readonly state: Schema.Literals<readonly ["issue-open", "issue-closed", "pr-open", "pr-closed", "pr-merged"]>;
16
22
  }>, {}>;
17
- /** Places Items with this GitHub state in the lane; Board moves cannot change the state. */
23
+ /** A lane source that matches Items in this state, which Board moves can't change. */
18
24
  export declare class StateLaneSource extends StateLaneSource_base {
19
25
  }
20
- /** A GitHub label or Item state that routes matching Items to a Board lane. */
21
26
  export declare const LaneSource: Schema.Union<readonly [typeof LabelLaneSource, typeof StateLaneSource]>;
22
27
  export type LaneSource = typeof LaneSource.Type;
23
28
  declare const Lane_base: Schema.Class<Lane, Schema.Struct<{
24
29
  readonly name: Schema.brand<Schema.String, "LaneName">;
25
30
  readonly sources: Schema.$Array<Schema.Union<readonly [typeof LabelLaneSource, typeof StateLaneSource]>>;
26
31
  }>, {}>;
27
- /** A named Board column containing Items that match any of its configured sources. */
32
+ /** A Board column that contains the Items matching any of `sources`. */
28
33
  export declare class Lane extends Lane_base {
29
34
  }
30
35
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,kEAAkE;AAClE,eAAO,MAAM,QAAQ,yCAEpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAE5C,6EAA6E;AAC7E,eAAO,MAAM,aAAa,+FAMxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;;;;AAEtD,wFAAwF;AACxF,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;;;;AAEJ,4FAA4F;AAC5F,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;AAEJ,+EAA+E;AAC/E,eAAO,MAAM,UAAU,yEAAmD,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;;;;;AAEhD,sFAAsF;AACtF,qBAAa,IAAK,SAAQ,SAGxB;CAAG"}
1
+ {"version":3,"file":"board.d.ts","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAIhC,eAAO,MAAM,QAAQ,yCAEpB,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;AAE5C,eAAO,MAAM,aAAa,+FAMxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;AAEtD,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,sEAA8D,CAAC;AAE5F,MAAM,MAAM,gBAAgB,GAAG,OAAO,gBAAgB,CAAC,IAAI,CAAC;AAI5D;;;GAGG;AACH,eAAO,MAAM,kBAAkB,UAAW,aAAa,KAAG,KAAK,IAAI,gBACjD,CAAC;;;;AAEnB,0FAA0F;AAC1F,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;;;;AAEJ,sFAAsF;AACtF,qBAAa,eAAgB,SAAQ,oBAIpC;CAAG;AAEJ,eAAO,MAAM,UAAU,yEAAmD,CAAC;AAE3E,MAAM,MAAM,UAAU,GAAG,OAAO,UAAU,CAAC,IAAI,CAAC;;;;;AAEhD,wEAAwE;AACxE,qBAAa,IAAK,SAAQ,SAGxB;CAAG"}
package/dist/board.js CHANGED
@@ -1,9 +1,7 @@
1
1
  import { Schema } from "effect";
2
2
  import { nonBlankString } from "./checks.js";
3
3
  import { GitHubLabelName } from "./label.js";
4
- /** The operator-visible name of one lane on a Project's Board. */
5
4
  export const LaneName = nonBlankString("Expected a non-blank lane name").pipe(Schema.brand("LaneName"));
6
- /** An issue or pull-request state that can place an Item in a Board lane. */
7
5
  export const LaneItemState = Schema.Literals([
8
6
  "issue-open",
9
7
  "issue-closed",
@@ -11,19 +9,26 @@ export const LaneItemState = Schema.Literals([
11
9
  "pr-closed",
12
10
  "pr-merged",
13
11
  ]);
14
- /** Places Items with this GitHub label in the lane; Board moves can write the label. */
12
+ /** The state of a closed issue or a closed or merged pull request. */
13
+ export const SettledItemState = Schema.Literals(["issue-closed", "pr-closed", "pr-merged"]);
14
+ const isSettled = Schema.is(SettledItemState);
15
+ /**
16
+ * Returns whether `state` is a closed issue or a closed or merged pull request, which the Board
17
+ * places by state regardless of labels.
18
+ */
19
+ export const isSettledItemState = (state) => isSettled(state);
20
+ /** A lane source that matches Items with this GitHub label, which Board moves can set. */
15
21
  export class LabelLaneSource extends Schema.Class("@usine/config/LabelLaneSource")({
16
22
  label: GitHubLabelName,
17
23
  }) {
18
24
  }
19
- /** Places Items with this GitHub state in the lane; Board moves cannot change the state. */
25
+ /** A lane source that matches Items in this state, which Board moves can't change. */
20
26
  export class StateLaneSource extends Schema.Class("@usine/config/StateLaneSource")({
21
27
  state: LaneItemState,
22
28
  }) {
23
29
  }
24
- /** A GitHub label or Item state that routes matching Items to a Board lane. */
25
30
  export const LaneSource = Schema.Union([LabelLaneSource, StateLaneSource]);
26
- /** A named Board column containing Items that match any of its configured sources. */
31
+ /** A Board column that contains the Items matching any of `sources`. */
27
32
  export class Lane extends Schema.Class("@usine/config/Lane")({
28
33
  name: LaneName,
29
34
  sources: Schema.Array(LaneSource).check(Schema.isNonEmpty()),
package/dist/board.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"board.js","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,kEAAkE;AAClE,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAC3E,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CACzB,CAAC;AAIF,6EAA6E;AAC7E,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3C,YAAY;IACZ,cAAc;IACd,SAAS;IACT,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAIH,wFAAwF;AACxF,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,eAAe;CACvB,CACF;CAAG;AAEJ,4FAA4F;AAC5F,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,aAAa;CACrB,CACF;CAAG;AAEJ,+EAA+E;AAC/E,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;AAI3E,sFAAsF;AACtF,MAAM,OAAO,IAAK,SAAQ,MAAM,CAAC,KAAK,CAAO,oBAAoB,CAAC,CAAC;IACjE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;CAC7D,CAAC;CAAG"}
1
+ {"version":3,"file":"board.js","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,QAAQ,GAAG,cAAc,CAAC,gCAAgC,CAAC,CAAC,IAAI,CAC3E,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CACzB,CAAC;AAIF,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3C,YAAY;IACZ,cAAc;IACd,SAAS;IACT,WAAW;IACX,WAAW;CACZ,CAAC,CAAC;AAIH,sEAAsE;AACtE,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,cAAc,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AAI5F,MAAM,SAAS,GAAG,MAAM,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAE9C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAoB,EAA6B,EAAE,CACpF,SAAS,CAAC,KAAK,CAAC,CAAC;AAEnB,0FAA0F;AAC1F,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,eAAe;CACvB,CACF;CAAG;AAEJ,sFAAsF;AACtF,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,KAAK,CAAkB,+BAA+B,CAAC,CACjG;IACE,KAAK,EAAE,aAAa;CACrB,CACF;CAAG;AAEJ,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;AAI3E,wEAAwE;AACxE,MAAM,OAAO,IAAK,SAAQ,MAAM,CAAC,KAAK,CAAO,oBAAoB,CAAC,CAAC;IACjE,IAAI,EAAE,QAAQ;IACd,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;CAC7D,CAAC;CAAG"}
package/dist/checks.d.ts CHANGED
@@ -1,3 +1,6 @@
1
+ import { type RepositoryName } from "@usine/core/repository";
1
2
  import { Schema } from "effect";
2
3
  export declare const nonBlankString: (message: string) => Schema.String;
4
+ /** Returns a filter that rejects two names GitHub treats as the same repository. */
5
+ export declare const uniqueRepositoryNames: <A>(nameOf: (value: A) => RepositoryName) => import("effect/SchemaAST").Filter<readonly A[]>;
3
6
  //# sourceMappingURL=checks.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,eAAO,MAAM,cAAc,YAAa,MAAM,kBACa,CAAC"}
1
+ {"version":3,"file":"checks.d.ts","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,eAAO,MAAM,cAAc,YAAa,MAAM,kBACa,CAAC;AAE5D,oFAAoF;AACpF,eAAO,MAAM,qBAAqB,GAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC,KAAK,cAAc,oDAK1E,CAAC"}
package/dist/checks.js CHANGED
@@ -1,3 +1,6 @@
1
+ import { canonicalRepositoryName } from "@usine/core/repository";
1
2
  import { Schema } from "effect";
2
3
  export const nonBlankString = (message) => Schema.String.check(Schema.isPattern(/\S/u, { message }));
4
+ /** Returns a filter that rejects two names GitHub treats as the same repository. */
5
+ export const uniqueRepositoryNames = (nameOf) => Schema.makeFilter((values) => new Set(values.map((value) => canonicalRepositoryName(nameOf(value)))).size === values.length, { message: "Expected unique repository names, ignoring case" });
3
6
  //# sourceMappingURL=checks.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE,CAChD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"checks.js","sourceRoot":"","sources":["../src/checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAuB,MAAM,wBAAwB,CAAC;AACtF,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE,CAChD,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;AAE5D,oFAAoF;AACpF,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAI,MAAoC,EAAE,EAAE,CAC/E,MAAM,CAAC,UAAU,CACf,CAAC,MAAM,EAAE,EAAE,CACT,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,uBAAuB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,MAAM,EAC/F,EAAE,OAAO,EAAE,iDAAiD,EAAE,CAC/D,CAAC"}
package/dist/factory.d.ts CHANGED
@@ -1,46 +1,231 @@
1
1
  import { Schema } from "effect";
2
2
  import { Lane } from "./board.ts";
3
3
  import { DeclaredLabel } from "./label.ts";
4
- /** A factory-defined repository grouping that Loops can select by tag. */
4
+ /** A repository tag that Loop selectors match. */
5
5
  export declare const RegistryTag: Schema.brand<Schema.String, "RegistryTag">;
6
6
  export type RegistryTag = typeof RegistryTag.Type;
7
- /** GitHub login identifying the human operator for this factory. */
8
- export declare const OperatorLogin: Schema.brand<Schema.String, "OperatorLogin">;
9
- export type OperatorLogin = typeof OperatorLogin.Type;
10
7
  declare const ManagedRepo_base: Schema.Class<ManagedRepo, Schema.Struct<{
11
8
  readonly name: Schema.brand<Schema.String, "RepositoryName">;
12
9
  readonly tags: Schema.withDecodingDefaultKey<Schema.$Array<Schema.brand<Schema.String, "RegistryTag">>, never>;
13
10
  readonly lanes: Schema.withDecodingDefaultKey<Schema.$Array<typeof Lane>, never>;
14
11
  }>, {}>;
15
- /** A repository the factory manages, with its selector tags and configured Board lanes. */
16
12
  export declare class ManagedRepo extends ManagedRepo_base {
17
13
  }
18
- declare const Worker_base: Schema.Class<Worker, Schema.Struct<{
14
+ declare const LocalWorker_base: Schema.Class<LocalWorker, Schema.Struct<{
19
15
  readonly name: Schema.brand<Schema.String, "WorkerName">;
20
- readonly kind: Schema.Literals<readonly ["local", "exe.dev"]>;
16
+ readonly kind: Schema.Literal<"local">;
21
17
  readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
22
18
  }>, {}>;
23
- /** A named place to execute Attempts, with the number it may run at the same time. */
24
- export declare class Worker extends Worker_base {
19
+ /** A Worker that runs Attempts on the orchestrator's machine. */
20
+ export declare class LocalWorker extends LocalWorker_base {
25
21
  }
22
+ declare const ExeDevWorker_base: Schema.Class<ExeDevWorker, Schema.Struct<{
23
+ readonly name: Schema.brand<Schema.String, "WorkerName">;
24
+ readonly kind: Schema.Literal<"exe.dev">;
25
+ readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
26
+ }>, {}>;
27
+ /** A Worker on the exe.dev VM with the same name. */
28
+ export declare class ExeDevWorker extends ExeDevWorker_base {
29
+ }
30
+ declare const WorkerGateway_base: Schema.Class<WorkerGateway, Schema.Struct<{
31
+ readonly domain: Schema.brand<Schema.String, "GatewayDomain">;
32
+ readonly destination: Schema.brand<Schema.String, "SshDestination">;
33
+ readonly adminPort: Schema.withDecodingDefaultKey<Schema.brand<Schema.Int, "GatewayAdminPort">, never>;
34
+ readonly adminTokenEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
35
+ readonly llmProviders: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Literals<readonly ["anthropic", "openai"]>>, never>;
36
+ }>, {}>;
37
+ /**
38
+ * The Gateway in front of an SSH Worker's machine on a private network (ADR 0027).
39
+ *
40
+ * - `domain`: the Gateway's private DNS domain.
41
+ * - `destination`: the Gateway's `ssh` destination, usually the Host alias in the Worker's
42
+ * `ProxyJump`. The executor forwards through it to the admin API at `adminPort` on the
43
+ * Gateway's loopback interface.
44
+ * - `adminTokenEnv`: the orchestrator environment variable with the admin token, read when
45
+ * `usine up` starts or a reload adds the Worker.
46
+ * - `llmProviders`: the providers whose credential the Gateway injects: `anthropic` for Claude
47
+ * Code, `openai` for Codex. Harnesses for other providers use the operator's login on the
48
+ * Worker through the forward proxy.
49
+ */
50
+ export declare class WorkerGateway extends WorkerGateway_base {
51
+ }
52
+ declare const WorkerContainer_base: Schema.Class<WorkerContainer, Schema.Struct<{
53
+ readonly image: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "ContainerImage">>;
54
+ readonly cpus: Schema.OptionFromOptionalKey<Schema.brand<Schema.Finite, "ContainerCpus">>;
55
+ readonly memoryMib: Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "ContainerMemoryMib">>;
56
+ readonly pids: Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "ContainerPids">>;
57
+ }>, {}>;
58
+ /**
59
+ * The container that each Attempt on an SSH Worker runs in, if the machine has Docker.
60
+ *
61
+ * - `image`: the image to run. If `None`, the executor's image for the harness versions of this
62
+ * release.
63
+ * - `cpus`, `memoryMib`, and `pids`: the limits of each Attempt's container. If `None`, the
64
+ * executor derives the limit from the machine at preflight: the machine's total less a reserve
65
+ * for its own processes, divided by `maxConcurrentAttempts`.
66
+ */
67
+ export declare class WorkerContainer extends WorkerContainer_base {
68
+ }
69
+ declare const ProviderApiKeys_base: Schema.Class<ProviderApiKeys, Schema.Struct<{
70
+ readonly anthropic: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "EnvironmentVariableName">>;
71
+ readonly openai: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "EnvironmentVariableName">>;
72
+ }>, {}>;
73
+ /**
74
+ * The orchestrator environment variables with the LLM provider API keys that each Attempt on a
75
+ * provisioned Worker gets in its environment, read when `usine up` starts or a reload adds the
76
+ * Worker. `anthropic` becomes `ANTHROPIC_API_KEY` for Claude Code, and `openai` becomes
77
+ * `OPENAI_API_KEY` for Codex.
78
+ */
79
+ export declare class ProviderApiKeys extends ProviderApiKeys_base {
80
+ }
81
+ declare const HetznerProvisioner_base: Schema.Class<HetznerProvisioner, Schema.Struct<{
82
+ readonly provider: Schema.Literal<"hetzner">;
83
+ readonly tokenEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
84
+ readonly serverType: Schema.brand<Schema.String, "HetznerServerType">;
85
+ readonly location: Schema.brand<Schema.String, "HetznerLocation">;
86
+ readonly image: Schema.brand<Schema.String, "HetznerImage">;
87
+ readonly network: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "HetznerResourceName">>;
88
+ readonly firewall: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "HetznerResourceName">>;
89
+ readonly sshKey: Schema.brand<Schema.String, "HetznerResourceName">;
90
+ readonly sshUser: Schema.withDecodingDefaultKey<Schema.brand<Schema.String, "SshUser">, never>;
91
+ readonly labels: Schema.withDecodingDefaultKey<Schema.$Record<Schema.String, Schema.String>, never>;
92
+ readonly apiKeys: Schema.withDecodingDefaultKey<typeof ProviderApiKeys, never>;
93
+ }>, {}>;
94
+ /**
95
+ * Creates one Hetzner Cloud server per Attempt from a snapshot, and deletes it after the
96
+ * Attempt (#550).
97
+ *
98
+ * - `tokenEnv`: the orchestrator environment variable with a Hetzner Cloud API token with read
99
+ * and write access to the project.
100
+ * - `serverType` and `location`: each server's type and location.
101
+ * - `image`: the snapshot's ID or description, which `infra/hetzner/snapshot.sh` prints.
102
+ * - `network`: the private network to attach each server to. With a Gateway, it's the Gateway's
103
+ * network and the server gets no public address.
104
+ * - `firewall`: the project's firewall to apply to each server, such as one that admits SSH only
105
+ * from the orchestrator's address to a server with a public address.
106
+ * - `sshKey`: the name of the SSH key in the project that each server authorizes.
107
+ * - `sshUser`: the user the executor connects as.
108
+ * - `labels`: extra labels for each server.
109
+ * - `apiKeys`: provider API keys for each Attempt, for harnesses whose credential the Gateway
110
+ * doesn't have.
111
+ */
112
+ export declare class HetznerProvisioner extends HetznerProvisioner_base {
113
+ }
114
+ declare const BoatProvisioner_base: Schema.Class<BoatProvisioner, Schema.Struct<{
115
+ readonly provider: Schema.Literal<"boat">;
116
+ readonly tokenEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
117
+ readonly size: Schema.withDecodingDefaultKey<Schema.Literals<readonly ["small", "default", "large", "xlarge"]>, never>;
118
+ readonly apiKeys: Schema.withDecodingDefaultKey<typeof ProviderApiKeys, never>;
119
+ }>, {}>;
120
+ /**
121
+ * Creates one Boat sandbox per Attempt and deletes it after the Attempt (#550). Boat has no
122
+ * network rules, so a Boat Worker has no Gateway, and each Attempt's GitHub token is on its
123
+ * machine (ADR 0026). Boat documents no region choice; its machines are in Germany, Finland, and
124
+ * France.
125
+ *
126
+ * - `tokenEnv`: the orchestrator environment variable with a Boat API key.
127
+ * - `size`: each sandbox's Boat machine type.
128
+ * - `apiKeys`: provider API keys for each Attempt. A harness without one can't authenticate,
129
+ * because a subscription login needs a Gateway.
130
+ */
131
+ export declare class BoatProvisioner extends BoatProvisioner_base {
132
+ }
133
+ /** The provider that creates one machine per Attempt for an SSH Worker; `provider` selects it. */
134
+ export declare const WorkerProvisioner: Schema.Union<readonly [typeof HetznerProvisioner, typeof BoatProvisioner]>;
135
+ export type WorkerProvisioner = typeof WorkerProvisioner.Type;
136
+ declare const SshWorker_base: Schema.Class<SshWorker, Schema.Struct<{
137
+ readonly name: Schema.brand<Schema.String, "WorkerName">;
138
+ readonly kind: Schema.Literal<"ssh">;
139
+ readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
140
+ readonly destination: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshDestination">>;
141
+ readonly provisioner: Schema.OptionFromOptionalKey<Schema.Union<readonly [Schema.encodeKeys<typeof HetznerProvisioner, {
142
+ readonly tokenEnv: "token_env";
143
+ readonly serverType: "server_type";
144
+ readonly sshKey: "ssh_key";
145
+ readonly sshUser: "ssh_user";
146
+ readonly apiKeys: "api_keys";
147
+ }>, Schema.encodeKeys<typeof BoatProvisioner, {
148
+ readonly tokenEnv: "token_env";
149
+ readonly apiKeys: "api_keys";
150
+ }>]>>;
151
+ readonly identityFile: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshIdentityFile">>;
152
+ readonly port: Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "SshPort">>;
153
+ readonly root: Schema.brand<Schema.String, "WorkerRoot">;
154
+ readonly gateway: Schema.OptionFromOptionalKey<Schema.encodeKeys<typeof WorkerGateway, {
155
+ readonly adminPort: "admin_port";
156
+ readonly adminTokenEnv: "admin_token_env";
157
+ readonly llmProviders: "llm_providers";
158
+ }>>;
159
+ readonly container: Schema.withDecodingDefaultKey<Schema.encodeKeys<typeof WorkerContainer, {
160
+ readonly memoryMib: "memory_mib";
161
+ }>, never>;
162
+ }>, {}>;
163
+ /**
164
+ * A Linux machine reached with `ssh`, with Worker state under `<root>/workers/<name>`. If
165
+ * `gateway` is set, the machine stores no GitHub token; the executor sends each Attempt's token
166
+ * to the Gateway. A Worker sets either `destination`, for one long-lived machine, or
167
+ * `provisioner`, for one machine per Attempt; `maxConcurrentAttempts` then caps the machines in
168
+ * flight.
169
+ */
170
+ export declare class SshWorker extends SshWorker_base {
171
+ }
172
+ declare const CloudflareLlmProviderKey_base: Schema.Class<CloudflareLlmProviderKey, Schema.Struct<{
173
+ readonly provider: Schema.Literals<readonly ["anthropic", "openai"]>;
174
+ readonly apiKeyEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
175
+ }>, {}>;
176
+ /**
177
+ * An LLM provider whose API key the Cloudflare Worker's outbound handlers hold for each Attempt.
178
+ * `apiKeyEnv` is the orchestrator environment variable with the key, read when `usine up` starts.
179
+ */
180
+ export declare class CloudflareLlmProviderKey extends CloudflareLlmProviderKey_base {
181
+ }
182
+ declare const CloudflareWorker_base: Schema.Class<CloudflareWorker, Schema.Struct<{
183
+ readonly name: Schema.brand<Schema.String, "WorkerName">;
184
+ readonly kind: Schema.Literal<"cloudflare">;
185
+ readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
186
+ readonly workerUrl: Schema.URLFromString;
187
+ readonly accessClientIdEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
188
+ readonly accessClientSecretEnv: Schema.brand<Schema.String, "EnvironmentVariableName">;
189
+ readonly image: Schema.brand<Schema.String, "CloudflareImageName">;
190
+ readonly instanceType: Schema.withDecodingDefaultKey<Schema.Literals<readonly ["lite", "basic", "standard-1", "standard-2", "standard-3", "standard-4"]>, never>;
191
+ readonly llmProviders: Schema.withDecodingDefaultKey<Schema.$Array<Schema.encodeKeys<typeof CloudflareLlmProviderKey, {
192
+ readonly apiKeyEnv: "api_key_env";
193
+ }>>, never>;
194
+ }>, {}>;
195
+ /**
196
+ * A Worker that runs each Attempt in its own Cloudflare sandbox, through the Worker that the
197
+ * operator deploys from `@usine/cloudflare`.
198
+ *
199
+ * - `workerUrl`: the deployed Worker's origin.
200
+ * - `accessClientIdEnv` and `accessClientSecretEnv`: the orchestrator environment variables with
201
+ * the Cloudflare Access service token that the Worker accepts, read when `usine up` starts.
202
+ * - `image`: the name of the image in the Worker's `containers[].images`.
203
+ * - `instanceType`: the container instance type of each sandbox.
204
+ * - `llmProviders`: the providers whose API key the Worker's outbound handlers inject. Claude Code
205
+ * needs `anthropic` and Codex needs `openai`; a sandbox holds no harness login.
206
+ */
207
+ export declare class CloudflareWorker extends CloudflareWorker_base {
208
+ }
209
+ /** A configured Worker; `kind` selects the adapter. */
210
+ export declare const Worker: Schema.Union<readonly [typeof LocalWorker, typeof ExeDevWorker, typeof SshWorker, typeof CloudflareWorker]>;
211
+ export type Worker = typeof Worker.Type;
26
212
  declare const Settings_base: Schema.Class<Settings, Schema.Struct<{
27
- /** Seconds between routine GitHub polling cycles; defaults to 60. */
213
+ /** The interval between GitHub polling cycles, in seconds. */
28
214
  readonly pollInterval: Schema.withDecodingDefaultKey<Schema.Int, never>;
29
- /** Total child sessions allowed over one Attempt's lifetime, including sequential spawns; defaults to four. */
215
+ /** The maximum number of child sessions per Attempt, counting sequential spawns. */
30
216
  readonly maxChildren: Schema.withDecodingDefaultKey<Schema.brand<Schema.Int, "ChildSessionBudget">, never>;
31
- /** Configured Attempt duration ceiling in minutes; defaults to 60. */
32
- readonly maxAttemptMinutes: Schema.withDecodingDefaultKey<Schema.Int, never>;
33
- /** Configured total-token ceiling per Attempt; defaults to 10,000,000. */
34
- readonly maxAttemptTokens: Schema.withDecodingDefaultKey<Schema.Int, never>;
35
- /** Parent model used when the Agent has no override; an absent default leaves selection to Pi. */
217
+ /** The wall-clock limit per Attempt, in minutes, or `None` for no limit. */
218
+ readonly maxAttemptMinutes: Schema.OptionFromOptionalKey<Schema.Int>;
219
+ /** The token limit per Attempt, counting the parent and every child, or `None` for no limit. */
220
+ readonly maxAttemptTokens: Schema.OptionFromOptionalKey<Schema.Int>;
221
+ /** The parent model for Agents that set none, or `None` to let Pi select it. */
36
222
  readonly parentModel: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "ModelId">>;
37
- /** Default parent reasoning effort; if neither Agent nor factory supplies one, the child's effort applies. */
223
+ /** The parent reasoning effort for Agents that set none, or `None` to use the child's effort. */
38
224
  readonly parentEffort: Schema.OptionFromOptionalKey<Schema.Literals<readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"]>>;
39
225
  }>, {}>;
40
- /** Factory-wide polling, Attempt limits, and defaults for the coordinating parent. */
41
226
  export declare class Settings extends Settings_base {
42
227
  }
43
- /** How GitHub hints reach the factory to request earlier polling; routine polling remains the backstop. */
228
+ /** The source of GitHub webhook events that trigger an early poll; polling continues in every mode. */
44
229
  export declare const Webhooks: Schema.Union<readonly [Schema.Struct<{
45
230
  readonly mode: Schema.Literal<"off">;
46
231
  }>, Schema.Struct<{
@@ -52,6 +237,18 @@ export declare const Webhooks: Schema.Union<readonly [Schema.Struct<{
52
237
  readonly publicUrl: "public_url";
53
238
  }>]>;
54
239
  export type Webhooks = typeof Webhooks.Type;
240
+ declare const Tracing_base: Schema.Class<Tracing, Schema.Struct<{
241
+ /**
242
+ * The collector's OTLP/HTTP traces endpoint, used as given, such as
243
+ * `http://localhost:4318/v1/traces`. It has no credentials or query string.
244
+ */
245
+ readonly otlpUrl: Schema.URLFromString;
246
+ /** The `service.name` resource attribute of every exported span. */
247
+ readonly serviceName: Schema.withDecodingDefaultKey<Schema.String, never>;
248
+ }>, {}>;
249
+ /** Span export over OTLP/HTTP (ADR 0028). */
250
+ export declare class Tracing extends Tracing_base {
251
+ }
55
252
  declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
56
253
  readonly version: Schema.Literal<1>;
57
254
  readonly labels: Schema.withDecodingDefaultKey<Schema.$Array<typeof DeclaredLabel>, never>;
@@ -64,9 +261,44 @@ declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
64
261
  readonly parentModel: "parent_model";
65
262
  readonly parentEffort: "parent_effort";
66
263
  }>, never>;
67
- readonly workers: Schema.withDecodingDefaultKey<Schema.$Array<Schema.encodeKeys<typeof Worker, {
264
+ readonly workers: Schema.withDecodingDefaultKey<Schema.$Array<Schema.Union<readonly [Schema.encodeKeys<typeof LocalWorker, {
68
265
  readonly maxConcurrentAttempts: "max_concurrent_attempts";
69
- }>>, never>;
266
+ }>, Schema.encodeKeys<typeof ExeDevWorker, {
267
+ readonly maxConcurrentAttempts: "max_concurrent_attempts";
268
+ }>, Schema.decodeTo<typeof SshWorker, Schema.Struct<{
269
+ readonly container: Schema.toEncoded<Schema.withDecodingDefaultKey<Schema.encodeKeys<typeof WorkerContainer, {
270
+ readonly memoryMib: "memory_mib";
271
+ }>, never>>;
272
+ readonly destination: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshDestination">>>;
273
+ readonly gateway: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.encodeKeys<typeof WorkerGateway, {
274
+ readonly adminPort: "admin_port";
275
+ readonly adminTokenEnv: "admin_token_env";
276
+ readonly llmProviders: "llm_providers";
277
+ }>>>;
278
+ readonly identity_file: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "SshIdentityFile">>>;
279
+ readonly kind: Schema.toEncoded<Schema.Literal<"ssh">>;
280
+ readonly max_concurrent_attempts: Schema.toEncoded<Schema.withDecodingDefaultKey<Schema.Int, never>>;
281
+ readonly name: Schema.toEncoded<Schema.brand<Schema.String, "WorkerName">>;
282
+ readonly port: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.brand<Schema.Int, "SshPort">>>;
283
+ readonly provisioner: Schema.toEncoded<Schema.OptionFromOptionalKey<Schema.Union<readonly [Schema.encodeKeys<typeof HetznerProvisioner, {
284
+ readonly tokenEnv: "token_env";
285
+ readonly serverType: "server_type";
286
+ readonly sshKey: "ssh_key";
287
+ readonly sshUser: "ssh_user";
288
+ readonly apiKeys: "api_keys";
289
+ }>, Schema.encodeKeys<typeof BoatProvisioner, {
290
+ readonly tokenEnv: "token_env";
291
+ readonly apiKeys: "api_keys";
292
+ }>]>>>;
293
+ readonly root: Schema.toEncoded<Schema.brand<Schema.String, "WorkerRoot">>;
294
+ }>, never, never>, Schema.encodeKeys<typeof CloudflareWorker, {
295
+ readonly maxConcurrentAttempts: "max_concurrent_attempts";
296
+ readonly workerUrl: "worker_url";
297
+ readonly accessClientIdEnv: "access_client_id_env";
298
+ readonly accessClientSecretEnv: "access_client_secret_env";
299
+ readonly instanceType: "instance_type";
300
+ readonly llmProviders: "llm_providers";
301
+ }>]>>, never>;
70
302
  readonly webhooks: Schema.withDecodingDefaultKey<Schema.Union<readonly [Schema.Struct<{
71
303
  readonly mode: Schema.Literal<"off">;
72
304
  }>, Schema.Struct<{
@@ -78,8 +310,12 @@ declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
78
310
  readonly publicUrl: "public_url";
79
311
  }>]>, never>;
80
312
  readonly operator: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "OperatorLogin">>;
313
+ readonly tracing: Schema.OptionFromOptionalKey<Schema.encodeKeys<typeof Tracing, {
314
+ readonly otlpUrl: "otlp_url";
315
+ readonly serviceName: "service_name";
316
+ }>>;
81
317
  }>, {}>;
82
- /** The factory's repository registry, Worker capacity, labels, and operating defaults from `usine.yaml`. */
318
+ /** The decoded `usine.yaml`. */
83
319
  export declare class UsineConfig extends UsineConfig_base {
84
320
  }
85
321
  export {};