@pmelab/gtd 15.7.0 → 15.9.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.
@@ -2916,7 +2916,7 @@ const isNonEmptyArray = isNonEmptyArray$1;
2916
2916
  */
2917
2917
  const isNonEmptyReadonlyArray = isNonEmptyArray$1;
2918
2918
  const isOutOfBounds = (i, as) => i < 0 || i >= as.length;
2919
- const clamp = (i, as) => Math.floor(Math.min(Math.max(0, i), as.length));
2919
+ const clamp$1 = (i, as) => Math.floor(Math.min(Math.max(0, i), as.length));
2920
2920
  /**
2921
2921
  * This function provides a safe way to read a value at a particular index from a `ReadonlyArray`.
2922
2922
  *
@@ -3037,7 +3037,7 @@ const span = /*#__PURE__*/ dual(2, (self, predicate) => splitAt(self, spanIndex(
3037
3037
  */
3038
3038
  const drop$1 = /*#__PURE__*/ dual(2, (self, n) => {
3039
3039
  const input = fromIterable$6(self);
3040
- return input.slice(clamp(n, input), input.length);
3040
+ return input.slice(clamp$1(n, input), input.length);
3041
3041
  });
3042
3042
  /**
3043
3043
  * Reverse an `Iterable`, creating a new `Array`.
@@ -5273,7 +5273,7 @@ const empty$21 = /*#__PURE__*/ (() => {
5273
5273
  return o;
5274
5274
  })();
5275
5275
  /** @internal */
5276
- const fail$8 = (error) => {
5276
+ const fail$11 = (error) => {
5277
5277
  const o = Object.create(proto$10);
5278
5278
  o._tag = OP_FAIL$2;
5279
5279
  o.error = error;
@@ -5353,7 +5353,7 @@ const failureOrCause$1 = (self) => {
5353
5353
  /** @internal */
5354
5354
  const flipCauseOption$1 = (self) => match$7(self, {
5355
5355
  onEmpty: some(empty$21),
5356
- onFail: map$14(fail$8),
5356
+ onFail: map$14(fail$11),
5357
5357
  onDie: (defect) => some(die$4(defect)),
5358
5358
  onInterrupt: (fiberId) => some(interrupt$5(fiberId)),
5359
5359
  onSequential: mergeWith$1(sequential$3),
@@ -5389,7 +5389,7 @@ const electFailures = (self) => match$7(self, {
5389
5389
  onParallel: parallel$3
5390
5390
  });
5391
5391
  /** @internal */
5392
- const map$10 = /*#__PURE__*/ dual(2, (self, f) => flatMap$7(self, (e) => fail$8(f(e))));
5392
+ const map$10 = /*#__PURE__*/ dual(2, (self, f) => flatMap$7(self, (e) => fail$11(f(e))));
5393
5393
  /** @internal */
5394
5394
  const flatMap$7 = /*#__PURE__*/ dual(2, (self, f) => match$7(self, {
5395
5395
  onEmpty: empty$21,
@@ -8141,8 +8141,8 @@ const exit$2 = (self) => matchCause$1(self, {
8141
8141
  onFailure: exitFailCause$1,
8142
8142
  onSuccess: exitSucceed$1
8143
8143
  });
8144
- const fail$7 = (error) => isObject$2(error) && !(spanSymbol in error) ? withFiberRuntime$1((fiber) => failCause$6(fail$8(capture(error, currentSpanFromFiber(fiber))))) : failCause$6(fail$8(error));
8145
- const failSync = (evaluate) => flatMap$6(sync$2(evaluate), fail$7);
8144
+ const fail$10 = (error) => isObject$2(error) && !(spanSymbol in error) ? withFiberRuntime$1((fiber) => failCause$6(fail$11(capture(error, currentSpanFromFiber(fiber))))) : failCause$6(fail$11(error));
8145
+ const failSync = (evaluate) => flatMap$6(sync$2(evaluate), fail$10);
8146
8146
  const failCause$6 = (cause) => {
8147
8147
  const effect = new EffectPrimitiveFailure(OP_FAILURE);
8148
8148
  effect.effect_instruction_i0 = cause;
@@ -8161,7 +8161,7 @@ const andThen$1 = /*#__PURE__*/ dual(2, (self, f) => flatMap$6(self, (a) => {
8161
8161
  const b = typeof f === "function" ? f(a) : f;
8162
8162
  if (isEffect$1(b)) return b;
8163
8163
  else if (isPromiseLike(b)) return unsafeAsync((resume) => {
8164
- b.then((a) => resume(succeed$8(a)), (e) => resume(fail$7(new UnknownException(e, "An unknown error occurred in Effect.andThen"))));
8164
+ b.then((a) => resume(succeed$8(a)), (e) => resume(fail$10(new UnknownException(e, "An unknown error occurred in Effect.andThen"))));
8165
8165
  });
8166
8166
  return succeed$8(b);
8167
8167
  }));
@@ -8281,7 +8281,7 @@ const tap$1 = /*#__PURE__*/ dual((args) => args.length === 3 || args.length ===
8281
8281
  const b = typeof f === "function" ? f(a) : f;
8282
8282
  if (isEffect$1(b)) return as$1(b, a);
8283
8283
  else if (isPromiseLike(b)) return unsafeAsync((resume) => {
8284
- b.then((_) => resume(succeed$8(a)), (e) => resume(fail$7(new UnknownException(e, "An unknown error occurred in Effect.tap"))));
8284
+ b.then((_) => resume(succeed$8(a)), (e) => resume(fail$10(new UnknownException(e, "An unknown error occurred in Effect.tap"))));
8285
8285
  });
8286
8286
  return succeed$8(a);
8287
8287
  }));
@@ -8574,7 +8574,7 @@ const causeSquashWith = /*#__PURE__*/ dual(2, (self, f) => {
8574
8574
  const YieldableError$1 = /*#__PURE__*/ function() {
8575
8575
  class YieldableError extends globalThis.Error {
8576
8576
  commit() {
8577
- return fail$7(this);
8577
+ return fail$10(this);
8578
8578
  }
8579
8579
  toJSON() {
8580
8580
  const obj = { ...this };
@@ -8584,7 +8584,7 @@ const YieldableError$1 = /*#__PURE__*/ function() {
8584
8584
  }
8585
8585
  [NodeInspectSymbol]() {
8586
8586
  if (this.toString !== globalThis.Error.prototype.toString) return this.stack ? `${this.toString()}\n${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
8587
- else if ("Bun" in globalThis) return pretty$1(fail$8(this), { renderErrorCause: true });
8587
+ else if ("Bun" in globalThis) return pretty$1(fail$11(this), { renderErrorCause: true });
8588
8588
  return this;
8589
8589
  }
8590
8590
  }
@@ -8661,7 +8661,7 @@ const exitCollectAll = (exits, options) => exitCollectAllInternal(exits, options
8661
8661
  /** @internal */
8662
8662
  const exitDie$1 = (defect) => exitFailCause$1(die$4(defect));
8663
8663
  /** @internal */
8664
- const exitFail = (error) => exitFailCause$1(fail$8(error));
8664
+ const exitFail = (error) => exitFailCause$1(fail$11(error));
8665
8665
  /** @internal */
8666
8666
  const exitFailCause$1 = (cause) => {
8667
8667
  const effect = new EffectPrimitiveFailure(OP_FAILURE);
@@ -8781,7 +8781,7 @@ const deferredCompleteWith = /*#__PURE__*/ dual(2, (self, effect) => sync$2(() =
8781
8781
  }
8782
8782
  }));
8783
8783
  const deferredDone = /*#__PURE__*/ dual(2, (self, exit) => deferredCompleteWith(self, exit));
8784
- const deferredFail = /*#__PURE__*/ dual(2, (self, error) => deferredCompleteWith(self, fail$7(error)));
8784
+ const deferredFail = /*#__PURE__*/ dual(2, (self, error) => deferredCompleteWith(self, fail$10(error)));
8785
8785
  const deferredFailCause = /*#__PURE__*/ dual(2, (self, cause) => deferredCompleteWith(self, failCause$6(cause)));
8786
8786
  const deferredInterrupt = (self) => flatMap$6(fiberId, (fiberId) => deferredCompleteWith(self, interruptWith(fiberId)));
8787
8787
  const deferredInterruptWith = /*#__PURE__*/ dual(2, (self, fiberId) => deferredCompleteWith(self, interruptWith(fiberId)));
@@ -8843,7 +8843,7 @@ const empty$12 = empty$21;
8843
8843
  * @since 2.0.0
8844
8844
  * @category Constructors
8845
8845
  */
8846
- const fail$6 = fail$8;
8846
+ const fail$9 = fail$11;
8847
8847
  /**
8848
8848
  * Creates a `Die` cause from an unexpected error.
8849
8849
  *
@@ -9141,7 +9141,7 @@ const complete$1 = deferredComplete;
9141
9141
  * @since 2.0.0
9142
9142
  * @category utils
9143
9143
  */
9144
- const fail$5 = deferredFail;
9144
+ const fail$8 = deferredFail;
9145
9145
  /**
9146
9146
  * Fails the `Deferred` with the specified `Cause`, which will be propagated to
9147
9147
  * all fibers waiting on the value of the `Deferred`.
@@ -9257,7 +9257,7 @@ const Order$1 = number;
9257
9257
  * @since 2.0.0
9258
9258
  * @category constructors
9259
9259
  */
9260
- const parse$1 = (s) => {
9260
+ const parse$2 = (s) => {
9261
9261
  if (s === "NaN") return some$1(NaN);
9262
9262
  if (s === "Infinity") return some$1(Infinity);
9263
9263
  if (s === "-Infinity") return some$1(-Infinity);
@@ -9490,7 +9490,7 @@ const makeFlat = (options) => ({
9490
9490
  /** @internal */
9491
9491
  const fromFlat = (flat) => make$33({
9492
9492
  load: (config) => flatMap$6(fromFlatLoop(flat, empty$26(), config, false), (chunk) => match$8(head$2(chunk), {
9493
- onNone: () => fail$7(MissingData(empty$26(), `Expected a single value having structure: ${config}`)),
9493
+ onNone: () => fail$10(MissingData(empty$26(), `Expected a single value having structure: ${config}`)),
9494
9494
  onSome: succeed$8
9495
9495
  })),
9496
9496
  flattened: flat
@@ -9549,10 +9549,10 @@ const fromFlatLoop = (flat, prefix, config, split) => {
9549
9549
  switch (op._tag) {
9550
9550
  case OP_CONSTANT: return succeed$8(of$2(op.value));
9551
9551
  case OP_DESCRIBED: return suspend$7(() => fromFlatLoop(flat, prefix, op.config, split));
9552
- case OP_FAIL$1: return fail$7(MissingData(prefix, op.message));
9552
+ case OP_FAIL$1: return fail$10(MissingData(prefix, op.message));
9553
9553
  case OP_FALLBACK: return pipe(suspend$7(() => fromFlatLoop(flat, prefix, op.first, split)), catchAll$1((error1) => {
9554
- if (op.condition(error1)) return pipe(fromFlatLoop(flat, prefix, op.second, split), catchAll$1((error2) => fail$7(Or(error1, error2))));
9555
- return fail$7(error1);
9554
+ if (op.condition(error1)) return pipe(fromFlatLoop(flat, prefix, op.second, split), catchAll$1((error2) => fail$10(Or(error1, error2))));
9555
+ return fail$10(error1);
9556
9556
  }));
9557
9557
  case OP_LAZY: return suspend$7(() => fromFlatLoop(flat, prefix, op.config(), split));
9558
9558
  case OP_MAP_OR_FAIL: return suspend$7(() => pipe(fromFlatLoop(flat, prefix, op.original, split), flatMap$6(forEachSequential((a) => pipe(op.mapOrFail(a), mapError$2(prefixed(appendConfigPath(prefix, op.original))))))));
@@ -9560,7 +9560,7 @@ const fromFlatLoop = (flat, prefix, config, split) => {
9560
9560
  case OP_PRIMITIVE: return pipe(patch$3(prefix, flat.patch), flatMap$6((prefix) => pipe(flat.load(prefix, op, split), flatMap$6((values) => {
9561
9561
  if (values.length === 0) {
9562
9562
  const name = pipe(last(prefix), getOrElse(() => "<n/a>"));
9563
- return fail$7(MissingData([], `Expected ${op.description} with name ${name}`));
9563
+ return fail$10(MissingData([], `Expected ${op.description} with name ${name}`));
9564
9564
  }
9565
9565
  return succeed$8(values);
9566
9566
  }))));
@@ -9579,9 +9579,9 @@ const fromFlatLoop = (flat, prefix, config, split) => {
9579
9579
  }));
9580
9580
  })))));
9581
9581
  case OP_ZIP_WITH$1: return suspend$7(() => pipe(fromFlatLoop(flat, prefix, op.left, split), either$1, flatMap$6((left) => pipe(fromFlatLoop(flat, prefix, op.right, split), either$1, flatMap$6((right$9) => {
9582
- if (isLeft(left) && isLeft(right$9)) return fail$7(And(left.left, right$9.left));
9583
- if (isLeft(left) && isRight(right$9)) return fail$7(left.left);
9584
- if (isRight(left) && isLeft(right$9)) return fail$7(right$9.left);
9582
+ if (isLeft(left) && isLeft(right$9)) return fail$10(And(left.left, right$9.left));
9583
+ if (isLeft(left) && isRight(right$9)) return fail$10(left.left);
9584
+ if (isRight(left) && isLeft(right$9)) return fail$10(right$9.left);
9585
9585
  if (isRight(left) && isRight(right$9)) {
9586
9586
  const path = pipe(prefix, join$4("."));
9587
9587
  const fail = fromFlatLoopFail(prefix, path);
@@ -9852,7 +9852,7 @@ const liveServices = /*#__PURE__*/ pipe(/*#__PURE__*/ empty$19(), /*#__PURE__*/
9852
9852
  */
9853
9853
  const currentServices = /*#__PURE__*/ globalValue(/*#__PURE__*/ Symbol.for("effect/DefaultServices/currentServices"), () => fiberRefUnsafeMakeContext(liveServices));
9854
9854
  /** @internal */
9855
- const sleep$2 = (duration) => {
9855
+ const sleep$3 = (duration) => {
9856
9856
  const decodedDuration = decode$1(duration);
9857
9857
  return clockWith((clock) => clock.sleep(decodedDuration));
9858
9858
  };
@@ -10699,7 +10699,7 @@ const failCause$4 = /*#__PURE__*/ makeExit({
10699
10699
  * @experimental
10700
10700
  * @category constructors
10701
10701
  */
10702
- const fail$4 = (error) => failCause$4(causeFail(error));
10702
+ const fail$7 = (error) => failCause$4(causeFail(error));
10703
10703
  /**
10704
10704
  * Pause the execution of the current `Micro` effect, and resume it on the next
10705
10705
  * scheduler tick.
@@ -10997,7 +10997,7 @@ const YieldableError = /*#__PURE__*/ function() {
10997
10997
  Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype, {
10998
10998
  [identifier]: "Failure",
10999
10999
  [evaluate]() {
11000
- return fail$4(this);
11000
+ return fail$7(this);
11001
11001
  },
11002
11002
  toString() {
11003
11003
  return this.message ? `${this.name}: ${this.message}` : this.name;
@@ -11258,7 +11258,7 @@ const match$5 = (concurrency, sequential, unbounded, bounded) => {
11258
11258
  * @since 2.0.0
11259
11259
  * @category constructors
11260
11260
  */
11261
- const sleep$1 = sleep$2;
11261
+ const sleep$2 = sleep$3;
11262
11262
  /**
11263
11263
  * @since 2.0.0
11264
11264
  * @category constructors
@@ -11335,7 +11335,7 @@ const try_$1 = (arg) => {
11335
11335
  try {
11336
11336
  return succeed$8(internalCall(evaluate));
11337
11337
  } catch (error) {
11338
- return fail$7(onFailure ? internalCall(() => onFailure(error)) : new UnknownException(error, "An unknown error occurred in Effect.try"));
11338
+ return fail$10(onFailure ? internalCall(() => onFailure(error)) : new UnknownException(error, "An unknown error occurred in Effect.try"));
11339
11339
  }
11340
11340
  });
11341
11341
  };
@@ -11408,10 +11408,10 @@ const promise$1 = (evaluate) => evaluate.length >= 1 ? async_((resolve, signal)
11408
11408
  const provideService$1 = /*#__PURE__*/ dual(3, (self, tag, service) => contextWithEffect((env) => provideContext$1(self, add(env, tag, service))));
11409
11409
  const provideServiceEffect = /*#__PURE__*/ dual(3, (self, tag, effect) => contextWithEffect((env) => flatMap$6(effect, (service) => provideContext$1(self, pipe(env, add(tag, service))))));
11410
11410
  const sandbox$1 = (self) => matchCauseEffect$2(self, {
11411
- onFailure: fail$7,
11411
+ onFailure: fail$10,
11412
11412
  onSuccess: succeed$8
11413
11413
  });
11414
- const sleep = sleep$1;
11414
+ const sleep$1 = sleep$2;
11415
11415
  const succeedNone = /*#__PURE__*/ succeed$8(/*#__PURE__*/ none$4());
11416
11416
  const summarized = /*#__PURE__*/ dual(3, (self, summary, f) => flatMap$6(summary, (start) => flatMap$6(self, (value) => map$8(summary, (end) => [f(start, end), value]))));
11417
11417
  const tapErrorCause$1 = /*#__PURE__*/ dual(2, (self, f) => matchCauseEffect$2(self, {
@@ -11426,7 +11426,7 @@ const tryPromise$1 = (arg) => {
11426
11426
  evaluate = arg.try;
11427
11427
  catcher = arg.catch;
11428
11428
  }
11429
- const fail = (e) => catcher ? failSync(() => catcher(e)) : fail$7(new UnknownException(e, "An unknown error occurred in Effect.tryPromise"));
11429
+ const fail = (e) => catcher ? failSync(() => catcher(e)) : fail$10(new UnknownException(e, "An unknown error occurred in Effect.tryPromise"));
11430
11430
  if (evaluate.length >= 1) return async_((resolve, signal) => {
11431
11431
  try {
11432
11432
  evaluate(signal).then((a) => resolve(succeed$8(a)), (e) => resolve(fail(e)));
@@ -11491,7 +11491,7 @@ const die$1 = exitDie$1;
11491
11491
  * @since 2.0.0
11492
11492
  * @category constructors
11493
11493
  */
11494
- const fail$3 = exitFail;
11494
+ const fail$6 = exitFail;
11495
11495
  /**
11496
11496
  * Constructs a new `Exit.Failure` from the specified `Cause` of type `E`.
11497
11497
  *
@@ -13667,10 +13667,10 @@ var FiberRuntime = class extends Class {
13667
13667
  return sync$2(() => unsafeGet(this.currentContext, op));
13668
13668
  }
13669
13669
  ["Left"](op) {
13670
- return fail$7(op.left);
13670
+ return fail$10(op.left);
13671
13671
  }
13672
13672
  ["None"](_) {
13673
- return fail$7(new NoSuchElementException$2());
13673
+ return fail$10(new NoSuchElementException$2());
13674
13674
  }
13675
13675
  ["Right"](op) {
13676
13676
  return exitSucceed$1(op.right);
@@ -13686,7 +13686,7 @@ var FiberRuntime = class extends Class {
13686
13686
  if (exit._tag === "Success") return resume(exitSucceed$1(exit.value));
13687
13687
  switch (exit.cause._tag) {
13688
13688
  case "Interrupt": return resume(exitFailCause$1(interrupt$5(none$2)));
13689
- case "Fail": return resume(fail$7(exit.cause.error));
13689
+ case "Fail": return resume(fail$10(exit.cause.error));
13690
13690
  case "Die": return resume(die$3(exit.cause.defect));
13691
13691
  }
13692
13692
  });
@@ -13946,7 +13946,7 @@ const allValidate = (effects, reconcile, options) => {
13946
13946
  errors[i] = none;
13947
13947
  }
13948
13948
  }
13949
- if (errored) return reconcile._tag === "Some" ? fail$7(reconcile.value(errors)) : fail$7(errors);
13949
+ if (errored) return reconcile._tag === "Some" ? fail$10(reconcile.value(errors)) : fail$10(errors);
13950
13950
  else if (options?.discard) return void_$4;
13951
13951
  return reconcile._tag === "Some" ? succeed$8(reconcile.value(successes)) : succeed$8(successes);
13952
13952
  });
@@ -14815,7 +14815,7 @@ const timeoutFail = /*#__PURE__*/ dual(2, (self, { duration, onTimeout }) => fla
14815
14815
  duration
14816
14816
  })));
14817
14817
  /** @internal */
14818
- const timeoutTo = /*#__PURE__*/ dual(2, (self, { duration, onSuccess, onTimeout }) => fiberIdWith$1((parentFiberId) => uninterruptibleMask$2((restore) => raceFibersWith(restore(self), interruptible$2(sleep(duration)), {
14818
+ const timeoutTo = /*#__PURE__*/ dual(2, (self, { duration, onSuccess, onTimeout }) => fiberIdWith$1((parentFiberId) => uninterruptibleMask$2((restore) => raceFibersWith(restore(self), interruptible$2(sleep$1(duration)), {
14819
14819
  onSelfWin: (winner, loser) => flatMap$6(winner.await, (exit) => {
14820
14820
  if (exit._tag === "Success") return flatMap$6(winner.inheritAll, () => as$1(interruptAsFiber(loser, parentFiberId), onSuccess(exit.value)));
14821
14821
  else return flatMap$6(interruptAsFiber(loser, parentFiberId), () => exitFailCause$1(exit.cause));
@@ -15934,11 +15934,11 @@ var ScheduleDriverImpl = class {
15934
15934
  next(input) {
15935
15935
  return pipe(map$8(get$4(this.ref), (tuple) => tuple[1]), flatMap$6((state) => pipe(currentTimeMillis, flatMap$6((now) => pipe(suspend$7(() => this.schedule.step(now, input, state)), flatMap$6(([state, out, decision]) => {
15936
15936
  const setState = set$2(this.ref, [some(out), state]);
15937
- if (isDone(decision)) return setState.pipe(zipRight$3(fail$7(none$4())));
15937
+ if (isDone(decision)) return setState.pipe(zipRight$3(fail$10(none$4())));
15938
15938
  const millis$1 = start$1(decision.intervals) - now;
15939
15939
  if (millis$1 <= 0) return setState.pipe(zipRight$3(updateInfo(this.iterationMeta, now, input, out)), as$1(out));
15940
15940
  const duration = millis(millis$1);
15941
- return pipe(setState, zipRight$3(updateInfo(this.iterationMeta, now, input, out)), zipRight$3(sleep(duration)), as$1(out));
15941
+ return pipe(setState, zipRight$3(updateInfo(this.iterationMeta, now, input, out)), zipRight$3(sleep$1(duration)), as$1(out));
15942
15942
  }))))));
15943
15943
  }
15944
15944
  };
@@ -16072,12 +16072,12 @@ const scheduleDefectWrap = (self) => catchAll$1(self, (e) => die$3(new ScheduleD
16072
16072
  /** @internal */
16073
16073
  const scheduleDefectRefailCause = (cause) => match$8(find(cause, (_) => isDieType$1(_) && isScheduleDefect(_.defect) ? some(_.defect) : none$4()), {
16074
16074
  onNone: () => cause,
16075
- onSome: (error) => fail$8(error.error)
16075
+ onSome: (error) => fail$11(error.error)
16076
16076
  });
16077
16077
  /** @internal */
16078
16078
  const scheduleDefectRefail = (effect) => catchAllCause$1(effect, (cause) => failCause$6(scheduleDefectRefailCause(cause)));
16079
16079
  /** @internal */
16080
- const repeat_Effect = /*#__PURE__*/ dual(2, (self, schedule) => repeatOrElse_Effect(self, schedule, (e, _) => fail$7(e)));
16080
+ const repeat_Effect = /*#__PURE__*/ dual(2, (self, schedule) => repeatOrElse_Effect(self, schedule, (e, _) => fail$10(e)));
16081
16081
  /** @internal */
16082
16082
  const repeat_combined = /*#__PURE__*/ dual(2, (self, options) => {
16083
16083
  if (isSchedule(options)) return repeat_Effect(self, options);
@@ -16109,7 +16109,7 @@ const repeatOrElseEffectLoop = (self, driver, orElse, value) => matchEffect$1(dr
16109
16109
  })
16110
16110
  });
16111
16111
  /** @internal */
16112
- const retry_Effect = /*#__PURE__*/ dual(2, (self, policy) => retryOrElse_Effect(self, policy, (e, _) => fail$7(e)));
16112
+ const retry_Effect = /*#__PURE__*/ dual(2, (self, policy) => retryOrElse_Effect(self, policy, (e, _) => fail$10(e)));
16113
16113
  /** @internal */
16114
16114
  const retry_combined = /*#__PURE__*/ dual(2, (self, options) => {
16115
16115
  if (isSchedule(options)) return retry_Effect(self, options);
@@ -16876,7 +16876,7 @@ const withFiberRuntime = withFiberRuntime$1;
16876
16876
  * @since 2.0.0
16877
16877
  * @category Creating Effects
16878
16878
  */
16879
- const fail$2 = fail$7;
16879
+ const fail$5 = fail$10;
16880
16880
  /**
16881
16881
  * Creates an `Effect` that fails with the specified `Cause`.
16882
16882
  *
@@ -21005,7 +21005,7 @@ const collectElementsReader = (builder) => readWith({
21005
21005
  onInput: (outElem) => flatMap$3(sync(() => {
21006
21006
  builder.push(outElem);
21007
21007
  }), () => collectElementsReader(builder)),
21008
- onFailure: fail$1,
21008
+ onFailure: fail$4,
21009
21009
  onDone: succeedNow
21010
21010
  });
21011
21011
  /** @internal */
@@ -21049,7 +21049,7 @@ const ensuringWith = /*#__PURE__*/ dual(2, (self, finalizer) => {
21049
21049
  return op;
21050
21050
  });
21051
21051
  /** @internal */
21052
- const fail$1 = (error) => failCause$1(fail$6(error));
21052
+ const fail$4 = (error) => failCause$1(fail$9(error));
21053
21053
  /** @internal */
21054
21054
  const failCause$1 = (cause) => failCauseSync(() => cause);
21055
21055
  /** @internal */
@@ -22036,7 +22036,7 @@ var SingleProducerAsyncInputImpl = class {
22036
22036
  }));
22037
22037
  }
22038
22038
  get take() {
22039
- return this.takeWith((cause) => failCause$3(map$7(cause, left)), (elem) => succeed$5(elem), (done) => fail$3(right(done)));
22039
+ return this.takeWith((cause) => failCause$3(map$7(cause, left)), (elem) => succeed$5(elem), (done) => fail$6(right(done)));
22040
22040
  }
22041
22041
  takeWith(onError, onElement, onDone) {
22042
22042
  return flatMap$4(make$35(), (deferred) => flatten$5(modify(this.ref, (state) => {
@@ -22087,7 +22087,7 @@ const fromInput = (input) => unwrap$2(input.takeWith(failCause$1, (elem) => flat
22087
22087
  /** @internal */
22088
22088
  const identityChannel = () => readWith({
22089
22089
  onInput: (input) => flatMap$3(write$1(input), () => identityChannel()),
22090
- onFailure: fail$1,
22090
+ onFailure: fail$4,
22091
22091
  onDone: succeedNow
22092
22092
  });
22093
22093
  /** @internal */
@@ -22096,7 +22096,7 @@ const map$3 = /*#__PURE__*/ dual(2, (self, f) => flatMap$3(self, (a) => sync(()
22096
22096
  const mapOut = /*#__PURE__*/ dual(2, (self, f) => {
22097
22097
  const reader = readWith({
22098
22098
  onInput: (outElem) => flatMap$3(write$1(f(outElem)), () => reader),
22099
- onFailure: fail$1,
22099
+ onFailure: fail$4,
22100
22100
  onDone: succeedNow
22101
22101
  });
22102
22102
  return pipeTo$1(self, reader);
@@ -22261,7 +22261,7 @@ const pipeToOrFail = /*#__PURE__*/ dual(2, (self, that) => suspend$4(() => {
22261
22261
  });
22262
22262
  const writer = readWithCause({
22263
22263
  onInput: (outElem) => pipe(write$1(outElem), flatMap$3(() => writer)),
22264
- onFailure: (cause) => isDieType(cause) && isChannelException(cause.defect) && equals$2(cause.defect, channelException) ? fail$1(cause.defect.error) : failCause$1(cause),
22264
+ onFailure: (cause) => isDieType(cause) && isChannelException(cause.defect) && equals$2(cause.defect, channelException) ? fail$4(cause.defect.error) : failCause$1(cause),
22265
22265
  onDone: succeedNow
22266
22266
  });
22267
22267
  return pipeTo$1(pipeTo$1(pipeTo$1(self, reader), that), writer);
@@ -22428,7 +22428,7 @@ const foldChunksReader = (s, contFn, f) => {
22428
22428
  if (!contFn(s)) return succeedNow(s);
22429
22429
  return readWith({
22430
22430
  onInput: (input) => foldChunksReader(f(s, input), contFn, f),
22431
- onFailure: fail$1,
22431
+ onFailure: fail$4,
22432
22432
  onDone: () => succeedNow(s)
22433
22433
  });
22434
22434
  };
@@ -22534,7 +22534,7 @@ const get$1 = (self_) => {
22534
22534
  self.state = stateEmpty;
22535
22535
  return scopeClose(state.scope, exitVoid$1);
22536
22536
  }
22537
- return sleep(self.idleTimeToLive).pipe(interruptible$2, zipRight$3(suspend$7(() => {
22537
+ return sleep$1(self.idleTimeToLive).pipe(interruptible$2, zipRight$3(suspend$7(() => {
22538
22538
  if (self.state._tag === "Acquired" && self.state.refCount === 0) {
22539
22539
  self.state = stateEmpty;
22540
22540
  return scopeClose(state.scope, exitVoid$1);
@@ -22652,10 +22652,10 @@ const make$12 = (emit) => {
22652
22652
  })));
22653
22653
  },
22654
22654
  end() {
22655
- return this(fail$2(none$4()));
22655
+ return this(fail$5(none$4()));
22656
22656
  },
22657
22657
  fail(e) {
22658
- return this(fail$2(some(e)));
22658
+ return this(fail$5(some(e)));
22659
22659
  },
22660
22660
  fromEffect(effect) {
22661
22661
  return this(mapBoth$1(effect, {
@@ -22698,7 +22698,7 @@ const chunk = (chunk) => new TakeImpl(succeed$5(chunk));
22698
22698
  /** @internal */
22699
22699
  const done = (self) => suspend$5(() => self.exit);
22700
22700
  /** @internal */
22701
- const end$1 = /*#__PURE__*/ new TakeImpl(/*#__PURE__*/ fail$3(/*#__PURE__*/ none$4()));
22701
+ const end$1 = /*#__PURE__*/ new TakeImpl(/*#__PURE__*/ fail$6(/*#__PURE__*/ none$4()));
22702
22702
  /** @internal */
22703
22703
  const failCause = (cause) => new TakeImpl(failCause$3(pipe(cause, map$7(some))));
22704
22704
  /** @internal */
@@ -22720,7 +22720,7 @@ const match = /*#__PURE__*/ dual(2, (self, { onEnd, onFailure, onSuccess }) => m
22720
22720
  //#endregion
22721
22721
  //#region node_modules/effect/dist/esm/internal/stream/pull.js
22722
22722
  /** @internal */
22723
- const end = () => fail$2(none$4());
22723
+ const end = () => fail$5(none$4());
22724
22724
  /** @internal */
22725
22725
  const StreamTypeId = /*#__PURE__*/ Symbol.for("effect/Stream");
22726
22726
  /** @internal */
@@ -22833,7 +22833,7 @@ const fromEffect$1 = (effect) => pipe(effect, mapError$1(some), fromEffectOption
22833
22833
  const fromEffectOption = (effect) => new StreamImpl(unwrap$2(match$2(effect, {
22834
22834
  onFailure: match$8({
22835
22835
  onNone: () => void_$1,
22836
- onSome: fail$1
22836
+ onSome: fail$4
22837
22837
  }),
22838
22838
  onSuccess: (a) => write$1(of$1(a))
22839
22839
  })));
@@ -22848,7 +22848,7 @@ const pipeThroughChannel = /*#__PURE__*/ dual(2, (self, channel) => new StreamIm
22848
22848
  /** @internal */
22849
22849
  const repeatEffectChunkOption = (effect) => unfoldChunkEffect(effect, (effect) => pipe(map$4(effect, (chunk) => some([chunk, effect])), catchAll(match$8({
22850
22850
  onNone: () => succeed$3(none$4()),
22851
- onSome: fail$2
22851
+ onSome: fail$5
22852
22852
  }))));
22853
22853
  /** @internal */
22854
22854
  const run$4 = /*#__PURE__*/ dual(2, (self, sink) => toChannel$2(self).pipe(pipeToOrFail(toChannel$3(sink)), runDrain));
@@ -22880,7 +22880,7 @@ const transduce$1 = /*#__PURE__*/ dual(2, (self, sink) => {
22880
22880
  const leftover = leftovers.ref;
22881
22881
  if (isEmpty$7(leftover)) return readWith({
22882
22882
  onInput: (input) => pipe(write$1(input), flatMap$3(() => buffer)),
22883
- onFailure: fail$1,
22883
+ onFailure: fail$4,
22884
22884
  onDone: succeedNow
22885
22885
  });
22886
22886
  leftovers.ref = empty$25();
@@ -22894,7 +22894,7 @@ const transduce$1 = /*#__PURE__*/ dual(2, (self, sink) => {
22894
22894
  };
22895
22895
  const upstreamMarker = readWith({
22896
22896
  onInput: (input) => flatMap$3(write$1(input), () => upstreamMarker),
22897
- onFailure: fail$1,
22897
+ onFailure: fail$4,
22898
22898
  onDone: (done) => zipRight(sync(() => {
22899
22899
  upstreamDone.ref = true;
22900
22900
  }), succeedNow(done))
@@ -25445,7 +25445,7 @@ const succeed = right;
25445
25445
  * @category constructors
25446
25446
  * @since 3.10.0
25447
25447
  */
25448
- const fail = left;
25448
+ const fail$3 = left;
25449
25449
  const _try = try_$2;
25450
25450
  /**
25451
25451
  * @category constructors
@@ -26487,7 +26487,7 @@ function Literal(...literals) {
26487
26487
  }
26488
26488
  const declareConstructor = (typeParameters, options, annotations) => makeDeclareClass(typeParameters, new Declaration(typeParameters.map((tp) => tp.ast), (...typeParameters) => options.decode(...typeParameters.map(make$10)), (...typeParameters) => options.encode(...typeParameters.map(make$10)), toASTAnnotations(annotations)));
26489
26489
  const declarePrimitive = (is, annotations) => {
26490
- const decodeUnknown = () => (input, _, ast) => is(input) ? succeed(input) : fail(new Type(ast, input));
26490
+ const decodeUnknown = () => (input, _, ast) => is(input) ? succeed(input) : fail$3(new Type(ast, input));
26491
26491
  return makeDeclareClass([], new Declaration([], decodeUnknown, decodeUnknown, toASTAnnotations(annotations)));
26492
26492
  };
26493
26493
  function makeDeclareClass(typeParameters, ast) {
@@ -27615,7 +27615,7 @@ const nonNegative = (annotations) => greaterThanOrEqualTo(0, {
27615
27615
  function parseNumber(self) {
27616
27616
  return transformOrFail(self, Number$, {
27617
27617
  strict: false,
27618
- decode: (i, _, ast) => fromOption(parse$1(i), () => new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a number`)),
27618
+ decode: (i, _, ast) => fromOption(parse$2(i), () => new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a number`)),
27619
27619
  encode: (a) => succeed(String(a))
27620
27620
  });
27621
27621
  }
@@ -27651,7 +27651,7 @@ transform$1(/*#__PURE__*/ Boolean$.annotations({ description: "a boolean that wi
27651
27651
  });
27652
27652
  const encodeSymbol = (sym, ast) => {
27653
27653
  const key = Symbol.keyFor(sym);
27654
- return key === void 0 ? fail(new Type(ast, sym, `Unable to encode a unique symbol ${String(sym)} into a string`)) : succeed(key);
27654
+ return key === void 0 ? fail$3(new Type(ast, sym, `Unable to encode a unique symbol ${String(sym)} into a string`)) : succeed(key);
27655
27655
  };
27656
27656
  const decodeSymbol = (s) => succeed(Symbol.for(s));
27657
27657
  transformOrFail(String$.annotations({ description: "a string to be decoded into a globally shared symbol" }), SymbolFromSelf, {
@@ -27737,7 +27737,7 @@ transformOrFail(NonNegativeBigIntFromSelf.annotations({ description: "a bigint t
27737
27737
  strict: true,
27738
27738
  decode: (i) => succeed(nanos(i)),
27739
27739
  encode: (a, _, ast) => match$8(toNanos(a), {
27740
- onNone: () => fail(new Type(ast, a, `Unable to encode ${a} into a bigint`)),
27740
+ onNone: () => fail$3(new Type(ast, a, `Unable to encode ${a} into a bigint`)),
27741
27741
  onSome: (nanos) => succeed(nanos)
27742
27742
  })
27743
27743
  }).annotations({ identifier: "DurationFromNanos" });
@@ -27961,7 +27961,7 @@ var TimeZoneFromSelf = class extends Union(TimeZoneOffsetFromSelf, TimeZoneNamed
27961
27961
  transformOrFail(String$.annotations({ description: "a string to be decoded into a TimeZone" }), TimeZoneFromSelf, {
27962
27962
  strict: true,
27963
27963
  decode: (i, _, ast) => match$8(zoneFromString(i), {
27964
- onNone: () => fail(new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a TimeZone`)),
27964
+ onNone: () => fail$3(new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a TimeZone`)),
27965
27965
  onSome: succeed
27966
27966
  }),
27967
27967
  encode: (a) => succeed(zoneToString(a))
@@ -27987,7 +27987,7 @@ var DateTimeZonedFromSelf = class extends declare((u) => isDateTime(u) && isZone
27987
27987
  transformOrFail(String$.annotations({ description: "a string to be decoded into a DateTime.Zoned" }), DateTimeZonedFromSelf, {
27988
27988
  strict: true,
27989
27989
  decode: (i, _, ast) => match$8(makeZonedFromString(i), {
27990
- onNone: () => fail(new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a DateTime.Zoned`)),
27990
+ onNone: () => fail$3(new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a DateTime.Zoned`)),
27991
27991
  onSome: succeed
27992
27992
  }),
27993
27993
  encode: (a) => succeed(formatIsoZoned(a))
@@ -28001,7 +28001,7 @@ const optionPretty = (value) => match$8({
28001
28001
  onNone: () => "none()",
28002
28002
  onSome: (a) => `some(${value(a)})`
28003
28003
  });
28004
- const optionParse = (decodeUnknown) => (u, options, ast) => isOption(u) ? isNone(u) ? succeed(none$4()) : toComposite(decodeUnknown(u.value, options), some, ast, u) : fail(new Type(ast, u));
28004
+ const optionParse = (decodeUnknown) => (u, options, ast) => isOption(u) ? isNone(u) ? succeed(none$4()) : toComposite(decodeUnknown(u.value, options), some, ast, u) : fail$3(new Type(ast, u));
28005
28005
  const OptionFromSelf_ = (value) => {
28006
28006
  return declare([value], {
28007
28007
  decode: (value) => optionParse(decodeUnknown$1(value)),
@@ -28044,7 +28044,7 @@ var BigDecimalFromSelf = class extends declare(isBigDecimal, {
28044
28044
  transformOrFail(String$.annotations({ description: "a string to be decoded into a BigDecimal" }), BigDecimalFromSelf, {
28045
28045
  strict: true,
28046
28046
  decode: (i, _, ast) => fromString$1(i).pipe(match$8({
28047
- onNone: () => fail(new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a BigDecimal`)),
28047
+ onNone: () => fail$3(new Type(ast, i, `Unable to decode ${JSON.stringify(i)} into a BigDecimal`)),
28048
28048
  onSome: (val) => succeed(normalize(val))
28049
28049
  })),
28050
28050
  encode: (a) => succeed(format$1(normalize(a)))
@@ -28166,7 +28166,7 @@ const makeClass = ({ Base, annotations, disableToString, fields, identifier, kin
28166
28166
  let out = astCache.get(this);
28167
28167
  if (out) return out;
28168
28168
  const declaration = declare([schema], {
28169
- decode: () => (input, _, ast) => input instanceof this || fallbackInstanceOf(input) ? succeed(input) : fail(new Type(ast, input)),
28169
+ decode: () => (input, _, ast) => input instanceof this || fallbackInstanceOf(input) ? succeed(input) : fail$3(new Type(ast, input)),
28170
28170
  encode: () => (input, options) => input instanceof this ? succeed(input) : map(encodeUnknown(typeSide)(input, options), (props) => new this(props, true))
28171
28171
  }, {
28172
28172
  identifier,
@@ -28393,7 +28393,7 @@ const causePretty = (error) => (cause) => {
28393
28393
  };
28394
28394
  return f(cause);
28395
28395
  };
28396
- const causeParse = (decodeUnknown) => (u, options, ast) => isCause(u) ? toComposite(decodeUnknown(causeEncode(u), options), causeDecode, ast, u) : fail(new Type(ast, u));
28396
+ const causeParse = (decodeUnknown) => (u, options, ast) => isCause(u) ? toComposite(decodeUnknown(causeEncode(u), options), causeDecode, ast, u) : fail$3(new Type(ast, u));
28397
28397
  /**
28398
28398
  * @category Cause transformations
28399
28399
  * @since 3.10.0
@@ -28412,7 +28412,7 @@ const CauseFromSelf = ({ defect, error }) => {
28412
28412
  function causeDecode(cause) {
28413
28413
  switch (cause._tag) {
28414
28414
  case "Empty": return empty$12;
28415
- case "Fail": return fail$6(cause.error);
28415
+ case "Fail": return fail$9(cause.error);
28416
28416
  case "Die": return die$2(cause.defect);
28417
28417
  case "Interrupt": return interrupt$3(fiberIdDecode(cause.fiberId));
28418
28418
  case "Sequential": return sequential$2(causeDecode(cause.left), causeDecode(cause.right));
@@ -28995,11 +28995,11 @@ var SystemError = class extends TaggedError("@effect/platform/Error/SystemError"
28995
28995
  const effectify$1 = (fn, onError, onSyncError) => (...args) => async((resume) => {
28996
28996
  try {
28997
28997
  fn(...args, (err, result) => {
28998
- if (err) resume(fail$2(onError ? onError(err, args) : err));
28998
+ if (err) resume(fail$5(onError ? onError(err, args) : err));
28999
28999
  else resume(succeed$3(result));
29000
29000
  });
29001
29001
  } catch (err) {
29002
- resume(onSyncError ? fail$2(onSyncError(err, args)) : die(err));
29002
+ resume(onSyncError ? fail$5(onSyncError(err, args)) : die(err));
29003
29003
  }
29004
29004
  });
29005
29005
  //#endregion
@@ -29020,7 +29020,7 @@ bigint1024 * bigint1024 * bigint1024 * bigint1024 * bigint1024;
29020
29020
  const make$7 = (impl) => {
29021
29021
  return tag$1.of({
29022
29022
  ...impl,
29023
- exists: (path) => pipe(impl.access(path), as(true), catchTag("SystemError", (e) => e.reason === "NotFound" ? succeed$3(false) : fail$2(e))),
29023
+ exists: (path) => pipe(impl.access(path), as(true), catchTag("SystemError", (e) => e.reason === "NotFound" ? succeed$3(false) : fail$5(e))),
29024
29024
  readFileString: (path, encoding) => tryMap(impl.readFile(path), {
29025
29025
  try: (_) => new TextDecoder(encoding).decode(_),
29026
29026
  catch: (cause) => new BadArgument({
@@ -29840,7 +29840,7 @@ const layerManager$3 = /*#__PURE__*/ effect$1(WorkerManager, /* @__PURE__ */ gen
29840
29840
  return DeferredTypeId in mailbox ? succeed$7(mailbox, response[2][0]) : zipRight$1(mailbox.offerAll(response[2]), mailbox.end);
29841
29841
  case 2:
29842
29842
  case 3: {
29843
- if (response[1] === 2) return DeferredTypeId in mailbox ? fail$5(mailbox, response[2]) : mailbox.fail(response[2]);
29843
+ if (response[1] === 2) return DeferredTypeId in mailbox ? fail$8(mailbox, response[2]) : mailbox.fail(response[2]);
29844
29844
  const cause = WorkerError.decodeCause(response[2]);
29845
29845
  return DeferredTypeId in mailbox ? failCause$5(mailbox, cause) : mailbox.failCause(cause);
29846
29846
  }
@@ -30144,7 +30144,7 @@ const makeFile = /*#__PURE__*/ (() => {
30144
30144
  }
30145
30145
  writeAllChunk(buffer) {
30146
30146
  return flatMap$4(suspend$5(() => nodeWriteAll(this.fd, buffer, void 0, void 0, this.append ? void 0 : Number(this.position))), (bytesWritten) => {
30147
- if (bytesWritten === 0) return fail$2(new SystemError({
30147
+ if (bytesWritten === 0) return fail$5(new SystemError({
30148
30148
  module: "FileSystem",
30149
30149
  method: "writeAll",
30150
30150
  reason: "WriteZero",
@@ -30180,11 +30180,11 @@ const readDirectory = (path, options) => tryPromise({
30180
30180
  const readFile$1 = (path) => async((resume, signal) => {
30181
30181
  try {
30182
30182
  NFS.readFile(path, { signal }, (err, data) => {
30183
- if (err) resume(fail$2(handleErrnoException("FileSystem", "readFile")(err, [path])));
30183
+ if (err) resume(fail$5(handleErrnoException("FileSystem", "readFile")(err, [path])));
30184
30184
  else resume(succeed$3(data));
30185
30185
  });
30186
30186
  } catch (err) {
30187
- resume(fail$2(handleBadArgument("readFile")(err)));
30187
+ resume(fail$5(handleBadArgument("readFile")(err)));
30188
30188
  }
30189
30189
  });
30190
30190
  const readLink = /*#__PURE__*/ (() => {
@@ -30238,7 +30238,7 @@ const watchNode = (path, options) => asyncScoped((emit) => acquireRelease(sync$1
30238
30238
  case "rename":
30239
30239
  emit.fromEffect(matchEffect(stat(path), {
30240
30240
  onSuccess: (_) => succeed$3(WatchEventCreate({ path })),
30241
- onFailure: (err) => err._tag === "SystemError" && err.reason === "NotFound" ? succeed$3(WatchEventRemove({ path })) : fail$2(err)
30241
+ onFailure: (err) => err._tag === "SystemError" && err.reason === "NotFound" ? succeed$3(WatchEventRemove({ path })) : fail$5(err)
30242
30242
  }));
30243
30243
  return;
30244
30244
  case "change":
@@ -30268,11 +30268,11 @@ const writeFile$1 = (path, data, options) => async((resume, signal) => {
30268
30268
  flag: options?.flag,
30269
30269
  mode: options?.mode
30270
30270
  }, (err) => {
30271
- if (err) resume(fail$2(handleErrnoException("FileSystem", "writeFile")(err, [path])));
30271
+ if (err) resume(fail$5(handleErrnoException("FileSystem", "writeFile")(err, [path])));
30272
30272
  else resume(_void);
30273
30273
  });
30274
30274
  } catch (err) {
30275
- resume(fail$2(handleBadArgument("writeFile")(err)));
30275
+ resume(fail$5(handleBadArgument("writeFile")(err)));
30276
30276
  }
30277
30277
  });
30278
30278
  //#endregion
@@ -30356,7 +30356,7 @@ const unsafeReadableRead = (readable, onError, exit, options) => {
30356
30356
  latch.unsafeOpen();
30357
30357
  }
30358
30358
  function onErr(err) {
30359
- exit.current = fail$3(onError(err));
30359
+ exit.current = fail$6(onError(err));
30360
30360
  latch.unsafeOpen();
30361
30361
  }
30362
30362
  function onEnd() {
@@ -30396,7 +30396,7 @@ const fromWritable = (evaluate, onError, options) => fromChannel(fromWritableCha
30396
30396
  const fromWritableChannel = (writable, onError, options) => flatMap$1(zip$1(sync$1(() => writable()), make$35()), ([writable, deferred]) => embedInput(writableOutput(writable, deferred, onError), writeInput(writable, (cause) => failCause$5(deferred, cause), options, complete$1(deferred, _void))));
30397
30397
  const writableOutput = (writable, deferred, onError) => suspend$5(() => {
30398
30398
  function handleError(err) {
30399
- unsafeDone(deferred, fail$2(onError(err)));
30399
+ unsafeDone(deferred, fail$5(onError(err)));
30400
30400
  }
30401
30401
  writable.on("error", handleError);
30402
30402
  return ensuring$2(_await$2(deferred), sync$1(() => {
@@ -30444,7 +30444,7 @@ const runCommand$1 = (fileSystem) => (command) => {
30444
30444
  detached: process.platform !== "win32"
30445
30445
  });
30446
30446
  handle.on("error", (err) => {
30447
- resume(fail$2(toPlatformError("spawn", err, command)));
30447
+ resume(fail$5(toPlatformError("spawn", err, command)));
30448
30448
  });
30449
30449
  handle.on("exit", (...args) => {
30450
30450
  unsafeDone(exitCode, succeed$3(args));
@@ -30458,14 +30458,14 @@ const runCommand$1 = (fileSystem) => (command) => {
30458
30458
  }));
30459
30459
  const killProcessGroup = process.platform === "win32" ? (handle, _) => async((resume) => {
30460
30460
  ChildProcess.exec(`taskkill /pid ${handle.pid} /T /F`, (error) => {
30461
- if (error) resume(fail$2(toPlatformError("kill", toError$2(error), command)));
30461
+ if (error) resume(fail$5(toPlatformError("kill", toError$2(error), command)));
30462
30462
  else resume(_void);
30463
30463
  });
30464
30464
  }) : (handle, signal) => try_({
30465
30465
  try: () => process.kill(-handle.pid, signal),
30466
30466
  catch: (error) => toPlatformError("kill", toError$2(error), command)
30467
30467
  });
30468
- const killProcess = (handle, signal) => suspend$5(() => handle.kill(signal) ? _void : fail$2(toPlatformError("kill", new globalThis.Error("Failed to kill process"), command)));
30468
+ const killProcess = (handle, signal) => suspend$5(() => handle.kill(signal) ? _void : fail$5(toPlatformError("kill", new globalThis.Error("Failed to kill process"), command)));
30469
30469
  return pipe(match$8(command.cwd, {
30470
30470
  onNone: () => _void,
30471
30471
  onSome: (dir) => fileSystem.access(dir)
@@ -30480,7 +30480,7 @@ const runCommand$1 = (fileSystem) => (command) => {
30480
30480
  if (handle.stdin !== null) stdin = fromWritable(() => handle.stdin, (err) => toPlatformError("toWritable", toError$2(err), command));
30481
30481
  const exitCode = flatMap$4(_await$2(exitCodeDeferred), ([code, signal]) => {
30482
30482
  if (code !== null) return succeed$3(ExitCode(code));
30483
- return fail$2(toPlatformError("exitCode", new globalThis.Error(`Process interrupted due to receipt of signal: ${signal}`), command));
30483
+ return fail$5(toPlatformError("exitCode", new globalThis.Error(`Process interrupted due to receipt of signal: ${signal}`), command));
30484
30484
  });
30485
30485
  const isRunning = negate(isDone$4(exitCodeDeferred));
30486
30486
  const kill = (signal = "SIGTERM") => killProcessGroup(handle, signal).pipe(orElse$1(() => killProcess(handle, signal)), zipRight$1(asVoid(_await$2(exitCodeDeferred))));
@@ -30611,7 +30611,7 @@ const layer = /*#__PURE__*/ pipe(/*#__PURE__*/ mergeAll$1(layer$3, layer$5, /* @
30611
30611
  return sync$1(() => readlineInterface.off("line", onLine));
30612
30612
  })), scoped$3);
30613
30613
  const display = (prompt) => uninterruptible(async((resume) => {
30614
- stdout.write(prompt, (err) => err ? resume(fail$2(new BadArgument({
30614
+ stdout.write(prompt, (err) => err ? resume(fail$5(new BadArgument({
30615
30615
  module: "Terminal",
30616
30616
  method: "display",
30617
30617
  description: "Failed to write prompt to stdout",
@@ -40599,7 +40599,7 @@ function serializeChunks(chunks, expandTabs) {
40599
40599
  * @returns {ParseContext}
40600
40600
  * Parser.
40601
40601
  */
40602
- function parse(options) {
40602
+ function parse$1(options) {
40603
40603
  /** @type {ParseContext} */
40604
40604
  const parser = {
40605
40605
  constructs: combineExtensions([constructs_exports, ...(options || {}).extensions || []]),
@@ -40914,7 +40914,7 @@ function fromMarkdown(value, encoding, options) {
40914
40914
  options = encoding;
40915
40915
  encoding = void 0;
40916
40916
  }
40917
- return compiler(options)(postprocess(parse(options).document().write(preprocess()(value, encoding, true))));
40917
+ return compiler(options)(postprocess(parse$1(options).document().write(preprocess()(value, encoding, true))));
40918
40918
  }
40919
40919
  /**
40920
40920
  * Note this compiler only understand complete buffering, not streaming.
@@ -47049,6 +47049,65 @@ const reviewDescriptor = {
47049
47049
  clearTicks: reviewClearTicks,
47050
47050
  openThreads: openThreadsOf
47051
47051
  };
47052
+ const pointerLabel = (f) => `${f.path}${f.line === void 0 ? "" : `#${f.line}${f.rangeEnd === void 0 ? "" : `-${f.rangeEnd}`}`}`;
47053
+ const chunkNote = (chunk, prior) => chunk.description === (prior?.description ?? "") ? [] : [{
47054
+ line: chunk.headingLine,
47055
+ note: {
47056
+ kind: "chunk",
47057
+ anchor: chunk.title,
47058
+ before: prior?.description ?? "",
47059
+ text: chunk.description
47060
+ }
47061
+ }];
47062
+ const pointerNotes = (chunk, prior) => chunk.files.flatMap((file) => {
47063
+ const label = pointerLabel(file);
47064
+ const was = prior?.files.find((f) => pointerLabel(f) === label);
47065
+ if (file.note === void 0 || file.note === (was?.note ?? "")) return [];
47066
+ return [{
47067
+ line: file.sourceLine,
47068
+ note: {
47069
+ kind: "pointer",
47070
+ anchor: `${chunk.title} ${label}`,
47071
+ before: was?.note ?? "",
47072
+ text: file.note
47073
+ }
47074
+ }];
47075
+ });
47076
+ const footnoteNotes = (before, after) => {
47077
+ const lines = after.split(/\r?\n/);
47078
+ const threadNames = new Set(parseThreads(after).map((t) => t.name));
47079
+ const knownNames = new Set(parseFootnotes(before).definitions.map((d) => d.name));
47080
+ const parsed = parseFootnotes(after);
47081
+ const markerOf = new Map(parsed.markers.map((m) => [m.name, m.line]));
47082
+ return parsed.definitions.filter((def) => !threadNames.has(def.name) && !knownNames.has(def.name)).map((def) => {
47083
+ const at = markerOf.get(def.name);
47084
+ return {
47085
+ line: def.line,
47086
+ note: {
47087
+ kind: "footnote",
47088
+ anchor: at === void 0 ? `[^${def.name}]` : (lines[at] ?? "").trim(),
47089
+ before: "",
47090
+ text: def.body
47091
+ }
47092
+ };
47093
+ });
47094
+ };
47095
+ /**
47096
+ * Every note the human added to `after` relative to `before`, in document
47097
+ * order: pointer notes, one-shot footnotes (never `H:`/`A:` threads) and
47098
+ * chunk prose.
47099
+ */
47100
+ const reviewNotes = (before, after) => {
47101
+ if (before === after) return [];
47102
+ const oldChunks = new Map(parseReviewDoc(before).changesets.map((c) => [c.title, c]));
47103
+ return [...parseReviewDoc(after).changesets.flatMap((chunk) => {
47104
+ const prior = oldChunks.get(chunk.title);
47105
+ return [...chunkNote(chunk, prior), ...pointerNotes(chunk, prior)];
47106
+ }), ...footnoteNotes(before, after)].sort((a, b) => a.line - b.line).map((f, i) => ({
47107
+ id: `note-${i + 1}`,
47108
+ ...f.note
47109
+ }));
47110
+ };
47052
47111
  //#endregion
47053
47112
  //#region src/steering/freeform.ts
47054
47113
  const FREE_FORM_SAMPLE = `Sample plan. Add a thing.
@@ -48001,10 +48060,11 @@ questions, then write one package spec per concern with no further
48001
48060
  judgement call: the grouping is already decided.`;
48002
48061
  const reviewerPersona = `You are the independent reviewing mind in gtd's build pipeline —
48003
48062
  deliberately separate from whoever wrote the code, with no attachment
48004
- to it. Two turns: write a structured review document grouping a diff
48005
- into chunks; later, classify a round of the human's feedback as
48006
- actionable or just approving, never fixing anything yourself. You judge
48007
- and classify; you never build.`;
48063
+ to it. Write a structured review document grouping a diff into
48064
+ chunks; classify a round of the human's feedback as actionable or
48065
+ just approving; answer the human's questions inline in the review;
48066
+ and, when asked, fix the small nits the human flagged in one batch.
48067
+ Beyond that you never fix or build anything yourself.`;
48008
48068
  const specReviewerPersona = `You are the adversarial spec-conformance checker in gtd's build
48009
48069
  pipeline, checking one freshly-built package against its spec. Verify
48010
48070
  only: tasks done, criteria met, code sound and consistent with the
@@ -48631,19 +48691,25 @@ When you've been through the whole diff, run \`gtd land\`:
48631
48691
  rests at this same gate again — no revert, no development lap. A
48632
48692
  round that also leaves notes or edits folds those in the same turn
48633
48693
  and answers the thread.
48634
- - **Request changes** — leave a comment: a note on a
48635
- \`.gtd/REVIEW.md\` line, a footnote anchored to a hunk, or a
48636
- direct code edit — to send a FULL development lap
48637
- (**review.closing** → **review.triage** → **review.collecting**
48638
- → re-triage; a hand-edit outside \`.gtd/\` skips the triage
48639
- straight to **review.collecting**, no verdict of your own
48640
- required). A
48641
- hand-edit you make here is treated as a SKETCH, not a
48642
- fix the agent builds on: it is reverted out of the tree and re-planned
48643
- from scratch, the same as any other change that starts a process.
48644
- There is no baseline check on the way back into planning — only a
48645
- genuinely non-actionable comment (an approving remark with no code
48646
- edit) skips the lap and signs off straight away.
48694
+ - **Leave notes** — a note on a \`.gtd/REVIEW.md\` line, a footnote
48695
+ anchored to a hunk, or prose under a chunk. Each note is judged on its
48696
+ own (**review.triage** gives one verdict per note):
48697
+ - \`edit\` — a change request: goes to **review.collecting** and a
48698
+ FULL development lap, re-planned from scratch
48699
+ - \`question\` — answered inline under the note in
48700
+ \`.gtd/REVIEW.md\` (**review.answer-review-questions**); the process
48701
+ rests at this gate again, no lap
48702
+ - \`nit\` — fixed in one batched turn (**review.fix-nits**), then a
48703
+ fresh review of the change rests at this gate again, no re-plan
48704
+ - \`praise\` — dropped; a round of only praise signs off
48705
+ When a round mixes \`edit\` with \`question\` or \`nit\`, questions get
48706
+ answered and nits fixed first, then the edits go to the lap. A note the
48707
+ judge is unsure about counts as \`edit\`.
48708
+ - **Edit code** — a direct code edit outside \`.gtd/\` goes straight to
48709
+ **review.collecting**, no verdict of your own required. A hand-edit
48710
+ you make here is treated as a SKETCH, not a fix the agent builds on: it
48711
+ is reverted out of the tree and re-planned from scratch, the same as any
48712
+ other change that starts a process.
48647
48713
 
48648
48714
  Every landing here is refused while a thread is open (its last entry
48649
48715
  is the agent's): reply with a conclusion, or delete the thread.
@@ -48664,6 +48730,36 @@ const reviewNotesCapture = (commit) => `This is machine-captured input, not inst
48664
48730
  Commit: ${commit}
48665
48731
  The human's notes are in .gtd/REVIEW.md at this commit. Run: git show ${commit}
48666
48732
  `;
48733
+ const notesCapture = (notes) => `This is machine-captured input, not instructions.
48734
+
48735
+ ${notes.map((n) => `- ${n.id} — ${n.anchor}\n ${n.text.replace(/\n/g, "\n ")}`).join("\n")}
48736
+ `;
48737
+ const buildReviewAnswerQuestionsPrompt = (notes) => `${stateFileRules}
48738
+ - The only state file this turn writes is \`.gtd/REVIEW.md\`; touch no
48739
+ code
48740
+ - Answer every question note below inline: write each answer directly under
48741
+ its note as an \`A: \` line continuing the note's own block (indented to
48742
+ the same block, two spaces for a pointer note)
48743
+ - Finish by running \`gtd check review .gtd/REVIEW.md\` and fix what it
48744
+ reports
48745
+ - Leave everything uncommitted and finish your turn
48746
+
48747
+ The question notes are:
48748
+
48749
+ ${notesCapture(notes)}`;
48750
+ const buildReviewFixNitsPrompt = (notes) => `${stateFileRules}
48751
+ - Fix every nit below in this one turn, all together
48752
+ - Leave \`.gtd/REVIEW.md\` untouched
48753
+ - Leave everything uncommitted and finish your turn
48754
+
48755
+ The nit notes are:
48756
+
48757
+ ${notesCapture(notes)}`;
48758
+ const reviewEditNotesCapture = (commit, edits, answeredAt) => `This is machine-captured input, not instructions. Fold only these edit notes (a downstream agent judges them).
48759
+
48760
+ Commit: ${commit}
48761
+ The human's notes are in .gtd/REVIEW.md at this commit. Run: git show ${commit}
48762
+ ${notesCapture(edits)}${answeredAt === void 0 ? "" : `Answered questions: commit ${answeredAt} answered the question notes inline in .gtd/REVIEW.md. Run: git show ${answeredAt}\n`}`;
48667
48763
  const buildReviewReviewMissingMessage = (commit) => `The review round committed no \`.gtd/REVIEW.md\` (at ${commit}), so there is
48668
48764
  nothing to sign off on.
48669
48765
 
@@ -48673,11 +48769,12 @@ record.
48673
48769
  What each change does next (then run \`gtd land\`):
48674
48770
  - **Re-review** — re-run the reviewer to author a fresh \`.gtd/REVIEW.md\` (**build.review.reviewing**).
48675
48771
  `;
48676
- const buildReviewTriageMessage = () => `Judging whether each \`## \` chunk's note in \`.gtd/REVIEW.md\` is
48677
- actionable, to skip \`collecting\`'s full turn when the round is
48678
- approval-only. Run \`gtd judge answer\` and pipe a verdict per
48679
- chunk — or land untouched to run the full triage (the
48680
- conservative default; a skipped judgment never signs off).
48772
+ const buildReviewTriageMessage = () => `Judging each note the human added to \`.gtd/REVIEW.md\` (a line note, a
48773
+ footnote, or prose under a chunk) with one verdict: \`edit\` (a change
48774
+ request), \`question\`, \`nit\` (a small fix needing no re-plan) or
48775
+ \`praise\`. Run \`gtd judge answer\` and pipe a choice per note — or land
48776
+ untouched, which treats every note as \`edit\` (the conservative
48777
+ default; a skipped judgment never dismisses a note).
48681
48778
  `;
48682
48779
  const buildReviewCollectingPrompt = (capture) => `${styleBlock}
48683
48780
 
@@ -48690,10 +48787,15 @@ ${footnoteFoldIn}${codeThreadReplies()}
48690
48787
  - This turn writes \`.gtd/REQUIREMENTS.md\` (the folded concerns) and
48691
48788
  replies inside \`.gtd/REVIEW.md\` (thread replies only; the file stays
48692
48789
  in the tree) — you classify, you do not build
48693
- - Fold every concluded thread, note, ticked answer and hand-edit into
48790
+ - Fold every concluded thread, ticked answer and hand-edit — and each
48791
+ \`edit\` note the capture lists, no other note — into
48694
48792
  \`.gtd/REQUIREMENTS.md\` and delete the folded threads from
48695
48793
  \`.gtd/REVIEW.md\`; append one \`- A:\` reply to each thread
48696
48794
  whose last entry is a \`- H:\` question
48795
+ - When the capture names an answering commit, carry each answered
48796
+ question into \`.gtd/REQUIREMENTS.md\`'s \`## Answered Questions\` as
48797
+ \`### <the note>\` plus its answer — the lap replaces \`.gtd/REVIEW.md\`
48798
+ - Nit notes were already fixed: never re-raise a fixed nit as a concern
48697
48799
  - Finish by running \`gtd check review .gtd/REVIEW.md\` and fix
48698
48800
  what it reports
48699
48801
 
@@ -48734,7 +48836,7 @@ actionability, and never dismiss a real note or edit as approval.
48734
48836
  - If not: finish without writing anything — changing nothing is
48735
48837
  the sign-off
48736
48838
  `;
48737
- const buildReviewReviewingPrompt = (base) => `${styleBlock}
48839
+ const buildReviewReviewingPrompt = (base, carry) => `${styleBlock}
48738
48840
 
48739
48841
  ${styleFormatContract}
48740
48842
 
@@ -48773,7 +48875,12 @@ from \`${base}\` to the working tree (committed turns
48773
48875
  plus anything pending); on a feedback round that's the previous
48774
48876
  review's boundary, so it covers only what's new.
48775
48877
 
48776
- Leave \`.gtd/REVIEW.md\` uncommitted and finish.
48878
+ ${carry === void 0 ? "" : `Carry-over: commit \`${carry}\` answered questions inline in the previous
48879
+ review (each \`A: \` line under the note it answers). Copy each answered
48880
+ note and its \`A: \` answer, verbatim, under the matching hunk of this fresh
48881
+ review. Run: git show ${carry}
48882
+
48883
+ `}Leave \`.gtd/REVIEW.md\` uncommitted and finish.
48777
48884
  `;
48778
48885
  /** `gtd summary`'s prompt: printed cold, no session identity, no diff inlined. */
48779
48886
  const summaryPrompt = (it) => {
@@ -48819,7 +48926,7 @@ const SPEC_FEEDBACK = ".gtd/SPEC_FEEDBACK.md";
48819
48926
  const planner = () => vars.plannerModel ?? "";
48820
48927
  const coder = () => vars.coderModel ?? "";
48821
48928
  /** Turn the sketch since `base` into `.gtd/REQUIREMENTS.md`. */
48822
- const triage = (base) => agentWithSkills("triage", vars.triageSkills, designTriagePrompt(base), {
48929
+ const triage$1 = (base) => agentWithSkills("triage", vars.triageSkills, designTriagePrompt(base), {
48823
48930
  label: "Triaging the change",
48824
48931
  file: REQUIREMENTS,
48825
48932
  mode: "qa",
@@ -48916,8 +49023,8 @@ const fixQuality = () => agentWithSkills("fix-quality", vars.reviewFixSkills, bu
48916
49023
  system: finisherSystem(),
48917
49024
  allowEmpty: true
48918
49025
  });
48919
- /** Write `.gtd/REVIEW.md` over everything since `base`. */
48920
- const reviewing = (base) => agentWithSkills("review.reviewing", vars.reviewSkills, buildReviewReviewingPrompt(base), {
49026
+ /** Write `.gtd/REVIEW.md` over everything since `base`, carrying the answers of commit `carry` when given. */
49027
+ const reviewing = (base, carry) => agentWithSkills("review.reviewing", vars.reviewSkills, buildReviewReviewingPrompt(base, carry), {
48921
49028
  label: "Reviewing",
48922
49029
  file: REVIEW,
48923
49030
  mode: "review",
@@ -48925,6 +49032,24 @@ const reviewing = (base) => agentWithSkills("review.reviewing", vars.reviewSkill
48925
49032
  system: reviewerSystem(),
48926
49033
  base
48927
49034
  });
49035
+ /** Answer every `question` note inline in `.gtd/REVIEW.md`. */
49036
+ const answerReviewQuestions = (notes) => agentWithSkills("review.answer-review-questions", vars.reviewSkills, buildReviewAnswerQuestionsPrompt(notes), {
49037
+ label: "Answering your questions",
49038
+ file: REVIEW,
49039
+ mode: "review",
49040
+ model: planner(),
49041
+ system: reviewerSystem()
49042
+ });
49043
+ /**
49044
+ * Fix every `nit` note in one turn. Its name puts it in the `build.review`
49045
+ * conversation, which has one identity — so it runs as the reviewer, not the coder.
49046
+ */
49047
+ const fixNits = (notes) => agentWithSkills("review.fix-nits", vars.reviewFixSkills, buildReviewFixNitsPrompt(notes), {
49048
+ label: "Fixing your nits",
49049
+ file: REVIEW,
49050
+ model: planner(),
49051
+ system: reviewerSystem()
49052
+ });
48928
49053
  const awaitReview = (base) => human("review.await-review", {
48929
49054
  message: buildReviewAwaitReviewMessage(base),
48930
49055
  label: "Awaiting your review",
@@ -48973,8 +49098,8 @@ const retryQuestion = (comparable) => comparable ? {
48973
49098
  } : {
48974
49099
  id: "verdict",
48975
49100
  primitive: "choice",
48976
- instructions: "state carries tailsNotComparable: one of the two check reports came back empty. There is nothing to compare here; answer from criteria alone.",
48977
- criteria: "identical is FORBIDDEN here — answer new-failure or progress instead, defaulting to progress if genuinely unsure."
49101
+ instructions: "state carries tailsNotComparable: one of the two check reports came back empty. There is nothing to compare here; answer from criteria alone. `identical` is FORBIDDEN here.",
49102
+ criteria: "new-failure: a materially different failure than before. progress: still red, but closer to green — the default if genuinely unsure."
48978
49103
  };
48979
49104
  const sameFailure = async (previous, current) => {
48980
49105
  const comparable = current.trim() !== "" && previous.trim() !== "";
@@ -49364,7 +49489,7 @@ const noteGate = async (file, answer) => {
49364
49489
  /** Triage the sketch since `base` into requirements, until no product question is open. */
49365
49490
  const design = (base) => scope("design", async () => {
49366
49491
  do {
49367
- await triage(base);
49492
+ await triage$1(base);
49368
49493
  requireProgress(REQUIREMENTS);
49369
49494
  requireReplies(REQUIREMENTS);
49370
49495
  } while (await noteGate(REQUIREMENTS, answerProductQuestions));
@@ -49423,29 +49548,37 @@ const fixQualityFindings = async (escalations) => {
49423
49548
  await escalation(escalations);
49424
49549
  return false;
49425
49550
  };
49426
- /** One noul per `## ` chunk of `.gtd/REVIEW.md`: is its note actionable? */
49427
- const triageQuestions = (chunks) => chunks.map((title, i) => ({
49428
- id: `chunk-${i + 1}`,
49429
- primitive: "noul",
49430
- instructions: `Is the note under review chunk "${title}" (in .gtd/REVIEW.md) actionable — anything beyond an approving remark with no code edit?`,
49431
- criteria: "A concrete request, a question, a code comment, or a hand-edit under this chunk answers yes. No note, or a purely approving remark, answers no."
49432
- }));
49433
- /** A note-only round: judge whether any chunk of `review` asks for something. */
49434
- const actionable = async (review) => {
49435
- const found = sectionBodies(review);
49436
- const chunks = found.map((section) => section.title);
49437
- const evidence = Object.fromEntries(found.map(({ body }, i) => [`chunk-${i + 1}`, body]));
49551
+ const VERDICTS = [
49552
+ "edit",
49553
+ "question",
49554
+ "nit",
49555
+ "praise"
49556
+ ];
49557
+ /** One four-way choice per note the human added to `.gtd/REVIEW.md`. */
49558
+ const verdictQuestion = (note) => ({
49559
+ id: note.id,
49560
+ primitive: "choice",
49561
+ instructions: `Classify the human's note on review item "${note.anchor}" (in .gtd/REVIEW.md). Its evidence holds the anchor, the reviewer's text and the human's text.`,
49562
+ criteria: "edit: a request to change behaviour, design or scope — anything needing a plan, or any note you are unsure about. question: asks something and wants an answer, with no change requested. nit: a small, local, unambiguous fix (naming, typo, formatting, comment wording) needing no re-plan. praise: an approving remark with nothing to do."
49563
+ });
49564
+ /**
49565
+ * One judge rest, one verdict per note. Dismissing a note is the risky
49566
+ * direction, so only a confident non-`edit` verdict on uncut evidence counts;
49567
+ * a cut, unanswered or below-floor note is an `edit`, and a blank floor makes
49568
+ * every note one.
49569
+ */
49570
+ const triage = async (notes) => {
49438
49571
  const { answers, truncated } = await judge("review.triage", {
49439
- questions: triageQuestions(chunks),
49440
- evidence,
49572
+ questions: notes.map(verdictQuestion),
49573
+ evidence: Object.fromEntries(notes.map((n) => [n.id, `Anchor: ${n.anchor}\nReviewer's text: ${n.before}\nHuman's text: ${n.text}`])),
49441
49574
  message: buildReviewTriageMessage(),
49442
- label: "Judging feedback actionability"
49575
+ label: "Judging each note"
49443
49576
  });
49444
49577
  const minP = numeric(vars.reviewNoteActionable, Infinity);
49445
- return chunks.length === 0 || chunks.some((_, i) => {
49446
- const id = `chunk-${i + 1}`;
49447
- return truncated.includes(id) || !answered(answers[id], "no", minP);
49448
- });
49578
+ return new Map(notes.map((n) => {
49579
+ const verdict = VERDICTS.find((v) => v !== "edit" && answered(answers[n.id], v, minP));
49580
+ return [n.id, truncated.includes(n.id) || verdict === void 0 ? "edit" : verdict];
49581
+ }));
49449
49582
  };
49450
49583
  const isCode = (path) => path !== ".gtd" && !path.startsWith(".gtd/");
49451
49584
  /** A code edit, not a thread-only change: lines that only add, answer or remove code threads don't count. */
@@ -49466,8 +49599,8 @@ const notedSince = (commit) => changesSince(commit).some((c) => c.path === ".gtd
49466
49599
  * commit of the last `review.collecting` turn, `"missing"` when the round
49467
49600
  * left no review, or `undefined` when no such turn ran.
49468
49601
  */
49469
- const converse = async (base) => {
49470
- let collectedAt;
49602
+ const converse = async (base, collectedBefore) => {
49603
+ let collectedAt = collectedBefore;
49471
49604
  for (;;) {
49472
49605
  await awaitReview(base);
49473
49606
  if (changes(".gtd/REVIEW.md").some((c) => c.status === "deleted")) refuse("gtd land: review-doc: .gtd/REVIEW.md was deleted — restore it, or leave a note (or edit code) to request changes.");
@@ -49496,39 +49629,103 @@ const settledAfter = (collectedAt) => ({
49496
49629
  folded: collectedAt !== void 0 && read(".gtd/REQUIREMENTS.md") !== void 0,
49497
49630
  settled: collectedAt !== void 0 && changesSince(collectedAt).every((c) => !isCodeEdit(c)) && !notedSince(collectedAt)
49498
49631
  });
49499
- const finish = async (reviewed, collectedAt) => {
49632
+ /** Judge every note, then run each verdict's route: answers, then nit fixes, then the edits' lap. */
49633
+ const routeNotes = async (notes, r) => {
49634
+ const verdicts = await triage(notes);
49635
+ const of = (v) => notes.filter((n) => verdicts.get(n.id) === v);
49636
+ const [edits, questions, nits] = [
49637
+ of("edit"),
49638
+ of("question"),
49639
+ of("nit")
49640
+ ];
49641
+ if (edits.length + questions.length + nits.length === 0) return r.unfolded();
49642
+ let answeredAt;
49643
+ if (questions.length > 0) {
49644
+ await answerReviewQuestions(questions);
49645
+ answeredAt = head();
49646
+ }
49647
+ if (nits.length > 0) {
49648
+ await fixNits(nits);
49649
+ await healthy(fix, { escalations: r.escalations });
49650
+ }
49651
+ if (edits.length > 0) {
49652
+ await r.close();
49653
+ return r.outcome(await collect(reviewEditNotesCapture(r.round, edits, answeredAt)));
49654
+ }
49655
+ if (nits.length > 0) {
49656
+ await r.close();
49657
+ return {
49658
+ next: "rereview",
49659
+ carry: answeredAt
49660
+ };
49661
+ }
49662
+ return {
49663
+ next: "await",
49664
+ reviewed: answeredAt
49665
+ };
49666
+ };
49667
+ const finish = async (reviewed, collectedAt, escalations) => {
49500
49668
  const round = head();
49501
49669
  const since = changesSince(reviewed);
49502
49670
  const edited = since.filter(isCodeEdit);
49671
+ const baselineText = since.get(".gtd/REVIEW.md")?.before ?? "";
49503
49672
  const record = read(".gtd/REVIEW.md") ?? "";
49504
49673
  const { folded, settled } = afterCollect(collectedAt);
49505
49674
  const noted = since.some((c) => c.path === REVIEW);
49675
+ const close = () => run$2("review.closing", removeScript([REVIEW]), {
49676
+ label: "Closing the review",
49677
+ base: round
49678
+ });
49506
49679
  const outcome = (verdict) => verdict === "signoff" ? { verdict } : {
49507
49680
  verdict,
49508
49681
  base: round,
49509
49682
  restoreFrom: reviewed,
49510
49683
  edited
49511
49684
  };
49512
- await run$2("review.closing", removeScript([REVIEW]), {
49513
- label: "Closing the review",
49514
- base: round
49685
+ const unfolded = async () => {
49686
+ await close();
49687
+ return outcome(folded ? "feedback" : "signoff");
49688
+ };
49689
+ const collectWith = async (capture) => {
49690
+ await close();
49691
+ return outcome(await collect(capture));
49692
+ };
49693
+ if (settled || edited.length === 0 && !noted) return unfolded();
49694
+ if (edited.length > 0) return collectWith(reviewEditsCapture(round));
49695
+ const notes = reviewNotes(baselineText, record);
49696
+ if (notes.length === 0) return collectWith(reviewNotesCapture(round));
49697
+ return routeNotes(notes, {
49698
+ round,
49699
+ escalations,
49700
+ close,
49701
+ outcome,
49702
+ unfolded
49515
49703
  });
49516
- if (settled) return outcome(folded ? "feedback" : "signoff");
49517
- if (edited.length > 0) return outcome(await collect(reviewEditsCapture(round)));
49518
- if (!noted || !await actionable(record)) return outcome(folded ? "feedback" : "signoff");
49519
- return outcome(await collect(reviewNotesCapture(round)));
49520
49704
  };
49521
49705
  /**
49522
49706
  * A reviewer writes `.gtd/REVIEW.md` over everything since `base`, a human
49523
- * reviews and signs off or comments, and a comment is classified into
49524
- * requirements for another lap.
49707
+ * reviews and signs off or comments, and each note is judged: edits go to
49708
+ * another planning lap, questions are answered in place, nits fixed in one
49709
+ * batch, praise dropped.
49525
49710
  */
49526
- const review = async (base) => {
49711
+ const review = async (base, escalations = { rounds: 0 }) => {
49712
+ let carry;
49527
49713
  for (;;) {
49528
- await reviewing(base);
49529
- const reviewed = head();
49530
- const collectedAt = await converse(base);
49531
- if (collectedAt !== "missing") return finish(reviewed, collectedAt);
49714
+ await reviewing(base, carry);
49715
+ carry = void 0;
49716
+ let reviewed = head();
49717
+ let collectedAt;
49718
+ for (;;) {
49719
+ collectedAt = await converse(base, collectedAt);
49720
+ if (collectedAt === "missing") break;
49721
+ const result = await finish(reviewed, collectedAt, escalations);
49722
+ if (!("next" in result)) return result;
49723
+ if (result.next === "rereview") {
49724
+ carry = result.carry;
49725
+ break;
49726
+ }
49727
+ reviewed = result.reviewed;
49728
+ }
49532
49729
  }
49533
49730
  };
49534
49731
  /** The build tail: fix (when entered red), keep green, the quality lap, then human review since `base`. */
@@ -49547,7 +49744,7 @@ const buildTail = (fixFirst, base) => scope("build", async () => {
49547
49744
  }
49548
49745
  const lap = lapped ? "clean" : await qualityLap();
49549
49746
  lapped = true;
49550
- if (lap === "clean") return review(base);
49747
+ if (lap === "clean") return review(base, escalations);
49551
49748
  if (await fixQualityFindings(escalations)) await healthy(fix, { escalations });
49552
49749
  else redFirst = true;
49553
49750
  }
@@ -49589,6 +49786,7 @@ var unified_exports = /* @__PURE__ */ __exportAll({
49589
49786
  afterTail: () => afterTail,
49590
49787
  agentWithSkills: () => agentWithSkills,
49591
49788
  answerProductQuestions: () => answerProductQuestions,
49789
+ answerReviewQuestions: () => answerReviewQuestions,
49592
49790
  answerTechnicalQuestions: () => answerTechnicalQuestions,
49593
49791
  architecture: () => architecture,
49594
49792
  architecturePass: () => architecturePass,
@@ -49608,6 +49806,7 @@ var unified_exports = /* @__PURE__ */ __exportAll({
49608
49806
  escalation: () => escalation,
49609
49807
  escalationExhausted: () => escalationExhausted,
49610
49808
  fix: () => fix,
49809
+ fixNits: () => fixNits,
49611
49810
  fixQuality: () => fixQuality,
49612
49811
  fixQualityFindings: () => fixQualityFindings,
49613
49812
  fixSpec: () => fixSpec,
@@ -49622,6 +49821,7 @@ var unified_exports = /* @__PURE__ */ __exportAll({
49622
49821
  qualityLap: () => qualityLap,
49623
49822
  qualityLenses: () => qualityLenses,
49624
49823
  reUnwind: () => reUnwind,
49824
+ retryQuestion: () => retryQuestion,
49625
49825
  review: () => review,
49626
49826
  reviewMissing: () => reviewMissing,
49627
49827
  reviewPackage: () => reviewPackage,
@@ -49631,7 +49831,7 @@ var unified_exports = /* @__PURE__ */ __exportAll({
49631
49831
  steering: () => steering,
49632
49832
  summary: () => summary,
49633
49833
  threads: () => threads,
49634
- triage: () => triage,
49834
+ triage: () => triage$1,
49635
49835
  unwind: () => unwind
49636
49836
  });
49637
49837
  /** Revert the sketch that started the process out of the working tree; its intent survives in history. */
@@ -49858,7 +50058,7 @@ const run$1 = (root, ...args) => scoped$3(gen(function* () {
49858
50058
  collect(process.stderr),
49859
50059
  process.exitCode
49860
50060
  ], { concurrency: "unbounded" });
49861
- if (exitCode !== 0) return yield* fail$2(/* @__PURE__ */ new Error(`${args.join(" ")} failed (exit ${exitCode}): ${stderr$3.trim()}`));
50061
+ if (exitCode !== 0) return yield* fail$5(/* @__PURE__ */ new Error(`${args.join(" ")} failed (exit ${exitCode}): ${stderr$3.trim()}`));
49862
50062
  return stdout$3;
49863
50063
  })).pipe(mapError$1((e) => e instanceof Error ? e : new Error(String(e))));
49864
50064
  /**
@@ -49882,7 +50082,7 @@ var InvalidRefError = class extends Error {
49882
50082
  * missing one. A separate pure function so this rare branch is unit-testable
49883
50083
  * without a real git repository contriving the condition.
49884
50084
  */
49885
- const resolvedRefOrCorrupted = (ref, hash) => /^[0-9a-f]{40}$/.test(hash) ? succeed$3(hash) : fail$2(new InvalidRefError(`Invalid ref: ${ref}`, [`ref: ${ref}`]));
50085
+ const resolvedRefOrCorrupted = (ref, hash) => /^[0-9a-f]{40}$/.test(hash) ? succeed$3(hash) : fail$5(new InvalidRefError(`Invalid ref: ${ref}`, [`ref: ${ref}`]));
49886
50086
  const makeGitImpl = (executor, root) => {
49887
50087
  const exec = (...args) => run$1(root, ...args).pipe(provide$2(succeed$2(CommandExecutor, executor)));
49888
50088
  return {
@@ -49960,10 +50160,10 @@ const makeGitImpl = (executor, root) => {
49960
50160
  },
49961
50161
  commitAllWithPrefix: (prefix) => gen(function* () {
49962
50162
  yield* exec("git", "add", "-A");
49963
- yield* exec("git", "commit", "--allow-empty", "-m", prefix).pipe(catchAll((error) => error.message.includes("empty git commit") ? exec("git", "commit", "--allow-empty", "--no-verify", "-m", prefix) : fail$2(error)));
50163
+ yield* exec("git", "commit", "--allow-empty", "-m", prefix).pipe(catchAll((error) => error.message.includes("empty git commit") ? exec("git", "commit", "--allow-empty", "--no-verify", "-m", prefix) : fail$5(error)));
49964
50164
  }).pipe(asVoid),
49965
50165
  softResetTo: (ref) => exec("git", "reset", "--soft", ref).pipe(asVoid),
49966
- commitAsIs: (message) => exec("git", "commit", "--allow-empty", "-m", message).pipe(catchAll((error) => error.message.includes("empty git commit") ? exec("git", "commit", "--allow-empty", "--no-verify", "-m", message) : fail$2(error))).pipe(asVoid),
50166
+ commitAsIs: (message) => exec("git", "commit", "--allow-empty", "-m", message).pipe(catchAll((error) => error.message.includes("empty git commit") ? exec("git", "commit", "--allow-empty", "--no-verify", "-m", message) : fail$5(error))).pipe(asVoid),
49967
50167
  discardPending: () => gen(function* () {
49968
50168
  yield* exec("git", "add", "-A");
49969
50169
  yield* exec("git", "reset", "--hard", "HEAD");
@@ -57583,7 +57783,7 @@ const load = gen(function* () {
57583
57783
  const fatal = diagnostics.filter((d) => d.severity === "error");
57584
57784
  if (fatal.length > 0) {
57585
57785
  const lines = fatal.map(formatDiagnostic);
57586
- return yield* fail$2(new GtdError(`gtd config:\n${lines.map((line) => ` - ${line}`).join("\n")}`));
57786
+ return yield* fail$5(new GtdError(`gtd config:\n${lines.map((line) => ` - ${line}`).join("\n")}`));
57587
57787
  }
57588
57788
  const initial = yield* firstStep(loaded, resolveVars(loaded.defaults, compiled.rcVars, {}, host.env), headTree(yield* Workspace));
57589
57789
  return {
@@ -57717,7 +57917,7 @@ const replayToFirstStep = (loaded, vars, tree) => flatMap$4(promise(() => replay
57717
57917
  })), (outcome) => {
57718
57918
  if (outcome.kind === "rest") return succeed$3(outcome.rest.name);
57719
57919
  const problem = outcome.kind === "failed" || outcome.kind === "refused" ? outcome.message.replace(/^gtd: /, "") : "the default entry must begin at a step — that step is where a finished process waits";
57720
- return fail$2(new GtdError(`gtd config:\n - ${loaded.origin}: ${problem}`));
57920
+ return fail$5(new GtdError(`gtd config:\n - ${loaded.origin}: ${problem}`));
57721
57921
  });
57722
57922
  /**
57723
57923
  * The default entry's first step — where a finished process waits — found the
@@ -57732,7 +57932,7 @@ const firstStep = (loaded, vars, head) => gen(function* () {
57732
57932
  if (!empty.read()) return name;
57733
57933
  const atHead = yield* replayToFirstStep(loaded, vars, head);
57734
57934
  if (atHead === name) return name;
57735
- return yield* fail$2(new GtdError(`gtd config:\n - ${loaded.origin}: the flow's first step on an ordinary start depends on the repository's files ("${name}" without them, "${atHead}" at HEAD) — that step is where a finished process waits, so it must not change as files do`));
57935
+ return yield* fail$5(new GtdError(`gtd config:\n - ${loaded.origin}: the flow's first step on an ordinary start depends on the repository's files ("${name}" without them, "${atHead}" at HEAD) — that step is where a finished process waits, so it must not change as files do`));
57736
57936
  });
57737
57937
  var ConfigService = class ConfigService extends Tag("ConfigService")() {
57738
57938
  static Live = succeed$2(ConfigService, { load });
@@ -57751,6 +57951,203 @@ const renderInitScaffold = () => ({ config: JSON.stringify({
57751
57951
  modes: MODES_SUGGESTION
57752
57952
  }, null, 2) + "\n" });
57753
57953
  //#endregion
57954
+ //#region src/judges/providers/fixed.ts
57955
+ const fail$2 = (message) => {
57956
+ throw new Error(`gtd judge run: ${message}`);
57957
+ };
57958
+ const isAnswer = (v) => [
57959
+ "string",
57960
+ "number",
57961
+ "boolean"
57962
+ ].includes(typeof v);
57963
+ const isProbability = (v) => typeof v === "number" && v >= 0 && v <= 1;
57964
+ const validate = (entry, index) => {
57965
+ const { id, answer, p } = typeof entry === "object" && entry !== null ? entry : {};
57966
+ if (typeof id !== "string") return fail$2(`answers entry ${index} has no string "id"`);
57967
+ if (!isAnswer(answer)) return fail$2(`answers entry "${id}": "answer" must be a string, number or boolean`);
57968
+ if (!isProbability(p)) return fail$2(`answers entry "${id}": "p" must be a number in [0, 1]`);
57969
+ return {
57970
+ id,
57971
+ answer,
57972
+ p
57973
+ };
57974
+ };
57975
+ const fixed = ({ answersPath, env }) => async (questions) => {
57976
+ const inline = env["GTD_JUDGE_ANSWERS"];
57977
+ let raw;
57978
+ if (answersPath !== void 0) raw = await readFile(answersPath, "utf8").catch((e) => fail$2(`cannot read --answers ${answersPath}: ${e instanceof Error ? e.message : String(e)}`));
57979
+ else if (inline !== void 0 && inline !== "") raw = inline;
57980
+ else return fail$2("provider \"fixed\" needs --answers <path> or GTD_JUDGE_ANSWERS");
57981
+ let parsed;
57982
+ try {
57983
+ parsed = JSON.parse(raw);
57984
+ } catch {
57985
+ return fail$2("the fixed answers are not valid JSON");
57986
+ }
57987
+ if (!Array.isArray(parsed)) return fail$2("the fixed answers must be a JSON array");
57988
+ const asked = new Set(questions.map((q) => q.id));
57989
+ return parsed.flatMap((entry, i) => {
57990
+ const id = entry?.id;
57991
+ if (typeof id === "string" && !asked.has(id)) return [];
57992
+ return [validate(entry, i)];
57993
+ });
57994
+ };
57995
+ //#endregion
57996
+ //#region src/judges/providers/jev.ts
57997
+ const DEFAULT_URL = "https://api.typesafe.ai/v1/systemone";
57998
+ const MODEL = "jev-latest";
57999
+ const RETRIES = 3;
58000
+ const fail$1 = (message) => {
58001
+ throw new Error(`gtd judge run: ${message}`);
58002
+ };
58003
+ const LABEL = /(?:^|\. )([A-Za-z][A-Za-z0-9_-]*): /g;
58004
+ /** Same splitter as gtd-build's `judge_request`: text before the first label is dropped. */
58005
+ const splitLabels = (criteria) => {
58006
+ const hits = [...criteria.matchAll(LABEL)];
58007
+ return hits.map((m, i) => {
58008
+ const start = m.index + m[0].length;
58009
+ const end = hits[i + 1]?.index ?? criteria.length;
58010
+ return [m[1], criteria.slice(start, end).replace(/^ /, "")];
58011
+ });
58012
+ };
58013
+ const translate = (q) => {
58014
+ if (q.primitive === "noul") return {
58015
+ type: "noul",
58016
+ instructions: `${q.instructions}\n\nCriteria: ${q.criteria}`
58017
+ };
58018
+ const levels = splitLabels(q.criteria);
58019
+ if (q.primitive === "choice") {
58020
+ if (levels.length < 2) return fail$1(`question "${q.id}": choice criteria need at least 2 labelled options`);
58021
+ return {
58022
+ type: "choice",
58023
+ instructions: q.instructions,
58024
+ criteria: Object.fromEntries(levels)
58025
+ };
58026
+ }
58027
+ if (q.primitive === "score") {
58028
+ if (levels.length < 2 || levels.length > 10) return fail$1(`question "${q.id}": score criteria need 2 to 10 labelled levels, found ${levels.length}`);
58029
+ return {
58030
+ type: "score",
58031
+ instructions: q.instructions,
58032
+ criteria: levels.map(([, v]) => v)
58033
+ };
58034
+ }
58035
+ return fail$1(`question "${q.id}": unknown primitive "${String(q.primitive)}"`);
58036
+ };
58037
+ const toRequest = (questions, state) => ({
58038
+ model: MODEL,
58039
+ state,
58040
+ questions: Object.fromEntries(questions.map((q) => [q.id, translate(q)]))
58041
+ });
58042
+ const clamp = (n) => Math.min(1, Math.max(0, n));
58043
+ const unreadable = (why) => fail$1(`unreadable jev response: ${why}`);
58044
+ const num = (v, what) => typeof v === "number" && Number.isFinite(v) ? v : unreadable(`${what} is not a finite number`);
58045
+ const probs = (a, id) => {
58046
+ const raw = a["probabilities"];
58047
+ if (typeof raw !== "object" || raw === null) return unreadable(`"${id}" has no probabilities`);
58048
+ return Object.fromEntries(Object.entries(raw).map(([k, v]) => [k, num(v, `"${id}" probability "${k}"`)]));
58049
+ };
58050
+ const toVerdict = (q, a) => {
58051
+ if (a["type"] !== q.primitive) return unreadable(`"${q.id}" answered as ${String(a["type"])}, asked ${q.primitive}`);
58052
+ if (q.primitive === "noul") {
58053
+ const n = num(a["noul"], `"${q.id}" noul`);
58054
+ return n >= .5 ? {
58055
+ id: q.id,
58056
+ answer: "yes",
58057
+ p: clamp(n)
58058
+ } : {
58059
+ id: q.id,
58060
+ answer: "no",
58061
+ p: clamp(1 - n)
58062
+ };
58063
+ }
58064
+ const p = probs(a, q.id);
58065
+ if (q.primitive === "choice") {
58066
+ const choice = a["choice"];
58067
+ if (typeof choice !== "string" || !(choice in p)) return unreadable(`"${q.id}" choice is absent from its probabilities`);
58068
+ return {
58069
+ id: q.id,
58070
+ answer: choice,
58071
+ p: clamp(p[choice])
58072
+ };
58073
+ }
58074
+ const levels = Object.entries(p).map(([k, v]) => [Number(k), v]);
58075
+ if (levels.length === 0 || levels.some(([k]) => !Number.isFinite(k))) return unreadable(`"${q.id}" score probabilities are not numeric levels`);
58076
+ const top = levels.reduce((best, cur) => cur[1] > best[1] || cur[1] === best[1] && cur[0] < best[0] ? cur : best);
58077
+ return {
58078
+ id: q.id,
58079
+ answer: top[0],
58080
+ p: clamp(top[1])
58081
+ };
58082
+ };
58083
+ const toVerdicts = (questions, response) => {
58084
+ const answers = response?.answers;
58085
+ if (typeof answers !== "object" || answers === null || Array.isArray(answers)) return unreadable("no \"answers\" object");
58086
+ const map = answers;
58087
+ const missing = questions.filter((q) => typeof map[q.id] !== "object" || map[q.id] === null);
58088
+ if (missing.length > 0) return fail$1(`jev answered ${questions.length - missing.length} of ${questions.length} questions; missing ${missing.map((q) => q.id).join(", ")}`);
58089
+ return questions.map((q) => toVerdict(q, map[q.id]));
58090
+ };
58091
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
58092
+ const post = async (url, key, body, delayMs) => {
58093
+ for (let attempt = 0;; attempt++) {
58094
+ const res = await fetch(url, {
58095
+ method: "POST",
58096
+ headers: {
58097
+ Authorization: `Bearer ${key}`,
58098
+ "Content-Type": "application/json"
58099
+ },
58100
+ body,
58101
+ signal: AbortSignal.timeout(18e4)
58102
+ }).catch((e) => fail$1(`jev request failed: ${e instanceof Error ? e.message : String(e)}`));
58103
+ const text = await res.text();
58104
+ if (res.status === 200) return text;
58105
+ if ((res.status === 429 || res.status === 529) && attempt < RETRIES) {
58106
+ await sleep(delayMs);
58107
+ continue;
58108
+ }
58109
+ return fail$1(`jev responded ${res.status}: ${text.slice(0, 2048)}`);
58110
+ }
58111
+ };
58112
+ const parse = (text) => {
58113
+ try {
58114
+ return JSON.parse(text);
58115
+ } catch {
58116
+ return unreadable("not JSON");
58117
+ }
58118
+ };
58119
+ const jev = ({ env, retryDelayMs = 2e3 }) => async (questions, state) => {
58120
+ const key = env["TYPESAFE_API_KEY"];
58121
+ if (key === void 0 || key === "") return fail$1("--provider jev needs TYPESAFE_API_KEY");
58122
+ const url = env["JEV_BASE_URL"] || DEFAULT_URL;
58123
+ const text = await post(url, key, JSON.stringify(toRequest(questions, state)), retryDelayMs);
58124
+ return toVerdicts(questions, parse(text));
58125
+ };
58126
+ //#endregion
58127
+ //#region src/judges/run.ts
58128
+ const fail = (message) => {
58129
+ throw new Error(`gtd judge run: ${message}`);
58130
+ };
58131
+ const answererFor = ({ provider, answers, env }) => {
58132
+ if (provider === "fixed") return fixed({
58133
+ answersPath: answers,
58134
+ env
58135
+ });
58136
+ return jev({ env });
58137
+ };
58138
+ const runJudge = async (opts) => {
58139
+ let doc;
58140
+ try {
58141
+ doc = JSON.parse(opts.input);
58142
+ } catch {
58143
+ return fail("stdin is not valid JSON");
58144
+ }
58145
+ const { questions, state } = doc ?? {};
58146
+ if (!Array.isArray(questions)) return fail("stdin has no \"questions\" array");
58147
+ const verdicts = await answererFor(opts)(questions, typeof state === "object" && state !== null ? state : {});
58148
+ return JSON.stringify(verdicts) + "\n";
58149
+ };
58150
+ //#endregion
57754
58151
  //#region node_modules/@trpc/server/dist/codes-DagpWZLc.mjs
57755
58152
  /**
57756
58153
  * Ensures there are no duplicate keys when building a procedure.
@@ -62139,7 +62536,7 @@ const generateSelfSignedCert = (request) => gen(function* () {
62139
62536
  `-addext "extendedKeyUsage=serverAuth"`,
62140
62537
  `-addext "basicConstraints=critical,CA:FALSE"`
62141
62538
  ].join(" ");
62142
- return yield* runner.bash(command).pipe(mapError$1((e) => new GtdError(`gtd ui: could not run openssl to issue a certificate: ${e.message}`)), flatMap$4((outcome) => outcome.status !== 0 ? fail$2(new GtdError("gtd ui: openssl exited without issuing a certificate", [`exit status: ${outcome.status ?? "signal"}`, ...outcome.output.trim().split("\n").filter(Boolean)])) : try_({
62539
+ return yield* runner.bash(command).pipe(mapError$1((e) => new GtdError(`gtd ui: could not run openssl to issue a certificate: ${e.message}`)), flatMap$4((outcome) => outcome.status !== 0 ? fail$5(new GtdError("gtd ui: openssl exited without issuing a certificate", [`exit status: ${outcome.status ?? "signal"}`, ...outcome.output.trim().split("\n").filter(Boolean)])) : try_({
62143
62540
  try: () => ({
62144
62541
  cert: readFileSync(certPath, "utf8"),
62145
62542
  key: readFileSync(keyPath, "utf8")
@@ -62171,7 +62568,7 @@ const obtainTailscaleCert = (domain) => gen(function* () {
62171
62568
  `--key-file ${shellQuote(keyPath)}`,
62172
62569
  shellQuote(domain)
62173
62570
  ].join(" ");
62174
- return yield* runner.bash(command).pipe(mapError$1((e) => new GtdError(`gtd ui: could not run tailscale cert to issue a certificate: ${e.message}`)), flatMap$4((outcome) => outcome.status !== 0 ? fail$2(new GtdError("gtd ui: tailscale cert exited without issuing a certificate", [`exit status: ${outcome.status ?? "signal"}`, ...outcome.output.trim().split("\n").filter(Boolean)])) : try_({
62571
+ return yield* runner.bash(command).pipe(mapError$1((e) => new GtdError(`gtd ui: could not run tailscale cert to issue a certificate: ${e.message}`)), flatMap$4((outcome) => outcome.status !== 0 ? fail$5(new GtdError("gtd ui: tailscale cert exited without issuing a certificate", [`exit status: ${outcome.status ?? "signal"}`, ...outcome.output.trim().split("\n").filter(Boolean)])) : try_({
62175
62572
  try: () => ({
62176
62573
  cert: readFileSync(certPath, "utf8"),
62177
62574
  key: readFileSync(keyPath, "utf8")
@@ -62208,7 +62605,7 @@ const TRPC_PATH_PREFIX = "/trpc";
62208
62605
  */
62209
62606
  const resolveBindHost = (host, config, pickHost = () => pickBindHost(OS.networkInterfaces())) => {
62210
62607
  const resolved = host ?? config?.host ?? pickHost();
62211
- return resolved === void 0 ? fail$2(new GtdError("gtd ui: no Tailscale interface found to bind to, and no --host given", ["join a tailnet, so a CGNAT (100.64.0.0/10) address is available", "or pass --host <address> to bind explicitly"])) : succeed$3(resolved);
62608
+ return resolved === void 0 ? fail$5(new GtdError("gtd ui: no Tailscale interface found to bind to, and no --host given", ["join a tailnet, so a CGNAT (100.64.0.0/10) address is available", "or pass --host <address> to bind explicitly"])) : succeed$3(resolved);
62212
62609
  };
62213
62610
  /**
62214
62611
  * `--self-signed`, then a configured pair, then a real `tailscale cert`, then
@@ -62225,11 +62622,11 @@ const resolveCertPair = (options, config, bindHost, displayHost, tailscaleStatus
62225
62622
  if (config?.cert !== void 0 && config.key !== void 0) return loadCertPair(config.cert, config.key);
62226
62623
  if (config?.cert !== void 0 || config?.key !== void 0) {
62227
62624
  const missing = config.cert === void 0 ? "ui.cert" : "ui.key";
62228
- return fail$2(new GtdError(`gtd ui: ${missing} is not configured — both cert and key are required`, [`ui.${config.cert === void 0 ? "key" : "cert"} is configured, but ${missing} is not`, "pass --self-signed for a throwaway certificate instead"]));
62625
+ return fail$5(new GtdError(`gtd ui: ${missing} is not configured — both cert and key are required`, [`ui.${config.cert === void 0 ? "key" : "cert"} is configured, but ${missing} is not`, "pass --self-signed for a throwaway certificate instead"]));
62229
62626
  }
62230
62627
  const certDomain = tailscaleStatus?.certDomains[0];
62231
62628
  if (certDomain !== void 0) return obtainTailscaleCert(certDomain);
62232
- return fail$2(new GtdError("gtd ui: HTTPS is mandatory and no certificate is configured", [
62629
+ return fail$5(new GtdError("gtd ui: HTTPS is mandatory and no certificate is configured", [
62233
62630
  "pass --self-signed for a throwaway certificate",
62234
62631
  "or configure ui.cert and ui.key",
62235
62632
  "or join a tailnet with HTTPS certs enabled for an automatic one"
@@ -62250,7 +62647,7 @@ var UiListener = class UiListener extends Tag("UiListener")() {
62250
62647
  key: tls.key
62251
62648
  }, handler) : http.createServer(handler);
62252
62649
  server.once("error", (err) => {
62253
- resume(fail$2(err.code === "EADDRINUSE" ? new GtdError(`gtd ui: port ${port} is already in use`) : new GtdError(`gtd ui: could not start the server: ${err.message}`)));
62650
+ resume(fail$5(err.code === "EADDRINUSE" ? new GtdError(`gtd ui: port ${port} is already in use`) : new GtdError(`gtd ui: could not start the server: ${err.message}`)));
62254
62651
  });
62255
62652
  server.listen(port, host, () => {
62256
62653
  const address = server.address();
@@ -62309,7 +62706,7 @@ const readDevTemplate = (fs, root) => fs.readFileString(join(root, "src/web/inde
62309
62706
  */
62310
62707
  const rebuildDevClientScript = (runner, fs, root) => gen(function* () {
62311
62708
  const outcome = yield* runner.bash(`cd ${JSON.stringify(root)} && npx tsdown --filter web`).pipe(mapError$1((e) => new GtdError(`gtd ui --dev: could not rebuild the client: ${e.message}`)));
62312
- if (outcome.status !== 0) return yield* fail$2(new GtdError("gtd ui --dev: rebuilding the client failed", outcome.output.trim().split("\n").filter(Boolean)));
62709
+ if (outcome.status !== 0) return yield* fail$5(new GtdError("gtd ui --dev: rebuilding the client failed", outcome.output.trim().split("\n").filter(Boolean)));
62313
62710
  return yield* fs.readFileString(join(root, "dist/web/main.js")).pipe(mapError$1((e) => new GtdError(`gtd ui --dev: could not read the rebuilt client: ${e.message}`)));
62314
62711
  });
62315
62712
  /**
@@ -62320,7 +62717,7 @@ const rebuildDevClientScript = (runner, fs, root) => gen(function* () {
62320
62717
  */
62321
62718
  const rebuildDevClientCss = (runner, fs, root) => gen(function* () {
62322
62719
  const outcome = yield* runner.bash(`cd ${JSON.stringify(root)} && npx @tailwindcss/cli -i src/web/styles.css -o dist/web/main.css`).pipe(mapError$1((e) => new GtdError(`gtd ui --dev: could not rebuild the stylesheet: ${e.message}`)));
62323
- if (outcome.status !== 0) return yield* fail$2(new GtdError("gtd ui --dev: rebuilding the stylesheet failed", outcome.output.trim().split("\n").filter(Boolean)));
62720
+ if (outcome.status !== 0) return yield* fail$5(new GtdError("gtd ui --dev: rebuilding the stylesheet failed", outcome.output.trim().split("\n").filter(Boolean)));
62324
62721
  return yield* fs.readFileString(join(root, "dist/web/main.css")).pipe(mapError$1((e) => new GtdError(`gtd ui --dev: could not read the rebuilt stylesheet: ${e.message}`)));
62325
62722
  });
62326
62723
  /** The one piece of content this server ever serves: the client HTML, with its JS AND CSS inlined — a build-time constant in production, resolved ONCE at startup under `--dev` too (T5) and held for the process's whole lifetime, never re-read or rebuilt per request. */
@@ -62588,7 +62985,7 @@ const resolveListener = (args) => gen(function* () {
62588
62985
  const runUiCommand = (options, config, out) => gen(function* () {
62589
62986
  const cwd = yield* Host;
62590
62987
  const step = yield* promise(() => readStep({ path: cwd.root }, liveBeatDeps));
62591
- if (step.status === "broken" || !isRenderable(step)) return yield* fail$2(refusalFor(step));
62988
+ if (step.status === "broken" || !isRenderable(step)) return yield* fail$5(refusalFor(step));
62592
62989
  const servedState = step.state;
62593
62990
  const servedLabel = step.label;
62594
62991
  const runner = yield* CommandRunner;
@@ -63420,11 +63817,11 @@ const restAt = (ref) => gen(function* () {
63420
63817
  };
63421
63818
  const outcome = yield* promise(() => replayFor(setup));
63422
63819
  const error = replayError(outcome);
63423
- if (error !== void 0 || outcome.kind !== "rest") return yield* fail$2(error ?? /* @__PURE__ */ new Error("gtd: replay found no rest"));
63820
+ if (error !== void 0 || outcome.kind !== "rest") return yield* fail$5(error ?? /* @__PURE__ */ new Error("gtd: replay found no rest"));
63424
63821
  const step = outcome.rest;
63425
63822
  yield* (yield* Narrator).narrate(`rest resolved: ${step.name} (awaits ${step.actor})`);
63426
63823
  const stepDef = stepDefOf(step);
63427
- if (stepDef.mode !== void 0 && def.modes[stepDef.mode] === void 0) return yield* fail$2(/* @__PURE__ */ new Error(`gtd config: step "${step.name}": mode "${stepDef.mode}" is not a mode this workflow knows (${knownModes(def).join(", ")})`));
63824
+ if (stepDef.mode !== void 0 && def.modes[stepDef.mode] === void 0) return yield* fail$5(/* @__PURE__ */ new Error(`gtd config: step "${step.name}": mode "${stepDef.mode}" is not a mode this workflow knows (${knownModes(def).join(", ")})`));
63428
63825
  const changes = ref === void 0 ? (yield* git.changedPaths()).map((e) => ({
63429
63826
  status: normalizeStatus(e.status),
63430
63827
  path: e.path
@@ -63538,7 +63935,7 @@ const decideLanding = (rest, verdicts) => gen(function* () {
63538
63935
  kind: "refusal",
63539
63936
  message: outcome.message
63540
63937
  };
63541
- if (outcome.kind === "divergence" || outcome.kind === "failed") return yield* fail$2(new Error(outcome.message));
63938
+ if (outcome.kind === "divergence" || outcome.kind === "failed") return yield* fail$5(new Error(outcome.message));
63542
63939
  const to = outcome.kind === "rest" ? outcome.rest.name : rest.def.initial;
63543
63940
  if (rest.changes.length === 0 && rest.stepDef.kind === "script" && to === rest.state) return {
63544
63941
  kind: "noop",
@@ -76172,7 +76569,7 @@ var SelectorUsageError = class extends Error {};
76172
76569
  const writeSelection = (out, fields, path) => gen(function* () {
76173
76570
  const selection = selectPath(fields, path);
76174
76571
  if (selection.kind === "value") out.write(`${selection.text}\n`);
76175
- else if (selection.kind === "unknown") return yield* fail$2(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
76572
+ else if (selection.kind === "unknown") return yield* fail$5(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
76176
76573
  });
76177
76574
  /** `needs: "none"` skips the repo-root guard — the server is keyed on file name, not workflow state. */
76178
76575
  const runLspCommand = () => startLspServer();
@@ -76192,7 +76589,7 @@ const runInitCommand = (out) => gen(function* () {
76192
76589
  const git = yield* GitService;
76193
76590
  const host = yield* Host;
76194
76591
  const inRepo = yield* assertInitLocation(git, host);
76195
- if (yield* configPresentAt(host.root)) return yield* fail$2(/* @__PURE__ */ new Error("gtd init: a gtd config already exists — remove it before re-initializing"));
76592
+ if (yield* configPresentAt(host.root)) return yield* fail$5(/* @__PURE__ */ new Error("gtd init: a gtd config already exists — remove it before re-initializing"));
76196
76593
  const scaffold = renderInitScaffold();
76197
76594
  yield* (yield* Workspace).write(".gtdrc.json", scaffold.config);
76198
76595
  const wrote = "Wrote .gtdrc.json seeding the default variables (the test command) and a\nPrettier formatting suggestion. gtd runs its built-in workflow by default — add\na workflow: key only if you want to customize the machine itself.\n\n";
@@ -76221,7 +76618,7 @@ const EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
76221
76618
  const planLanding = (opts = {}) => gen(function* () {
76222
76619
  const rest = yield* currentRest;
76223
76620
  const outcome = planStep(yield* snapshotFromRest(rest, opts.judge), opts);
76224
- if (outcome.kind === "refusal") return yield* fail$2(new Error(outcome.message));
76621
+ if (outcome.kind === "refusal") return yield* fail$5(new Error(outcome.message));
76225
76622
  if (outcome.kind === "noop") {
76226
76623
  const required = ScriptSurface.render([{
76227
76624
  kind: "outcome",
@@ -76260,13 +76657,13 @@ const planLanding = (opts = {}) => gen(function* () {
76260
76657
  */
76261
76658
  const runSummaryCommand = (out) => gen(function* () {
76262
76659
  const rendered = yield* summaryFor(yield* summaryRun);
76263
- if (rendered === void 0) return yield* fail$2(/* @__PURE__ */ new Error("gtd summary: refused — either this workflow declares no \"summary:\" template, or there is no finished/in-flight process to summarize at HEAD"));
76660
+ if (rendered === void 0) return yield* fail$5(/* @__PURE__ */ new Error("gtd summary: refused — either this workflow declares no \"summary:\" template, or there is no finished/in-flight process to summarize at HEAD"));
76264
76661
  out.write(rendered.endsWith("\n") ? rendered : rendered + "\n");
76265
76662
  });
76266
76663
  /** Prints the review anchor hash bare, so an external tool can be pointed at the range under review. Nothing is written. Refuses when the run has no commits, where the hash would name a range with no review. */
76267
76664
  const runBaseCommand = (out) => gen(function* () {
76268
76665
  const rest = yield* currentRest;
76269
- if (rest.run.trace.length === 0) return yield* fail$2(/* @__PURE__ */ new Error("gtd base: refused — no process is underway at HEAD"));
76666
+ if (rest.run.trace.length === 0) return yield* fail$5(/* @__PURE__ */ new Error("gtd base: refused — no process is underway at HEAD"));
76270
76667
  const base = reviewBaseFor(rest);
76271
76668
  out.write(`${base}\n`);
76272
76669
  });
@@ -76274,7 +76671,7 @@ const runBaseCommand = (out) => gen(function* () {
76274
76671
  const runJudgeCommand = (json, out) => gen(function* () {
76275
76672
  const rest = yield* currentRest;
76276
76673
  const rendered = yield* renderRest(rest);
76277
- if (rendered.judge === void 0) return yield* fail$2(/* @__PURE__ */ new Error(`gtd judge: refused — the resolved rest ("${rest.state}") declares no "judge:"`));
76674
+ if (rendered.judge === void 0) return yield* fail$5(/* @__PURE__ */ new Error(`gtd judge: refused — the resolved rest ("${rest.state}") declares no "judge:"`));
76278
76675
  const document = rendered.judge.endsWith("\n") ? rendered.judge : `${rendered.judge}\n`;
76279
76676
  if (json.kind === "select") {
76280
76677
  const selection = selectPath(yield* try_({
@@ -76282,7 +76679,7 @@ const runJudgeCommand = (json, out) => gen(function* () {
76282
76679
  catch: () => new SelectorUsageError("gtd judge: the resolved rest's \"judge:\" template did not render valid JSON")
76283
76680
  }), json.path);
76284
76681
  if (selection.kind === "value") out.write(`${selection.text}\n`);
76285
- else if (selection.kind === "unknown") return yield* fail$2(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
76682
+ else if (selection.kind === "unknown") return yield* fail$5(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
76286
76683
  return;
76287
76684
  }
76288
76685
  out.write(document);
@@ -76304,6 +76701,21 @@ const readStdin = () => tryPromise({
76304
76701
  },
76305
76702
  catch: (e) => e instanceof Error ? e : new Error(String(e))
76306
76703
  });
76704
+ /** Stdout is written once, after the answerer resolves — a rejection leaves it empty. */
76705
+ const runJudgeRunCommand = (command, out) => gen(function* () {
76706
+ const host = yield* Host;
76707
+ const input = yield* readStdin();
76708
+ const verdict = yield* tryPromise({
76709
+ try: () => runJudge({
76710
+ provider: command.provider,
76711
+ answers: command.answers,
76712
+ env: host.env,
76713
+ input
76714
+ }),
76715
+ catch: (e) => e instanceof Error ? e : new Error(String(e))
76716
+ });
76717
+ out.write(verdict);
76718
+ });
76307
76719
  /** A verdict's own `answer` shape covers every `judge:` primitive (`noul` → boolean, `choice` → string, `score` → number) without gtd itself interpreting which one applies — that's a driver/judge-model concern, not this decode's. */
76308
76720
  const VerdictAnswer = Union(String$, Number$, Boolean$);
76309
76721
  /**
@@ -76328,7 +76740,7 @@ const verdictSchemaFor = (ids) => Array$(Struct({
76328
76740
  const runJudgeAnswerCommand = (json, out) => gen(function* () {
76329
76741
  const rest = yield* currentRest;
76330
76742
  const rendered = yield* renderRest(rest);
76331
- if (rendered.judge === void 0) return yield* fail$2(/* @__PURE__ */ new Error(`gtd judge answer: refused — the resolved rest ("${rest.state}") declares no "judge:"`));
76743
+ if (rendered.judge === void 0) return yield* fail$5(/* @__PURE__ */ new Error(`gtd judge answer: refused — the resolved rest ("${rest.state}") declares no "judge:"`));
76332
76744
  const ids = (yield* parseJudgeDocument(rendered.judge)).questions.map((q) => q.id);
76333
76745
  const raw = yield* readStdin();
76334
76746
  const parsed = yield* try_({
@@ -76374,7 +76786,7 @@ const runEntryCommand = (actor, entryState, varOverrides, out, commandLabel) =>
76374
76786
  commandLabel,
76375
76787
  vars: varOverrides
76376
76788
  });
76377
- if (plan.kind === "refusal") return yield* fail$2(new Error(plan.message));
76789
+ if (plan.kind === "refusal") return yield* fail$5(new Error(plan.message));
76378
76790
  out.write(landingScript(ScriptSurface.render(plan.steps)));
76379
76791
  });
76380
76792
  /**
@@ -76403,7 +76815,7 @@ const runAbandonCommand = (out) => gen(function* () {
76403
76815
  return;
76404
76816
  }
76405
76817
  const restState = run.trace[run.trace.length - 1].state;
76406
- if (run.startParentHash === EMPTY_TREE) return yield* fail$2(/* @__PURE__ */ new Error(`gtd abandon: the process underway (resting at "${restState}") starts at the repository's first commit — there is no earlier commit to rewind to`));
76818
+ if (run.startParentHash === EMPTY_TREE) return yield* fail$5(/* @__PURE__ */ new Error(`gtd abandon: the process underway (resting at "${restState}") starts at the repository's first commit — there is no earlier commit to rewind to`));
76407
76819
  const required = emitScripts([
76408
76820
  {
76409
76821
  kind: "gitWrite",
@@ -76429,13 +76841,13 @@ const runAbandonCommand = (out) => gen(function* () {
76429
76841
  */
76430
76842
  const runRestoreCommand = (out) => gen(function* () {
76431
76843
  const git = yield* GitService;
76432
- if ((yield* currentRest).changes.length > 0) return yield* fail$2(/* @__PURE__ */ new Error("gtd restore: refuses on a dirty working tree — commit, stash, or discard your changes first."));
76844
+ if ((yield* currentRest).changes.length > 0) return yield* fail$5(/* @__PURE__ */ new Error("gtd restore: refuses on a dirty working tree — commit, stash, or discard your changes first."));
76433
76845
  const retained = yield* readRetainedHistory(git);
76434
- if (isNone(retained)) return yield* fail$2(/* @__PURE__ */ new Error("gtd restore: no retained history to restore."));
76846
+ if (isNone(retained)) return yield* fail$5(/* @__PURE__ */ new Error("gtd restore: no retained history to restore."));
76435
76847
  const tip = retained.value;
76436
76848
  const headHash = yield* git.resolveRef("HEAD");
76437
76849
  const check = yield* restorability(git, headHash, tip);
76438
- if (!check.ok) return yield* fail$2(/* @__PURE__ */ new Error(`gtd restore: ${check.reason} — HEAD ${headHash.slice(0, 7)} is ahead of the retained tip ${tip.slice(0, 7)}.`));
76850
+ if (!check.ok) return yield* fail$5(/* @__PURE__ */ new Error(`gtd restore: ${check.reason} — HEAD ${headHash.slice(0, 7)} is ahead of the retained tip ${tip.slice(0, 7)}.`));
76439
76851
  const after = yield* restAt(tip);
76440
76852
  const required = emitScripts([
76441
76853
  {
@@ -76479,7 +76891,7 @@ const resolveValidateScript = (rest) => gen(function* () {
76479
76891
  const mode = rest.stepDef.mode;
76480
76892
  if (file === void 0 || mode === void 0) return void 0;
76481
76893
  const resolved = resolveMode(rest.def, rest.state, mode);
76482
- if (resolved.kind === "unknown") return yield* fail$2(new Error(resolved.message));
76894
+ if (resolved.kind === "unknown") return yield* fail$5(new Error(resolved.message));
76483
76895
  const { script } = yield* validateScriptFor(resolved, file);
76484
76896
  return {
76485
76897
  file,
@@ -76535,23 +76947,23 @@ const formatFinding = (file, finding) => {
76535
76947
  */
76536
76948
  const runCheckCommand = (mode, file, openQuestions, openThreadsFlag) => gen(function* () {
76537
76949
  const format = steeringFormatFor(mode);
76538
- if (format === void 0) return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: unknown mode "${mode}" — known modes: ${BUILT_IN_MODE_NAMES.join(", ")}`));
76950
+ if (format === void 0) return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: unknown mode "${mode}" — known modes: ${BUILT_IN_MODE_NAMES.join(", ")}`));
76539
76951
  if (openThreadsFlag) {
76540
- if (openQuestions) return yield* fail$2(/* @__PURE__ */ new Error("gtd check: --open-threads and --open-questions are mutually exclusive"));
76952
+ if (openQuestions) return yield* fail$5(/* @__PURE__ */ new Error("gtd check: --open-threads and --open-questions are mutually exclusive"));
76541
76953
  if (format.openThreads === void 0) {
76542
76954
  const accepted = BUILT_IN_MODE_NAMES.filter((name) => steeringFormatFor(name)?.openThreads !== void 0);
76543
- return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: --open-threads only applies to modes ${accepted.join(", ")} — got "${mode}"`));
76955
+ return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: --open-threads only applies to modes ${accepted.join(", ")} — got "${mode}"`));
76544
76956
  }
76545
76957
  return yield* runOpenThreadsCheckCommand(format, file);
76546
76958
  }
76547
76959
  if (openQuestions) {
76548
- if (mode !== "qa") return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: --open-questions only applies to mode "qa" — got "${mode}"`));
76960
+ if (mode !== "qa") return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: --open-questions only applies to mode "qa" — got "${mode}"`));
76549
76961
  return yield* runOpenQuestionsCheckCommand(format, file);
76550
76962
  }
76551
76963
  const content = (yield* Workspace).atPath(file);
76552
76964
  const errors = content !== void 0 ? format.validate(content).map((finding) => formatFinding(file, finding)) : [];
76553
76965
  if (errors.length === 0) return;
76554
- return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: ${file} is not valid under mode "${mode}" (${errors.length} finding(s)):\n` + errors.join("\n")));
76966
+ return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: ${file} is not valid under mode "${mode}" (${errors.length} finding(s)):\n` + errors.join("\n")));
76555
76967
  });
76556
76968
  /**
76557
76969
  * The bare `gtd check --open-threads`: code-comment threads in the files the
@@ -76568,15 +76980,15 @@ const runCodeThreadsCheckCommand = () => gen(function* () {
76568
76980
  return [...threads.filter((t) => t.waitingOn === "human").map((t) => `${path}:${t.line + 1}: ${t.entries[0].text}`), ...findings.map((f) => `${path}:${(f.line ?? 0) + 1}: ${f.message}`)];
76569
76981
  });
76570
76982
  if (lines.length === 0) return;
76571
- return yield* fail$2(new Error(lines.join("\n")));
76983
+ return yield* fail$5(new Error(lines.join("\n")));
76572
76984
  });
76573
76985
  /** Prints one `file:line: [^name]: <first H entry>` line per open thread; a missing file fails, like `--open-questions`. */
76574
76986
  const runOpenThreadsCheckCommand = (format, file) => gen(function* () {
76575
76987
  const content = (yield* Workspace).atPath(file);
76576
- if (content === void 0) return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: ${file} does not exist`));
76988
+ if (content === void 0) return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: ${file} does not exist`));
76577
76989
  const errors = openThreads(format, content).map((t) => `${file}:${t.line + 1}: [^${t.name}]: ${t.firstMe}`);
76578
76990
  if (errors.length === 0) return;
76579
- return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: ${errors.length} open thread(s) in ${file}:\n` + errors.join("\n")));
76991
+ return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: ${errors.length} open thread(s) in ${file}:\n` + errors.join("\n")));
76580
76992
  });
76581
76993
  /**
76582
76994
  * Runs the SAME `unansweredQuestions` predicate a flow's `openQuestions()`
@@ -76585,10 +76997,10 @@ const runOpenThreadsCheckCommand = (format, file) => gen(function* () {
76585
76997
  */
76586
76998
  const runOpenQuestionsCheckCommand = (format, file) => gen(function* () {
76587
76999
  const content = (yield* Workspace).atPath(file);
76588
- if (content === void 0) return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: ${file} does not exist`));
77000
+ if (content === void 0) return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: ${file} does not exist`));
76589
77001
  const errors = unansweredQuestions(format, content).map((q) => `${file}:${q.headingLine + 1}: ${q.question}`);
76590
77002
  if (errors.length === 0) return;
76591
- return yield* fail$2(/* @__PURE__ */ new Error(`gtd check: ${errors.length} open question(s) unanswered in ${file}:\n` + errors.join("\n")));
77003
+ return yield* fail$5(/* @__PURE__ */ new Error(`gtd check: ${errors.length} open question(s) unanswered in ${file}:\n` + errors.join("\n")));
76592
77004
  });
76593
77005
  /**
76594
77006
  * Clears the `review` format's ticks in `<file>`, writing back only when the
@@ -76665,11 +77077,11 @@ const runUiCliCommand = (command, out) => gen(function* () {
76665
77077
  */
76666
77078
  const assertRunningFromRepoRoot = (git, host) => gen(function* () {
76667
77079
  const topLevel = yield* git.topLevel();
76668
- if ((yield* host.realPath(topLevel)) !== (yield* host.realPath(host.root))) return yield* fail$2(/* @__PURE__ */ new Error(`gtd must be run from the repository root (${topLevel}); the current directory is ${host.root}`));
77080
+ if ((yield* host.realPath(topLevel)) !== (yield* host.realPath(host.root))) return yield* fail$5(/* @__PURE__ */ new Error(`gtd must be run from the repository root (${topLevel}); the current directory is ${host.root}`));
76669
77081
  });
76670
77082
  /** A command that derives workflow state needs at least one commit too — a commitless repository has no HEAD to resolve a `Rest` at. */
76671
77083
  const assertRepositoryHasCommits = (git) => gen(function* () {
76672
- if (!(yield* git.hasCommits())) return yield* fail$2(/* @__PURE__ */ new Error("gtd requires a repository with at least one commit — make an initial commit, then run gtd again"));
77084
+ if (!(yield* git.hasCommits())) return yield* fail$5(/* @__PURE__ */ new Error("gtd requires a repository with at least one commit — make an initial commit, then run gtd again"));
76673
77085
  });
76674
77086
  /**
76675
77087
  * `gtd init` may run either at a repository root or in a directory outside
@@ -76682,7 +77094,7 @@ const assertRepositoryHasCommits = (git) => gen(function* () {
76682
77094
  const assertInitLocation = (git, host) => gen(function* () {
76683
77095
  const topLevel = yield* either(git.topLevel());
76684
77096
  if (topLevel._tag === "Left") return false;
76685
- if ((yield* host.realPath(topLevel.right)) !== (yield* host.realPath(host.root))) return yield* fail$2(/* @__PURE__ */ new Error(`gtd init must be run from the repository root (${topLevel.right}) or from a directory outside any git repository; the current directory is a repository subdirectory: ${host.root}`));
77097
+ if ((yield* host.realPath(topLevel.right)) !== (yield* host.realPath(host.root))) return yield* fail$5(/* @__PURE__ */ new Error(`gtd init must be run from the repository root (${topLevel.right}) or from a directory outside any git repository; the current directory is a repository subdirectory: ${host.root}`));
76686
77098
  return true;
76687
77099
  });
76688
77100
  /**
@@ -76695,7 +77107,8 @@ const assertInitLocation = (git, host) => gen(function* () {
76695
77107
  const needsOf = (kind) => {
76696
77108
  switch (kind) {
76697
77109
  case "lsp":
76698
- case "install": return "none";
77110
+ case "install":
77111
+ case "judgeRun": return "none";
76699
77112
  case "init":
76700
77113
  case "check":
76701
77114
  case "uncheck": return "fs";
@@ -76732,6 +77145,7 @@ const dispatchVoidCommand = (command, json, out) => {
76732
77145
  case "base": return runBaseCommand(out);
76733
77146
  case "judge": return runJudgeCommand(json, out);
76734
77147
  case "judgeAnswer": return runJudgeAnswerCommand(json, out);
77148
+ case "judgeRun": return runJudgeRunCommand(command, out);
76735
77149
  }
76736
77150
  };
76737
77151
  /**
@@ -76851,6 +77265,30 @@ const FLAGS = [
76851
77265
  valueHint: "",
76852
77266
  help: ["(gtd ui only) run against local development sources", "instead of the packaged build"]
76853
77267
  },
77268
+ {
77269
+ name: "--provider",
77270
+ arity: 1,
77271
+ repeatable: false,
77272
+ scope: (kind) => kind === "judgeRun",
77273
+ decode: ([raw]) => raw === "fixed" || raw === "jev" ? right(raw) : left(`gtd: --provider must be one of fixed, jev — got "${raw ?? ""}"`),
77274
+ scopeError: "gtd: --provider is only valid for `gtd judge run`",
77275
+ valueHint: "<name>",
77276
+ help: ["(gtd judge run only, required) the answerer: fixed | jev"]
77277
+ },
77278
+ {
77279
+ name: "--answers",
77280
+ arity: 1,
77281
+ repeatable: false,
77282
+ scope: (kind) => kind === "judgeRun",
77283
+ decode: ([raw]) => raw === void 0 || raw === "" ? left("gtd: --answers must be a non-empty path") : right(raw),
77284
+ scopeError: "gtd: --answers is only valid for `gtd judge run`",
77285
+ valueHint: "<path>",
77286
+ help: [
77287
+ "(gtd judge run --provider fixed only) a JSON verdict array",
77288
+ "[{ id, answer, p }]; else the GTD_JUDGE_ANSWERS env var",
77289
+ "(inline JSON) is read"
77290
+ ]
77291
+ },
76854
77292
  {
76855
77293
  name: "--cost",
76856
77294
  arity: 1,
@@ -77215,6 +77653,20 @@ const COMMAND_ROWS = [
77215
77653
  "selector) when stdin isn't valid JSON or the verdict",
77216
77654
  "doesn't decode against the pending question ids."
77217
77655
  ]
77656
+ },
77657
+ {
77658
+ token: "judge run",
77659
+ kind: "judgeRun",
77660
+ arity: "none",
77661
+ details: [
77662
+ "Answer a judgment: read the `gtd judge --json` document off",
77663
+ "stdin, write a verdict [{ id, answer, p }] on stdout — what",
77664
+ "`gtd judge answer` decodes. --provider fixed answers from",
77665
+ "--answers <path> or GTD_JUDGE_ANSWERS; questions the file",
77666
+ "does not cover are left out. Needs no repository. Exits 1",
77667
+ "on an unreadable or malformed answers file, with nothing",
77668
+ "on stdout"
77669
+ ]
77218
77670
  }
77219
77671
  ];
77220
77672
  const commandByToken = (token) => COMMAND_ROWS.find((r) => r.token === token);
@@ -77399,14 +77851,15 @@ const parseArgv = (argv) => {
77399
77851
  const row = first === void 0 ? void 0 : commandByToken(first);
77400
77852
  const judgeAnswer = row?.kind === "judge" && positionals[1] === "answer";
77401
77853
  const selectsEntry = entryPresent && first === void 0;
77402
- const kind = selectsEntry ? "entry" : judgeAnswer ? "judgeAnswer" : row?.kind;
77854
+ const judgeRun = row?.kind === "judge" && positionals[1] === "run";
77855
+ const kind = selectsEntry ? "entry" : judgeAnswer ? "judgeAnswer" : judgeRun ? "judgeRun" : row?.kind;
77403
77856
  if (row === void 0 && !selectsEntry) {
77404
77857
  const violation = scopeViolation(void 0, present);
77405
77858
  if (violation !== void 0) return usagePlan(violation, jsonSeen);
77406
77859
  if (first === void 0) return usagePlan("gtd: missing command — gtd decides and prints, a driver executes; run `gtd install`, or copy one from https://github.com/pmelab/gtd/blob/main/docs/driver.md's \"A complete minimal driver\" section and run that, or see usage above (`gtd --help`)", jsonSeen, renderHelp());
77407
77860
  return usagePlan(`unknown command '${first}'`, jsonSeen);
77408
77861
  }
77409
- const restPositionals = first === void 0 ? positionals : positionals.slice(judgeAnswer ? 2 : 1);
77862
+ const restPositionals = first === void 0 ? positionals : positionals.slice(judgeAnswer || judgeRun ? 2 : 1);
77410
77863
  if (kind === "entry" && first === void 0) {
77411
77864
  if (restPositionals.length > 0) return usagePlan(`gtd: too many arguments — expected none, got: ${restPositionals.join(", ")}`, jsonSeen);
77412
77865
  } else {
@@ -77473,6 +77926,20 @@ const parseArgv = (argv) => {
77473
77926
  json,
77474
77927
  verbose
77475
77928
  };
77929
+ if (kind === "judgeRun") {
77930
+ if (bag["--provider"] === void 0) return usagePlan("gtd judge run: --provider <fixed|jev> is required", jsonSeen);
77931
+ if (bag["--provider"] === "jev" && bag["--answers"] !== void 0) return usagePlan("gtd judge run: --answers is only valid with --provider fixed", jsonSeen);
77932
+ return {
77933
+ kind: "command",
77934
+ command: {
77935
+ kind: "judgeRun",
77936
+ provider: bag["--provider"],
77937
+ ...bag["--answers"] !== void 0 ? { answers: bag["--answers"] } : {}
77938
+ },
77939
+ json,
77940
+ verbose
77941
+ };
77942
+ }
77476
77943
  if (kind === "uncheck") return {
77477
77944
  kind: "command",
77478
77945
  command: {