@usine/executor 0.2.1 → 0.3.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 (177) hide show
  1. package/README.md +115 -37
  2. package/dist/child-command.d.ts +4 -7
  3. package/dist/child-command.d.ts.map +1 -1
  4. package/dist/child-command.js +6 -12
  5. package/dist/child-command.js.map +1 -1
  6. package/dist/claude-login-lock.d.ts +8 -0
  7. package/dist/claude-login-lock.d.ts.map +1 -0
  8. package/dist/claude-login-lock.js +9 -0
  9. package/dist/claude-login-lock.js.map +1 -0
  10. package/dist/credential-environment.d.ts +20 -0
  11. package/dist/credential-environment.d.ts.map +1 -0
  12. package/dist/credential-environment.js +20 -0
  13. package/dist/credential-environment.js.map +1 -0
  14. package/dist/durable-session.d.ts +63 -0
  15. package/dist/durable-session.d.ts.map +1 -0
  16. package/dist/durable-session.js +491 -0
  17. package/dist/durable-session.js.map +1 -0
  18. package/dist/exe-dev/commands.d.ts +23 -13
  19. package/dist/exe-dev/commands.d.ts.map +1 -1
  20. package/dist/exe-dev/commands.js +11 -57
  21. package/dist/exe-dev/commands.js.map +1 -1
  22. package/dist/exe-dev/exe-dev.d.ts +9 -3
  23. package/dist/exe-dev/exe-dev.d.ts.map +1 -1
  24. package/dist/exe-dev/exe-dev.js +53 -128
  25. package/dist/exe-dev/exe-dev.js.map +1 -1
  26. package/dist/exe-dev/grants.d.ts.map +1 -1
  27. package/dist/exe-dev/grants.js +35 -15
  28. package/dist/exe-dev/grants.js.map +1 -1
  29. package/dist/exe-dev/model.d.ts +15 -19
  30. package/dist/exe-dev/model.d.ts.map +1 -1
  31. package/dist/exe-dev/model.js +9 -12
  32. package/dist/exe-dev/model.js.map +1 -1
  33. package/dist/exe-dev/preflight.d.ts +8 -4
  34. package/dist/exe-dev/preflight.d.ts.map +1 -1
  35. package/dist/exe-dev/preflight.js +23 -33
  36. package/dist/exe-dev/preflight.js.map +1 -1
  37. package/dist/executor.d.ts +140 -41
  38. package/dist/executor.d.ts.map +1 -1
  39. package/dist/executor.js +90 -19
  40. package/dist/executor.js.map +1 -1
  41. package/dist/guard.d.ts +57 -7
  42. package/dist/guard.d.ts.map +1 -1
  43. package/dist/guard.js +273 -59
  44. package/dist/guard.js.map +1 -1
  45. package/dist/harness-preflight.d.ts +25 -4
  46. package/dist/harness-preflight.d.ts.map +1 -1
  47. package/dist/harness-preflight.js +25 -29
  48. package/dist/harness-preflight.js.map +1 -1
  49. package/dist/keyed-lock.d.ts +2 -3
  50. package/dist/keyed-lock.d.ts.map +1 -1
  51. package/dist/keyed-lock.js +2 -3
  52. package/dist/keyed-lock.js.map +1 -1
  53. package/dist/leftovers.d.ts +9 -0
  54. package/dist/leftovers.d.ts.map +1 -0
  55. package/dist/leftovers.js +14 -0
  56. package/dist/leftovers.js.map +1 -0
  57. package/dist/local/credentials.d.ts +21 -0
  58. package/dist/local/credentials.d.ts.map +1 -0
  59. package/dist/local/credentials.js +39 -0
  60. package/dist/local/credentials.js.map +1 -0
  61. package/dist/local/leftovers.d.ts +8 -0
  62. package/dist/local/leftovers.d.ts.map +1 -0
  63. package/dist/local/leftovers.js +23 -0
  64. package/dist/local/leftovers.js.map +1 -0
  65. package/dist/local/local.d.ts +16 -10
  66. package/dist/local/local.d.ts.map +1 -1
  67. package/dist/local/local.js +163 -129
  68. package/dist/local/local.js.map +1 -1
  69. package/dist/memory-preflight.d.ts +25 -0
  70. package/dist/memory-preflight.d.ts.map +1 -0
  71. package/dist/memory-preflight.js +83 -0
  72. package/dist/memory-preflight.js.map +1 -0
  73. package/dist/pre-push-hook.d.ts +20 -0
  74. package/dist/pre-push-hook.d.ts.map +1 -0
  75. package/dist/pre-push-hook.js +33 -0
  76. package/dist/pre-push-hook.js.map +1 -0
  77. package/dist/prepared-attempt.d.ts +33 -3
  78. package/dist/prepared-attempt.d.ts.map +1 -1
  79. package/dist/prepared-attempt.js +109 -31
  80. package/dist/prepared-attempt.js.map +1 -1
  81. package/dist/provision.d.ts +77 -14
  82. package/dist/provision.d.ts.map +1 -1
  83. package/dist/provision.js +357 -55
  84. package/dist/provision.js.map +1 -1
  85. package/dist/remote/commands.d.ts +51 -0
  86. package/dist/remote/commands.d.ts.map +1 -0
  87. package/dist/remote/commands.js +94 -0
  88. package/dist/remote/commands.js.map +1 -0
  89. package/dist/remote/leftovers.d.ts +14 -0
  90. package/dist/remote/leftovers.d.ts.map +1 -0
  91. package/dist/remote/leftovers.js +22 -0
  92. package/dist/remote/leftovers.js.map +1 -0
  93. package/dist/remote/liveness.d.ts +33 -0
  94. package/dist/remote/liveness.d.ts.map +1 -0
  95. package/dist/remote/liveness.js +194 -0
  96. package/dist/remote/liveness.js.map +1 -0
  97. package/dist/remote/machine.d.ts +64 -0
  98. package/dist/remote/machine.d.ts.map +1 -0
  99. package/dist/remote/machine.js +2 -0
  100. package/dist/remote/machine.js.map +1 -0
  101. package/dist/remote/remote.d.ts +24 -0
  102. package/dist/remote/remote.d.ts.map +1 -0
  103. package/dist/remote/remote.js +308 -0
  104. package/dist/remote/remote.js.map +1 -0
  105. package/dist/remote/sweep.d.ts +15 -0
  106. package/dist/remote/sweep.d.ts.map +1 -0
  107. package/dist/remote/sweep.js +116 -0
  108. package/dist/remote/sweep.js.map +1 -0
  109. package/dist/renewable-credential.d.ts +17 -0
  110. package/dist/renewable-credential.d.ts.map +1 -0
  111. package/dist/renewable-credential.js +58 -0
  112. package/dist/renewable-credential.js.map +1 -0
  113. package/dist/salvage.d.ts +30 -0
  114. package/dist/salvage.d.ts.map +1 -0
  115. package/dist/salvage.js +104 -0
  116. package/dist/salvage.js.map +1 -0
  117. package/dist/ssh/credentials.d.ts +40 -0
  118. package/dist/ssh/credentials.d.ts.map +1 -0
  119. package/dist/ssh/credentials.js +83 -0
  120. package/dist/ssh/credentials.js.map +1 -0
  121. package/dist/ssh/gateway/admin.d.ts +45 -0
  122. package/dist/ssh/gateway/admin.d.ts.map +1 -0
  123. package/dist/ssh/gateway/admin.js +129 -0
  124. package/dist/ssh/gateway/admin.js.map +1 -0
  125. package/dist/ssh/gateway/attachments.d.ts +22 -0
  126. package/dist/ssh/gateway/attachments.d.ts.map +1 -0
  127. package/dist/ssh/gateway/attachments.js +154 -0
  128. package/dist/ssh/gateway/attachments.js.map +1 -0
  129. package/dist/ssh/gateway/environment.d.ts +52 -0
  130. package/dist/ssh/gateway/environment.d.ts.map +1 -0
  131. package/dist/ssh/gateway/environment.js +78 -0
  132. package/dist/ssh/gateway/environment.js.map +1 -0
  133. package/dist/ssh/gateway/forward.d.ts +74 -0
  134. package/dist/ssh/gateway/forward.d.ts.map +1 -0
  135. package/dist/ssh/gateway/forward.js +247 -0
  136. package/dist/ssh/gateway/forward.js.map +1 -0
  137. package/dist/ssh/gateway/preflight.d.ts +28 -0
  138. package/dist/ssh/gateway/preflight.d.ts.map +1 -0
  139. package/dist/ssh/gateway/preflight.js +234 -0
  140. package/dist/ssh/gateway/preflight.js.map +1 -0
  141. package/dist/ssh/model.d.ts +65 -0
  142. package/dist/ssh/model.d.ts.map +1 -0
  143. package/dist/ssh/model.js +2 -0
  144. package/dist/ssh/model.js.map +1 -0
  145. package/dist/ssh/preflight.d.ts +16 -0
  146. package/dist/ssh/preflight.d.ts.map +1 -0
  147. package/dist/ssh/preflight.js +47 -0
  148. package/dist/ssh/preflight.js.map +1 -0
  149. package/dist/ssh/ssh.d.ts +20 -0
  150. package/dist/ssh/ssh.d.ts.map +1 -0
  151. package/dist/ssh/ssh.js +78 -0
  152. package/dist/ssh/ssh.js.map +1 -0
  153. package/dist/ssh/workers.d.ts +53 -0
  154. package/dist/ssh/workers.d.ts.map +1 -0
  155. package/dist/ssh/workers.js +173 -0
  156. package/dist/ssh/workers.js.map +1 -0
  157. package/package.json +12 -4
  158. package/dist/exe-dev/channel.d.ts +0 -12
  159. package/dist/exe-dev/channel.d.ts.map +0 -1
  160. package/dist/exe-dev/channel.js +0 -42
  161. package/dist/exe-dev/channel.js.map +0 -1
  162. package/dist/exe-dev/shell.d.ts +0 -12
  163. package/dist/exe-dev/shell.d.ts.map +0 -1
  164. package/dist/exe-dev/shell.js +0 -31
  165. package/dist/exe-dev/shell.js.map +0 -1
  166. package/dist/exe-dev/sweep.d.ts +0 -10
  167. package/dist/exe-dev/sweep.d.ts.map +0 -1
  168. package/dist/exe-dev/sweep.js +0 -117
  169. package/dist/exe-dev/sweep.js.map +0 -1
  170. package/dist/invalid-frame.d.ts +0 -17
  171. package/dist/invalid-frame.d.ts.map +0 -1
  172. package/dist/invalid-frame.js +0 -111
  173. package/dist/invalid-frame.js.map +0 -1
  174. package/dist/run-host-session.d.ts +0 -27
  175. package/dist/run-host-session.d.ts.map +0 -1
  176. package/dist/run-host-session.js +0 -303
  177. package/dist/run-host-session.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-push-hook.js","sourceRoot":"","sources":["../src/pre-push-hook.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC;;;GAGG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG,aAAa,CAAC;AAEtD,MAAM,KAAK,GAAG,CAAC,KAAa,EAAU,EAAE,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;AAE/E,+FAA+F;AAC/F,MAAM,WAAW,GAAG,CAAC,IAAc,EAAU,EAAE,CAC7C,qCAAqC,IAAI,wEAAwE,CAAC;AAEpH;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAc,EAAU,EAAE,CACpD,mBAAmB,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC;AAE9D;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,WAA6C,EAC7C,KAA4B,EACJ,EAAE,CAC1B,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE;IAClB,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,WAAW,EAAE,CAAC;IAClC,MAAM,EAAE,CAAC,SAAS,EAAE,EAAE;QACpB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC;QAC1D,OAAO;YACL,GAAG,WAAW;YACd,gBAAgB,EAAE,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;YACnC,CAAC,kBAAkB,KAAK,EAAE,CAAC,EAAE,gBAAgB;YAC7C,CAAC,oBAAoB,KAAK,EAAE,CAAC,EAAE,SAAS;SACzC,CAAC;IACJ,CAAC;CACF,CAAC,CAAC"}
@@ -1,5 +1,35 @@
1
- import { Effect, Scope } from "effect";
1
+ import type { AttemptId } from "@usine/core/attempt";
2
+ import * as AttemptChannel from "@usine/core/attempt/channel";
3
+ import { type AttemptFailure, InfraFailure, type RunawayCeiling } from "@usine/core/attempt/failure";
4
+ import { type Duration, Effect, Scope } from "effect";
2
5
  import type { CheckoutRequest, ExecutorError, PreparedAttempt } from "./executor.ts";
3
- /** Owns partial preparation and the run host in one child scope, released at the Attempt's end. */
4
- export declare const prepareAttempt: (acquire: Effect.Effect<PreparedAttempt, ExecutorError, Scope.Scope>, request: CheckoutRequest) => Effect.Effect<PreparedAttempt, ExecutorError, Scope.Scope>;
6
+ import { type AttemptGuardSeed } from "./guard.ts";
7
+ import type { ProvisionedWorktree } from "./provision.ts";
8
+ export type AttemptStop = {
9
+ readonly _tag: "Cancel";
10
+ } | {
11
+ readonly _tag: "Runaway";
12
+ readonly ceiling: RunawayCeiling;
13
+ };
14
+ /** The result of an executor's `acquire`: the prepared Attempt and its salvage handles. */
15
+ export interface AcquiredAttempt extends PreparedAttempt {
16
+ readonly salvaged: ProvisionedWorktree["salvaged"];
17
+ readonly recordSalvage: ProvisionedWorktree["recordSalvage"];
18
+ }
19
+ /**
20
+ * Returns `prepare` and `cancel` for one executor's Attempts, tracked from preparation until
21
+ * release so `cancel` works at any stage. `cancel`, a failed `prepare`, and `launch` each return
22
+ * only after the Attempt's resources are released.
23
+ *
24
+ * - `stop`: stops the live session and returns whether one existed.
25
+ * - `registered`: completes when the launch registers the live session.
26
+ * - `warnParent`: sends the guard's warning steer; can wait for the parent's channel.
27
+ * - `guardSeed`: returns the guard's initial state. If it fails, the launch records salvage,
28
+ * releases the resources, and fails.
29
+ * - `recordUnsupervised`: persists the guard's unsupervised time for a later reattachment.
30
+ */
31
+ export declare const preparedAttemptsFor: (stop: (attemptId: AttemptId, reason: AttemptStop) => Effect.Effect<boolean, ExecutorError>, warnParent: (attemptId: AttemptId, intervention: AttemptChannel.Intervention) => Effect.Effect<void, AttemptFailure>, registered: (attemptId: AttemptId) => Effect.Effect<void>, guardSeed: (request: CheckoutRequest, io: AttemptChannel.Sink) => Effect.Effect<AttemptGuardSeed, InfraFailure>, recordUnsupervised: (attemptId: AttemptId, unsupervised: Duration.Duration) => Effect.Effect<void, AttemptFailure>) => Effect.Effect<{
32
+ prepare: (acquire: Effect.Effect<AcquiredAttempt, ExecutorError, Scope.Scope>, request: CheckoutRequest) => Effect.Effect<PreparedAttempt, ExecutorError, Scope.Scope>;
33
+ cancel: (attemptId: string & import("effect/Brand").Brand<"AttemptId">) => Effect.Effect<void, import("./executor.ts").CredentialUnavailableError | import("./executor.ts").ExecutorOperationError | import("./executor.ts").WorkerCapabilityError, never>;
34
+ }, never, never>;
5
35
  //# sourceMappingURL=prepared-attempt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepared-attempt.d.ts","sourceRoot":"","sources":["../src/prepared-attempt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAoB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGrF,mGAAmG;AACnG,eAAO,MAAM,cAAc,YAChB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,WAC1D,eAAe,KACvB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAqCzD,CAAC"}
1
+ {"version":3,"file":"prepared-attempt.d.ts","sourceRoot":"","sources":["../src/prepared-attempt.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,cAAc,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EACL,KAAK,cAAc,EACnB,YAAY,EACZ,KAAK,cAAc,EACpB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAmB,KAAK,QAAQ,EAAE,MAAM,EAAoB,KAAK,EAAE,MAAM,QAAQ,CAAC;AACzF,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,MAAM,WAAW,GACnB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GAC3B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CAAC;AAEnE,2FAA2F;AAC3F,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC,UAAU,CAAC,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,mBAAmB,CAAC,eAAe,CAAC,CAAC;CAC9D;AASD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,mBAAmB,SACxB,CAAC,SAAS,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,cAC9E,CACV,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,cAAc,CAAC,YAAY,KACtC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,cAC5B,CAAC,SAAS,EAAE,SAAS,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAC9C,CACT,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,cAAc,CAAC,IAAI,KACpB,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC,sBAC9B,CAClB,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,QAAQ,CAAC,QAAQ,KAC5B,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC;uBAwB3B,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,WAC1D,eAAe,KACvB,MAAM,CAAC,MAAM,CAAC,eAAe,EAAE,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC;;gBAoH7D,CAAC"}
@@ -1,32 +1,110 @@
1
- import { InfraFailure } from "@usine/core/attempt/failure";
2
- import { Effect, Exit, Fiber, Ref, Scope } from "effect";
3
- import { withAttemptGuard } from "./guard.js";
4
- /** Owns partial preparation and the run host in one child scope, released at the Attempt's end. */
5
- export const prepareAttempt = (acquire, request) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
6
- const scope = yield* Scope.fork(yield* Effect.scope);
7
- // acquireRelease masks acquisition by default in Effect rc.111. Only the
8
- // ownership transfer is masked here; clone, fetch, and lock waits must stop
9
- // promptly. Each acquiring implementation registers its own finalizers.
10
- const prepared = yield* restore(acquire).pipe(Scope.provide(scope), Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause))));
11
- const unavailable = yield* Ref.make(false);
12
- yield* Scope.addFinalizer(scope, Ref.set(unavailable, true));
13
- return {
14
- workspace: prepared.workspace,
15
- launch: Effect.fn("PreparedAttempt.launch")(function* (io) {
16
- const attemptId = prepared.workspace.spec.attemptId;
17
- yield* Effect.annotateCurrentSpan({ attemptId, worker: prepared.workspace.worker });
18
- if (yield* Ref.getAndSet(unavailable, true)) {
19
- yield* Effect.logWarning("Attempt was already launched or released", { attemptId });
20
- return yield* new InfraFailure({
21
- message: `Attempt ${attemptId} was already launched or released`,
22
- cause: new Error("prepared Attempt is no longer available"),
23
- });
24
- }
25
- // Closing the owner's scope interrupts the session before checkout and
26
- // credential finalizers. Interrupting a caller waiting on join must also
27
- // stop that scoped fiber, so timeout/cancel completes the handshake first.
28
- return yield* Effect.acquireUseRelease(Effect.forkIn(withAttemptGuard(request, io, prepared.launch), scope), Fiber.join, Fiber.interrupt).pipe(Effect.onExit((exit) => Scope.close(scope, exit)));
29
- }),
30
- };
31
- }));
1
+ import * as AttemptChannel from "@usine/core/attempt/channel";
2
+ import { InfraFailure, } from "@usine/core/attempt/failure";
3
+ import { Cause, Deferred, Effect, Exit, Fiber, Ref, Scope } from "effect";
4
+ import { attemptGuard } from "./guard.js";
5
+ /**
6
+ * Returns `prepare` and `cancel` for one executor's Attempts, tracked from preparation until
7
+ * release so `cancel` works at any stage. `cancel`, a failed `prepare`, and `launch` each return
8
+ * only after the Attempt's resources are released.
9
+ *
10
+ * - `stop`: stops the live session and returns whether one existed.
11
+ * - `registered`: completes when the launch registers the live session.
12
+ * - `warnParent`: sends the guard's warning steer; can wait for the parent's channel.
13
+ * - `guardSeed`: returns the guard's initial state. If it fails, the launch records salvage,
14
+ * releases the resources, and fails.
15
+ * - `recordUnsupervised`: persists the guard's unsupervised time for a later reattachment.
16
+ */
17
+ export const preparedAttemptsFor = (stop, warnParent, registered, guardSeed, recordUnsupervised) => Effect.sync(() => {
18
+ const attempts = new Map();
19
+ const cancel = Effect.fn("PreparedAttempt.cancel")(function* (attemptId) {
20
+ yield* Effect.annotateCurrentSpan({ attemptId });
21
+ const active = attempts.get(attemptId);
22
+ if (active === undefined) {
23
+ yield* Effect.logDebug("Attempt cancellation was a no-op", { attemptId });
24
+ return;
25
+ }
26
+ yield* Ref.set(active.unavailable, true);
27
+ // With a live session, stops it so its terminal envelope and typed errors are kept. Before
28
+ // registration, closing the scope interrupts preparation or process spawn.
29
+ if (!(yield* stop(attemptId, { _tag: "Cancel" }))) {
30
+ yield* Effect.logInfo("Canceling Attempt before its channel is ready", { attemptId });
31
+ yield* active.release(Exit.void);
32
+ }
33
+ else {
34
+ yield* active.released;
35
+ }
36
+ }, Effect.uninterruptible);
37
+ /** Runs preparation and the live session in one child scope that closes when the Attempt ends. */
38
+ const prepare = (acquire, request) => Effect.uninterruptibleMask((restore) => Effect.gen(function* () {
39
+ const scope = yield* Scope.fork(yield* Effect.scope);
40
+ const unavailable = yield* Ref.make(false);
41
+ const released = yield* Deferred.make();
42
+ // Scope.close returns immediately when another fiber is already closing the scope, so the
43
+ // owner and a concurrent cancel both wait for `released`, set by the first-registered
44
+ // (last-run) finalizer.
45
+ const release = (exit) => Scope.close(scope, exit).pipe(Effect.andThen(Deferred.await(released)));
46
+ attempts.set(request.attemptId, {
47
+ unavailable,
48
+ release,
49
+ released: Deferred.await(released),
50
+ });
51
+ yield* Scope.addFinalizer(scope, Effect.suspend(() => {
52
+ attempts.delete(request.attemptId);
53
+ return Deferred.succeed(released, undefined);
54
+ }));
55
+ yield* Scope.addFinalizer(scope, Ref.set(unavailable, true));
56
+ // A separate child scope, so the acquiring fiber is interrupted before its resources are
57
+ // released.
58
+ const resources = yield* Scope.fork(scope);
59
+ const acquiring = yield* Effect.forkIn(Scope.provide(acquire, resources), scope);
60
+ const prepared = yield* restore(Fiber.join(acquiring)).pipe(Effect.onError((cause) => release(Exit.failCause(cause))));
61
+ /** Releases the Attempt's resources, then fails if its salvage couldn't be recorded. */
62
+ const releaseSalvaged = (exit) => release(exit).pipe(Effect.andThen(Effect.asVoid(prepared.salvaged)));
63
+ return {
64
+ workspace: prepared.workspace,
65
+ launch: Effect.fn("PreparedAttempt.launch")(function* (io) {
66
+ const attemptId = prepared.workspace.spec.attemptId;
67
+ yield* Effect.annotateCurrentSpan({ attemptId, worker: prepared.workspace.worker });
68
+ if (yield* Ref.getAndSet(unavailable, true)) {
69
+ yield* Effect.logWarning("Attempt was already launched or released", { attemptId });
70
+ return yield* new InfraFailure({
71
+ message: `Attempt ${attemptId} was already launched or released`,
72
+ cause: new Error("prepared attempt is no longer available"),
73
+ });
74
+ }
75
+ // If the seed can't be read, records salvage and releases the checkout without launching, so
76
+ // the Run's next Attempt starts from it. On interruption, such as process shutdown, the
77
+ // owner's scope handles the checkout.
78
+ const seed = yield* guardSeed(request, io).pipe(Effect.onExit((exit) => Exit.isSuccess(exit) || Cause.hasInterruptsOnly(exit.cause)
79
+ ? Effect.void
80
+ : Effect.logWarning("The Attempt's runaway guard cannot start; releasing its checkout without launching it", { attemptId }).pipe(Effect.andThen(prepared.recordSalvage(io.salvage)), Effect.andThen(releaseSalvaged(exit)))));
81
+ const guard = yield* attemptGuard({
82
+ attemptId,
83
+ maxAttemptMinutes: request.maxAttemptMinutes,
84
+ maxAttemptTokens: request.maxAttemptTokens,
85
+ warn: (message) => warnParent(attemptId, new AttemptChannel.Intervention({
86
+ operator: "engine",
87
+ target: new AttemptChannel.ParentTarget(),
88
+ action: new AttemptChannel.Steer({ message }),
89
+ })),
90
+ recordUnsupervised: (unsupervised) => recordUnsupervised(attemptId, unsupervised),
91
+ }, io, seed);
92
+ // Starts the clock only after the launch registers its session. A remote launch first waits
93
+ // for the Worker's liveness watch, and a seed with no time left could trip before there's a
94
+ // session to stop.
95
+ const tripped = registered(attemptId).pipe(Effect.andThen(guard.tripped), Effect.tapError(({ ceiling }) => stop(attemptId, { _tag: "Runaway", ceiling }).pipe(Effect.tapError((error) => Effect.logWarning("Could not stop the runaway Attempt", {
96
+ attemptId,
97
+ ceiling,
98
+ errorTag: error._tag,
99
+ })), Effect.ignore)));
100
+ yield* prepared.recordSalvage(io.salvage);
101
+ // Closing the owner's scope interrupts the session before the checkout and credential
102
+ // finalizers. acquireUseRelease interrupts the forked fiber when the caller waiting on join
103
+ // is interrupted.
104
+ return yield* Effect.acquireUseRelease(Effect.forkIn(Effect.raceFirst(prepared.launch(guard.sink), tripped), scope), Fiber.join, Fiber.interrupt).pipe(Effect.onExit((exit) => releaseSalvaged(exit)));
105
+ }),
106
+ };
107
+ }));
108
+ return { prepare, cancel };
109
+ });
32
110
  //# sourceMappingURL=prepared-attempt.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prepared-attempt.js","sourceRoot":"","sources":["../src/prepared-attempt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,mGAAmG;AACnG,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,OAAmE,EACnE,OAAwB,EACoC,EAAE,CAC9D,MAAM,CAAC,mBAAmB,CAAC,CAAC,OAAO,EAAE,EAAE,CACrC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrD,yEAAyE;IACzE,4EAA4E;IAC5E,wEAAwE;IACxE,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAC3C,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EACpB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CACrE,CAAC;IACF,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3C,KAAK,CAAC,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;IAE7D,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE;YACvD,MAAM,SAAS,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC;YACpD,KAAK,CAAC,CAAC,MAAM,CAAC,mBAAmB,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC;YACpF,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC5C,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,0CAA0C,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;gBACpF,OAAO,KAAK,CAAC,CAAC,IAAI,YAAY,CAAC;oBAC7B,OAAO,EAAE,WAAW,SAAS,mCAAmC;oBAChE,KAAK,EAAE,IAAI,KAAK,CAAC,yCAAyC,CAAC;iBAC5D,CAAC,CAAC;YACL,CAAC;YACD,uEAAuE;YACvE,yEAAyE;YACzE,2EAA2E;YAC3E,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,iBAAiB,CACpC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,EACpE,KAAK,CAAC,IAAI,EACV,KAAK,CAAC,SAAS,CAChB,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5D,CAAC,CAAC;KACuB,CAAC;AAC9B,CAAC,CAAC,CACH,CAAC"}
1
+ {"version":3,"file":"prepared-attempt.js","sourceRoot":"","sources":["../src/prepared-attempt.ts"],"names":[],"mappings":"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"}
@@ -1,14 +1,15 @@
1
+ import type { AttemptFailure } from "@usine/core/attempt/failure";
2
+ import * as AttemptChannel from "@usine/core/attempt/channel";
3
+ import { type AttemptRecovery, type AttemptSalvage, SalvagePushed } from "@usine/core/attempt/salvage";
1
4
  import { RepositoryName } from "@usine/core/repository";
2
- import { Effect } from "effect";
5
+ import { Effect, Option } from "effect";
3
6
  import { ExecutorOperationError, AttemptWorkspace, type CheckoutRequest } from "./executor.ts";
4
- export declare const safeSegment: (value: string) => string;
5
- /** The bare cache directory name for a repository under `repos/`, shared by every adapter. */
7
+ /** Returns the bare cache directory name for `repository` under `repos/`. */
6
8
  export declare const cacheDirectoryName: (repository: RepositoryName) => string;
7
9
  /**
8
- * Whether a `repos/` entry is one of our bare caches, decided by the name we
9
- * mint rather than by probing contents: a `HEAD` lookup fails with ENOTDIR on
10
- * a stray file, and a `.cloning` leftover or a tool's scratch directory must
11
- * never reach `git worktree prune`.
10
+ * Returns whether a `repos/` entry is a bare cache, by name only. Probing `HEAD` fails with
11
+ * ENOTDIR on a stray file, and a `.cloning` leftover or another tool's directory must never be
12
+ * passed to `git worktree prune`.
12
13
  */
13
14
  export declare const isCacheDirectoryName: (entry: string) => boolean;
14
15
  interface WorkspaceLayout {
@@ -16,14 +17,16 @@ interface WorkspaceLayout {
16
17
  readonly staging: string;
17
18
  readonly worktree: string;
18
19
  }
19
- /** The adapter-specific primitives; everything else about provisioning is shared. */
20
+ /** Executor-specific operations for the shared provisioning code. */
20
21
  export interface WorkspaceOps<E> {
21
22
  readonly ensureRoots: Effect.Effect<void, E>;
22
23
  readonly removePath: (operation: "prepare" | "cleanup", target: string) => Effect.Effect<void, E>;
23
24
  readonly cacheExists: Effect.Effect<boolean, E>;
24
- /** Atomically promote the finished staging clone to the cache path. */
25
+ /** Atomically moves the finished staging clone to the cache path. */
25
26
  readonly promoteStaging: Effect.Effect<void, E>;
26
27
  readonly git: (operation: "prepare" | "cleanup", args: ReadonlyArray<string>) => Effect.Effect<string, E>;
28
+ /** Writes `content` to `path` on the Worker's machine, creating its directory, and makes it executable. */
29
+ readonly writeExecutable: (path: string, content: string) => Effect.Effect<void, E>;
27
30
  }
28
31
  export interface ProvisionOptions<E> {
29
32
  readonly request: CheckoutRequest;
@@ -32,12 +35,72 @@ export interface ProvisionOptions<E> {
32
35
  readonly layout: WorkspaceLayout;
33
36
  readonly ops: WorkspaceOps<E>;
34
37
  }
38
+ export interface ProvisionedWorktree {
39
+ readonly workspace: AttemptWorkspace;
40
+ /** Waits for the workspace scope to close and returns the salvage, or `None` after a successful Attempt or a clean worktree. */
41
+ readonly salvaged: Effect.Effect<Option.Option<AttemptSalvage>, AttemptFailure>;
42
+ /** Sets the salvage sink; call before launch. If salvage isn't recorded, cleanup keeps the worktree on disk. */
43
+ readonly recordSalvage: (record: AttemptChannel.Sink["salvage"]) => Effect.Effect<void>;
44
+ /**
45
+ * Skips checkout removal when the scope closes, so a restart can reattach the parent task or
46
+ * repeat a harvest whose result was not stored.
47
+ */
48
+ readonly keepForReattach: Effect.Effect<void>;
49
+ /**
50
+ * The hooks directory for the children's git (`withGitHooks`), set only for a
51
+ * `permissions: read` Loop. If `None`, the repository's own hooks apply.
52
+ */
53
+ readonly gitHooks: Option.Option<string>;
54
+ }
55
+ interface ReleaseOptions<E> {
56
+ readonly request: CheckoutRequest;
57
+ readonly host: string;
58
+ readonly layout: Pick<WorkspaceLayout, "cache" | "worktree">;
59
+ readonly ops: Pick<WorkspaceOps<E>, "cacheExists" | "git" | "removePath">;
60
+ }
61
+ /**
62
+ * Clones into a staging directory and promotes it on success, fetches the requested revision,
63
+ * and checks out a detached worktree at the resolved commit, applying the previous Attempt's
64
+ * salvage if the request resumes one. Registers the release finalizer before the first
65
+ * filesystem change.
66
+ */
67
+ export declare const provisionWorktree: <E extends Error>(options: ProvisionOptions<E>) => Effect.Effect<{
68
+ workspace: AttemptWorkspace;
69
+ salvaged: Effect.Effect<Option.Option<SalvagePushed | import("@usine/core/attempt/salvage").SalvageRetained>, import("@usine/core/attempt/failure").AgentFailure | import("@usine/core/attempt/failure").BlockedFailure | import("@usine/core/attempt/failure").ChildSessionBudgetFailure | import("@usine/core/attempt/failure").DefectFailure | import("@usine/core/attempt/failure").InfraFailure | import("@usine/core/attempt/failure").QuestionFailure | import("@usine/core/attempt/failure").RunawayFailure, never>;
70
+ recordSalvage: (record: AttemptChannel.Sink["salvage"]) => Effect.Effect<void, never, never>;
71
+ keepForReattach: Effect.Effect<void, never, never>;
72
+ gitHooks: Option.Option<string>;
73
+ }, E | ExecutorOperationError, import("effect/Scope").Scope>;
74
+ export interface ReattachOptions<E> extends ReleaseOptions<E> {
75
+ readonly ops: Pick<WorkspaceOps<E>, "cacheExists" | "git" | "removePath" | "writeExecutable">;
76
+ /** The RunSpec from the parent's durable request. */
77
+ readonly spec: AttemptChannel.RunSpec;
78
+ }
79
+ /**
80
+ * Reuses an Attempt's checkout after an orchestrator restart without cloning, fetching, or
81
+ * checking out. The same release as a new checkout salvages and removes it when the Attempt
82
+ * ends.
83
+ */
84
+ export declare const reattachWorktree: <E extends Error>(options: ReattachOptions<E>) => Effect.Effect<{
85
+ workspace: AttemptWorkspace;
86
+ salvaged: Effect.Effect<Option.Option<SalvagePushed | import("@usine/core/attempt/salvage").SalvageRetained>, import("@usine/core/attempt/failure").AgentFailure | import("@usine/core/attempt/failure").BlockedFailure | import("@usine/core/attempt/failure").ChildSessionBudgetFailure | import("@usine/core/attempt/failure").DefectFailure | import("@usine/core/attempt/failure").InfraFailure | import("@usine/core/attempt/failure").QuestionFailure | import("@usine/core/attempt/failure").RunawayFailure, never>;
87
+ recordSalvage: (record: AttemptChannel.Sink["salvage"]) => Effect.Effect<void, never, never>;
88
+ keepForReattach: Effect.Effect<void, never, never>;
89
+ gitHooks: Option.Option<string>;
90
+ }, E, import("effect/Scope").Scope>;
91
+ export interface RecoveryOptions<E> {
92
+ readonly attempt: AttemptRecovery;
93
+ readonly host: string;
94
+ readonly worktree: string;
95
+ readonly cache: string;
96
+ /** Runs git with the Worker's repository credentials. */
97
+ readonly git: (args: ReadonlyArray<string>) => Effect.Effect<string, E>;
98
+ }
35
99
  /**
36
- * The clone-to-worktree sequence every Executor shares: clone into a staging
37
- * sibling and promote it on success, so an interrupted clone never leaves a
38
- * half-initialized cache that later fetches would poison; then fetch the
39
- * requested revision and check out a detached worktree at the resolved commit.
100
+ * Reconciles a checkout left by an earlier process: salvages it without a known base, records
101
+ * the result, and removes the worktree only after its work is pushed. Checkouts of succeeded
102
+ * Attempts and of `permissions: read` Loops are removed without salvage.
40
103
  */
41
- export declare const provisionWorktree: <E>(options: ProvisionOptions<E>) => Effect.Effect<AttemptWorkspace, E | ExecutorOperationError, import("effect/Scope").Scope>;
104
+ export declare const recoverWorktree: <E extends Error, RecordError>(options: RecoveryOptions<E>, record: (salvage: AttemptSalvage) => Effect.Effect<void, RecordError>) => Effect.Effect<void, E | RecordError, never>;
42
105
  export {};
43
106
  //# sourceMappingURL=provision.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../src/provision.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAa,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,MAAM,EAAU,MAAM,QAAQ,CAAC;AACxC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAEhB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,WAAW,UAAW,MAAM,KAAG,MAAoD,CAAC;AAIjG,8FAA8F;AAC9F,eAAO,MAAM,kBAAkB,eAAgB,cAAc,KAAG,MACT,CAAC;AAExD;;;;;GAKG;AACH,eAAO,MAAM,oBAAoB,UAAW,MAAM,KAAG,OACmC,CAAC;AAIzF,UAAU,eAAe;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,qFAAqF;AACrF,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7C,QAAQ,CAAC,UAAU,EAAE,CAAC,SAAS,EAAE,SAAS,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAClG,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAChD,uEAAuE;IACvE,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAChD,QAAQ,CAAC,GAAG,EAAE,CACZ,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,KACxB,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC;CAC/B;AAED;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAAsD,CAAC,4HAwJnF,CAAC"}
1
+ {"version":3,"file":"provision.d.ts","sourceRoot":"","sources":["../src/provision.ts"],"names":[],"mappings":"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"}