@usine/config 0.0.1 → 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 (78) hide show
  1. package/README.md +50 -2
  2. package/dist/agent.d.ts +23 -0
  3. package/dist/agent.d.ts.map +1 -0
  4. package/dist/agent.js +22 -0
  5. package/dist/agent.js.map +1 -0
  6. package/dist/board.d.ts +31 -0
  7. package/dist/board.d.ts.map +1 -0
  8. package/dist/board.js +32 -0
  9. package/dist/board.js.map +1 -0
  10. package/dist/checks.d.ts +3 -0
  11. package/dist/checks.d.ts.map +1 -0
  12. package/dist/checks.js +3 -0
  13. package/dist/checks.js.map +1 -0
  14. package/dist/factory.d.ts +86 -0
  15. package/dist/factory.d.ts.map +1 -0
  16. package/dist/factory.js +87 -0
  17. package/dist/factory.js.map +1 -0
  18. package/dist/file.d.ts +27 -0
  19. package/dist/file.d.ts.map +1 -0
  20. package/dist/file.js +29 -0
  21. package/dist/file.js.map +1 -0
  22. package/dist/frontmatter.d.ts +10 -0
  23. package/dist/frontmatter.d.ts.map +1 -0
  24. package/dist/frontmatter.js +51 -0
  25. package/dist/frontmatter.js.map +1 -0
  26. package/dist/instance/diagnostics.d.ts +19 -0
  27. package/dist/instance/diagnostics.d.ts.map +1 -0
  28. package/dist/instance/diagnostics.js +22 -0
  29. package/dist/instance/diagnostics.js.map +1 -0
  30. package/dist/instance/instance.d.ts +17 -0
  31. package/dist/instance/instance.d.ts.map +1 -0
  32. package/dist/instance/instance.js +21 -0
  33. package/dist/instance/instance.js.map +1 -0
  34. package/dist/instance/references.d.ts +21 -0
  35. package/dist/instance/references.d.ts.map +1 -0
  36. package/dist/instance/references.js +38 -0
  37. package/dist/instance/references.js.map +1 -0
  38. package/dist/instance-folder.d.ts +14 -0
  39. package/dist/instance-folder.d.ts.map +1 -0
  40. package/dist/instance-folder.js +101 -0
  41. package/dist/instance-folder.js.map +1 -0
  42. package/dist/label.d.ts +22 -0
  43. package/dist/label.d.ts.map +1 -0
  44. package/dist/label.js +25 -0
  45. package/dist/label.js.map +1 -0
  46. package/dist/loop.d.ts +42 -0
  47. package/dist/loop.d.ts.map +1 -0
  48. package/dist/loop.js +36 -0
  49. package/dist/loop.js.map +1 -0
  50. package/dist/parser.d.ts +25 -0
  51. package/dist/parser.d.ts.map +1 -0
  52. package/dist/parser.js +204 -0
  53. package/dist/parser.js.map +1 -0
  54. package/dist/payload-slices.d.ts +17 -0
  55. package/dist/payload-slices.d.ts.map +1 -0
  56. package/dist/payload-slices.js +218 -0
  57. package/dist/payload-slices.js.map +1 -0
  58. package/dist/selector.d.ts +27 -0
  59. package/dist/selector.d.ts.map +1 -0
  60. package/dist/selector.js +29 -0
  61. package/dist/selector.js.map +1 -0
  62. package/dist/trigger.d.ts +37 -0
  63. package/dist/trigger.d.ts.map +1 -0
  64. package/dist/trigger.js +34 -0
  65. package/dist/trigger.js.map +1 -0
  66. package/dist/yaml/document.d.ts +9 -0
  67. package/dist/yaml/document.d.ts.map +1 -0
  68. package/dist/yaml/document.js +38 -0
  69. package/dist/yaml/document.js.map +1 -0
  70. package/dist/yaml/writer.d.ts +16 -0
  71. package/dist/yaml/writer.d.ts.map +1 -0
  72. package/dist/yaml/writer.js +33 -0
  73. package/dist/yaml/writer.js.map +1 -0
  74. package/package.json +64 -5
  75. package/dist/index.d.ts +0 -10
  76. package/dist/index.d.ts.map +0 -1
  77. package/dist/index.js +0 -10
  78. package/dist/index.js.map +0 -1
package/README.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # @usine/config
2
2
 
3
- Config file machinery for [usine](https://github.com/basaltbytes/usine), an agent-agnostic software factory: parse, validate, and surgically rewrite the instance repo's files — `usine.yaml` (version, registry, settings), loop files (`loops/*.md`), and agent files (`agents/*.md`). Markdown-with-frontmatter parsing, strict schema validation, and a comment-preserving YAML-AST writer so UI edits never clobber hand-authored formatting.
3
+ Reads and edits the authored files in a [usine](https://github.com/basaltbytes/usine) instance folder:
4
4
 
5
- Part of usine. This block is not implemented yet — its 0.0.x releases reserve the seam while the engine grows. Everything here is 0.x: APIs change without notice.
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.
9
+
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.
11
+
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 `#`:
13
+
14
+ ```yaml
15
+ labels:
16
+ - name: ready-for-agent
17
+ color: a2eeef
18
+ description: Ready for an agent to claim
19
+ - name: ready-for-review
20
+ ```
21
+
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.
25
+
26
+ Each managed repository can define an exclusive Board lane map. A lane accepts one or more GitHub label or Item-state sources:
27
+
28
+ ```yaml
29
+ repos:
30
+ - name: acme/widget
31
+ lanes:
32
+ - name: Ready
33
+ sources:
34
+ - label: ready-for-agent
35
+ - name: In review
36
+ sources:
37
+ - label: ready-for-review
38
+ - state: pr-open
39
+ ```
40
+
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.
42
+
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.
44
+
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.
46
+
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.
48
+
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`.
50
+
51
+ All APIs remain 0.x and can change between minor releases.
52
+
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.
@@ -0,0 +1,23 @@
1
+ import { Schema } from "effect";
2
+ import { ConfigFileError } from "./file.ts";
3
+ declare const AgentFile_base: Schema.Class<AgentFile, Schema.Struct<{
4
+ readonly name: Schema.brand<Schema.String, "AgentName">;
5
+ readonly harness: Schema.Literals<readonly ["claude", "codex", "pi"]>;
6
+ readonly model: Schema.brand<Schema.String, "ModelId">;
7
+ readonly effort: Schema.Literals<readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"]>;
8
+ readonly parentModel: Schema.Option<Schema.brand<Schema.String, "ModelId">>;
9
+ readonly parentEffort: Schema.Option<Schema.Literals<readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"]>>;
10
+ readonly persona: Schema.brand<Schema.String, "AgentPersona">;
11
+ }>, {}>;
12
+ /** An Agent's authored brain, parent overrides, and standing instructions, named by its Markdown filename. */
13
+ export declare class AgentFile extends AgentFile_base {
14
+ }
15
+ declare const InvalidAgent_base: Schema.Class<InvalidAgent, Schema.Struct<{
16
+ readonly file: Schema.brand<Schema.NonEmptyString, "InstancePath">;
17
+ readonly error: typeof ConfigFileError;
18
+ }>, {}>;
19
+ /** An Agent file excluded from the roster because it could not be loaded. */
20
+ export declare class InvalidAgent extends InvalidAgent_base {
21
+ }
22
+ export {};
23
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAgB,eAAe,EAAE,MAAM,WAAW,CAAC;;;;;;;;;;AAE1D,8GAA8G;AAC9G,qBAAa,SAAU,SAAQ,cAQ7B;CAAG;;;;;AAEL,6EAA6E;AAC7E,qBAAa,YAAa,SAAQ,iBAGhC;CAAG"}
package/dist/agent.js ADDED
@@ -0,0 +1,22 @@
1
+ import { AgentPersona, AgentName } from "@usine/core/agent";
2
+ import { Effort, Harness, ModelId } from "@usine/core/agent/brain";
3
+ import { Schema } from "effect";
4
+ import { InstancePath, ConfigFileError } from "./file.js";
5
+ /** An Agent's authored brain, parent overrides, and standing instructions, named by its Markdown filename. */
6
+ export class AgentFile extends Schema.Class("@usine/config/AgentFile")({
7
+ name: AgentName,
8
+ harness: Harness,
9
+ model: ModelId,
10
+ effort: Effort,
11
+ parentModel: Schema.Option(ModelId),
12
+ parentEffort: Schema.Option(Effort),
13
+ persona: AgentPersona,
14
+ }) {
15
+ }
16
+ /** An Agent file excluded from the roster because it could not be loaded. */
17
+ export class InvalidAgent extends Schema.Class("@usine/config/InvalidAgent")({
18
+ file: InstancePath,
19
+ error: ConfigFileError,
20
+ }) {
21
+ }
22
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AACnE,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;CAAG;AAEL,6EAA6E;AAC7E,MAAM,OAAO,YAAa,SAAQ,MAAM,CAAC,KAAK,CAAe,4BAA4B,CAAC,CAAC;IACzF,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,eAAe;CACvB,CAAC;CAAG"}
@@ -0,0 +1,31 @@
1
+ import { Schema } from "effect";
2
+ /** The operator-visible name of one lane on a Project's Board. */
3
+ export declare const LaneName: Schema.brand<Schema.String, "LaneName">;
4
+ export type LaneName = typeof LaneName.Type;
5
+ /** An issue or pull-request state that can place an Item in a Board lane. */
6
+ export declare const LaneItemState: Schema.Literals<readonly ["issue-open", "issue-closed", "pr-open", "pr-closed", "pr-merged"]>;
7
+ export type LaneItemState = typeof LaneItemState.Type;
8
+ declare const LabelLaneSource_base: Schema.Class<LabelLaneSource, Schema.Struct<{
9
+ readonly label: Schema.brand<Schema.String, "GitHubLabelName">;
10
+ }>, {}>;
11
+ /** Places Items with this GitHub label in the lane; Board moves can write the label. */
12
+ export declare class LabelLaneSource extends LabelLaneSource_base {
13
+ }
14
+ declare const StateLaneSource_base: Schema.Class<StateLaneSource, Schema.Struct<{
15
+ readonly state: Schema.Literals<readonly ["issue-open", "issue-closed", "pr-open", "pr-closed", "pr-merged"]>;
16
+ }>, {}>;
17
+ /** Places Items with this GitHub state in the lane; Board moves cannot change the state. */
18
+ export declare class StateLaneSource extends StateLaneSource_base {
19
+ }
20
+ /** A GitHub label or Item state that routes matching Items to a Board lane. */
21
+ export declare const LaneSource: Schema.Union<readonly [typeof LabelLaneSource, typeof StateLaneSource]>;
22
+ export type LaneSource = typeof LaneSource.Type;
23
+ declare const Lane_base: Schema.Class<Lane, Schema.Struct<{
24
+ readonly name: Schema.brand<Schema.String, "LaneName">;
25
+ readonly sources: Schema.$Array<Schema.Union<readonly [typeof LabelLaneSource, typeof StateLaneSource]>>;
26
+ }>, {}>;
27
+ /** A named Board column containing Items that match any of its configured sources. */
28
+ export declare class Lane extends Lane_base {
29
+ }
30
+ export {};
31
+ //# sourceMappingURL=board.d.ts.map
@@ -0,0 +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"}
package/dist/board.js ADDED
@@ -0,0 +1,32 @@
1
+ import { Schema } from "effect";
2
+ import { nonBlankString } from "./checks.js";
3
+ import { GitHubLabelName } from "./label.js";
4
+ /** The operator-visible name of one lane on a Project's Board. */
5
+ 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
+ export const LaneItemState = Schema.Literals([
8
+ "issue-open",
9
+ "issue-closed",
10
+ "pr-open",
11
+ "pr-closed",
12
+ "pr-merged",
13
+ ]);
14
+ /** Places Items with this GitHub label in the lane; Board moves can write the label. */
15
+ export class LabelLaneSource extends Schema.Class("@usine/config/LabelLaneSource")({
16
+ label: GitHubLabelName,
17
+ }) {
18
+ }
19
+ /** Places Items with this GitHub state in the lane; Board moves cannot change the state. */
20
+ export class StateLaneSource extends Schema.Class("@usine/config/StateLaneSource")({
21
+ state: LaneItemState,
22
+ }) {
23
+ }
24
+ /** A GitHub label or Item state that routes matching Items to a Board lane. */
25
+ export const LaneSource = Schema.Union([LabelLaneSource, StateLaneSource]);
26
+ /** A named Board column containing Items that match any of its configured sources. */
27
+ export class Lane extends Schema.Class("@usine/config/Lane")({
28
+ name: LaneName,
29
+ sources: Schema.Array(LaneSource).check(Schema.isNonEmpty()),
30
+ }) {
31
+ }
32
+ //# sourceMappingURL=board.js.map
@@ -0,0 +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"}
@@ -0,0 +1,3 @@
1
+ import { Schema } from "effect";
2
+ export declare const nonBlankString: (message: string) => Schema.String;
3
+ //# sourceMappingURL=checks.d.ts.map
@@ -0,0 +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"}
package/dist/checks.js ADDED
@@ -0,0 +1,3 @@
1
+ import { Schema } from "effect";
2
+ export const nonBlankString = (message) => Schema.String.check(Schema.isPattern(/\S/u, { message }));
3
+ //# sourceMappingURL=checks.js.map
@@ -0,0 +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"}
@@ -0,0 +1,86 @@
1
+ import { Schema } from "effect";
2
+ import { Lane } from "./board.ts";
3
+ import { DeclaredLabel } from "./label.ts";
4
+ /** A factory-defined repository grouping that Loops can select by tag. */
5
+ export declare const RegistryTag: Schema.brand<Schema.String, "RegistryTag">;
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
+ declare const ManagedRepo_base: Schema.Class<ManagedRepo, Schema.Struct<{
11
+ readonly name: Schema.brand<Schema.String, "RepositoryName">;
12
+ readonly tags: Schema.withDecodingDefaultKey<Schema.$Array<Schema.brand<Schema.String, "RegistryTag">>, never>;
13
+ readonly lanes: Schema.withDecodingDefaultKey<Schema.$Array<typeof Lane>, never>;
14
+ }>, {}>;
15
+ /** A repository the factory manages, with its selector tags and configured Board lanes. */
16
+ export declare class ManagedRepo extends ManagedRepo_base {
17
+ }
18
+ declare const Worker_base: Schema.Class<Worker, Schema.Struct<{
19
+ readonly name: Schema.brand<Schema.String, "WorkerName">;
20
+ readonly kind: Schema.Literals<readonly ["local", "exe.dev"]>;
21
+ readonly maxConcurrentAttempts: Schema.withDecodingDefaultKey<Schema.Int, never>;
22
+ }>, {}>;
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 {
25
+ }
26
+ declare const Settings_base: Schema.Class<Settings, Schema.Struct<{
27
+ /** Seconds between routine GitHub polling cycles; defaults to 60. */
28
+ readonly pollInterval: Schema.withDecodingDefaultKey<Schema.Int, never>;
29
+ /** Total child sessions allowed over one Attempt's lifetime, including sequential spawns; defaults to four. */
30
+ 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. */
36
+ 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. */
38
+ readonly parentEffort: Schema.OptionFromOptionalKey<Schema.Literals<readonly ["off", "minimal", "low", "medium", "high", "xhigh", "max"]>>;
39
+ }>, {}>;
40
+ /** Factory-wide polling, Attempt limits, and defaults for the coordinating parent. */
41
+ export declare class Settings extends Settings_base {
42
+ }
43
+ /** How GitHub hints reach the factory to request earlier polling; routine polling remains the backstop. */
44
+ export declare const Webhooks: Schema.Union<readonly [Schema.Struct<{
45
+ readonly mode: Schema.Literal<"off">;
46
+ }>, Schema.Struct<{
47
+ readonly mode: Schema.Literal<"deliveries">;
48
+ }>, Schema.encodeKeys<Schema.Struct<{
49
+ readonly mode: Schema.Literal<"endpoint">;
50
+ readonly publicUrl: Schema.URLFromString;
51
+ }>, {
52
+ readonly publicUrl: "public_url";
53
+ }>]>;
54
+ export type Webhooks = typeof Webhooks.Type;
55
+ declare const UsineConfig_base: Schema.Class<UsineConfig, Schema.Struct<{
56
+ readonly version: Schema.Literal<1>;
57
+ readonly labels: Schema.withDecodingDefaultKey<Schema.$Array<typeof DeclaredLabel>, never>;
58
+ readonly repos: Schema.$Array<typeof ManagedRepo>;
59
+ readonly settings: Schema.withDecodingDefaultKey<Schema.encodeKeys<typeof Settings, {
60
+ readonly pollInterval: "poll_interval";
61
+ readonly maxChildren: "max_children";
62
+ readonly maxAttemptMinutes: "max_attempt_minutes";
63
+ readonly maxAttemptTokens: "max_attempt_tokens";
64
+ readonly parentModel: "parent_model";
65
+ readonly parentEffort: "parent_effort";
66
+ }>, never>;
67
+ readonly workers: Schema.withDecodingDefaultKey<Schema.$Array<Schema.encodeKeys<typeof Worker, {
68
+ readonly maxConcurrentAttempts: "max_concurrent_attempts";
69
+ }>>, never>;
70
+ readonly webhooks: Schema.withDecodingDefaultKey<Schema.Union<readonly [Schema.Struct<{
71
+ readonly mode: Schema.Literal<"off">;
72
+ }>, Schema.Struct<{
73
+ readonly mode: Schema.Literal<"deliveries">;
74
+ }>, Schema.encodeKeys<Schema.Struct<{
75
+ readonly mode: Schema.Literal<"endpoint">;
76
+ readonly publicUrl: Schema.URLFromString;
77
+ }>, {
78
+ readonly publicUrl: "public_url";
79
+ }>]>, never>;
80
+ readonly operator: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "OperatorLogin">>;
81
+ }>, {}>;
82
+ /** The factory's repository registry, Worker capacity, labels, and operating defaults from `usine.yaml`. */
83
+ export declare class UsineConfig extends UsineConfig_base {
84
+ }
85
+ export {};
86
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"AAIA,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AAExC,OAAO,EAAc,IAAI,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAsB,aAAa,EAAE,MAAM,YAAY,CAAC;AAE/D,0EAA0E;AAC1E,eAAO,MAAM,WAAW,4CAEvB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC;AAElD,oEAAoE;AACpE,eAAO,MAAM,aAAa,8CAIW,CAAC;AAEtC,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC;;;;;;AA6BtD,2FAA2F;AAC3F,qBAAa,WAAY,SAAQ,gBAM/B;CAAG;;;;;;AAEL,sFAAsF;AACtF,qBAAa,MAAO,SAAQ,WAI1B;CAAG;;IAIH,qEAAqE;;IAErE,+GAA+G;;IAE/G,sEAAsE;;IAEtE,0EAA0E;;IAE1E,kGAAkG;;IAElG,8GAA8G;;;AAZhH,sFAAsF;AACtF,qBAAa,QAAS,SAAQ,aAa5B;CAAG;AAEL,2GAA2G;AAC3G,eAAO,MAAM,QAAQ;;;;;;;;;IAMnB,CAAC;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuB5C,4GAA4G;AAC5G,qBAAa,WAAY,SAAQ,gBAU/B;CAAG"}
@@ -0,0 +1,87 @@
1
+ import { Effort, ModelId } from "@usine/core/agent/brain";
2
+ import { ChildSessionBudget } from "@usine/core/agent/session";
3
+ import { RepositoryName } from "@usine/core/repository";
4
+ import { WorkerName, WorkerKind } from "@usine/core/worker";
5
+ import { Effect, Schema } from "effect";
6
+ import { nonBlankString } from "./checks.js";
7
+ import { LaneSource, Lane } from "./board.js";
8
+ import { canonicalLabelName, DeclaredLabel } from "./label.js";
9
+ /** A factory-defined repository grouping that Loops can select by tag. */
10
+ export const RegistryTag = nonBlankString("Expected a non-blank registry tag").pipe(Schema.brand("RegistryTag"));
11
+ /** GitHub login identifying the human operator for this factory. */
12
+ export const OperatorLogin = Schema.String.check(Schema.isPattern(/^[A-Za-z0-9](?:[A-Za-z0-9-]{0,37}[A-Za-z0-9])?$/u, {
13
+ message: "Expected a GitHub login",
14
+ })).pipe(Schema.brand("OperatorLogin"));
15
+ const PositiveInt = Schema.Int.check(Schema.isGreaterThanOrEqualTo(1));
16
+ const uniqueNames = Schema.makeFilter((values) => new Set(values.map(({ name }) => name)).size === values.length, { message: "Expected unique names" });
17
+ const laneSourceKey = (source) => "label" in source ? `label:${source.label}` : `state:${source.state}`;
18
+ const uniqueLaneSources = Schema.makeFilter((lanes) => {
19
+ const keys = lanes.flatMap(({ sources }) => sources.map(laneSourceKey));
20
+ return new Set(keys).size === keys.length;
21
+ }, { message: "Expected every lane source to be mapped once" });
22
+ const Lanes = Schema.Array(Lane).check(uniqueNames, uniqueLaneSources);
23
+ const uniqueLabelNames = Schema.makeFilter((values) => new Set(values.map(({ name }) => canonicalLabelName(name))).size === values.length, { message: "Expected unique GitHub label names" });
24
+ const DeclaredLabels = Schema.Array(DeclaredLabel).check(uniqueLabelNames);
25
+ /** A repository the factory manages, with its selector tags and configured Board lanes. */
26
+ export class ManagedRepo extends Schema.Class("@usine/config/ManagedRepo")({
27
+ name: RepositoryName,
28
+ tags: Schema.Array(RegistryTag)
29
+ .check(Schema.isUnique())
30
+ .pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
31
+ lanes: Lanes.pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
32
+ }) {
33
+ }
34
+ /** A named place to execute Attempts, with the number it may run at the same time. */
35
+ export class Worker extends Schema.Class("@usine/config/Worker")({
36
+ name: WorkerName,
37
+ kind: WorkerKind,
38
+ maxConcurrentAttempts: PositiveInt.pipe(Schema.withDecodingDefaultKey(Effect.succeed(1))),
39
+ }) {
40
+ }
41
+ /** Factory-wide polling, Attempt limits, and defaults for the coordinating parent. */
42
+ export class Settings extends Schema.Class("@usine/config/Settings")({
43
+ /** Seconds between routine GitHub polling cycles; defaults to 60. */
44
+ pollInterval: PositiveInt.pipe(Schema.withDecodingDefaultKey(Effect.succeed(60))),
45
+ /** Total child sessions allowed over one Attempt's lifetime, including sequential spawns; defaults to four. */
46
+ maxChildren: ChildSessionBudget.pipe(Schema.withDecodingDefaultKey(Effect.succeed(4))),
47
+ /** Configured Attempt duration ceiling in minutes; defaults to 60. */
48
+ maxAttemptMinutes: PositiveInt.pipe(Schema.withDecodingDefaultKey(Effect.succeed(60))),
49
+ /** Configured total-token ceiling per Attempt; defaults to 10,000,000. */
50
+ maxAttemptTokens: PositiveInt.pipe(Schema.withDecodingDefaultKey(Effect.succeed(10_000_000))),
51
+ /** Parent model used when the Agent has no override; an absent default leaves selection to Pi. */
52
+ parentModel: Schema.OptionFromOptionalKey(ModelId),
53
+ /** Default parent reasoning effort; if neither Agent nor factory supplies one, the child's effort applies. */
54
+ parentEffort: Schema.OptionFromOptionalKey(Effort),
55
+ }) {
56
+ }
57
+ /** How GitHub hints reach the factory to request earlier polling; routine polling remains the backstop. */
58
+ export const Webhooks = Schema.Union([
59
+ Schema.Struct({ mode: Schema.Literal("off") }),
60
+ Schema.Struct({ mode: Schema.Literal("deliveries") }),
61
+ Schema.Struct({ mode: Schema.Literal("endpoint"), publicUrl: Schema.URLFromString }).pipe(Schema.encodeKeys({ publicUrl: "public_url" })),
62
+ ]);
63
+ // Authored YAML keys are snake_case and domain fields camelCase. The rename
64
+ // happens once here and encodes back for edits.
65
+ const SettingsFromYaml = Settings.pipe(Schema.encodeKeys({
66
+ pollInterval: "poll_interval",
67
+ maxChildren: "max_children",
68
+ maxAttemptMinutes: "max_attempt_minutes",
69
+ maxAttemptTokens: "max_attempt_tokens",
70
+ parentModel: "parent_model",
71
+ parentEffort: "parent_effort",
72
+ }));
73
+ const WorkerFromYaml = Worker.pipe(Schema.encodeKeys({ maxConcurrentAttempts: "max_concurrent_attempts" }));
74
+ const ManagedRepos = Schema.Array(ManagedRepo).check(uniqueNames);
75
+ const Workers = Schema.Array(WorkerFromYaml).check(Schema.isNonEmpty(), uniqueNames);
76
+ /** The factory's repository registry, Worker capacity, labels, and operating defaults from `usine.yaml`. */
77
+ export class UsineConfig extends Schema.Class("@usine/config/UsineConfig")({
78
+ version: Schema.Literal(1),
79
+ labels: DeclaredLabels.pipe(Schema.withDecodingDefaultKey(Effect.succeed([]))),
80
+ repos: ManagedRepos,
81
+ settings: SettingsFromYaml.pipe(Schema.withDecodingDefaultKey(Effect.succeed({}))),
82
+ workers: Workers.pipe(Schema.withDecodingDefaultKey(Effect.succeed([{ name: "local", kind: "local" }]))),
83
+ webhooks: Webhooks.pipe(Schema.withDecodingDefaultKey(Effect.succeed({ mode: "off" }))),
84
+ operator: Schema.OptionFromOptionalKey(OperatorLogin),
85
+ }) {
86
+ }
87
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../src/factory.ts"],"names":[],"mappings":"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"}
package/dist/file.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ import { Schema } from "effect";
2
+ /** Path of one authored file, relative to the instance folder. */
3
+ export declare const InstancePath: Schema.brand<Schema.NonEmptyString, "InstancePath">;
4
+ export type InstancePath = typeof InstancePath.Type;
5
+ export declare const FileStage: Schema.Literals<readonly ["expression", "frontmatter", "read", "reference", "schema", "yaml"]>;
6
+ export type FileStage = typeof FileStage.Type;
7
+ declare const ConfigFileError_base: Schema.Class<ConfigFileError, Schema.TaggedStruct<"ConfigFileError", {
8
+ readonly file: Schema.brand<Schema.NonEmptyString, "InstancePath">;
9
+ readonly stage: Schema.Literals<readonly ["expression", "frontmatter", "read", "reference", "schema", "yaml"]>;
10
+ readonly expression: Schema.OptionFromOptionalKey<Schema.brand<Schema.String, "ExpressionSource">>;
11
+ readonly message: Schema.NonEmptyString;
12
+ }>, import("effect/Cause").YieldableError>;
13
+ /** A failure pinned to one authored file and one parse stage, so the UI can quarantine that file alone. */
14
+ export declare class ConfigFileError extends ConfigFileError_base {
15
+ }
16
+ declare const FactoryConfigError_base: Schema.Class<FactoryConfigError, Schema.TaggedStruct<"FactoryConfigError", {
17
+ readonly file: Schema.brand<Schema.NonEmptyString, "InstancePath">;
18
+ readonly stage: Schema.Literals<readonly ["expression", "frontmatter", "read", "reference", "schema", "yaml"]>;
19
+ readonly message: Schema.NonEmptyString;
20
+ }>, import("effect/Cause").YieldableError>;
21
+ /** The registry or settings could not be loaded, which blocks the whole instance. */
22
+ export declare class FactoryConfigError extends FactoryConfigError_base {
23
+ }
24
+ export declare const ConfigError: Schema.Union<readonly [typeof ConfigFileError, typeof FactoryConfigError]>;
25
+ export type ConfigError = typeof ConfigError.Type;
26
+ export {};
27
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,kEAAkE;AAClE,eAAO,MAAM,YAAY,qDAA2D,CAAC;AAErF,MAAM,MAAM,YAAY,GAAG,OAAO,YAAY,CAAC,IAAI,CAAC;AAEpD,eAAO,MAAM,SAAS,gGAOpB,CAAC;AAEH,MAAM,MAAM,SAAS,GAAG,OAAO,SAAS,CAAC,IAAI,CAAC;;;;;;;AAE9C,2GAA2G;AAC3G,qBAAa,eAAgB,SAAQ,oBAOnC;CAAG;;;;;;AAEL,qFAAqF;AACrF,qBAAa,kBAAmB,SAAQ,uBAMtC;CAAG;AAEL,eAAO,MAAM,WAAW,4EAAsD,CAAC;AAE/E,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC,IAAI,CAAC"}
package/dist/file.js ADDED
@@ -0,0 +1,29 @@
1
+ import { Source } from "@usine/expression/expression-engine";
2
+ import { Schema } from "effect";
3
+ /** Path of one authored file, relative to the instance folder. */
4
+ export const InstancePath = Schema.NonEmptyString.pipe(Schema.brand("InstancePath"));
5
+ export const FileStage = Schema.Literals([
6
+ "expression",
7
+ "frontmatter",
8
+ "read",
9
+ "reference",
10
+ "schema",
11
+ "yaml",
12
+ ]);
13
+ /** A failure pinned to one authored file and one parse stage, so the UI can quarantine that file alone. */
14
+ export class ConfigFileError extends Schema.TaggedError("@usine/config/ConfigFileError")("ConfigFileError", {
15
+ file: InstancePath,
16
+ stage: FileStage,
17
+ expression: Schema.OptionFromOptionalKey(Source),
18
+ message: Schema.NonEmptyString,
19
+ }) {
20
+ }
21
+ /** The registry or settings could not be loaded, which blocks the whole instance. */
22
+ export class FactoryConfigError extends Schema.TaggedError("@usine/config/FactoryConfigError")("FactoryConfigError", {
23
+ file: InstancePath,
24
+ stage: FileStage,
25
+ message: Schema.NonEmptyString,
26
+ }) {
27
+ }
28
+ export const ConfigError = Schema.Union([ConfigFileError, FactoryConfigError]);
29
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../src/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,qCAAqC,CAAC;AAC7D,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,kEAAkE;AAClE,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC;AAIrF,MAAM,CAAC,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;IACvC,YAAY;IACZ,aAAa;IACb,MAAM;IACN,WAAW;IACX,QAAQ;IACR,MAAM;CACP,CAAC,CAAC;AAIH,2GAA2G;AAC3G,MAAM,OAAO,eAAgB,SAAQ,MAAM,CAAC,WAAW,CACrD,+BAA+B,CAChC,CAAC,iBAAiB,EAAE;IACnB,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,SAAS;IAChB,UAAU,EAAE,MAAM,CAAC,qBAAqB,CAAC,MAAM,CAAC;IAChD,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG;AAEL,qFAAqF;AACrF,MAAM,OAAO,kBAAmB,SAAQ,MAAM,CAAC,WAAW,CACxD,kCAAkC,CACnC,CAAC,oBAAoB,EAAE;IACtB,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,SAAS;IAChB,OAAO,EAAE,MAAM,CAAC,cAAc;CAC/B,CAAC;CAAG;AAEL,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { Effect } from "effect";
2
+ import { ConfigFileError, type InstancePath } from "./file.ts";
3
+ export interface MarkdownParts {
4
+ readonly yaml: string;
5
+ readonly body: string;
6
+ readonly newline: "\n" | "\r\n";
7
+ }
8
+ /** Splits a Markdown file into its YAML half and its body without parsing either. */
9
+ export declare const splitMarkdown: (file: InstancePath, source: string) => Effect.Effect<MarkdownParts, ConfigFileError>;
10
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAE/D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,IAAI,GAAG,MAAM,CAAC;CACjC;AAeD,qFAAqF;AACrF,eAAO,MAAM,aAAa,SAClB,YAAY,UACV,MAAM,KACb,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,eAAe,CAoC9C,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { Effect, Option } from "effect";
2
+ import { ConfigFileError } from "./file.js";
3
+ const closingDelimiterAt = (source, newline, from) => {
4
+ const delimiter = `${newline}---`;
5
+ let candidate = source.indexOf(delimiter, from);
6
+ while (candidate >= 0) {
7
+ const afterDelimiter = candidate + delimiter.length;
8
+ if (afterDelimiter === source.length || source.startsWith(newline, afterDelimiter)) {
9
+ return candidate;
10
+ }
11
+ candidate = source.indexOf(delimiter, afterDelimiter);
12
+ }
13
+ return -1;
14
+ };
15
+ /** Splits a Markdown file into its YAML half and its body without parsing either. */
16
+ export const splitMarkdown = (file, source) => {
17
+ const newline = source.startsWith("---\r\n")
18
+ ? "\r\n"
19
+ : source.startsWith("---\n")
20
+ ? "\n"
21
+ : undefined;
22
+ if (newline === undefined) {
23
+ return new ConfigFileError({
24
+ file,
25
+ stage: "frontmatter",
26
+ expression: Option.none(),
27
+ message: "Expected the file to start with a YAML frontmatter delimiter (---)",
28
+ });
29
+ }
30
+ const yamlStart = 3 + newline.length;
31
+ const closingDelimiter = `${newline}---`;
32
+ const yamlEnd = closingDelimiterAt(source, newline, yamlStart);
33
+ if (yamlEnd < 0) {
34
+ return new ConfigFileError({
35
+ file,
36
+ stage: "frontmatter",
37
+ expression: Option.none(),
38
+ message: "Expected a closing YAML frontmatter delimiter (---)",
39
+ });
40
+ }
41
+ const afterDelimiter = yamlEnd + closingDelimiter.length;
42
+ const bodyStart = source.startsWith(newline, afterDelimiter)
43
+ ? afterDelimiter + newline.length
44
+ : afterDelimiter;
45
+ return Effect.succeed({
46
+ yaml: source.slice(yamlStart, yamlEnd),
47
+ body: source.slice(bodyStart),
48
+ newline,
49
+ });
50
+ };
51
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,eAAe,EAAqB,MAAM,WAAW,CAAC;AAQ/D,MAAM,kBAAkB,GAAG,CAAC,MAAc,EAAE,OAAsB,EAAE,IAAY,EAAU,EAAE;IAC1F,MAAM,SAAS,GAAG,GAAG,OAAO,KAAK,CAAC;IAClC,IAAI,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAChD,OAAO,SAAS,IAAI,CAAC,EAAE,CAAC;QACtB,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;QACpD,IAAI,cAAc,KAAK,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC,EAAE,CAAC;YACnF,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC,CAAC;AAEF,qFAAqF;AACrF,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,IAAkB,EAClB,MAAc,EACiC,EAAE;IACjD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC;QAC1C,CAAC,CAAC,MAAM;QACR,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;YAC1B,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,SAAS,CAAC;IAChB,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,IAAI,eAAe,CAAC;YACzB,IAAI;YACJ,KAAK,EAAE,aAAa;YACpB,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE;YACzB,OAAO,EAAE,oEAAoE;SAC9E,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IACrC,MAAM,gBAAgB,GAAG,GAAG,OAAO,KAAK,CAAC;IACzC,MAAM,OAAO,GAAG,kBAAkB,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC;IAC/D,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,IAAI,eAAe,CAAC;YACzB,IAAI;YACJ,KAAK,EAAE,aAAa;YACpB,UAAU,EAAE,MAAM,CAAC,IAAI,EAAE;YACzB,OAAO,EAAE,qDAAqD;SAC/D,CAAC,CAAC;IACL,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC;IACzD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC;QAC1D,CAAC,CAAC,cAAc,GAAG,OAAO,CAAC,MAAM;QACjC,CAAC,CAAC,cAAc,CAAC;IACnB,OAAO,MAAM,CAAC,OAAO,CAAC;QACpB,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC;QACtC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC;QAC7B,OAAO;KACR,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,19 @@
1
+ import { Schema } from "effect";
2
+ declare const UndeclaredLaneLabelWarning_base: Schema.Class<UndeclaredLaneLabelWarning, Schema.TaggedStruct<"UndeclaredLaneLabelWarning", {
3
+ readonly repository: Schema.brand<Schema.String, "RepositoryName">;
4
+ readonly lane: Schema.brand<Schema.String, "LaneName">;
5
+ readonly label: Schema.brand<Schema.String, "GitHubLabelName">;
6
+ }>, {}>;
7
+ export declare class UndeclaredLaneLabelWarning extends UndeclaredLaneLabelWarning_base {
8
+ }
9
+ declare const UndeclaredTriggerLabelWarning_base: Schema.Class<UndeclaredTriggerLabelWarning, Schema.TaggedStruct<"UndeclaredTriggerLabelWarning", {
10
+ readonly loop: Schema.brand<Schema.NonEmptyString, "LoopName">;
11
+ readonly label: Schema.brand<Schema.String, "GitHubLabelName">;
12
+ }>, {}>;
13
+ export declare class UndeclaredTriggerLabelWarning extends UndeclaredTriggerLabelWarning_base {
14
+ }
15
+ /** Diagnostics that do not block a load. */
16
+ export declare const ConfigWarning: Schema.Union<readonly [typeof UndeclaredLaneLabelWarning, typeof UndeclaredTriggerLabelWarning]>;
17
+ export type ConfigWarning = typeof ConfigWarning.Type;
18
+ export {};
19
+ //# sourceMappingURL=diagnostics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../src/instance/diagnostics.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;;AAKhC,qBAAa,0BAA2B,SAAQ,+BAM9C;CAAG;;;;;AAEL,qBAAa,6BAA8B,SAAQ,kCAKjD;CAAG;AAEL,4CAA4C;AAC5C,eAAO,MAAM,aAAa,kGAGxB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,OAAO,aAAa,CAAC,IAAI,CAAC"}
@@ -0,0 +1,22 @@
1
+ import { RepositoryName } from "@usine/core/repository";
2
+ import { Schema } from "effect";
3
+ import { LaneName } from "../board.js";
4
+ import { GitHubLabelName } from "../label.js";
5
+ import { LoopFile } from "../loop.js";
6
+ export class UndeclaredLaneLabelWarning extends Schema.TaggedClass("@usine/config/UndeclaredLaneLabelWarning")("UndeclaredLaneLabelWarning", {
7
+ repository: RepositoryName,
8
+ lane: LaneName,
9
+ label: GitHubLabelName,
10
+ }) {
11
+ }
12
+ export class UndeclaredTriggerLabelWarning extends Schema.TaggedClass("@usine/config/UndeclaredTriggerLabelWarning")("UndeclaredTriggerLabelWarning", {
13
+ loop: LoopFile.fields.name,
14
+ label: GitHubLabelName,
15
+ }) {
16
+ }
17
+ /** Diagnostics that do not block a load. */
18
+ export const ConfigWarning = Schema.Union([
19
+ UndeclaredLaneLabelWarning,
20
+ UndeclaredTriggerLabelWarning,
21
+ ]);
22
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../../src/instance/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,MAAM,OAAO,0BAA2B,SAAQ,MAAM,CAAC,WAAW,CAChE,0CAA0C,CAC3C,CAAC,4BAA4B,EAAE;IAC9B,UAAU,EAAE,cAAc;IAC1B,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,eAAe;CACvB,CAAC;CAAG;AAEL,MAAM,OAAO,6BAA8B,SAAQ,MAAM,CAAC,WAAW,CACnE,6CAA6C,CAC9C,CAAC,+BAA+B,EAAE;IACjC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI;IAC1B,KAAK,EAAE,eAAe;CACvB,CAAC;CAAG;AAEL,4CAA4C;AAC5C,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC;IACxC,0BAA0B;IAC1B,6BAA6B;CAC9B,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { Schema } from "effect";
2
+ import { UsineConfig } from "../factory.ts";
3
+ import { LoopFile, QuarantinedLoop } from "../loop.ts";
4
+ import { AgentFile, InvalidAgent } from "../agent.ts";
5
+ declare const LoadedInstance_base: Schema.Class<LoadedInstance, Schema.Struct<{
6
+ readonly config: typeof UsineConfig;
7
+ readonly agents: Schema.$Array<typeof AgentFile>;
8
+ readonly invalidAgents: Schema.$Array<typeof InvalidAgent>;
9
+ readonly loops: Schema.$Array<typeof LoopFile>;
10
+ readonly quarantinedLoops: Schema.$Array<typeof QuarantinedLoop>;
11
+ readonly warnings: Schema.$Array<Schema.Union<readonly [typeof import("./diagnostics.ts").UndeclaredLaneLabelWarning, typeof import("./diagnostics.ts").UndeclaredTriggerLabelWarning]>>;
12
+ }>, {}>;
13
+ /** One consistent snapshot of an instance folder. Construction fails if a loop references a name the instance does not have. */
14
+ export declare class LoadedInstance extends LoadedInstance_base {
15
+ }
16
+ export { UndeclaredLaneLabelWarning, UndeclaredTriggerLabelWarning, ConfigWarning, } from "./diagnostics.ts";
17
+ //# sourceMappingURL=instance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"instance.d.ts","sourceRoot":"","sources":["../../src/instance/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAY,MAAM,YAAY,CAAC;AACjE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;;;;;;;;;AAItD,gIAAgI;AAChI,qBAAa,cAAe,SAAQ,mBAmBnC;CAAG;AAEJ,OAAO,EACL,0BAA0B,EAC1B,6BAA6B,EAC7B,aAAa,GACd,MAAM,kBAAkB,CAAC"}