@usine/orchestrator 0.1.0 → 0.2.1

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 (122) hide show
  1. package/README.md +46 -21
  2. package/dist/board/items.d.ts +18 -0
  3. package/dist/board/items.d.ts.map +1 -0
  4. package/dist/board/items.js +46 -0
  5. package/dist/board/items.js.map +1 -0
  6. package/dist/board/projection.d.ts +6 -5
  7. package/dist/board/projection.d.ts.map +1 -1
  8. package/dist/board/projection.js +25 -65
  9. package/dist/board/projection.js.map +1 -1
  10. package/dist/board/tasks.d.ts +8 -0
  11. package/dist/board/tasks.d.ts.map +1 -0
  12. package/dist/board/tasks.js +86 -0
  13. package/dist/board/tasks.js.map +1 -0
  14. package/dist/credentials.d.ts +6 -6
  15. package/dist/credentials.d.ts.map +1 -1
  16. package/dist/credentials.js +6 -6
  17. package/dist/credentials.js.map +1 -1
  18. package/dist/exe-dev.d.ts +5 -4
  19. package/dist/exe-dev.d.ts.map +1 -1
  20. package/dist/exe-dev.js +5 -4
  21. package/dist/exe-dev.js.map +1 -1
  22. package/dist/idle-triggers.d.ts +1 -1
  23. package/dist/idle-triggers.d.ts.map +1 -1
  24. package/dist/idle-triggers.js +3 -1
  25. package/dist/idle-triggers.js.map +1 -1
  26. package/dist/label-reconciler.d.ts +30 -0
  27. package/dist/label-reconciler.d.ts.map +1 -0
  28. package/dist/label-reconciler.js +119 -0
  29. package/dist/label-reconciler.js.map +1 -0
  30. package/dist/local.d.ts +17 -12
  31. package/dist/local.d.ts.map +1 -1
  32. package/dist/local.js +20 -13
  33. package/dist/local.js.map +1 -1
  34. package/dist/operator/attempt.d.ts +69 -0
  35. package/dist/operator/attempt.d.ts.map +1 -0
  36. package/dist/operator/attempt.js +62 -0
  37. package/dist/operator/attempt.js.map +1 -0
  38. package/dist/operator/board.d.ts +119 -0
  39. package/dist/operator/board.d.ts.map +1 -0
  40. package/dist/operator/board.js +101 -0
  41. package/dist/operator/board.js.map +1 -0
  42. package/dist/operator/http.d.ts +180 -0
  43. package/dist/operator/http.d.ts.map +1 -0
  44. package/dist/operator/http.js +150 -0
  45. package/dist/operator/http.js.map +1 -0
  46. package/dist/operator/need.d.ts +66 -0
  47. package/dist/operator/need.d.ts.map +1 -0
  48. package/dist/operator/need.js +70 -0
  49. package/dist/operator/need.js.map +1 -0
  50. package/dist/operator/operator.d.ts +68 -0
  51. package/dist/operator/operator.d.ts.map +1 -0
  52. package/dist/operator/operator.js +402 -0
  53. package/dist/operator/operator.js.map +1 -0
  54. package/dist/operator/overview.d.ts +51 -0
  55. package/dist/operator/overview.d.ts.map +1 -0
  56. package/dist/operator/overview.js +48 -0
  57. package/dist/operator/overview.js.map +1 -0
  58. package/dist/operator/projection.d.ts +12 -9
  59. package/dist/operator/projection.d.ts.map +1 -1
  60. package/dist/operator/projection.js +44 -17
  61. package/dist/operator/projection.js.map +1 -1
  62. package/dist/operator/run.d.ts +62 -0
  63. package/dist/operator/run.d.ts.map +1 -0
  64. package/dist/operator/run.js +61 -0
  65. package/dist/operator/run.js.map +1 -0
  66. package/dist/operator/transcript.d.ts +59 -0
  67. package/dist/operator/transcript.d.ts.map +1 -0
  68. package/dist/operator/transcript.js +66 -0
  69. package/dist/operator/transcript.js.map +1 -0
  70. package/dist/orchestrator.d.ts +3 -2
  71. package/dist/orchestrator.d.ts.map +1 -1
  72. package/dist/orchestrator.js +1 -1
  73. package/dist/orchestrator.js.map +1 -1
  74. package/dist/polling/cycle.d.ts +51 -0
  75. package/dist/polling/cycle.d.ts.map +1 -0
  76. package/dist/polling/cycle.js +44 -0
  77. package/dist/polling/cycle.js.map +1 -0
  78. package/dist/polling/hints.d.ts +20 -0
  79. package/dist/polling/hints.d.ts.map +1 -0
  80. package/dist/polling/hints.js +54 -0
  81. package/dist/polling/hints.js.map +1 -0
  82. package/dist/polling/loop-evaluation.d.ts +21 -0
  83. package/dist/polling/loop-evaluation.d.ts.map +1 -0
  84. package/dist/polling/loop-evaluation.js +131 -0
  85. package/dist/polling/loop-evaluation.js.map +1 -0
  86. package/dist/polling/polling.d.ts +36 -0
  87. package/dist/polling/polling.d.ts.map +1 -0
  88. package/dist/polling/polling.js +296 -0
  89. package/dist/polling/polling.js.map +1 -0
  90. package/dist/polling/repository-sync.d.ts +45 -0
  91. package/dist/polling/repository-sync.d.ts.map +1 -0
  92. package/dist/polling/repository-sync.js +169 -0
  93. package/dist/polling/repository-sync.js.map +1 -0
  94. package/dist/polling-triggers.d.ts +3 -39
  95. package/dist/polling-triggers.d.ts.map +1 -1
  96. package/dist/polling-triggers.js +3 -393
  97. package/dist/polling-triggers.js.map +1 -1
  98. package/dist/schedule-triggers.d.ts +17 -15
  99. package/dist/schedule-triggers.d.ts.map +1 -1
  100. package/dist/schedule-triggers.js +53 -43
  101. package/dist/schedule-triggers.js.map +1 -1
  102. package/dist/scheduler.d.ts +5 -5
  103. package/dist/scheduler.d.ts.map +1 -1
  104. package/dist/scheduler.js +30 -44
  105. package/dist/scheduler.js.map +1 -1
  106. package/dist/trigger-submission.d.ts +33 -24
  107. package/dist/trigger-submission.d.ts.map +1 -1
  108. package/dist/trigger-submission.js +30 -37
  109. package/dist/trigger-submission.js.map +1 -1
  110. package/package.json +50 -14
  111. package/dist/index.d.ts +0 -11
  112. package/dist/index.d.ts.map +0 -1
  113. package/dist/index.js +0 -11
  114. package/dist/index.js.map +0 -1
  115. package/dist/operator/model.d.ts +0 -280
  116. package/dist/operator/model.d.ts.map +0 -1
  117. package/dist/operator/model.js +0 -242
  118. package/dist/operator/model.js.map +0 -1
  119. package/dist/operator/service.d.ts +0 -36
  120. package/dist/operator/service.d.ts.map +0 -1
  121. package/dist/operator/service.js +0 -248
  122. package/dist/operator/service.js.map +0 -1
package/README.md CHANGED
@@ -2,27 +2,52 @@
2
2
 
3
3
  `@usine/orchestrator` connects loaded loop files to GitHub polling, the durable run engine, and configured workers for [usine](https://github.com/basaltbytes/usine).
4
4
 
5
- Its platform-free root exports the complete embeddable application surface: `PollingTriggers`, `ScheduleTriggers`, `Orchestrator`, and `Operator`. `Orchestrator.run(instance)` runs both trigger streams; `Operator` provides run and Board observation, structured protocol transcript pages, label-backed Board moves, approve/retry/cancel, and database-backed Loop pause/unpause. Transcript payloads, Attempt brains/outcomes, and items needing attention remain typed data; consuming apps own their wording and presentation. `OperatorObservation` exposes the same read-only projection without constructing execution services. The latest polling and schedule failures remain visible through `Operator.overview(instance)` after their sibling work continues. Concurrent overview reads with the same durable revision share one projection computation.
5
+ Its platform-free entry points provide `PollingTriggers` at `/polling-triggers`, `ScheduleTriggers` at `/schedule-triggers`, `Orchestrator` at `/orchestrator`, and `Operator` with its request and response types at `/operator`. `Orchestrator.run(instance)` runs both trigger streams; `Operator` provides run and Board observation, structured protocol transcript pages, label-backed Board moves, approve/retry/cancel, and database-backed Loop pause/unpause. Transcript payloads, Attempt brains/outcomes, and items needing attention remain typed data. Captured executor defects appear as `DefectFailure` with a safe message; original causes stay out of operator responses. Consuming apps own their wording and presentation. `OperatorObservation` exposes the same read-only projection without constructing execution services. The latest polling and schedule failures remain visible through `Operator.overview(instance)` after their sibling work continues. Concurrent overview reads with the same durable revision share one projection computation.
6
6
 
7
- `Operator.overview(instance)` groups the latest polled Items into each repository's authored lanes. Repositories without configured lanes receive proposals from the repository label catalog, including unused labels and repositories with no Items. Items that match no source appear in a read-only `Unmapped` lane, and label matches take precedence over state sources. Each card references its newest recorded Run for the same Item. A malformed Item projection is quarantined and reported in the Board and needs-you strip while valid siblings remain visible.
7
+ `Operator.overview(instance)` joins the latest 500 polled Items into Task cards in each repository's authored lanes. Explicit same-repository issue closing links and saved Run PR results join an issue to a PR. Repositories without configured lanes receive proposals from the repository label catalog, including unused labels and repositories with no Items. Items that match no source appear in a read-only `Unmapped` lane, and label matches take precedence over state sources. Each card retains every saved Run on its member Items, oldest first. The newest open Run determines the current Item; between Runs an open PR, then the latest settled PR, takes over from the issue. Its labels and state determine the lane, so removing the issue's trigger label does not strand a task whose PR is under review. See ADR 0024. A malformed Item projection is quarantined and reported in the Board and needs-you strip while valid siblings remain visible. Failed declared-label creation also appears as a repository preflight finding without blocking trigger work.
8
8
 
9
- `Operator.moveBoardItem(instance, move)` adds the target lane labels and removes only labels owned by the lane map. GitHub labels outside that map remain unchanged even when the Item snapshot is stale or its label connection is truncated. The normal polling cycle evaluates the resulting trigger state.
9
+ `Operator.moveBoardItem(instance, move)` accepts authored label-backed lanes, adds the target lane labels, and removes only labels owned by the authored map. Proposed lanes are read-only; direct move requests return `BoardLaneReadOnlyError`. GitHub labels outside the authored map remain unchanged even when the Item snapshot is stale or its label connection is truncated. Configure `repos[].lanes` in `usine.yaml` and restart the orchestrator to enable moves; see the [lane configuration example](../config/README.md). Every attempted GitHub label write queues an Item Hint, including an uncertain or partially applied failure: the running poller fetches the current GitHub snapshot, projects its Board position, and evaluates its Loops immediately unless GitHub has requested backoff.
10
10
 
11
11
  `Operator.detail` accepts distinct cold, live-tail, and earlier-page requests. A cold read keeps the newest 500 rows per Attempt and returns an earlier cursor for every truncated Attempt; clients can page each cursor backward until the entire transcript is reachable without ballooning the first drawer response. A live-tail response returns at most 500 rows across the Run and advances its cursor from the last returned row.
12
12
 
13
+ ## Operator HTTP
14
+
15
+ Import `FactoryOverview`, `RunView`, `RunDetailView`, Board views, operator needs,
16
+ and transcript request types from `@usine/orchestrator/operator`. The `Operator`
17
+ service and its HTTP contract use the same schemas for these views and requests.
18
+
19
+ `@usine/orchestrator/operator/http` exports `OperatorApi`, the shared HTTP contract
20
+ for operator observation and interventions. Use Effect's `HttpApiClient.make` with
21
+ an `HttpClient` layer to call it, or `HttpApiBuilder.group` to implement its
22
+ `operator` group. Server implementations provide `OperatorHttpPolicy` to enforce
23
+ origin checks and translate request failures; `apps/server` provides the local
24
+ server implementation.
25
+
26
+ The generated client accepts the same `ColdTranscriptRequest`,
27
+ `TailTranscriptRequest`, and `EarlierTranscriptRequest` values as `Operator.detail`.
28
+ It encodes their exclusive query parameters and decodes responses through the
29
+ shared read-model schemas. `OperatorHttpError` preserves the failure's `error`
30
+ discriminator, operator-readable `message`, and associated `status`. The wire
31
+ response remains `{ error, message }`. Successful actions return `{ ok: true }`;
32
+ clients observe subsequent Run or Board progress through the read endpoints.
33
+
13
34
  ## Polling triggers
14
35
 
15
- `PollingTriggers.poll(instance)` performs one cycle; `PollingTriggers.run(instance)` repeats cycles using the instance's factory-wide `poll_interval` and waits longer when GitHub reports rate-limit pressure. Per-repository failures are isolated and reported on the cycle — one failing repository never stops its siblings.
36
+ `PollingTriggers.poll(instance)` performs one cycle; `PollingTriggers.run(instance)` repeats cycles using the instance's factory-wide `poll_interval` and waits longer when GitHub reports rate-limit pressure. Per-repository failures are isolated and reported on the cycle — one failing repository never stops its siblings. `PollingTriggers.hint(repository, item)` queues a bounded, coalesced self-write nudge. The running poller serializes Hint snapshots with regular cycles and uses the same projection and Event dedup path. Hints leave REST cursors, the normal conditional-poll cadence, and the last complete cycle’s findings intact; dropped or failed Hints are repaired by the polling backstop. GitHub request backoff, including deadlines reported by a failed writer, also delays Hint fetches. The original write outcome still reaches its caller.
37
+
38
+ Each cycle first refreshes the complete label catalog in every managed repository and reconciles the factory-wide declarations from `usine.yaml`. Usine creates missing labels before change detection or Item evaluation. It leaves existing labels untouched and logs color or description drift. Creation failures become preflight findings, and the cycle continues into triggers. The updated catalog remains the Board's source for lane colors.
16
39
 
17
- Each cycle asks `GitHubPolling` for changed items and the complete label catalog in every managed repository. It stores the catalog, fetches one payload snapshot per changed item, updates the durable Item projection, and evaluates each stream-matching loop's CEL `if:` expression against that snapshot. A match renders every `{{ CEL expression }}` in the loop body, resolves the named agent and effective parent model, then stores that immutable execution context with the Event. The Event identity covers the loop, canonical repository, item number, and timestamp-free content hash. An unmatch revokes pending or approval-waiting work for that loop and item. Repositories without matching loops are still polled for their Board projection.
40
+ After label preflight, the cycle asks `GitHubPolling` for changed items, fetches one payload snapshot per changed item, updates the durable Item projection, and evaluates each stream-matching loop's CEL `if:` expression against that snapshot. A match renders every `{{ CEL expression }}` in the loop body, resolves the named agent and effective parent model, then stores that immutable execution context with the Event. The Event identity covers the loop, canonical repository, item number, and timestamp-free content hash. An unmatch revokes pending or approval-waiting work for that loop and item. Repositories without matching loops are still polled for their Board projection.
18
41
 
19
42
  Polling cursors live in the engine's `CursorStore`. When a loop starts watching a repository or its trigger expression changes, the orchestrator discards that repository's efficiency cursor and performs a cold poll, while the permanent Event ledger absorbs repeated state.
20
43
 
21
- `PollingTriggers.layer` requires `CursorStore`, `LoopControl`, `RunEngine`, `ConfigParser`, `ExpressionEngine`, and `GitHubPolling`. The engine's local SQLite layer supplies the engine services:
44
+ PR-triggered Attempts fetch and check out the immutable `headRefOid` saved in their Event payload. A later push creates a new Event with its new head commit. Issue and schedule Attempts use the repository's default branch.
45
+
46
+ `PollingTriggers.layer` requires `CursorStore`, `LoopControl`, `RunEngine`, `ConfigParser`, `ExpressionEngine`, `GitHubPolling`, the repository-label projection reader/writer, and `LabelReconciler`. `LabelReconciler.layer` in turn requires `GitHubLabelWriter`. The engine's local SQLite layer supplies the engine services:
22
47
 
23
48
  ```ts
24
49
  import { Layer } from "effect"
25
- import { PollingTriggers } from "@usine/orchestrator"
50
+ import { PollingTriggers } from "@usine/orchestrator/polling-triggers"
26
51
 
27
52
  const dependencies = Layer.mergeAll(
28
53
  engineLayer,
@@ -48,43 +73,37 @@ The Event key covers the loop, canonical repository, and scheduled time. An in-m
48
73
 
49
74
  ## Worker scheduling
50
75
 
51
- The platform-free root entry exports `stepExecutorLayer`. At startup it verifies every configured worker, creates one capacity slot per `max_concurrent_attempts`, and assigns slots by Event receipt time. Runs stay pending while every slot is occupied. The layer rejects worker kinds that its supplied executor cannot run.
76
+ `@usine/orchestrator/scheduler` exports the platform-free `stepExecutorLayer`. `stepExecutorLayer(config, brains)` accepts the roster’s `BrainSpec` values. At startup it verifies every configured worker against that roster, creates one capacity slot per `max_concurrent_attempts`, and assigns slots by Event receipt time. Runs stay pending while every slot is occupied. Each Attempt receives the configured `max_children` child-session budget. The layer rejects worker kinds that its supplied executor cannot run. Worker capability failures during preparation become non-retryable `AgentFailure` outcomes, like unavailable model credentials.
52
77
 
53
78
  `@usine/orchestrator/local` composes the scheduler with the Node local executor and the engine's local SQLite adapter. It requires a caller-owned `CredentialProvider`; use `gitHubCredentialLayer` with `@usine/github`, or supply another provider that mints one repository credential per Attempt.
54
79
 
55
80
  ```ts
56
81
  import { layer as localLayer } from "@usine/orchestrator/local"
57
82
 
58
- const EngineLive = localLayer(instanceDirectory, config, {
83
+ const EngineLive = localLayer(instanceDirectory, config, brains, {
59
84
  repositoryUrl: (repository) => `https://github.com/${repository}.git`,
60
85
  })
61
86
  ```
62
87
 
63
88
  Provide `CredentialProvider` to `EngineLive`, then request `RunEngine` from the resulting Effect layer. The local composition caches repositories under `<instance>/.usine/workers/<worker>/repos` and removes Attempt worktrees after completion or cancellation.
64
89
 
65
- For the whole local application, `runtimeLayer(instanceDirectory, instance, options)` additionally composes GitHub polling, schedule triggers, CEL parsing, `Orchestrator`, and `Operator`. It requires only `GitHubCredentials`; the server or another host owns how those credentials are loaded. `operatorObservationLayer(instanceDirectory)` is the read-only Node composition for setup and maintenance surfaces: it reads durable Runs and Loop runtime state while trigger execution remains idle.
90
+ For the whole local application, `runtimeLayer(instanceDirectory, instance, options)` additionally composes GitHub polling, schedule triggers, CEL parsing, `Orchestrator`, and `Operator`. It derives worker preflight requirements from `instance.agents` and requires only `GitHubCredentials`; the server or another host owns how those credentials are loaded. `operatorObservationLayer(instanceDirectory)` is the read-only Node composition for setup and maintenance surfaces: it reads durable Runs and Loop runtime state while trigger execution remains idle.
66
91
 
67
92
  For an exe.dev Worker, use the `@usine/orchestrator/exe-dev` composition. It keeps the engine and SQLite runtime local while the unchanged Worker contract runs on the named VM:
68
93
 
69
94
  ```ts
70
- import { Repository } from "@usine/core"
71
- import { GitHubIntegration, HarnessLoginCheck, IntegrationName } from "@usine/executor/exe-dev"
95
+ import { RepositoryName } from "@usine/core/repository"
96
+ import { GitHubIntegration, IntegrationName } from "@usine/executor/exe-dev"
72
97
  import { layer as exeDevLayer } from "@usine/orchestrator/exe-dev"
73
98
 
74
- const EngineLive = exeDevLayer(instanceDirectory, config, {
99
+ const EngineLive = exeDevLayer(instanceDirectory, config, brains, {
75
100
  githubIntegrations: [
76
101
  new GitHubIntegration({
77
- repository: Repository.Name.make("acme/widget"),
102
+ repository: RepositoryName.make("acme/widget"),
78
103
  name: IntegrationName.make("usine-acme-widget"),
79
104
  }),
80
105
  ],
81
- harnessLoginChecks: [
82
- new HarnessLoginCheck({
83
- harness: "codex",
84
- command: "codex",
85
- args: ["login", "status"],
86
- }),
87
- ],
106
+
88
107
  })
89
108
  ```
90
109
 
@@ -124,3 +143,9 @@ pnpm --filter @usine/orchestrator test:integration:agent
124
143
  The test removes its kick and result comments during cleanup.
125
144
 
126
145
  Everything here is 0.x, so APIs can change between minor releases. Supply `effect` at the version pinned by the usine workspace.
146
+
147
+ Item cycle exhaustion appears as a `CycleBudgetNeed` in the overview and marks the Item’s Board card as needing attention. `Operator.resetCycleBudget` records an answer to the exact Ask; polling restarts the repository cursor, fetches current Items, and evaluates active Loops before opening further Runs. A failed refresh is retried. Each Item fetch captures its budget generation; resets supersede in-flight observations and fresh Events use the current Loop configuration. GitHub delivery of these Asks is tracked separately in [#36](https://github.com/basaltbytes/usine/issues/36).
148
+
149
+ The operator HTTP API exposes `POST /api/cycle-budgets/reset` with `{ "askId": "…" }`. A stale or differently answered Ask returns HTTP 409.
150
+
151
+ The orchestrator requires run-host Attempt channel protocol v6 for saved harness session metadata. Upgrade both together; worker preflight rejects a version mismatch. Stored v3–v5 transcripts remain readable.
@@ -0,0 +1,18 @@
1
+ import { GitHubLabelName } from "@usine/config/label";
2
+ import type { LaneItemState } from "@usine/config/board";
3
+ import { ItemKey, ItemNumber } from "@usine/core/item";
4
+ import type { ItemProjection } from "@usine/engine/item-projection";
5
+ import { Effect } from "effect";
6
+ import { BoardProjectionError } from "../operator/board.ts";
7
+ export interface ProjectedItem {
8
+ readonly itemKey: ItemKey;
9
+ readonly kind: "issue" | "pr";
10
+ readonly number: ItemNumber;
11
+ readonly title: string;
12
+ readonly url: string;
13
+ readonly state: LaneItemState;
14
+ readonly linkedPullRequests: ReadonlyArray<string>;
15
+ readonly labels: ReadonlyArray<GitHubLabelName>;
16
+ }
17
+ export declare const projectedItem: (item: ItemProjection) => Effect.Effect<ProjectedItem, BoardProjectionError>;
18
+ //# sourceMappingURL=items.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"items.d.ts","sourceRoot":"","sources":["../../src/board/items.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAEpE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAE5D,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,kBAAkB,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;CACjD;AAWD,eAAO,MAAM,aAAa,SAClB,cAAc,KACnB,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,oBAAoB,CA0ChD,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { GitHubLabelName } from "@usine/config/label";
2
+ import { ItemKey, ItemNumber } from "@usine/core/item";
3
+ import { IssuePayload, PullRequestPayload } from "@usine/github/polling";
4
+ import { Effect, Schema } from "effect";
5
+ import { BoardProjectionError } from "../operator/board.js";
6
+ const labelsFrom = Schema.decodeUnknownEffect(Schema.Array(GitHubLabelName));
7
+ const projectionError = (item, message) => new BoardProjectionError({
8
+ repository: item.repository,
9
+ itemKey: item.itemKey,
10
+ message,
11
+ });
12
+ export const projectedItem = (item) => Effect.gen(function* () {
13
+ if (item.source === "issue") {
14
+ const payload = yield* Schema.decodeUnknownEffect(IssuePayload)(item.payload).pipe(Effect.mapError((error) => projectionError(item, error.message)));
15
+ return {
16
+ itemKey: item.itemKey,
17
+ kind: "issue",
18
+ number: ItemNumber.make(item.number),
19
+ title: payload.title,
20
+ url: payload.url,
21
+ state: payload.state === "OPEN" ? "issue-open" : "issue-closed",
22
+ linkedPullRequests: payload.closedByPullRequestsReferences.nodes.map(({ url }) => url),
23
+ labels: yield* labelsFrom(payload.labels.nodes.map(({ name }) => name)).pipe(Effect.mapError((error) => projectionError(item, error.message))),
24
+ };
25
+ }
26
+ if (item.source === "pr") {
27
+ const payload = yield* Schema.decodeUnknownEffect(PullRequestPayload)(item.payload).pipe(Effect.mapError((error) => projectionError(item, error.message)));
28
+ const state = payload.merged
29
+ ? "pr-merged"
30
+ : payload.state === "OPEN"
31
+ ? "pr-open"
32
+ : "pr-closed";
33
+ return {
34
+ itemKey: item.itemKey,
35
+ kind: "pr",
36
+ number: ItemNumber.make(item.number),
37
+ title: payload.title,
38
+ url: payload.url,
39
+ state,
40
+ linkedPullRequests: [],
41
+ labels: yield* labelsFrom(payload.labels.nodes.map(({ name }) => name)).pipe(Effect.mapError((error) => projectionError(item, error.message))),
42
+ };
43
+ }
44
+ return yield* projectionError(item, `Unsupported Item projection source: ${item.source}`);
45
+ });
46
+ //# sourceMappingURL=items.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"items.js","sourceRoot":"","sources":["../../src/board/items.ts"],"names":[],"mappings":"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"}
@@ -1,8 +1,9 @@
1
- import { type ManagedRepo } from "@usine/config";
2
- import type { ItemProjection } from "@usine/engine";
3
- import { ItemLabelMutation } from "@usine/github";
1
+ import type { ManagedRepo } from "@usine/config/factory";
2
+ import type { ItemProjection } from "@usine/engine/item-projection";
3
+ import { ItemLabelMutation } from "@usine/github/item-writer";
4
4
  import { Effect } from "effect";
5
- import { BoardView, type RunView, WritableBoardLaneView } from "../operator/model.ts";
6
- export declare const projectBoard: (repository: ManagedRepo, repositoryLabels: readonly string[], storedItems: readonly ItemProjection[], runs: readonly RunView[]) => Effect.Effect<BoardView, never, never>;
5
+ import { BoardView, WritableBoardLaneView } from "../operator/board.ts";
6
+ import { type RunView } from "../operator/run.ts";
7
+ export declare const projectBoard: (repository: ManagedRepo, repositoryLabels: readonly string[], storedItems: readonly ItemProjection[], runs: readonly RunView[], cycleBlockedItems?: readonly (string & import("effect/Brand").Brand<"ItemKey">)[] | undefined) => Effect.Effect<BoardView, never, never>;
7
8
  export declare const labelMutationForBoardMove: (board: BoardView, target: WritableBoardLaneView) => ItemLabelMutation;
8
9
  //# sourceMappingURL=projection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../src/board/projection.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,KAAK,WAAW,EACjB,MAAM,eAAe,CAAC;AAEvB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAgB,iBAAiB,EAAsB,MAAM,eAAe,CAAC;AACpF,OAAO,EAAE,MAAM,EAAkB,MAAM,QAAQ,CAAC;AAChD,OAAO,EAIL,SAAS,EAET,KAAK,OAAO,EACZ,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAkH9B,eAAO,MAAM,YAAY,4KAgFxB,CAAC;AAEF,eAAO,MAAM,yBAAyB,UAC7B,SAAS,UACR,qBAAqB,KAC5B,iBAaF,CAAC"}
1
+ {"version":3,"file":"projection.d.ts","sourceRoot":"","sources":["../../src/board/projection.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EAIL,SAAS,EAET,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAgElD,eAAO,MAAM,YAAY,2QAwExB,CAAC;AAEF,eAAO,MAAM,yBAAyB,UAC7B,SAAS,UACR,qBAAqB,KAC5B,iBAaF,CAAC"}
@@ -1,46 +1,12 @@
1
- import { GitHubLabelName, LabelLaneSource, Lane, LaneName, } from "@usine/config";
2
- import { Item, RunState } from "@usine/core";
3
- import { IssuePayload, ItemLabelMutation, PullRequestPayload } from "@usine/github";
4
- import { Effect, Result, Schema } from "effect";
5
- import { BoardItemView, BoardLaneId, BoardProjectionError, BoardView, ReadOnlyBoardLaneView, WritableBoardLaneView, } from "../operator/model.js";
6
- const labelsFrom = Schema.decodeUnknownEffect(Schema.Array(GitHubLabelName));
7
- const projectionError = (item, message) => new BoardProjectionError({
8
- repository: item.repository,
9
- itemKey: item.itemKey,
10
- message,
11
- });
12
- const projectedItem = (item) => Effect.gen(function* () {
13
- if (item.source === "issue") {
14
- const payload = yield* Schema.decodeUnknownEffect(IssuePayload)(item.payload).pipe(Effect.mapError((error) => projectionError(item, error.message)));
15
- return {
16
- itemKey: item.itemKey,
17
- kind: "issue",
18
- number: Item.Number.make(item.number),
19
- title: payload.title,
20
- url: payload.url,
21
- state: payload.state === "OPEN" ? "issue-open" : "issue-closed",
22
- labels: yield* labelsFrom(payload.labels.nodes.map(({ name }) => name)).pipe(Effect.mapError((error) => projectionError(item, error.message))),
23
- };
24
- }
25
- if (item.source === "pr") {
26
- const payload = yield* Schema.decodeUnknownEffect(PullRequestPayload)(item.payload).pipe(Effect.mapError((error) => projectionError(item, error.message)));
27
- const state = payload.merged
28
- ? "pr-merged"
29
- : payload.state === "OPEN"
30
- ? "pr-open"
31
- : "pr-closed";
32
- return {
33
- itemKey: item.itemKey,
34
- kind: "pr",
35
- number: Item.Number.make(item.number),
36
- title: payload.title,
37
- url: payload.url,
38
- state,
39
- labels: yield* labelsFrom(payload.labels.nodes.map(({ name }) => name)).pipe(Effect.mapError((error) => projectionError(item, error.message))),
40
- };
41
- }
42
- return yield* projectionError(item, `Unsupported Item projection source: ${item.source}`);
43
- });
1
+ import { GitHubLabelName } from "@usine/config/label";
2
+ import { LabelLaneSource, Lane, LaneName, } from "@usine/config/board";
3
+ import { ItemKey } from "@usine/core/item";
4
+ import { ItemLabelMutation } from "@usine/github/item-writer";
5
+ import { Effect, Result } from "effect";
6
+ import { BoardTaskView, BoardLaneId, BoardProjectionError, BoardView, ReadOnlyBoardLaneView, WritableBoardLaneView, } from "../operator/board.js";
7
+ import {} from "../operator/run.js";
8
+ import { projectedItem } from "./items.js";
9
+ import { taskCards } from "./tasks.js";
44
10
  const labelSources = (sources) => sources.flatMap((source) => ("label" in source ? [source.label] : []));
45
11
  const stateSources = (sources) => sources.flatMap((source) => ("state" in source ? [source.state] : []));
46
12
  const proposedLanes = (repositoryLabels) => {
@@ -59,11 +25,14 @@ const effectiveLanes = (repository, repositoryLabels) => repository.lanes.length
59
25
  ? repository.lanes.map((lane) => ({ lane, origin: "authored" }))
60
26
  : proposedLanes(repositoryLabels);
61
27
  const laneId = (definition) => BoardLaneId.make(`${definition.origin}:${definition.lane.name}`);
62
- const laneFor = (item, lanes) => lanes.find(({ lane }) => labelSources(lane.sources).some((label) => item.labels.includes(label))) ?? lanes.find(({ lane }) => stateSources(lane.sources).includes(item.state));
63
- const isOpenRun = (run) => RunState.OPEN_STATE_TAGS.some((state) => state === run.state);
64
- const needsOperator = (run) => run.state === "Waiting" || run.state === "Failed";
65
- const preferredRun = (runs) => runs.find(needsOperator) ?? runs.find(isOpenRun) ?? runs[0] ?? null;
66
- export const projectBoard = Effect.fn("Board.project")((repository, repositoryLabels, storedItems, runs) => Effect.gen(function* () {
28
+ const SETTLED_STATES = ["pr-merged", "pr-closed", "issue-closed"];
29
+ const isSettled = (item) => SETTLED_STATES.includes(item.state);
30
+ const labelLaneFor = (item, lanes) => lanes.find(({ lane }) => labelSources(lane.sources).some((label) => item.labels.includes(label)));
31
+ const stateLaneFor = (item, lanes) => lanes.find(({ lane }) => stateSources(lane.sources).includes(item.state));
32
+ const laneFor = (item, lanes) => isSettled(item)
33
+ ? stateLaneFor(item, lanes)
34
+ : (labelLaneFor(item, lanes) ?? stateLaneFor(item, lanes));
35
+ export const projectBoard = Effect.fn("Board.project")((repository, repositoryLabels, storedItems, runs, cycleBlockedItems = []) => Effect.gen(function* () {
67
36
  yield* Effect.annotateCurrentSpan({ repository: repository.name });
68
37
  const results = yield* Effect.forEach(storedItems, (item) => projectedItem(item).pipe(Effect.result));
69
38
  const items = [];
@@ -82,21 +51,12 @@ export const projectBoard = Effect.fn("Board.project")((repository, repositoryLa
82
51
  });
83
52
  }
84
53
  const lanes = effectiveLanes(repository, repositoryLabels);
85
- const runsByItem = new Map();
86
- for (const run of runs) {
87
- const itemRuns = runsByItem.get(run.itemKey) ?? [];
88
- itemRuns.push(run);
89
- runsByItem.set(run.itemKey, itemRuns);
90
- }
91
- const cards = items.map((item) => {
92
- const itemRuns = runsByItem.get(item.itemKey) ?? [];
93
- const run = preferredRun(itemRuns);
94
- return new BoardItemView({
95
- ...item,
96
- runs: itemRuns,
97
- run,
98
- needsYou: itemRuns.some(needsOperator),
99
- });
54
+ const cards = taskCards(repository.name, items, runs, cycleBlockedItems);
55
+ yield* Effect.logDebug("Projected Task cards from linked Items", {
56
+ repository: repository.name,
57
+ items: items.length,
58
+ tasks: cards.length,
59
+ runs: runs.length,
100
60
  });
101
61
  const grouped = new Map();
102
62
  for (const definition of lanes)
@@ -122,8 +82,8 @@ export const projectBoard = Effect.fn("Board.project")((repository, repositoryLa
122
82
  origin: definition.origin,
123
83
  items: sortItems(grouped.get(laneId(definition)) ?? []),
124
84
  };
125
- return labels.length > 0
126
- ? new WritableBoardLaneView({ ...fields, labels })
85
+ return definition.origin === "authored" && labels.length > 0
86
+ ? new WritableBoardLaneView({ ...fields, origin: definition.origin, labels })
127
87
  : new ReadOnlyBoardLaneView(fields);
128
88
  }),
129
89
  new ReadOnlyBoardLaneView({
@@ -1 +1 @@
1
- {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../src/board/projection.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"projection.js","sourceRoot":"","sources":["../../src/board/projection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ItemKey } from "@usine/core/item";
2
+ import { type RepositoryName } from "@usine/core/repository";
3
+ import { BoardTaskView } from "../operator/board.ts";
4
+ import type { RunView } from "../operator/run.ts";
5
+ import type { ProjectedItem } from "./items.ts";
6
+ /** Joins explicit issue/PR relationships into Task cards without creating stored Task identities (ADR 0024). */
7
+ export declare const taskCards: (repository: RepositoryName, items: ReadonlyArray<ProjectedItem>, runs: ReadonlyArray<RunView>, cycleBlockedItems: ReadonlyArray<ItemKey>) => ReadonlyArray<BoardTaskView>;
8
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/board/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAA2B,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAEtF,OAAO,EAAiB,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAqBhD,gHAAgH;AAChH,eAAO,MAAM,SAAS,eACR,cAAc,SACnB,aAAa,CAAC,aAAa,CAAC,QAC7B,aAAa,CAAC,OAAO,CAAC,qBACT,aAAa,CAAC,OAAO,CAAC,KACxC,aAAa,CAAC,aAAa,CAuF7B,CAAC"}
@@ -0,0 +1,86 @@
1
+ import { canonicalRepositoryName } from "@usine/core/repository";
2
+ import { Array as EffectArray, Option, Order, Schema } from "effect";
3
+ import { BoardItemLink, BoardTaskView } from "../operator/board.js";
4
+ const decodeUrl = Schema.decodeUnknownOption(Schema.URLFromString);
5
+ const itemLink = (item) => new BoardItemLink({
6
+ itemKey: item.itemKey,
7
+ kind: item.kind,
8
+ number: item.number,
9
+ title: item.title,
10
+ url: item.url,
11
+ });
12
+ /** Joins explicit issue/PR relationships into Task cards without creating stored Task identities (ADR 0024). */
13
+ export const taskCards = (repository, items, runs, cycleBlockedItems) => {
14
+ const runsByItem = EffectArray.groupBy(runs, ({ itemKey }) => itemKey);
15
+ const nodes = items.map((item) => ({
16
+ item,
17
+ runs: runsByItem[item.itemKey] ?? [],
18
+ related: new Set(),
19
+ }));
20
+ const repositoryPath = `/${canonicalRepositoryName(repository)}/pull/`;
21
+ const pullRequests = new Map(nodes
22
+ .filter(({ item }) => item.kind === "pr")
23
+ .map((node) => [`${repositoryPath}${node.item.number}`, node]));
24
+ const blocked = new Set(cycleBlockedItems);
25
+ for (const node of nodes) {
26
+ if (node.item.kind !== "issue")
27
+ continue;
28
+ const urls = [
29
+ ...node.item.linkedPullRequests,
30
+ ...node.runs.flatMap(({ pullRequestUrl }) => pullRequestUrl === null ? [] : [pullRequestUrl]),
31
+ ];
32
+ for (const value of urls) {
33
+ const url = decodeUrl(value);
34
+ if (Option.isNone(url) || url.value.protocol !== "https:" || url.value.host !== "github.com")
35
+ continue;
36
+ // Match the canonical PR path, not a numeric coercion of its last segment.
37
+ // Number-only payload references can point to another repository.
38
+ const pr = pullRequests.get(url.value.pathname.toLowerCase());
39
+ if (pr === undefined)
40
+ continue;
41
+ node.related.add(pr);
42
+ pr.related.add(node);
43
+ }
44
+ }
45
+ const visited = new Set();
46
+ const cards = [];
47
+ for (const seed of nodes) {
48
+ if (visited.has(seed))
49
+ continue;
50
+ visited.add(seed);
51
+ const members = [seed];
52
+ for (const member of members) {
53
+ for (const related of member.related) {
54
+ if (visited.has(related))
55
+ continue;
56
+ visited.add(related);
57
+ members.push(related);
58
+ }
59
+ }
60
+ const ordered = EffectArray.sort(members, ({ item: a }, { item: b }) => (a.kind === b.kind ? 0 : a.kind === "issue" ? -1 : 1) || Order.Number(a.number, b.number));
61
+ const origin = ordered[0];
62
+ const history = members
63
+ .flatMap(({ item, runs }) => runs.map((run) => ({ item, run })))
64
+ .sort(({ run: a }, { run: b }) => b.openedAt.localeCompare(a.openedAt) || b.id.localeCompare(a.id));
65
+ const active = history.find(({ run }) => run.canCancel);
66
+ const prs = members
67
+ .filter(({ item }) => item.kind === "pr")
68
+ .sort(({ item: a }, { item: b }) => Number(b.state === "pr-open") - Number(a.state === "pr-open") || b.number - a.number);
69
+ // An open Run controls the lane. Between stages, a PR takes over from its issue.
70
+ const current = active?.item ?? prs[0]?.item ?? origin.item;
71
+ const preferred = history.find(({ run }) => run.canApprove || run.canRetry) ?? active ?? history[0];
72
+ cards.push(new BoardTaskView({
73
+ ...itemLink(current),
74
+ title: origin.item.title,
75
+ state: current.state,
76
+ labels: current.labels,
77
+ items: ordered.map(({ item }) => itemLink(item)),
78
+ runs: history.map(({ run }) => run).reverse(),
79
+ run: preferred?.run ?? null,
80
+ needsYou: history.some(({ run }) => run.canApprove || run.canRetry) ||
81
+ members.some(({ item }) => blocked.has(item.itemKey)),
82
+ }));
83
+ }
84
+ return cards;
85
+ };
86
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/board/tasks.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
- import type { UsineConfig } from "@usine/config";
1
+ import type { UsineConfig } from "@usine/config/factory";
2
2
  import { CredentialProvider } from "@usine/executor";
3
- import { GitHubApp } from "@usine/github";
3
+ import { GitHubApp } from "@usine/github/github-app";
4
4
  import { Layer } from "effect";
5
5
  /**
6
- * Mints one fresh, single-repository GitHub App token per Attempt. Project
7
- * access is discovered lazily on the first mint and cached — a GitHub outage
8
- * cannot block orchestrator startup, and a repository added to the
9
- * installation later is picked up by the next refresh after a miss.
6
+ * Mints one fresh single-repository GitHub App token per Attempt. Project
7
+ * access is discovered on the first mint and cached, so a GitHub outage cannot
8
+ * block startup, and a repository added to the installation later is found by
9
+ * the refresh that follows a miss.
10
10
  */
11
11
  export declare const gitHubCredentialLayer: (config: UsineConfig) => Layer.Layer<CredentialProvider, never, GitHubApp>;
12
12
  //# sourceMappingURL=credentials.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAE,kBAAkB,EAA8B,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAkB,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAU,KAAK,EAA2B,MAAM,QAAQ,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,WACxB,WAAW,KAClB,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAoFhD,CAAC"}
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,kBAAkB,EAA8B,MAAM,iBAAiB,CAAC;AACjF,OAAO,EAAE,SAAS,EAAkB,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAU,KAAK,EAA2B,MAAM,QAAQ,CAAC;AAEhE;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,WACxB,WAAW,KAClB,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,EAAE,SAAS,CAoFhD,CAAC"}
@@ -1,11 +1,11 @@
1
1
  import { CredentialProvider, CredentialUnavailableError } from "@usine/executor";
2
- import { CoveredProject, GitHubApp } from "@usine/github";
2
+ import { GitHubApp, CoveredProject } from "@usine/github/github-app";
3
3
  import { Effect, Layer, Option, SynchronizedRef } from "effect";
4
4
  /**
5
- * Mints one fresh, single-repository GitHub App token per Attempt. Project
6
- * access is discovered lazily on the first mint and cached — a GitHub outage
7
- * cannot block orchestrator startup, and a repository added to the
8
- * installation later is picked up by the next refresh after a miss.
5
+ * Mints one fresh single-repository GitHub App token per Attempt. Project
6
+ * access is discovered on the first mint and cached, so a GitHub outage cannot
7
+ * block startup, and a repository added to the installation later is found by
8
+ * the refresh that follows a miss.
9
9
  */
10
10
  export const gitHubCredentialLayer = (config) => Layer.effect(CredentialProvider, Effect.gen(function* () {
11
11
  const app = yield* GitHubApp;
@@ -17,7 +17,7 @@ export const gitHubCredentialLayer = (config) => Layer.effect(CredentialProvider
17
17
  message: "Could not discover GitHub App repository access",
18
18
  cause,
19
19
  })));
20
- /** Cached map; on a miss, refresh once before concluding "not covered". */
20
+ /** Refreshes the cached project map once on a miss before answering "not covered". */
21
21
  const projectFor = Effect.fn("GitHubCredentialProvider.projectFor")(function* (repository) {
22
22
  const project = yield* SynchronizedRef.modifyEffect(projectsRef, (current) => Effect.gen(function* () {
23
23
  if (Option.isSome(current)) {
@@ -1 +1 @@
1
- {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
package/dist/exe-dev.d.ts CHANGED
@@ -1,7 +1,8 @@
1
- import type { UsineConfig } from "@usine/config";
2
- import type { Instance } from "@usine/core";
1
+ import type { BrainSpec } from "@usine/core/agent/brain";
2
+ import type { UsineConfig } from "@usine/config/factory";
3
+ import type { InstanceDirectory } from "@usine/core/instance";
3
4
  import { type ExeDevExecutorOptions } from "@usine/executor/exe-dev";
4
5
  import { Layer } from "effect";
5
- /** Complete local-orchestrator / exe.dev-Worker engine composition. */
6
- export declare const layer: (instanceDirectory: Instance.Directory, config: UsineConfig, options: ExeDevExecutorOptions) => Layer.Layer<import("@usine/engine").CursorStore | import("@usine/engine").ItemProjectionReader | import("@usine/engine").ItemProjectionWriter | import("@usine/engine").LoopControl | import("@usine/engine").RepositoryLabelProjectionReader | import("@usine/engine").RepositoryLabelProjectionWriter | import("@usine/engine").RunEngine | import("@usine/engine").RunReader, import("@usine/engine").AttemptCancellationError | import("@usine/executor").CredentialUnavailableError | import("@usine/engine").EnginePersistenceError | import("@usine/executor").ExecutorOperationError | import("@usine/engine").RunNotFoundError | import("@usine/engine").RunOperationRejectedError | import("./scheduler.ts").UnsupportedWorkerError | import("@usine/executor").WorkerCapabilityError, never>;
6
+ /** The full engine composition for a local orchestrator driving exe.dev Workers; brains are the instance roster checked at startup. */
7
+ export declare const layer: (instanceDirectory: InstanceDirectory, config: UsineConfig, brains: ReadonlyArray<BrainSpec>, options: ExeDevExecutorOptions) => Layer.Layer<import("@usine/engine/cursor").CursorStore | import("@usine/engine/cycle-budget").CycleBudgets | import("@usine/engine/item-projection").ItemProjectionReader | import("@usine/engine/item-projection").ItemProjectionWriter | import("@usine/engine/loop-control").LoopControl | import("@usine/engine/repository-label-projection").RepositoryLabelProjectionReader | import("@usine/engine/repository-label-projection").RepositoryLabelProjectionWriter | import("@usine/engine/engine").RunEngine | import("@usine/engine/run-reader").RunReader, import("@usine/engine/engine").AttemptCancellationError | import("@usine/executor").CredentialUnavailableError | import("@usine/engine/engine").EnginePersistenceError | import("@usine/executor").ExecutorOperationError | import("@usine/engine/engine").RunInterventionRejectedError | import("@usine/engine/engine").RunNotFoundError | import("@usine/engine/engine").RunOperationRejectedError | import("./scheduler.ts").UnsupportedWorkerError | import("@usine/executor").WorkerCapabilityError, never>;
7
8
  //# sourceMappingURL=exe-dev.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"exe-dev.d.ts","sourceRoot":"","sources":["../src/exe-dev.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAGL,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG/B,uEAAuE;AACvE,eAAO,MAAM,KAAK,sBACG,QAAQ,CAAC,SAAS,UAC7B,WAAW,WACV,qBAAqB,4wBAU/B,CAAC"}
1
+ {"version":3,"file":"exe-dev.d.ts","sourceRoot":"","sources":["../src/exe-dev.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAA0B,KAAK,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAE7F,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAG/B,uIAAuI;AACvI,eAAO,MAAM,KAAK,sBACG,iBAAiB,UAC5B,WAAW,UACX,aAAa,CAAC,SAAS,CAAC,WACvB,qBAAqB,whCAU/B,CAAC"}