@boxxy/dispatch 0.1.0 → 0.1.3

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 (202) hide show
  1. package/README.md +4 -1
  2. package/dist/attempts/attempt-machine.d.ts +804 -0
  3. package/dist/attempts/attempt-moves.d.ts +2 -0
  4. package/dist/attempts/bind-attempt-session.d.ts +14 -0
  5. package/dist/attempts/build-attempt-change.d.ts +73 -0
  6. package/dist/attempts/build-attempt-fact.d.ts +3 -0
  7. package/dist/attempts/end-item-attempts.d.ts +18 -0
  8. package/dist/attempts/is-same-guard.d.ts +5 -0
  9. package/dist/attempts/pick-call-attempt.d.ts +10 -0
  10. package/dist/attempts/stop-stray-session.d.ts +11 -0
  11. package/dist/attempts/types.d.ts +142 -0
  12. package/dist/attempts/write-attempt-move.d.ts +7 -0
  13. package/dist/attempts/write-session-bind.d.ts +3 -0
  14. package/dist/claims/build-snapshot-hash.d.ts +2 -0
  15. package/dist/claims/claim-next.d.ts +6 -0
  16. package/dist/claims/pick-kept-session.d.ts +9 -0
  17. package/dist/claims/request-wake.d.ts +3 -0
  18. package/dist/claims/resume-claim.d.ts +3 -0
  19. package/dist/claims/start-claim.d.ts +3 -0
  20. package/dist/claims/types.d.ts +44 -0
  21. package/dist/closeouts/build-settle-plans.d.ts +17 -0
  22. package/dist/closeouts/close-out-attempt.d.ts +3 -0
  23. package/dist/closeouts/effect-handlers.d.ts +2 -0
  24. package/dist/closeouts/pick-settlement.d.ts +14 -0
  25. package/dist/closeouts/settle-attempt.d.ts +3 -0
  26. package/dist/closeouts/types.d.ts +50 -0
  27. package/dist/index.d.ts +38 -0
  28. package/dist/notices/constants.d.ts +4 -0
  29. package/dist/notices/create-null-notifier.d.ts +2 -0
  30. package/dist/notices/send-notices.d.ts +2 -0
  31. package/dist/notices/types.d.ts +11 -0
  32. package/dist/outbox/build-backoff-ms.d.ts +2 -0
  33. package/dist/outbox/build-initial-sender-state.d.ts +2 -0
  34. package/dist/outbox/build-outbox-status.d.ts +15 -0
  35. package/dist/outbox/constants.d.ts +2 -0
  36. package/dist/outbox/measure-wire-bytes.d.ts +2 -0
  37. package/dist/outbox/pick-sender-move.d.ts +10 -0
  38. package/dist/outbox/run-sender-once.d.ts +2 -0
  39. package/dist/outbox/take-batch.d.ts +3 -0
  40. package/dist/outbox/types.d.ts +61 -0
  41. package/dist/pull-requests/build-link-change.d.ts +11 -0
  42. package/dist/pull-requests/build-state-fact.d.ts +8 -0
  43. package/dist/pull-requests/collect-attempt-trailers.d.ts +2 -0
  44. package/dist/pull-requests/collect-seen-state.d.ts +7 -0
  45. package/dist/pull-requests/constants.d.ts +3 -0
  46. package/dist/pull-requests/link-pull-request.d.ts +2 -0
  47. package/dist/pull-requests/parse-pull-request-url.d.ts +2 -0
  48. package/dist/pull-requests/types.d.ts +37 -0
  49. package/dist/pull-requests/watch-pull-requests.d.ts +2 -0
  50. package/dist/readings/act-on-reading.d.ts +3 -0
  51. package/dist/readings/find-waiting-since.d.ts +9 -0
  52. package/dist/readings/pick-reading-action.d.ts +2 -0
  53. package/dist/readings/types.d.ts +79 -0
  54. package/dist/sessions/build-keep-writes.d.ts +9 -0
  55. package/dist/sessions/build-kept-clear.d.ts +2 -0
  56. package/dist/sessions/forget-sessions.d.ts +2 -0
  57. package/dist/sessions/is-kept-due.d.ts +2 -0
  58. package/dist/sessions/resume-kept-session.d.ts +6 -0
  59. package/dist/sessions/types.d.ts +19 -0
  60. package/dist/test-utils/apply-memory-change.d.ts +3 -0
  61. package/dist/test-utils/build-memory-reader.d.ts +3 -0
  62. package/dist/test-utils/build-mock-bind-change.d.ts +7 -0
  63. package/dist/test-utils/build-mock-claim-change.d.ts +2 -0
  64. package/dist/test-utils/build-mock-file-item-change.d.ts +2 -0
  65. package/dist/test-utils/build-mock-lever-change.d.ts +2 -0
  66. package/dist/test-utils/build-mock-new-id.d.ts +2 -0
  67. package/dist/test-utils/build-mock-note-change.d.ts +2 -0
  68. package/dist/test-utils/build-mock-pause-change.d.ts +2 -0
  69. package/dist/test-utils/build-mock-pull-request-change.d.ts +8 -0
  70. package/dist/test-utils/build-mock-relation-change.d.ts +7 -0
  71. package/dist/test-utils/build-mock-running-reading.d.ts +6 -0
  72. package/dist/test-utils/build-mock-settle-change.d.ts +7 -0
  73. package/dist/test-utils/build-mock-start-change.d.ts +2 -0
  74. package/dist/test-utils/claim-store-attempt-reader-cases.d.ts +2 -0
  75. package/dist/test-utils/claim-store-claim-cases.d.ts +2 -0
  76. package/dist/test-utils/claim-store-close-cases.d.ts +2 -0
  77. package/dist/test-utils/claim-store-contract.d.ts +2 -0
  78. package/dist/test-utils/claim-store-copy-cases.d.ts +2 -0
  79. package/dist/test-utils/claim-store-exclusive-cases.d.ts +2 -0
  80. package/dist/test-utils/claim-store-guard-cases.d.ts +2 -0
  81. package/dist/test-utils/claim-store-item-reader-cases.d.ts +2 -0
  82. package/dist/test-utils/claim-store-outbox-cases.d.ts +2 -0
  83. package/dist/test-utils/claim-store-race-cases.d.ts +2 -0
  84. package/dist/test-utils/claim-store-rollback-cases.d.ts +2 -0
  85. package/dist/test-utils/claim-store-seat-cases.d.ts +2 -0
  86. package/dist/test-utils/claim-store-session-cases.d.ts +2 -0
  87. package/dist/test-utils/collect-memory-limit-fills.d.ts +3 -0
  88. package/dist/test-utils/compare-text.d.ts +1 -0
  89. package/dist/test-utils/create-fake-backoff.d.ts +2 -0
  90. package/dist/test-utils/create-fake-clock.d.ts +5 -0
  91. package/dist/test-utils/create-fake-fact-sink.d.ts +8 -0
  92. package/dist/test-utils/create-fake-forge.d.ts +17 -0
  93. package/dist/test-utils/create-fake-worker.d.ts +42 -0
  94. package/dist/test-utils/create-memory-claim-store.d.ts +2 -0
  95. package/dist/test-utils/create-test-dispatch.d.ts +46 -0
  96. package/dist/test-utils/forge-contract.d.ts +15 -0
  97. package/dist/test-utils/is-same-held-seat.d.ts +2 -0
  98. package/dist/test-utils/types.d.ts +19 -0
  99. package/dist/test-utils/worker-contract.d.ts +14 -0
  100. package/dist/timeouts.d.ts +2 -0
  101. package/dist/types.d.ts +13 -0
  102. package/package.json +15 -2
  103. package/src/attempts/attempt-machine.ts +147 -0
  104. package/src/attempts/attempt-moves.ts +218 -0
  105. package/src/attempts/bind-attempt-session.ts +61 -0
  106. package/src/attempts/build-attempt-change.ts +540 -0
  107. package/src/attempts/build-attempt-fact.ts +135 -0
  108. package/src/attempts/end-item-attempts.ts +95 -0
  109. package/src/attempts/is-same-guard.ts +22 -0
  110. package/src/attempts/pick-call-attempt.ts +32 -0
  111. package/src/attempts/stop-stray-session.ts +48 -0
  112. package/src/attempts/types.ts +231 -0
  113. package/src/attempts/write-attempt-move.ts +41 -0
  114. package/src/attempts/write-session-bind.ts +47 -0
  115. package/src/claims/build-snapshot-hash.ts +9 -0
  116. package/src/claims/claim-next.ts +306 -0
  117. package/src/claims/pick-kept-session.ts +41 -0
  118. package/src/claims/request-wake.ts +17 -0
  119. package/src/claims/resume-claim.ts +56 -0
  120. package/src/claims/start-claim.ts +99 -0
  121. package/src/claims/types.ts +67 -0
  122. package/src/closeouts/build-settle-plans.ts +173 -0
  123. package/src/closeouts/close-out-attempt.ts +156 -0
  124. package/src/closeouts/effect-handlers.ts +232 -0
  125. package/src/closeouts/pick-settlement.ts +80 -0
  126. package/src/closeouts/settle-attempt.ts +161 -0
  127. package/src/closeouts/types.ts +87 -0
  128. package/src/index.ts +61 -0
  129. package/src/notices/constants.ts +7 -0
  130. package/src/notices/create-null-notifier.ts +6 -0
  131. package/src/notices/send-notices.ts +41 -0
  132. package/src/notices/types.ts +14 -0
  133. package/src/outbox/build-backoff-ms.ts +14 -0
  134. package/src/outbox/build-initial-sender-state.ts +14 -0
  135. package/src/outbox/build-outbox-status.ts +43 -0
  136. package/src/outbox/constants.ts +15 -0
  137. package/src/outbox/measure-wire-bytes.ts +31 -0
  138. package/src/outbox/pick-sender-move.ts +37 -0
  139. package/src/outbox/run-sender-once.ts +174 -0
  140. package/src/outbox/take-batch.ts +35 -0
  141. package/src/outbox/types.ts +76 -0
  142. package/src/pull-requests/build-link-change.ts +95 -0
  143. package/src/pull-requests/build-state-fact.ts +39 -0
  144. package/src/pull-requests/collect-attempt-trailers.ts +20 -0
  145. package/src/pull-requests/collect-seen-state.ts +19 -0
  146. package/src/pull-requests/constants.ts +5 -0
  147. package/src/pull-requests/link-pull-request.ts +119 -0
  148. package/src/pull-requests/parse-pull-request-url.ts +30 -0
  149. package/src/pull-requests/types.ts +63 -0
  150. package/src/pull-requests/watch-pull-requests.ts +308 -0
  151. package/src/readings/act-on-reading.ts +318 -0
  152. package/src/readings/find-waiting-since.ts +46 -0
  153. package/src/readings/pick-reading-action.ts +315 -0
  154. package/src/readings/types.ts +98 -0
  155. package/src/sessions/build-keep-writes.ts +55 -0
  156. package/src/sessions/build-kept-clear.ts +12 -0
  157. package/src/sessions/forget-sessions.ts +106 -0
  158. package/src/sessions/is-kept-due.ts +27 -0
  159. package/src/sessions/resume-kept-session.ts +25 -0
  160. package/src/sessions/types.ts +39 -0
  161. package/src/test-utils/apply-memory-change.ts +252 -0
  162. package/src/test-utils/build-memory-reader.ts +364 -0
  163. package/src/test-utils/build-mock-bind-change.ts +43 -0
  164. package/src/test-utils/build-mock-claim-change.ts +52 -0
  165. package/src/test-utils/build-mock-file-item-change.ts +20 -0
  166. package/src/test-utils/build-mock-lever-change.ts +18 -0
  167. package/src/test-utils/build-mock-new-id.ts +12 -0
  168. package/src/test-utils/build-mock-note-change.ts +18 -0
  169. package/src/test-utils/build-mock-pause-change.ts +19 -0
  170. package/src/test-utils/build-mock-pull-request-change.ts +63 -0
  171. package/src/test-utils/build-mock-relation-change.ts +40 -0
  172. package/src/test-utils/build-mock-running-reading.ts +19 -0
  173. package/src/test-utils/build-mock-settle-change.ts +70 -0
  174. package/src/test-utils/build-mock-start-change.ts +38 -0
  175. package/src/test-utils/claim-store-attempt-reader-cases.ts +357 -0
  176. package/src/test-utils/claim-store-claim-cases.ts +314 -0
  177. package/src/test-utils/claim-store-close-cases.ts +95 -0
  178. package/src/test-utils/claim-store-contract.ts +28 -0
  179. package/src/test-utils/claim-store-copy-cases.ts +100 -0
  180. package/src/test-utils/claim-store-exclusive-cases.ts +243 -0
  181. package/src/test-utils/claim-store-guard-cases.ts +383 -0
  182. package/src/test-utils/claim-store-item-reader-cases.ts +471 -0
  183. package/src/test-utils/claim-store-outbox-cases.ts +281 -0
  184. package/src/test-utils/claim-store-race-cases.ts +150 -0
  185. package/src/test-utils/claim-store-rollback-cases.ts +175 -0
  186. package/src/test-utils/claim-store-seat-cases.ts +270 -0
  187. package/src/test-utils/claim-store-session-cases.ts +289 -0
  188. package/src/test-utils/collect-memory-limit-fills.ts +15 -0
  189. package/src/test-utils/compare-text.ts +8 -0
  190. package/src/test-utils/create-fake-backoff.ts +16 -0
  191. package/src/test-utils/create-fake-clock.ts +20 -0
  192. package/src/test-utils/create-fake-fact-sink.ts +74 -0
  193. package/src/test-utils/create-fake-forge.ts +117 -0
  194. package/src/test-utils/create-fake-worker.ts +303 -0
  195. package/src/test-utils/create-memory-claim-store.ts +163 -0
  196. package/src/test-utils/create-test-dispatch.ts +597 -0
  197. package/src/test-utils/forge-contract.ts +171 -0
  198. package/src/test-utils/is-same-held-seat.ts +11 -0
  199. package/src/test-utils/types.ts +23 -0
  200. package/src/test-utils/worker-contract.ts +192 -0
  201. package/src/timeouts.ts +17 -0
  202. package/src/types.ts +32 -0
@@ -0,0 +1,2 @@
1
+ import type { AttemptMove } from './types.ts';
2
+ export declare const attemptMoves: readonly AttemptMove[];
@@ -0,0 +1,14 @@
1
+ import type { AgentSessionId, ClaimStore, Instant, NewId, SessionFault } from '@boxxy/model';
2
+ import type { CallRef } from '../closeouts/types.ts';
3
+ export interface BindAttemptSessionInput {
4
+ readonly store: ClaimStore;
5
+ readonly call: CallRef;
6
+ readonly agentSession: AgentSessionId;
7
+ readonly missingSkills: readonly string[];
8
+ readonly now: Instant;
9
+ readonly newId: NewId;
10
+ }
11
+ export type BindAnswer = {
12
+ readonly kind: 'bound' | 'no-attempt' | 'not-current' | 'skill-missing';
13
+ } | SessionFault;
14
+ export declare function bindAttemptSession(input: BindAttemptSessionInput): Promise<BindAnswer>;
@@ -0,0 +1,73 @@
1
+ import type { ActorRef, AnyNewFact, AttemptRow, AttemptSessionRow, AttemptState, DecisionRow, Instant, ItemId, LeaseRow, NewId, PhaseName, SeatRelease, SeatTake } from '@boxxy/model';
2
+ import type { AttemptGuard } from './is-same-guard.ts';
3
+ import type { AttemptEvent, ClaimedEvent, MoveEvent } from './types.ts';
4
+ type AttemptWrite = {
5
+ readonly op: 'insert';
6
+ readonly table: 'attempts';
7
+ readonly row: AttemptRow;
8
+ } | {
9
+ readonly op: 'update';
10
+ readonly table: 'attempts';
11
+ readonly key: {
12
+ readonly id: AttemptRow['id'];
13
+ };
14
+ readonly expect: AttemptGuard;
15
+ readonly set: Partial<AttemptRow>;
16
+ } | {
17
+ readonly op: 'insert';
18
+ readonly table: 'attempt_sessions';
19
+ readonly row: AttemptSessionRow;
20
+ } | {
21
+ readonly op: 'insert';
22
+ readonly table: 'leases';
23
+ readonly row: LeaseRow;
24
+ } | {
25
+ readonly op: 'update';
26
+ readonly table: 'leases';
27
+ readonly key: Pick<LeaseRow, 'item' | 'phase' | 'gen'>;
28
+ readonly expect: Pick<LeaseRow, 'attempt' | 'releasedAt'>;
29
+ readonly set: Pick<LeaseRow, 'releasedAt'>;
30
+ } | {
31
+ readonly op: 'insert';
32
+ readonly table: 'decisions';
33
+ readonly row: DecisionRow;
34
+ } | {
35
+ readonly op: 'take-seats';
36
+ readonly take: SeatTake;
37
+ } | {
38
+ readonly op: 'release-seats';
39
+ readonly release: SeatRelease;
40
+ };
41
+ interface AttemptStoreChange {
42
+ readonly at: Instant;
43
+ readonly under: {
44
+ readonly item: ItemId;
45
+ readonly phase: PhaseName;
46
+ readonly gen: number;
47
+ readonly holdGen: number;
48
+ } | null;
49
+ readonly writes: readonly AttemptWrite[];
50
+ readonly facts: readonly AnyNewFact[];
51
+ }
52
+ export type AttemptChange = {
53
+ readonly kind: 'change';
54
+ readonly change: AttemptStoreChange;
55
+ } | {
56
+ readonly kind: 'not-allowed';
57
+ readonly state: AttemptState;
58
+ readonly event: AttemptEvent['kind'];
59
+ };
60
+ interface BuildAttemptChangeBase {
61
+ readonly actor: ActorRef;
62
+ readonly now: Instant;
63
+ readonly newId: NewId;
64
+ }
65
+ export type BuildAttemptChangeInput = BuildAttemptChangeBase & ({
66
+ readonly attempt: null;
67
+ readonly event: ClaimedEvent;
68
+ } | {
69
+ readonly attempt: AttemptRow;
70
+ readonly event: MoveEvent;
71
+ });
72
+ export declare function buildAttemptChange(input: BuildAttemptChangeInput): AttemptChange;
73
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { AnyNewFact, FactType } from '@boxxy/model';
2
+ import type { FactEnvelopeParts, MoveParts } from './types.ts';
3
+ export declare function buildAttemptFact(type: FactType, parts: MoveParts, envelope: FactEnvelopeParts): AnyNewFact;
@@ -0,0 +1,18 @@
1
+ import type { ActorRef, AnyNewFact, AttemptId, AttemptRow, Instant, NewId, RowWrite, StoreChange } from '@boxxy/model';
2
+ interface EndItemAttemptsInput {
3
+ readonly attempts: readonly AttemptRow[];
4
+ readonly actor: ActorRef;
5
+ readonly now: Instant;
6
+ readonly newId: NewId;
7
+ }
8
+ export interface EndedAttempts {
9
+ readonly under: NonNullable<StoreChange['under']> | null;
10
+ readonly writes: readonly RowWrite[];
11
+ readonly facts: readonly AnyNewFact[];
12
+ readonly ended: readonly {
13
+ readonly attempt: AttemptId;
14
+ readonly how: 'settled' | 'closing';
15
+ }[];
16
+ }
17
+ export declare function endItemAttempts(input: EndItemAttemptsInput): EndedAttempts;
18
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { AttemptRow } from '@boxxy/model';
2
+ declare const attemptGuardColumns: readonly ["state", "holdGen", "suspendRequestedAt", "wakeRequestedAt", "closing", "atcSession", "strayedAt", "sessionStoppedAt", "sessionForgottenAt"];
3
+ export type AttemptGuard = Pick<AttemptRow, (typeof attemptGuardColumns)[number]>;
4
+ export declare function isSameGuard(seen: Partial<AttemptGuard>, row: AttemptRow): boolean;
5
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { AttemptRow } from '@boxxy/model';
2
+ import type { CallRef } from '../closeouts/types.ts';
3
+ export type CallAttempt = {
4
+ readonly kind: 'attempt';
5
+ readonly attempt: AttemptRow;
6
+ } | {
7
+ readonly kind: 'refused';
8
+ readonly reason: 'no-attempt' | 'not-current';
9
+ };
10
+ export declare function pickCallAttempt(latest: AttemptRow | null, call: CallRef): CallAttempt;
@@ -0,0 +1,11 @@
1
+ import type { ActorRef, AttemptRow, ClaimStore, Instant, NewId, WorkerKind } from '@boxxy/model';
2
+ import type { MoveResult } from './types.ts';
3
+ export interface StopStraySessionInput {
4
+ readonly store: ClaimStore;
5
+ readonly worker: WorkerKind;
6
+ readonly attempt: AttemptRow;
7
+ readonly actor: ActorRef;
8
+ readonly now: Instant;
9
+ readonly newId: NewId;
10
+ }
11
+ export declare function stopStraySession(input: StopStraySessionInput): Promise<MoveResult | null>;
@@ -0,0 +1,142 @@
1
+ import type { ActorRef, AgentSessionId, AtcSessionId, AttemptId, AttemptRow, AttemptSessionRow, AttemptState, CallerIdentity, CloseOut, ClosingCause, CommitSha, DecisionRow, FactId, FactType, Instant, Minutes, NewId, ResolvedRecipe, RunnerId, SessionMode, StartPick, WakePick, WakeSource, WorkFacts } from '@boxxy/model';
2
+ export interface AttemptContext {
3
+ readonly mark: boolean;
4
+ readonly wakeRequested: boolean;
5
+ readonly mode: SessionMode;
6
+ readonly holdGen: number;
7
+ readonly closing: ClosingCause | null;
8
+ readonly hasSession: boolean;
9
+ readonly strayed: boolean;
10
+ readonly sessionStopped: boolean;
11
+ readonly sessionForgotten: boolean;
12
+ }
13
+ export type AttemptMachineEvent = {
14
+ readonly type: 'started';
15
+ readonly via: 'start' | 'reconcile';
16
+ } | {
17
+ readonly type: 'woken';
18
+ readonly overCap: boolean;
19
+ } | {
20
+ readonly type: 'settled';
21
+ readonly state: 'succeeded' | 'failed';
22
+ readonly sessionStopped: boolean;
23
+ } | {
24
+ readonly type: 'spawn-unanswered' | 'session-seen' | 'closed-out' | 'timed-out' | 'item-closed' | 'turn-ended' | 'stalled' | 'skill-missing' | 'usage-limited' | 'suspend-asked' | 'suspend-refused' | 'slept' | 'wake-requested' | 'resumed' | 'wake-refused' | 'stray-stopped' | 'session-forgotten';
25
+ };
26
+ export type MoveEffect = 'take-lease' | 'release-lease' | 'take-seats' | 'release-seats' | 'record-decision' | 'bind-session' | FactType;
27
+ export interface AttemptMove {
28
+ readonly event: AttemptMachineEvent['type'] | 'claimed';
29
+ readonly from: readonly AttemptState[];
30
+ readonly when?: (context: AttemptContext, event: AttemptMachineEvent) => boolean;
31
+ readonly to: AttemptState | 'same';
32
+ readonly effects: readonly MoveEffect[];
33
+ readonly context?: (context: AttemptContext, event: AttemptMachineEvent) => Partial<AttemptContext>;
34
+ }
35
+ export type DecisionDraft = Omit<DecisionRow, 'id' | 'attempt' | 'at'>;
36
+ export interface ClaimedEvent {
37
+ readonly kind: 'claimed';
38
+ readonly attempt: AttemptId;
39
+ readonly pick: StartPick;
40
+ readonly number: number;
41
+ readonly runner: RunnerId;
42
+ readonly leaseGen: number;
43
+ readonly recipe: Pick<ResolvedRecipe, 'hash' | 'rulesVersion'>;
44
+ readonly skillsRef: CommitSha | null;
45
+ readonly spawnRequest: AttemptRow['spawnRequest'];
46
+ readonly spawnRequestHash: AttemptRow['spawnRequestHash'];
47
+ readonly input: AttemptRow['input'];
48
+ readonly mode: SessionMode;
49
+ readonly caller: CallerIdentity | null;
50
+ readonly decision: DecisionDraft;
51
+ }
52
+ type SettledFact = WorkFacts['boxxy.attempt.settled'];
53
+ export type MoveEvent = {
54
+ readonly kind: 'started';
55
+ readonly via: 'start' | 'reconcile';
56
+ readonly atcSession: AtcSessionId;
57
+ readonly caller: CallerIdentity | null;
58
+ readonly resumeFallback: boolean;
59
+ } | {
60
+ readonly kind: 'spawn-unanswered';
61
+ readonly reason: string;
62
+ } | {
63
+ readonly kind: 'session-seen';
64
+ readonly row: AttemptSessionRow;
65
+ } | {
66
+ readonly kind: 'closed-out';
67
+ readonly closeOut: CloseOut;
68
+ readonly hash: NonNullable<AttemptRow['closeOutHash']>;
69
+ } | {
70
+ readonly kind: 'timed-out';
71
+ readonly afterMinutes: Minutes;
72
+ } | {
73
+ readonly kind: 'item-closed';
74
+ } | {
75
+ readonly kind: 'turn-ended';
76
+ } | {
77
+ readonly kind: 'stalled';
78
+ } | {
79
+ readonly kind: 'skill-missing';
80
+ } | {
81
+ readonly kind: 'usage-limited';
82
+ } | {
83
+ readonly kind: 'suspend-asked';
84
+ } | {
85
+ readonly kind: 'suspend-refused';
86
+ } | {
87
+ readonly kind: 'slept';
88
+ readonly idleSince: Instant;
89
+ readonly asked: boolean;
90
+ } | {
91
+ readonly kind: 'wake-requested';
92
+ readonly by: WakeSource;
93
+ } | {
94
+ readonly kind: 'woken';
95
+ readonly pick: WakePick;
96
+ readonly decision: DecisionDraft;
97
+ readonly overCap: boolean;
98
+ } | {
99
+ readonly kind: 'resumed';
100
+ readonly atcSession: AtcSessionId;
101
+ readonly caller: CallerIdentity | null;
102
+ } | {
103
+ readonly kind: 'wake-refused';
104
+ } | (Pick<SettledFact, 'state' | 'failure' | 'returnedOutcome' | 'sessionStopped' | 'criteria' | 'matched' | 'frictionDropped' | 'skippedEffects'> & {
105
+ readonly kind: 'settled';
106
+ readonly outcome: NonNullable<AttemptRow['outcome']>;
107
+ }) | {
108
+ readonly kind: 'stray-stopped';
109
+ } | {
110
+ readonly kind: 'session-forgotten';
111
+ };
112
+ export type AttemptEvent = ClaimedEvent | MoveEvent;
113
+ export interface MoveParts {
114
+ readonly before: AttemptRow;
115
+ readonly after: AttemptRow;
116
+ readonly event: AttemptEvent;
117
+ readonly decision: DecisionRow | null;
118
+ }
119
+ export interface MoveBase {
120
+ readonly actor: ActorRef;
121
+ readonly now: Instant;
122
+ readonly newId: NewId;
123
+ }
124
+ export type MoveResult = {
125
+ readonly kind: 'applied';
126
+ } | {
127
+ readonly kind: 'not-allowed';
128
+ } | {
129
+ readonly kind: 'refused';
130
+ readonly reason: string;
131
+ };
132
+ export interface SeenSession {
133
+ readonly atcSession: AtcSessionId;
134
+ readonly agentSession: AgentSessionId;
135
+ readonly keptFrom?: AttemptId | null;
136
+ }
137
+ export interface FactEnvelopeParts {
138
+ readonly id: FactId;
139
+ readonly actor: ActorRef;
140
+ readonly now: Instant;
141
+ }
142
+ export {};
@@ -0,0 +1,7 @@
1
+ import type { AttemptId, RowWrite, StoreTx } from '@boxxy/model';
2
+ import type { AttemptGuard } from './is-same-guard.ts';
3
+ import type { MoveBase, MoveEvent, MoveResult } from './types.ts';
4
+ export declare function writeAttemptMove(tx: StoreTx, attempt: AttemptId, event: MoveEvent, base: MoveBase & {
5
+ readonly also?: readonly RowWrite[];
6
+ readonly seen?: Partial<AttemptGuard>;
7
+ }): Promise<MoveResult>;
@@ -0,0 +1,3 @@
1
+ import type { AttemptRow, SessionFault, StoreTx } from '@boxxy/model';
2
+ import type { MoveBase, SeenSession } from './types.ts';
3
+ export declare function writeSessionBind(tx: StoreTx, attempt: AttemptRow, session: SeenSession, base: MoveBase): Promise<SessionFault | null>;
@@ -0,0 +1,2 @@
1
+ import type { PoolName, Snapshot, SnapshotHash } from '@boxxy/model';
2
+ export declare function buildSnapshotHash(snapshot: Snapshot, backoff: readonly PoolName[]): SnapshotHash;
@@ -0,0 +1,6 @@
1
+ import type { Claim } from '@boxxy/model';
2
+ import type { ClaimInput } from './types.ts';
3
+ export declare class ClaimRaceError extends Error {
4
+ constructor(result: string);
5
+ }
6
+ export declare function claimNext(input: ClaimInput): Promise<Claim | null>;
@@ -0,0 +1,9 @@
1
+ import type { AttemptRow, ItemView, KeptSession, PhaseName, Pipeline } from '@boxxy/model';
2
+ interface KeptSessionInput {
3
+ readonly item: ItemView;
4
+ readonly attempts: readonly AttemptRow[];
5
+ readonly pipeline: Pipeline;
6
+ readonly phase: PhaseName;
7
+ }
8
+ export declare function pickKeptSession(input: KeptSessionInput): KeptSession | null;
9
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { MoveResult } from '../attempts/types.ts';
2
+ import type { RequestWakeInput } from './types.ts';
3
+ export declare function requestWake(input: RequestWakeInput): Promise<MoveResult>;
@@ -0,0 +1,3 @@
1
+ import type { SessionFault } from '@boxxy/model';
2
+ import type { ResumeClaimInput } from './types.ts';
3
+ export declare function resumeClaim(input: ResumeClaimInput): Promise<SessionFault | null>;
@@ -0,0 +1,3 @@
1
+ import type { SessionFault } from '@boxxy/model';
2
+ import type { StartClaimInput } from './types.ts';
3
+ export declare function startClaim(input: StartClaimInput): Promise<SessionFault | null>;
@@ -0,0 +1,44 @@
1
+ import type { ActorRef, AttemptId, CapacityBackoff, Claim, ClaimStore, Instant, LoadedRules, NewId, RepoName, RunnerId, WakeSource, WorkerKind } from '@boxxy/model';
2
+ export interface SpawnSettings {
3
+ readonly target: string;
4
+ readonly repoPaths: ReadonlyMap<RepoName, string>;
5
+ readonly prompts: ReadonlyMap<string, string>;
6
+ }
7
+ export interface ClaimInput {
8
+ readonly store: ClaimStore;
9
+ readonly runner: RunnerId;
10
+ readonly rules: LoadedRules;
11
+ readonly now: Instant;
12
+ readonly newId: NewId;
13
+ readonly backoff: CapacityBackoff;
14
+ readonly spawn: SpawnSettings;
15
+ }
16
+ export interface StartClaimInput {
17
+ readonly store: ClaimStore;
18
+ readonly worker: WorkerKind;
19
+ readonly rules: LoadedRules;
20
+ readonly claim: Extract<Claim, {
21
+ kind: 'start';
22
+ }>;
23
+ readonly now: Instant;
24
+ readonly newId: NewId;
25
+ readonly backoff: CapacityBackoff;
26
+ }
27
+ export interface ResumeClaimInput {
28
+ readonly store: ClaimStore;
29
+ readonly worker: WorkerKind;
30
+ readonly claim: Extract<Claim, {
31
+ kind: 'wake';
32
+ }>;
33
+ readonly now: Instant;
34
+ readonly newId: NewId;
35
+ readonly backoff: CapacityBackoff;
36
+ }
37
+ export interface RequestWakeInput {
38
+ readonly store: ClaimStore;
39
+ readonly attempt: AttemptId;
40
+ readonly by: WakeSource;
41
+ readonly actor: ActorRef;
42
+ readonly now: Instant;
43
+ readonly newId: NewId;
44
+ }
@@ -0,0 +1,17 @@
1
+ import type { Effect, ItemId, ItemView, WorkFacts } from '@boxxy/model';
2
+ import type { EffectContext, EffectPlan } from './types.ts';
3
+ type SettledFact = WorkFacts['boxxy.attempt.settled'];
4
+ interface SettlePlansInput {
5
+ readonly effects: readonly Effect[];
6
+ readonly ctx: EffectContext;
7
+ readonly openIssues: readonly ItemView[];
8
+ readonly held: boolean;
9
+ }
10
+ export interface SettlePlans {
11
+ readonly plans: readonly EffectPlan[];
12
+ readonly criteria: SettledFact['criteria'];
13
+ readonly matched: readonly ItemId[];
14
+ readonly skippedEffects: SettledFact['skippedEffects'];
15
+ }
16
+ export declare function buildSettlePlans(input: SettlePlansInput): SettlePlans;
17
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { CloseOutAnswer } from '@boxxy/model';
2
+ import type { CloseOutInput } from './types.ts';
3
+ export declare function closeOutAttempt(input: CloseOutInput): Promise<CloseOutAnswer>;
@@ -0,0 +1,2 @@
1
+ import type { EffectHandlers } from './types.ts';
2
+ export declare const effectHandlers: EffectHandlers;
@@ -0,0 +1,14 @@
1
+ import type { AttemptRow, EngineOutcome, ForcedFailure, Instant, ItemView, LoadedRules, OutcomeName, Settlement } from '@boxxy/model';
2
+ interface SettlementInput {
3
+ readonly attempt: AttemptRow;
4
+ readonly item: ItemView;
5
+ readonly rules: LoadedRules;
6
+ readonly forced: ForcedFailure | null;
7
+ readonly now: Instant;
8
+ }
9
+ export interface PickedSettlement extends Omit<Settlement, 'outcome'> {
10
+ readonly outcome: OutcomeName | EngineOutcome;
11
+ readonly returnedOutcome: string | null;
12
+ }
13
+ export declare function pickSettlement(input: SettlementInput): PickedSettlement;
14
+ export {};
@@ -0,0 +1,3 @@
1
+ import type { MoveResult } from '../attempts/types.ts';
2
+ import type { SettleAttemptInput } from './types.ts';
3
+ export declare function settleAttempt(input: SettleAttemptInput): Promise<MoveResult>;
@@ -0,0 +1,50 @@
1
+ import type { ActorRef, AnyNewFact, AtcSessionId, AttemptId, AttemptRow, CallerIdentity, ClaimStore, Effect, ForcedFailure, Instant, ItemView, LoadedRules, NewId, RelationRow, RowWrite } from '@boxxy/model';
2
+ import type { AttemptGuard } from '../attempts/is-same-guard.ts';
3
+ export type EffectPlan = {
4
+ readonly kind: 'apply';
5
+ readonly effect: Effect;
6
+ readonly writes: readonly RowWrite[];
7
+ readonly facts: readonly AnyNewFact[];
8
+ } | {
9
+ readonly kind: 'skip';
10
+ readonly effect: Effect;
11
+ readonly reason: string;
12
+ };
13
+ export interface EffectContext {
14
+ readonly attempt: AttemptRow;
15
+ readonly item: ItemView;
16
+ readonly rules: LoadedRules;
17
+ readonly relations: readonly RelationRow[];
18
+ readonly actor: ActorRef;
19
+ readonly now: Instant;
20
+ readonly newId: NewId;
21
+ }
22
+ export type EffectHandlers = {
23
+ readonly [Kind in Effect['kind']]: (effect: Extract<Effect, {
24
+ kind: Kind;
25
+ }>, ctx: EffectContext) => EffectPlan;
26
+ };
27
+ export interface SettleAttemptInput {
28
+ readonly store: ClaimStore;
29
+ readonly attempt: AttemptId;
30
+ readonly forced: ForcedFailure | null;
31
+ readonly sessionStopped: boolean;
32
+ readonly seen?: Partial<AttemptGuard>;
33
+ readonly rules: LoadedRules;
34
+ readonly actor: ActorRef;
35
+ readonly now: Instant;
36
+ readonly newId: NewId;
37
+ }
38
+ export interface CallRef {
39
+ readonly attempt: AttemptId;
40
+ readonly session: AtcSessionId;
41
+ readonly caller: CallerIdentity;
42
+ }
43
+ export interface CloseOutInput {
44
+ readonly store: ClaimStore;
45
+ readonly call: CallRef;
46
+ readonly body: unknown;
47
+ readonly rules: LoadedRules;
48
+ readonly now: Instant;
49
+ readonly newId: NewId;
50
+ }
package/dist/index.d.ts CHANGED
@@ -1 +1,39 @@
1
+ export { bindAttemptSession } from './attempts/bind-attempt-session.ts';
2
+ export type { BindAnswer, BindAttemptSessionInput } from './attempts/bind-attempt-session.ts';
3
+ export { endItemAttempts } from './attempts/end-item-attempts.ts';
4
+ export type { EndedAttempts } from './attempts/end-item-attempts.ts';
5
+ export { pickCallAttempt } from './attempts/pick-call-attempt.ts';
6
+ export type { CallAttempt } from './attempts/pick-call-attempt.ts';
7
+ export { stopStraySession } from './attempts/stop-stray-session.ts';
8
+ export type { StopStraySessionInput } from './attempts/stop-stray-session.ts';
9
+ export type { MoveResult } from './attempts/types.ts';
10
+ export { ClaimRaceError, claimNext } from './claims/claim-next.ts';
11
+ export { requestWake } from './claims/request-wake.ts';
12
+ export { resumeClaim } from './claims/resume-claim.ts';
13
+ export { startClaim } from './claims/start-claim.ts';
14
+ export type { ClaimInput, RequestWakeInput, ResumeClaimInput, SpawnSettings, StartClaimInput, } from './claims/types.ts';
15
+ export { closeOutAttempt } from './closeouts/close-out-attempt.ts';
16
+ export { settleAttempt } from './closeouts/settle-attempt.ts';
17
+ export type { CallRef, CloseOutInput, EffectPlan, SettleAttemptInput } from './closeouts/types.ts';
18
+ export { noticeLimits } from './notices/constants.ts';
19
+ export { createNullNotifier } from './notices/create-null-notifier.ts';
20
+ export { sendNotices } from './notices/send-notices.ts';
21
+ export type { NoticeReport, SendNoticesInput } from './notices/types.ts';
1
22
  export { packageName } from './package-name.ts';
23
+ export { buildInitialSenderState } from './outbox/build-initial-sender-state.ts';
24
+ export { buildOutboxStatus } from './outbox/build-outbox-status.ts';
25
+ export { outboxLimits } from './outbox/constants.ts';
26
+ export { runSenderOnce } from './outbox/run-sender-once.ts';
27
+ export type { OutboxLimits, SenderDeps, SenderState, SenderStep, SenderTurn, } from './outbox/types.ts';
28
+ export { actOnReading } from './readings/act-on-reading.ts';
29
+ export { findWaitingSince } from './readings/find-waiting-since.ts';
30
+ export { pickReadingAction } from './readings/pick-reading-action.ts';
31
+ export type { ActOnReadingInput, ReadingAction, ReadingInput } from './readings/types.ts';
32
+ export { forgetSessions } from './sessions/forget-sessions.ts';
33
+ export type { ForgetReport, ForgetSessionsInput } from './sessions/types.ts';
34
+ export { timeouts } from './timeouts.ts';
35
+ export type { DispatchTimeouts } from './types.ts';
36
+ export { linkPullRequest } from './pull-requests/link-pull-request.ts';
37
+ export { parsePullRequestUrl } from './pull-requests/parse-pull-request-url.ts';
38
+ export type { LinkPullRequestInput, LinkPullRequestResult, WatchPullRequestsInput, WatchReport, } from './pull-requests/types.ts';
39
+ export { watchPullRequests } from './pull-requests/watch-pull-requests.ts';
@@ -0,0 +1,4 @@
1
+ export declare const noticeLimits: {
2
+ readonly maxTries: 5;
3
+ readonly readRows: 200;
4
+ };
@@ -0,0 +1,2 @@
1
+ import type { Notifier } from '@boxxy/model';
2
+ export declare function createNullNotifier(): Notifier;
@@ -0,0 +1,2 @@
1
+ import type { NoticeReport, SendNoticesInput } from './types.ts';
2
+ export declare function sendNotices(input: SendNoticesInput): Promise<NoticeReport>;
@@ -0,0 +1,11 @@
1
+ import type { ClaimStore, Instant, Notifier } from '@boxxy/model';
2
+ export interface SendNoticesInput {
3
+ readonly store: ClaimStore;
4
+ readonly notifier: Notifier;
5
+ readonly now: Instant;
6
+ }
7
+ export interface NoticeReport {
8
+ readonly sent: number;
9
+ readonly failed: number;
10
+ readonly stuck: number;
11
+ }
@@ -0,0 +1,2 @@
1
+ import type { OutboxLimits } from './types.ts';
2
+ export declare function buildBackoffMs(retries: number, limits: OutboxLimits, random: number): number;
@@ -0,0 +1,2 @@
1
+ import type { SenderState } from './types.ts';
2
+ export declare function buildInitialSenderState(): SenderState;
@@ -0,0 +1,15 @@
1
+ import type { Instant, OutboxStatus } from '@boxxy/model';
2
+ import type { SenderState } from './types.ts';
3
+ interface OutboxStatusInput {
4
+ readonly sink: 'pepys' | 'none';
5
+ readonly state: SenderState;
6
+ readonly counts: {
7
+ readonly unsent: number;
8
+ readonly parked: number;
9
+ readonly oldestUnsentAt: Instant | null;
10
+ };
11
+ readonly now: Instant;
12
+ readonly isSending: boolean;
13
+ }
14
+ export declare function buildOutboxStatus(input: OutboxStatusInput): OutboxStatus;
15
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { OutboxLimits } from './types.ts';
2
+ export declare const outboxLimits: OutboxLimits;
@@ -0,0 +1,2 @@
1
+ import type { OutboxFact } from '@boxxy/model';
2
+ export declare function measureWireBytes(fact: OutboxFact): number;
@@ -0,0 +1,10 @@
1
+ import type { SinkAnswer } from '@boxxy/model';
2
+ import type { OutboxLimits, SenderMove } from './types.ts';
3
+ interface SenderMoveInput {
4
+ readonly answer: SinkAnswer;
5
+ readonly batchSize: number;
6
+ readonly parkRun: number;
7
+ readonly limits: OutboxLimits;
8
+ }
9
+ export declare function pickSenderMove(input: SenderMoveInput): SenderMove;
10
+ export {};
@@ -0,0 +1,2 @@
1
+ import type { SenderDeps, SenderState, SenderTurn } from './types.ts';
2
+ export declare function runSenderOnce(deps: SenderDeps, state: SenderState): Promise<SenderTurn>;
@@ -0,0 +1,3 @@
1
+ import type { OutboxFact } from '@boxxy/model';
2
+ import type { OutboxLimits, TakenBatch } from './types.ts';
3
+ export declare function takeBatch(rows: readonly OutboxFact[], limits: OutboxLimits): TakenBatch;