@pmelab/gtd 15.9.0 → 16.0.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.
- package/README.md +22 -9
- package/dist/gtd.bundle.mjs +619 -270
- package/package.json +1 -1
- package/schema.json +10 -0
- package/src/flows/runtime.ts +13 -0
- package/src/workflows/review.ts +6 -2
- package/src/workflows/skills.test.ts +93 -0
- package/src/workflows/skills.ts +37 -0
- package/src/workflows/steps.test.ts +75 -68
- package/src/workflows/steps.ts +47 -61
- package/src/workflows/text.fixture.ts +36 -0
- package/src/workflows/text.test.ts +21 -28
- package/src/workflows/text.ts +19 -23
- package/src/workflows/unified.ts +1 -0
- package/src/workflows/vars.ts +7 -9
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -607,7 +607,7 @@ const isRecordOrArray = (input) => typeof input === "object" && input !== null;
|
|
|
607
607
|
* @since 2.0.0
|
|
608
608
|
* @see isRecord to check for plain objects (excluding arrays and functions).
|
|
609
609
|
*/
|
|
610
|
-
const isObject$
|
|
610
|
+
const isObject$3 = (input) => isRecordOrArray(input) || isFunction$1(input);
|
|
611
611
|
/**
|
|
612
612
|
* A refinement that checks if a value is an object-like value and has a specific property key.
|
|
613
613
|
*
|
|
@@ -630,7 +630,7 @@ const isObject$2 = (input) => isRecordOrArray(input) || isFunction$1(input);
|
|
|
630
630
|
* @category guards
|
|
631
631
|
* @since 2.0.0
|
|
632
632
|
*/
|
|
633
|
-
const hasProperty = /*#__PURE__*/ dual(2, (self, property) => isObject$
|
|
633
|
+
const hasProperty = /*#__PURE__*/ dual(2, (self, property) => isObject$3(self) && property in self);
|
|
634
634
|
/**
|
|
635
635
|
* A refinement that checks if a value is an object with a `_tag` property
|
|
636
636
|
* that matches the given tag. This is a powerful tool for working with
|
|
@@ -1295,7 +1295,7 @@ function formatUnknown(input, options) {
|
|
|
1295
1295
|
seen.add(v);
|
|
1296
1296
|
return `${v.constructor.name}(${go(Array.from(v), d)})`;
|
|
1297
1297
|
}
|
|
1298
|
-
if (isObject$
|
|
1298
|
+
if (isObject$3(v)) {
|
|
1299
1299
|
if (seen.has(v)) return CIRCULAR;
|
|
1300
1300
|
seen.add(v);
|
|
1301
1301
|
const keys = ownKeys(v);
|
|
@@ -5273,7 +5273,7 @@ const empty$21 = /*#__PURE__*/ (() => {
|
|
|
5273
5273
|
return o;
|
|
5274
5274
|
})();
|
|
5275
5275
|
/** @internal */
|
|
5276
|
-
const fail$
|
|
5276
|
+
const fail$12 = (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$
|
|
5356
|
+
onFail: map$14(fail$12),
|
|
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$
|
|
5392
|
+
const map$10 = /*#__PURE__*/ dual(2, (self, f) => flatMap$7(self, (e) => fail$12(f(e))));
|
|
5393
5393
|
/** @internal */
|
|
5394
5394
|
const flatMap$7 = /*#__PURE__*/ dual(2, (self, f) => match$7(self, {
|
|
5395
5395
|
onEmpty: empty$21,
|
|
@@ -8131,7 +8131,7 @@ const capture = (obj, span) => {
|
|
|
8131
8131
|
});
|
|
8132
8132
|
return obj;
|
|
8133
8133
|
};
|
|
8134
|
-
const die$3 = (defect) => isObject$
|
|
8134
|
+
const die$3 = (defect) => isObject$3(defect) && !(spanSymbol in defect) ? withFiberRuntime$1((fiber) => failCause$6(die$4(capture(defect, currentSpanFromFiber(fiber))))) : failCause$6(die$4(defect));
|
|
8135
8135
|
const dieMessage$1 = (message) => failCauseSync$1(() => die$4(new RuntimeException(message)));
|
|
8136
8136
|
const either$1 = (self) => matchEffect$1(self, {
|
|
8137
8137
|
onFailure: (e) => succeed$8(left(e)),
|
|
@@ -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$
|
|
8145
|
-
const failSync = (evaluate) => flatMap$6(sync$2(evaluate), fail$
|
|
8144
|
+
const fail$11 = (error) => isObject$3(error) && !(spanSymbol in error) ? withFiberRuntime$1((fiber) => failCause$6(fail$12(capture(error, currentSpanFromFiber(fiber))))) : failCause$6(fail$12(error));
|
|
8145
|
+
const failSync = (evaluate) => flatMap$6(sync$2(evaluate), fail$11);
|
|
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$
|
|
8164
|
+
b.then((a) => resume(succeed$8(a)), (e) => resume(fail$11(new UnknownException(e, "An unknown error occurred in Effect.andThen"))));
|
|
8165
8165
|
});
|
|
8166
8166
|
return succeed$8(b);
|
|
8167
8167
|
}));
|
|
@@ -8277,11 +8277,11 @@ const sync$2 = (thunk) => {
|
|
|
8277
8277
|
effect.effect_instruction_i0 = thunk;
|
|
8278
8278
|
return effect;
|
|
8279
8279
|
};
|
|
8280
|
-
const tap$1 = /*#__PURE__*/ dual((args) => args.length === 3 || args.length === 2 && !(isObject$
|
|
8280
|
+
const tap$1 = /*#__PURE__*/ dual((args) => args.length === 3 || args.length === 2 && !(isObject$3(args[1]) && "onlyEffect" in args[1]), (self, f) => flatMap$6(self, (a) => {
|
|
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$
|
|
8284
|
+
b.then((_) => resume(succeed$8(a)), (e) => resume(fail$11(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$
|
|
8577
|
+
return fail$11(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$
|
|
8587
|
+
else if ("Bun" in globalThis) return pretty$1(fail$12(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$
|
|
8664
|
+
const exitFail = (error) => exitFailCause$1(fail$12(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$
|
|
8784
|
+
const deferredFail = /*#__PURE__*/ dual(2, (self, error) => deferredCompleteWith(self, fail$11(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$
|
|
8846
|
+
const fail$10 = fail$12;
|
|
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$
|
|
9144
|
+
const fail$9 = 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`.
|
|
@@ -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$
|
|
9493
|
+
onNone: () => fail$11(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$
|
|
9552
|
+
case OP_FAIL$1: return fail$11(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$
|
|
9555
|
-
return fail$
|
|
9554
|
+
if (op.condition(error1)) return pipe(fromFlatLoop(flat, prefix, op.second, split), catchAll$1((error2) => fail$11(Or(error1, error2))));
|
|
9555
|
+
return fail$11(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$
|
|
9563
|
+
return fail$11(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$
|
|
9583
|
-
if (isLeft(left) && isRight(right$9)) return fail$
|
|
9584
|
-
if (isRight(left) && isLeft(right$9)) return fail$
|
|
9582
|
+
if (isLeft(left) && isLeft(right$9)) return fail$11(And(left.left, right$9.left));
|
|
9583
|
+
if (isLeft(left) && isRight(right$9)) return fail$11(left.left);
|
|
9584
|
+
if (isRight(left) && isLeft(right$9)) return fail$11(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);
|
|
@@ -10699,7 +10699,7 @@ const failCause$4 = /*#__PURE__*/ makeExit({
|
|
|
10699
10699
|
* @experimental
|
|
10700
10700
|
* @category constructors
|
|
10701
10701
|
*/
|
|
10702
|
-
const fail$
|
|
10702
|
+
const fail$8 = (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$
|
|
11000
|
+
return fail$8(this);
|
|
11001
11001
|
},
|
|
11002
11002
|
toString() {
|
|
11003
11003
|
return this.message ? `${this.name}: ${this.message}` : this.name;
|
|
@@ -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$
|
|
11338
|
+
return fail$11(onFailure ? internalCall(() => onFailure(error)) : new UnknownException(error, "An unknown error occurred in Effect.try"));
|
|
11339
11339
|
}
|
|
11340
11340
|
});
|
|
11341
11341
|
};
|
|
@@ -11408,7 +11408,7 @@ 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$
|
|
11411
|
+
onFailure: fail$11,
|
|
11412
11412
|
onSuccess: succeed$8
|
|
11413
11413
|
});
|
|
11414
11414
|
const sleep$1 = sleep$2;
|
|
@@ -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$
|
|
11429
|
+
const fail = (e) => catcher ? failSync(() => catcher(e)) : fail$11(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$
|
|
11494
|
+
const fail$7 = 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$
|
|
13670
|
+
return fail$11(op.left);
|
|
13671
13671
|
}
|
|
13672
13672
|
["None"](_) {
|
|
13673
|
-
return fail$
|
|
13673
|
+
return fail$11(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$
|
|
13689
|
+
case "Fail": return resume(fail$11(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$
|
|
13949
|
+
if (errored) return reconcile._tag === "Some" ? fail$11(reconcile.value(errors)) : fail$11(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
|
});
|
|
@@ -15934,7 +15934,7 @@ 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$
|
|
15937
|
+
if (isDone(decision)) return setState.pipe(zipRight$3(fail$11(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);
|
|
@@ -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$
|
|
16075
|
+
onSome: (error) => fail$12(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$
|
|
16080
|
+
const repeat_Effect = /*#__PURE__*/ dual(2, (self, schedule) => repeatOrElse_Effect(self, schedule, (e, _) => fail$11(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$
|
|
16112
|
+
const retry_Effect = /*#__PURE__*/ dual(2, (self, policy) => retryOrElse_Effect(self, policy, (e, _) => fail$11(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$
|
|
16879
|
+
const fail$6 = fail$11;
|
|
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$
|
|
21008
|
+
onFailure: fail$5,
|
|
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$
|
|
21052
|
+
const fail$5 = (error) => failCause$1(fail$10(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$
|
|
22039
|
+
return this.takeWith((cause) => failCause$3(map$7(cause, left)), (elem) => succeed$5(elem), (done) => fail$7(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$
|
|
22090
|
+
onFailure: fail$5,
|
|
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$
|
|
22099
|
+
onFailure: fail$5,
|
|
22100
22100
|
onDone: succeedNow
|
|
22101
22101
|
});
|
|
22102
22102
|
return pipeTo$1(self, reader);
|
|
@@ -22261,15 +22261,15 @@ 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$
|
|
22264
|
+
onFailure: (cause) => isDieType(cause) && isChannelException(cause.defect) && equals$2(cause.defect, channelException) ? fail$5(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);
|
|
22268
22268
|
}));
|
|
22269
22269
|
/** @internal */
|
|
22270
|
-
const run$
|
|
22270
|
+
const run$6 = (self) => scopedWith$1((scope) => runIn(self, scope));
|
|
22271
22271
|
/** @internal */
|
|
22272
|
-
const runDrain = (self) => run$
|
|
22272
|
+
const runDrain = (self) => run$6(drain$2(self));
|
|
22273
22273
|
/** @internal */
|
|
22274
22274
|
const runScoped = (self) => scopeWith((scope) => runIn(self, scope));
|
|
22275
22275
|
/** @internal */
|
|
@@ -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$
|
|
22431
|
+
onFailure: fail$5,
|
|
22432
22432
|
onDone: () => succeedNow(s)
|
|
22433
22433
|
});
|
|
22434
22434
|
};
|
|
@@ -22652,10 +22652,10 @@ const make$12 = (emit) => {
|
|
|
22652
22652
|
})));
|
|
22653
22653
|
},
|
|
22654
22654
|
end() {
|
|
22655
|
-
return this(fail$
|
|
22655
|
+
return this(fail$6(none$4()));
|
|
22656
22656
|
},
|
|
22657
22657
|
fail(e) {
|
|
22658
|
-
return this(fail$
|
|
22658
|
+
return this(fail$6(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$
|
|
22701
|
+
const end$1 = /*#__PURE__*/ new TakeImpl(/*#__PURE__*/ fail$7(/*#__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$
|
|
22723
|
+
const end = () => fail$6(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$
|
|
22836
|
+
onSome: fail$5
|
|
22837
22837
|
}),
|
|
22838
22838
|
onSuccess: (a) => write$1(of$1(a))
|
|
22839
22839
|
})));
|
|
@@ -22842,18 +22842,18 @@ const map$1 = /*#__PURE__*/ dual(2, (self, f) => new StreamImpl(pipe(toChannel$2
|
|
|
22842
22842
|
/** @internal */
|
|
22843
22843
|
const mapChunks$1 = /*#__PURE__*/ dual(2, (self, f) => new StreamImpl(pipe(toChannel$2(self), mapOut(f))));
|
|
22844
22844
|
/** @internal */
|
|
22845
|
-
const mkString$1 = (self) => run$
|
|
22845
|
+
const mkString$1 = (self) => run$5(self, mkString$2);
|
|
22846
22846
|
/** @internal */
|
|
22847
22847
|
const pipeThroughChannel = /*#__PURE__*/ dual(2, (self, channel) => new StreamImpl(pipeTo$1(toChannel$2(self), channel)));
|
|
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$
|
|
22851
|
+
onSome: fail$6
|
|
22852
22852
|
}))));
|
|
22853
22853
|
/** @internal */
|
|
22854
|
-
const run$
|
|
22854
|
+
const run$5 = /*#__PURE__*/ dual(2, (self, sink) => toChannel$2(self).pipe(pipeToOrFail(toChannel$3(sink)), runDrain));
|
|
22855
22855
|
/** @internal */
|
|
22856
|
-
const runCollect$1 = (self) => run$
|
|
22856
|
+
const runCollect$1 = (self) => run$5(self, collectAll());
|
|
22857
22857
|
/** @internal */
|
|
22858
22858
|
const runIntoQueueScoped = /*#__PURE__*/ dual(2, (self, queue) => {
|
|
22859
22859
|
const writer = readWithCause({
|
|
@@ -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$
|
|
22883
|
+
onFailure: fail$5,
|
|
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$
|
|
22897
|
+
onFailure: fail$5,
|
|
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$
|
|
25448
|
+
const fail$4 = left;
|
|
25449
25449
|
const _try = try_$2;
|
|
25450
25450
|
/**
|
|
25451
25451
|
* @category constructors
|
|
@@ -25635,7 +25635,7 @@ const go = (ast, isDecoding) => {
|
|
|
25635
25635
|
case "BooleanKeyword": return fromRefinement(ast, isBoolean);
|
|
25636
25636
|
case "BigIntKeyword": return fromRefinement(ast, isBigInt);
|
|
25637
25637
|
case "SymbolKeyword": return fromRefinement(ast, isSymbol);
|
|
25638
|
-
case "ObjectKeyword": return fromRefinement(ast, isObject$
|
|
25638
|
+
case "ObjectKeyword": return fromRefinement(ast, isObject$3);
|
|
25639
25639
|
case "Enums": return fromRefinement(ast, (u) => ast.enums.some(([_, value]) => value === u));
|
|
25640
25640
|
case "TemplateLiteral": {
|
|
25641
25641
|
const regex = getTemplateLiteralRegExp(ast);
|
|
@@ -26330,7 +26330,7 @@ const getArrayFormatterIssues = (issue, parentTag, path) => {
|
|
|
26330
26330
|
*
|
|
26331
26331
|
* @since 2.0.0
|
|
26332
26332
|
*/
|
|
26333
|
-
const pick = /*#__PURE__*/ dual((args) => isObject$
|
|
26333
|
+
const pick = /*#__PURE__*/ dual((args) => isObject$3(args[0]), (s, ...keys) => {
|
|
26334
26334
|
const out = {};
|
|
26335
26335
|
for (const k of keys) if (k in s) out[k] = s[k];
|
|
26336
26336
|
return out;
|
|
@@ -26349,7 +26349,7 @@ const pick = /*#__PURE__*/ dual((args) => isObject$2(args[0]), (s, ...keys) => {
|
|
|
26349
26349
|
*
|
|
26350
26350
|
* @since 2.0.0
|
|
26351
26351
|
*/
|
|
26352
|
-
const omit = /*#__PURE__*/ dual((args) => isObject$
|
|
26352
|
+
const omit = /*#__PURE__*/ dual((args) => isObject$3(args[0]), (s, ...keys) => {
|
|
26353
26353
|
const out = { ...s };
|
|
26354
26354
|
for (const k of keys) delete out[k];
|
|
26355
26355
|
return out;
|
|
@@ -26470,7 +26470,7 @@ const decodeUnknown = (schema, options) => {
|
|
|
26470
26470
|
* @category guards
|
|
26471
26471
|
* @since 3.10.0
|
|
26472
26472
|
*/
|
|
26473
|
-
const isSchema = (u) => hasProperty(u, TypeId$7) && isObject$
|
|
26473
|
+
const isSchema = (u) => hasProperty(u, TypeId$7) && isObject$3(u[TypeId$7]);
|
|
26474
26474
|
function getDefaultLiteralAST(literals) {
|
|
26475
26475
|
return isMembers(literals) ? Union$1.make(mapMembers(literals, (literal) => new Literal$1(literal))) : new Literal$1(literals[0]);
|
|
26476
26476
|
}
|
|
@@ -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$
|
|
26490
|
+
const decodeUnknown = () => (input, _, ast) => is(input) ? succeed(input) : fail$4(new Type(ast, input));
|
|
26491
26491
|
return makeDeclareClass([], new Declaration([], decodeUnknown, decodeUnknown, toASTAnnotations(annotations)));
|
|
26492
26492
|
};
|
|
26493
26493
|
function makeDeclareClass(typeParameters, ast) {
|
|
@@ -27177,8 +27177,8 @@ const LengthSchemaId = LengthSchemaId$1;
|
|
|
27177
27177
|
* @since 3.10.0
|
|
27178
27178
|
*/
|
|
27179
27179
|
const length = (length, annotations) => (self) => {
|
|
27180
|
-
const minLength = isObject$
|
|
27181
|
-
const maxLength = isObject$
|
|
27180
|
+
const minLength = isObject$3(length) ? Math.max(0, Math.floor(length.min)) : Math.max(0, Math.floor(length));
|
|
27181
|
+
const maxLength = isObject$3(length) ? Math.max(minLength, Math.floor(length.max)) : minLength;
|
|
27182
27182
|
if (minLength !== maxLength) return self.pipe(filter((a) => a.length >= minLength && a.length <= maxLength, {
|
|
27183
27183
|
schemaId: LengthSchemaId,
|
|
27184
27184
|
title: `length({ min: ${minLength}, max: ${maxLength})`,
|
|
@@ -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$
|
|
27654
|
+
return key === void 0 ? fail$4(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$
|
|
27740
|
+
onNone: () => fail$4(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$
|
|
27964
|
+
onNone: () => fail$4(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$
|
|
27990
|
+
onNone: () => fail$4(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$
|
|
28004
|
+
const optionParse = (decodeUnknown) => (u, options, ast) => isOption(u) ? isNone(u) ? succeed(none$4()) : toComposite(decodeUnknown(u.value, options), some, ast, u) : fail$4(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$
|
|
28047
|
+
onNone: () => fail$4(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$
|
|
28169
|
+
decode: () => (input, _, ast) => input instanceof this || fallbackInstanceOf(input) ? succeed(input) : fail$4(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$
|
|
28396
|
+
const causeParse = (decodeUnknown) => (u, options, ast) => isCause(u) ? toComposite(decodeUnknown(causeEncode(u), options), causeDecode, ast, u) : fail$4(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$
|
|
28415
|
+
case "Fail": return fail$10(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));
|
|
@@ -28478,7 +28478,7 @@ const Cause = ({ defect, error }) => {
|
|
|
28478
28478
|
var Defect = class extends transform$1(Unknown, Unknown, {
|
|
28479
28479
|
strict: true,
|
|
28480
28480
|
decode: (i) => {
|
|
28481
|
-
if (isObject$
|
|
28481
|
+
if (isObject$3(i) && "message" in i && typeof i.message === "string") {
|
|
28482
28482
|
const err = new Error(i.message, { cause: i });
|
|
28483
28483
|
if ("name" in i && typeof i.name === "string") err.name = i.name;
|
|
28484
28484
|
err.stack = "stack" in i && typeof i.stack === "string" ? i.stack : "";
|
|
@@ -28569,7 +28569,7 @@ const mkString = mkString$1;
|
|
|
28569
28569
|
* @since 2.0.0
|
|
28570
28570
|
* @category destructors
|
|
28571
28571
|
*/
|
|
28572
|
-
const run$
|
|
28572
|
+
const run$4 = run$5;
|
|
28573
28573
|
/**
|
|
28574
28574
|
* Runs the stream and collects all of its elements to a chunk.
|
|
28575
28575
|
*
|
|
@@ -28716,7 +28716,7 @@ const makeExecutor$1 = (start) => {
|
|
|
28716
28716
|
stream,
|
|
28717
28717
|
string: (command, encoding = "utf-8") => {
|
|
28718
28718
|
const decoder = new TextDecoder(encoding);
|
|
28719
|
-
return pipe(start(command), flatMap$4((process) => run$
|
|
28719
|
+
return pipe(start(command), flatMap$4((process) => run$4(process.stdout, collectUint8Array)), map$4((bytes) => decoder.decode(bytes)), scoped$3);
|
|
28720
28720
|
},
|
|
28721
28721
|
lines: (command, encoding = "utf-8") => {
|
|
28722
28722
|
return pipe(streamLines(command, encoding), runCollect, map$4(toArray$1));
|
|
@@ -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$
|
|
28998
|
+
if (err) resume(fail$6(onError ? onError(err, args) : err));
|
|
28999
28999
|
else resume(succeed$3(result));
|
|
29000
29000
|
});
|
|
29001
29001
|
} catch (err) {
|
|
29002
|
-
resume(onSyncError ? fail$
|
|
29002
|
+
resume(onSyncError ? fail$6(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$
|
|
29023
|
+
exists: (path) => pipe(impl.access(path), as(true), catchTag("SystemError", (e) => e.reason === "NotFound" ? succeed$3(false) : fail$6(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$
|
|
29843
|
+
if (response[1] === 2) return DeferredTypeId in mailbox ? fail$9(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$
|
|
30147
|
+
if (bytesWritten === 0) return fail$6(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$
|
|
30183
|
+
if (err) resume(fail$6(handleErrnoException("FileSystem", "readFile")(err, [path])));
|
|
30184
30184
|
else resume(succeed$3(data));
|
|
30185
30185
|
});
|
|
30186
30186
|
} catch (err) {
|
|
30187
|
-
resume(fail$
|
|
30187
|
+
resume(fail$6(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$
|
|
30241
|
+
onFailure: (err) => err._tag === "SystemError" && err.reason === "NotFound" ? succeed$3(WatchEventRemove({ path })) : fail$6(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$
|
|
30271
|
+
if (err) resume(fail$6(handleErrnoException("FileSystem", "writeFile")(err, [path])));
|
|
30272
30272
|
else resume(_void);
|
|
30273
30273
|
});
|
|
30274
30274
|
} catch (err) {
|
|
30275
|
-
resume(fail$
|
|
30275
|
+
resume(fail$6(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$
|
|
30359
|
+
exit.current = fail$7(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$
|
|
30399
|
+
unsafeDone(deferred, fail$6(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$
|
|
30447
|
+
resume(fail$6(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$
|
|
30461
|
+
if (error) resume(fail$6(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$
|
|
30468
|
+
const killProcess = (handle, signal) => suspend$5(() => handle.kill(signal) ? _void : fail$6(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$
|
|
30483
|
+
return fail$6(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))));
|
|
@@ -30497,7 +30497,7 @@ const runCommand$1 = (fileSystem) => (command) => {
|
|
|
30497
30497
|
stderr,
|
|
30498
30498
|
stdout
|
|
30499
30499
|
});
|
|
30500
|
-
}), typeof command.stdin === "string" ? identity$1 : tap((process) => forkDaemon(run$
|
|
30500
|
+
}), typeof command.stdin === "string" ? identity$1 : tap((process) => forkDaemon(run$4(command.stdin, process.stdin))));
|
|
30501
30501
|
}
|
|
30502
30502
|
case "PipedCommand": {
|
|
30503
30503
|
const flattened = flatten(command);
|
|
@@ -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$
|
|
30614
|
+
stdout.write(prompt, (err) => err ? resume(fail$6(new BadArgument({
|
|
30615
30615
|
module: "Terminal",
|
|
30616
30616
|
method: "display",
|
|
30617
30617
|
description: "Failed to write prompt to stdout",
|
|
@@ -30904,7 +30904,7 @@ const human = (name, options = {}) => ctx().step({
|
|
|
30904
30904
|
options
|
|
30905
30905
|
});
|
|
30906
30906
|
/** A check: `body` runs at the edge and its effect on the tree is committed. */
|
|
30907
|
-
const run$
|
|
30907
|
+
const run$3 = (name, body, options = {}) => ctx().step({
|
|
30908
30908
|
kind: "run",
|
|
30909
30909
|
name,
|
|
30910
30910
|
body,
|
|
@@ -30966,6 +30966,8 @@ const changesSince = (hash, pattern) => {
|
|
|
30966
30966
|
const head = () => ctx().head();
|
|
30967
30967
|
/** The process's diff base: the commit before it began, or the base `gtd --entry` fixed. */
|
|
30968
30968
|
const start = () => ctx().start();
|
|
30969
|
+
/** The skill list `localName` (scoped from here, same as `agent()`) resolves to — for a prompt preamble. See `FlowContext.skillsFor` for `ownSkills`. */
|
|
30970
|
+
const skillsFor = (localName, ownSkills) => ctx().skillsFor(localName, ownSkills);
|
|
30969
30971
|
/** The merged workflow variables. */
|
|
30970
30972
|
const vars = new Proxy({}, {
|
|
30971
30973
|
get: (_target, key) => typeof key === "string" ? ctx().vars[key] : void 0,
|
|
@@ -31096,7 +31098,7 @@ const wrote = (path) => changes(path).some((c) => c.status !== "deleted");
|
|
|
31096
31098
|
*/
|
|
31097
31099
|
const check = async (name, command, options) => {
|
|
31098
31100
|
const { report, label, sweep, sweepOnGreen } = options;
|
|
31099
|
-
await run$
|
|
31101
|
+
await run$3(name, checkScript(command, {
|
|
31100
31102
|
report,
|
|
31101
31103
|
stamp: head().slice(0, 7),
|
|
31102
31104
|
sweep,
|
|
@@ -31181,10 +31183,11 @@ var flows_exports = /* @__PURE__ */ __exportAll({
|
|
|
31181
31183
|
restart: () => restart,
|
|
31182
31184
|
restoreScript: () => restoreScript,
|
|
31183
31185
|
revertScript: () => revertScript,
|
|
31184
|
-
run: () => run$
|
|
31186
|
+
run: () => run$3,
|
|
31185
31187
|
scope: () => scope,
|
|
31186
31188
|
sectionBodies: () => sectionBodies,
|
|
31187
31189
|
sections: () => sections,
|
|
31190
|
+
skillsFor: () => skillsFor,
|
|
31188
31191
|
start: () => start,
|
|
31189
31192
|
threads: () => threads,
|
|
31190
31193
|
vars: () => vars,
|
|
@@ -47773,7 +47776,11 @@ const replay = async (input) => {
|
|
|
47773
47776
|
truncated: judgeCuts.get(request) ?? []
|
|
47774
47777
|
} : void 0;
|
|
47775
47778
|
const judgeCuts = /* @__PURE__ */ new WeakMap();
|
|
47776
|
-
const
|
|
47779
|
+
const resolveSkills = (name, ownSkills) => {
|
|
47780
|
+
const resolved = input.configuredSkills?.[name] ?? ownSkills ?? input.skills?.[name];
|
|
47781
|
+
return resolved !== void 0 && resolved.length === 0 ? void 0 : resolved;
|
|
47782
|
+
};
|
|
47783
|
+
const resolve = (request, name) => {
|
|
47777
47784
|
if (request.kind === "agent") {
|
|
47778
47785
|
const persona = {};
|
|
47779
47786
|
for (const s of scopes) {
|
|
@@ -47784,7 +47791,8 @@ const replay = async (input) => {
|
|
|
47784
47791
|
...request,
|
|
47785
47792
|
options: {
|
|
47786
47793
|
...persona,
|
|
47787
|
-
...request.options
|
|
47794
|
+
...request.options,
|
|
47795
|
+
skills: resolveSkills(name, request.options.skills)
|
|
47788
47796
|
}
|
|
47789
47797
|
};
|
|
47790
47798
|
}
|
|
@@ -47803,7 +47811,7 @@ const replay = async (input) => {
|
|
|
47803
47811
|
const name = scoped(request.name);
|
|
47804
47812
|
const occurrence = (occurrences.get(name) ?? 0) + 1;
|
|
47805
47813
|
occurrences.set(name, occurrence);
|
|
47806
|
-
const resolved = resolve(request);
|
|
47814
|
+
const resolved = resolve(request, name);
|
|
47807
47815
|
const reached = {
|
|
47808
47816
|
id: {
|
|
47809
47817
|
name,
|
|
@@ -47968,6 +47976,7 @@ const replay = async (input) => {
|
|
|
47968
47976
|
}),
|
|
47969
47977
|
vars: input.vars,
|
|
47970
47978
|
start: () => input.start,
|
|
47979
|
+
skillsFor: (localName, ownSkills) => resolveSkills(scoped(localName), ownSkills) ?? [],
|
|
47971
47980
|
head: () => {
|
|
47972
47981
|
const rest = commits.slice(cursor);
|
|
47973
47982
|
return rest.length > 0 && rest.every((c) => c.parsed.step === void 0) ? rest[rest.length - 1].hash : position.hash;
|
|
@@ -48241,21 +48250,18 @@ const withSkills = (skills, prompt) => {
|
|
|
48241
48250
|
if (skills === void 0 || skills.trim() === "") return prompt;
|
|
48242
48251
|
return `${skillsPreamble.replaceAll("{skills}", skills)}\n\n${prompt}`;
|
|
48243
48252
|
};
|
|
48244
|
-
/** `skills:` split on `,`, each name trimmed, empty entries dropped — `[]` for `undefined`, `""`, or blank. */
|
|
48245
|
-
const splitSkills = (raw) => (raw ?? "").split(",").map((name) => name.trim()).filter((name) => name.length > 0);
|
|
48246
48253
|
/**
|
|
48247
|
-
* An `agent()` step
|
|
48248
|
-
*
|
|
48249
|
-
*
|
|
48250
|
-
*
|
|
48254
|
+
* An `agent()` step whose preamble names its resolved skills: `skillsFor`
|
|
48255
|
+
* resolves `name` (scoped from here, same as `agent()`'s own resolver) for
|
|
48256
|
+
* the preamble prose, passing `options.skills` through as `ownSkills` — the
|
|
48257
|
+
* same precedence tier `agent()`'s own wire resolver gives a call's own
|
|
48258
|
+
* `skills` option, so a step that declares one (`reviewQuality`'s per-turn
|
|
48259
|
+
* lens) gets it in the preamble too, not just on the wire, whenever no
|
|
48260
|
+
* bundled or configured entry outranks it. Both reads share one resolver
|
|
48261
|
+
* (`Replay.ts`'s `resolveSkills`), so the preamble and the wire can't drift
|
|
48262
|
+
* apart.
|
|
48251
48263
|
*/
|
|
48252
|
-
const agentWithSkills = (name,
|
|
48253
|
-
const list = splitSkills(skills);
|
|
48254
|
-
return agent(name, withSkills(list.join(", "), prompt), {
|
|
48255
|
-
...options,
|
|
48256
|
-
skills: list
|
|
48257
|
-
});
|
|
48258
|
-
};
|
|
48264
|
+
const agentWithSkills = (name, prompt, options = {}) => agent(name, withSkills(skillsFor(name, options.skills).join(", "), prompt), options);
|
|
48259
48265
|
const unwindFailure = (commit) => `gtd could not unwind ${commit} out of your working tree.`;
|
|
48260
48266
|
const idleMessage = () => `No active gtd process.
|
|
48261
48267
|
|
|
@@ -48899,10 +48905,13 @@ every commit is machine-authored.
|
|
|
48899
48905
|
high-level architectural changes — never which files changed; \`git
|
|
48900
48906
|
diff --stat\` is for that, not this message
|
|
48901
48907
|
- If the range removes or renames a documented config key, CLI flag, or
|
|
48902
|
-
workflow state
|
|
48903
|
-
|
|
48904
|
-
|
|
48905
|
-
|
|
48908
|
+
workflow state, OR makes a previously-accepted config value now fail to
|
|
48909
|
+
load (a stricter validation, an escape a value must now spell differently)
|
|
48910
|
+
— a public surface, not an internal one, either way — add a literal
|
|
48911
|
+
\`BREAKING CHANGE:\` footer naming what breaks and, for the second case,
|
|
48912
|
+
the exact escape or rewrite a committed \`.gtdrc\` needs. A \`!\` on the
|
|
48913
|
+
type prefix alone (\`feat!:\`/\`refactor!:\`) is NOT enough: this repo's
|
|
48914
|
+
own commit-analyzer has missed that marker before, cutting no release
|
|
48906
48915
|
until a follow-up commit carried the literal footer instead
|
|
48907
48916
|
|
|
48908
48917
|
The process's entry commit is \`${it.entryCommit}\`. ${human}Inspect the range: \`git log ${it.processBase}..${it.processTip}\`
|
|
@@ -48926,21 +48935,21 @@ const SPEC_FEEDBACK = ".gtd/SPEC_FEEDBACK.md";
|
|
|
48926
48935
|
const planner = () => vars.plannerModel ?? "";
|
|
48927
48936
|
const coder = () => vars.coderModel ?? "";
|
|
48928
48937
|
/** Turn the sketch since `base` into `.gtd/REQUIREMENTS.md`. */
|
|
48929
|
-
const triage$1 = (base) => agentWithSkills("triage",
|
|
48938
|
+
const triage$1 = (base) => agentWithSkills("triage", designTriagePrompt(base), {
|
|
48930
48939
|
label: "Triaging the change",
|
|
48931
48940
|
file: REQUIREMENTS,
|
|
48932
48941
|
mode: "qa",
|
|
48933
48942
|
model: planner(),
|
|
48934
48943
|
system: designSystem()
|
|
48935
48944
|
});
|
|
48936
|
-
const author = () => agentWithSkills("author",
|
|
48945
|
+
const author = () => agentWithSkills("author", architectureAuthorPrompt(), {
|
|
48937
48946
|
label: "Refining the technical plan",
|
|
48938
48947
|
file: ARCHITECTURE,
|
|
48939
48948
|
mode: "qa",
|
|
48940
48949
|
model: planner(),
|
|
48941
48950
|
system: architectSystem()
|
|
48942
48951
|
});
|
|
48943
|
-
const decompose = () => agentWithSkills("decompose",
|
|
48952
|
+
const decompose = () => agentWithSkills("decompose", architectureDecomposePrompt(), {
|
|
48944
48953
|
label: "Decomposing into packages",
|
|
48945
48954
|
model: planner(),
|
|
48946
48955
|
system: architectSystem()
|
|
@@ -48959,37 +48968,37 @@ const answerTechnicalQuestions = () => human("gate.answer", {
|
|
|
48959
48968
|
mode: "qa",
|
|
48960
48969
|
acceptClean: true
|
|
48961
48970
|
});
|
|
48962
|
-
const build = (pkg) => agentWithSkills("building",
|
|
48971
|
+
const build = (pkg) => agentWithSkills("building", packagesItemBuildingPrompt(pkg), {
|
|
48963
48972
|
label: "Building",
|
|
48964
48973
|
model: coder(),
|
|
48965
48974
|
system: builderSystem()
|
|
48966
48975
|
});
|
|
48967
|
-
const fixSuite = () => agentWithSkills("fix-suite",
|
|
48976
|
+
const fixSuite = () => agentWithSkills("fix-suite", packagesItemFixSuitePrompt(), {
|
|
48968
48977
|
label: "Fixing the check",
|
|
48969
48978
|
file: FEEDBACK,
|
|
48970
48979
|
model: coder(),
|
|
48971
48980
|
system: builderSystem()
|
|
48972
48981
|
});
|
|
48973
|
-
const fixSpec = (pkg) => agentWithSkills("fix-spec",
|
|
48982
|
+
const fixSpec = (pkg) => agentWithSkills("fix-spec", packagesItemFixSpecPrompt(pkg), {
|
|
48974
48983
|
label: "Fixing review feedback",
|
|
48975
48984
|
file: SPEC_FEEDBACK,
|
|
48976
48985
|
model: coder(),
|
|
48977
48986
|
system: builderSystem()
|
|
48978
48987
|
});
|
|
48979
48988
|
/** Review `pkg` against its spec, focused on the `failing` sections the pre-judge could not clear. */
|
|
48980
|
-
const reviewPackage = (pkg, failing = []) => agentWithSkills("spec.review",
|
|
48989
|
+
const reviewPackage = (pkg, failing = []) => agentWithSkills("spec.review", packagesItemSpecReviewPrompt(pkg, failing), {
|
|
48981
48990
|
label: "Reviewing the package",
|
|
48982
48991
|
model: planner(),
|
|
48983
48992
|
system: specReviewerSystem(),
|
|
48984
48993
|
allowEmpty: true
|
|
48985
48994
|
});
|
|
48986
|
-
const fix = () => agentWithSkills("fix",
|
|
48995
|
+
const fix = () => agentWithSkills("fix", buildFixPrompt(), {
|
|
48987
48996
|
label: "Fixing the check",
|
|
48988
48997
|
file: FEEDBACK,
|
|
48989
48998
|
model: coder(),
|
|
48990
48999
|
system: finisherSystem()
|
|
48991
49000
|
});
|
|
48992
|
-
const describeEscalation = () => agentWithSkills("health.describe",
|
|
49001
|
+
const describeEscalation = () => agentWithSkills("health.describe", healthDescribePrompt(), {
|
|
48993
49002
|
label: "Describing the escalation",
|
|
48994
49003
|
file: FEEDBACK,
|
|
48995
49004
|
model: coder(),
|
|
@@ -49008,15 +49017,21 @@ const escalationExhausted = () => human("health.exhausted", {
|
|
|
49008
49017
|
file: ESCALATION,
|
|
49009
49018
|
acceptClean: true
|
|
49010
49019
|
});
|
|
49011
|
-
/**
|
|
49012
|
-
|
|
49020
|
+
/**
|
|
49021
|
+
* One quality review, through the skill `lens`. `lens` rides as this turn's
|
|
49022
|
+
* own `skills` option — a `.gtdrc` `build.quality.reviewing` entry still
|
|
49023
|
+
* overrides it (config beats a flow-supplied list same as any other step),
|
|
49024
|
+
* but absent one the lens itself is what the turn loads by default.
|
|
49025
|
+
*/
|
|
49026
|
+
const reviewQuality = (lens) => agentWithSkills("quality.reviewing", buildQualityReviewingPrompt(lens), {
|
|
49013
49027
|
label: "Reviewing (one quality lens)",
|
|
49014
49028
|
file: QUALITY,
|
|
49015
49029
|
model: planner(),
|
|
49016
49030
|
system: reviewerSystem(),
|
|
49017
|
-
allowEmpty: true
|
|
49031
|
+
allowEmpty: true,
|
|
49032
|
+
skills: [lens]
|
|
49018
49033
|
});
|
|
49019
|
-
const fixQuality = () => agentWithSkills("fix-quality",
|
|
49034
|
+
const fixQuality = () => agentWithSkills("fix-quality", buildFixQualityPrompt(), {
|
|
49020
49035
|
label: "Fixing quality findings",
|
|
49021
49036
|
file: QUALITY,
|
|
49022
49037
|
model: coder(),
|
|
@@ -49024,7 +49039,7 @@ const fixQuality = () => agentWithSkills("fix-quality", vars.reviewFixSkills, bu
|
|
|
49024
49039
|
allowEmpty: true
|
|
49025
49040
|
});
|
|
49026
49041
|
/** Write `.gtd/REVIEW.md` over everything since `base`, carrying the answers of commit `carry` when given. */
|
|
49027
|
-
const reviewing = (base, carry) => agentWithSkills("review.reviewing",
|
|
49042
|
+
const reviewing = (base, carry) => agentWithSkills("review.reviewing", buildReviewReviewingPrompt(base, carry), {
|
|
49028
49043
|
label: "Reviewing",
|
|
49029
49044
|
file: REVIEW,
|
|
49030
49045
|
mode: "review",
|
|
@@ -49033,7 +49048,7 @@ const reviewing = (base, carry) => agentWithSkills("review.reviewing", vars.revi
|
|
|
49033
49048
|
base
|
|
49034
49049
|
});
|
|
49035
49050
|
/** Answer every `question` note inline in `.gtd/REVIEW.md`. */
|
|
49036
|
-
const answerReviewQuestions = (notes) => agentWithSkills("review.answer-review-questions",
|
|
49051
|
+
const answerReviewQuestions = (notes) => agentWithSkills("review.answer-review-questions", buildReviewAnswerQuestionsPrompt(notes), {
|
|
49037
49052
|
label: "Answering your questions",
|
|
49038
49053
|
file: REVIEW,
|
|
49039
49054
|
mode: "review",
|
|
@@ -49044,7 +49059,7 @@ const answerReviewQuestions = (notes) => agentWithSkills("review.answer-review-q
|
|
|
49044
49059
|
* Fix every `nit` note in one turn. Its name puts it in the `build.review`
|
|
49045
49060
|
* conversation, which has one identity — so it runs as the reviewer, not the coder.
|
|
49046
49061
|
*/
|
|
49047
|
-
const fixNits = (notes) => agentWithSkills("review.fix-nits",
|
|
49062
|
+
const fixNits = (notes) => agentWithSkills("review.fix-nits", buildReviewFixNitsPrompt(notes), {
|
|
49048
49063
|
label: "Fixing your nits",
|
|
49049
49064
|
file: REVIEW,
|
|
49050
49065
|
model: planner(),
|
|
@@ -49063,7 +49078,7 @@ const reviewMissing = (round) => human("review.review-missing", {
|
|
|
49063
49078
|
label: "Nothing to review"
|
|
49064
49079
|
});
|
|
49065
49080
|
/** Turn the review round `capture` describes into `.gtd/REQUIREMENTS.md`, or change nothing. */
|
|
49066
|
-
const collecting = (capture) => agentWithSkills("review.collecting",
|
|
49081
|
+
const collecting = (capture) => agentWithSkills("review.collecting", buildReviewCollectingPrompt(capture), {
|
|
49067
49082
|
label: "Collecting your feedback",
|
|
49068
49083
|
file: REQUIREMENTS,
|
|
49069
49084
|
mode: "qa",
|
|
@@ -49458,7 +49473,7 @@ const packageItem = async (pkg) => {
|
|
|
49458
49473
|
if (await specReview(pkg, since)) break;
|
|
49459
49474
|
await fixSpec(pkg);
|
|
49460
49475
|
}
|
|
49461
|
-
await run$
|
|
49476
|
+
await run$3("closing", removeScript([
|
|
49462
49477
|
pkg,
|
|
49463
49478
|
SPEC_FEEDBACK,
|
|
49464
49479
|
".gtd/SATISFIED.md",
|
|
@@ -49521,15 +49536,15 @@ const architecturePass = async () => {
|
|
|
49521
49536
|
const skip = truncated.length === 0 && answered(answers.architectureWarranted, "no", numeric(vars.architectureSkipMinP, Infinity));
|
|
49522
49537
|
const plan = read(REQUIREMENTS);
|
|
49523
49538
|
if (skip && plan !== void 0) {
|
|
49524
|
-
await run$
|
|
49539
|
+
await run$3("architecture-promote", moveScript(REQUIREMENTS, `.gtd/packages/01-${slug(sections(plan)[0] ?? "")}.md`), { label: "Promoting the plan straight to a package" });
|
|
49525
49540
|
return;
|
|
49526
49541
|
}
|
|
49527
49542
|
await architecture();
|
|
49528
49543
|
};
|
|
49529
49544
|
//#endregion
|
|
49530
49545
|
//#region src/workflows/review.ts
|
|
49531
|
-
/** The
|
|
49532
|
-
const qualityLenses = () =>
|
|
49546
|
+
/** The lenses the quality lap reviews with, one turn each: the `qualityReviews` var, split on `,` and trimmed. Unlike a `skills:` entry, this fans out into one whole turn per entry rather than naming one step's skill list — see `build.quality.reviewing` in `./skills.ts` for the (separate) skills a lens turn itself loads. */
|
|
49547
|
+
const qualityLenses = () => (vars.qualityReviews ?? "").split(",").map((lens) => lens.trim()).filter((lens) => lens.length > 0);
|
|
49533
49548
|
/**
|
|
49534
49549
|
* One review turn per lens over the whole change, each appending what it
|
|
49535
49550
|
* finds blocking to `.gtd/QUALITY.md`. Resolves `"findings"` when that file
|
|
@@ -49672,7 +49687,7 @@ const finish = async (reviewed, collectedAt, escalations) => {
|
|
|
49672
49687
|
const record = read(".gtd/REVIEW.md") ?? "";
|
|
49673
49688
|
const { folded, settled } = afterCollect(collectedAt);
|
|
49674
49689
|
const noted = since.some((c) => c.path === REVIEW);
|
|
49675
|
-
const close = () => run$
|
|
49690
|
+
const close = () => run$3("review.closing", removeScript([REVIEW]), {
|
|
49676
49691
|
label: "Closing the review",
|
|
49677
49692
|
base: round
|
|
49678
49693
|
});
|
|
@@ -49761,18 +49776,33 @@ const defaults = {
|
|
|
49761
49776
|
specPreJudge: "0.9",
|
|
49762
49777
|
reviewNoteActionable: "0.7",
|
|
49763
49778
|
architectureSkipMinP: "0.85",
|
|
49764
|
-
triageSkills: "spec-driven-development, planning-and-task-breakdown",
|
|
49765
|
-
architectureSkills: "api-and-interface-design, documentation-and-adrs, ponytail",
|
|
49766
|
-
decomposeSkills: "incremental-implementation, planning-and-task-breakdown",
|
|
49767
|
-
buildSkills: "test-driven-development, incremental-implementation",
|
|
49768
|
-
fixSkills: "debugging-and-error-recovery",
|
|
49769
|
-
reviewFixSkills: "incremental-implementation, code-simplification",
|
|
49770
|
-
reviewSkills: "code-review-and-quality",
|
|
49771
|
-
specReviewSkills: "code-review-and-quality, spec-driven-development",
|
|
49772
|
-
escalateSkills: "debugging-and-error-recovery",
|
|
49773
49779
|
qualityReviews: "owasp-security, ponytail-review, test-audit"
|
|
49774
49780
|
};
|
|
49775
49781
|
//#endregion
|
|
49782
|
+
//#region src/workflows/skills.ts
|
|
49783
|
+
const skills = {
|
|
49784
|
+
"design.triage": ["spec-driven-development", "planning-and-task-breakdown"],
|
|
49785
|
+
"architecture.author": [
|
|
49786
|
+
"api-and-interface-design",
|
|
49787
|
+
"documentation-and-adrs",
|
|
49788
|
+
"ponytail"
|
|
49789
|
+
],
|
|
49790
|
+
"architecture.decompose": ["incremental-implementation", "planning-and-task-breakdown"],
|
|
49791
|
+
"packages.item.building": ["test-driven-development", "incremental-implementation"],
|
|
49792
|
+
"packages.item.fix-suite": ["debugging-and-error-recovery"],
|
|
49793
|
+
"packages.item.fix-spec": ["incremental-implementation", "code-simplification"],
|
|
49794
|
+
"packages.item.spec.review": ["code-review-and-quality", "spec-driven-development"],
|
|
49795
|
+
"packages.item.health.describe": ["debugging-and-error-recovery"],
|
|
49796
|
+
"build.fix": ["debugging-and-error-recovery"],
|
|
49797
|
+
"build.health.describe": ["debugging-and-error-recovery"],
|
|
49798
|
+
"build.quality.reviewing": [],
|
|
49799
|
+
"build.fix-quality": ["incremental-implementation", "code-simplification"],
|
|
49800
|
+
"build.review.reviewing": ["code-review-and-quality"],
|
|
49801
|
+
"build.review.answer-review-questions": ["code-review-and-quality"],
|
|
49802
|
+
"build.review.fix-nits": ["incremental-implementation", "code-simplification"],
|
|
49803
|
+
"build.review.collecting": ["code-review-and-quality"]
|
|
49804
|
+
};
|
|
49805
|
+
//#endregion
|
|
49776
49806
|
//#region src/workflows/unified.ts
|
|
49777
49807
|
var unified_exports = /* @__PURE__ */ __exportAll({
|
|
49778
49808
|
ARCHITECTURE: () => ARCHITECTURE,
|
|
@@ -49827,6 +49857,7 @@ var unified_exports = /* @__PURE__ */ __exportAll({
|
|
|
49827
49857
|
reviewPackage: () => reviewPackage,
|
|
49828
49858
|
reviewQuality: () => reviewQuality,
|
|
49829
49859
|
reviewing: () => reviewing,
|
|
49860
|
+
skills: () => skills,
|
|
49830
49861
|
specReview: () => specReview,
|
|
49831
49862
|
steering: () => steering,
|
|
49832
49863
|
summary: () => summary,
|
|
@@ -49837,7 +49868,7 @@ var unified_exports = /* @__PURE__ */ __exportAll({
|
|
|
49837
49868
|
/** Revert the sketch that started the process out of the working tree; its intent survives in history. */
|
|
49838
49869
|
const unwind = () => {
|
|
49839
49870
|
const commit = head();
|
|
49840
|
-
return run$
|
|
49871
|
+
return run$3("unwind", revertScript(commit, FEEDBACK, unwindFailure(commit)), { label: "Unwinding your input" });
|
|
49841
49872
|
};
|
|
49842
49873
|
/**
|
|
49843
49874
|
* Undo the human's review-round code edits. A path changed since the human
|
|
@@ -49845,7 +49876,7 @@ const unwind = () => {
|
|
|
49845
49876
|
*/
|
|
49846
49877
|
const reUnwind = async (feedback) => {
|
|
49847
49878
|
const { base, restoreFrom, edited } = feedback;
|
|
49848
|
-
await run$
|
|
49879
|
+
await run$3("re-unwind", restoreScript(base, {
|
|
49849
49880
|
restore: edited.filter((c) => c.status !== "added").map((c) => c.path),
|
|
49850
49881
|
remove: edited.filter((c) => c.status === "added").map((c) => c.path)
|
|
49851
49882
|
}, restoreFrom), {
|
|
@@ -50050,7 +50081,7 @@ const classifyUntracked = (exec, ref, untrackedPaths) => gen(function* () {
|
|
|
50050
50081
|
* `git add`. Callers that expect a probe to fail handle it with an explicit
|
|
50051
50082
|
* `catchAll`.
|
|
50052
50083
|
*/
|
|
50053
|
-
const run$
|
|
50084
|
+
const run$2 = (root, ...args) => scoped$3(gen(function* () {
|
|
50054
50085
|
const process = yield* (yield* CommandExecutor).start(make$8(...args).pipe(workingDirectory(root), stdout("pipe"), stderr("pipe")));
|
|
50055
50086
|
const collect = (stream) => stream.pipe(decodeText(), mkString);
|
|
50056
50087
|
const [stdout$3, stderr$3, exitCode] = yield* all$1([
|
|
@@ -50058,7 +50089,7 @@ const run$1 = (root, ...args) => scoped$3(gen(function* () {
|
|
|
50058
50089
|
collect(process.stderr),
|
|
50059
50090
|
process.exitCode
|
|
50060
50091
|
], { concurrency: "unbounded" });
|
|
50061
|
-
if (exitCode !== 0) return yield* fail$
|
|
50092
|
+
if (exitCode !== 0) return yield* fail$6(/* @__PURE__ */ new Error(`${args.join(" ")} failed (exit ${exitCode}): ${stderr$3.trim()}`));
|
|
50062
50093
|
return stdout$3;
|
|
50063
50094
|
})).pipe(mapError$1((e) => e instanceof Error ? e : new Error(String(e))));
|
|
50064
50095
|
/**
|
|
@@ -50082,9 +50113,9 @@ var InvalidRefError = class extends Error {
|
|
|
50082
50113
|
* missing one. A separate pure function so this rare branch is unit-testable
|
|
50083
50114
|
* without a real git repository contriving the condition.
|
|
50084
50115
|
*/
|
|
50085
|
-
const resolvedRefOrCorrupted = (ref, hash) => /^[0-9a-f]{40}$/.test(hash) ? succeed$3(hash) : fail$
|
|
50116
|
+
const resolvedRefOrCorrupted = (ref, hash) => /^[0-9a-f]{40}$/.test(hash) ? succeed$3(hash) : fail$6(new InvalidRefError(`Invalid ref: ${ref}`, [`ref: ${ref}`]));
|
|
50086
50117
|
const makeGitImpl = (executor, root) => {
|
|
50087
|
-
const exec = (...args) => run$
|
|
50118
|
+
const exec = (...args) => run$2(root, ...args).pipe(provide$2(succeed$2(CommandExecutor, executor)));
|
|
50088
50119
|
return {
|
|
50089
50120
|
lastCommitSubject: (ref = "HEAD") => exec("git", "log", "-1", "--pretty=%s", ref).pipe(map$4((s) => s.trim())),
|
|
50090
50121
|
lastCommitMessage: () => exec("git", "log", "-1", "--pretty=%B").pipe(map$4((s) => s.trim())),
|
|
@@ -50109,7 +50140,7 @@ const makeGitImpl = (executor, root) => {
|
|
|
50109
50140
|
}),
|
|
50110
50141
|
resolveRef: (ref) => exec("git", "rev-parse", "--verify", ref).pipe(map$4((s) => s.trim()), flatMap$4((hash) => resolvedRefOrCorrupted(ref, hash))),
|
|
50111
50142
|
readRefOption: (ref) => exec("git", "rev-parse", "--verify", "--quiet", ref).pipe(map$4((s) => some(s.trim())), catchAll(() => succeed$3(none$4()))),
|
|
50112
|
-
isAncestor: (a, b) => run$
|
|
50143
|
+
isAncestor: (a, b) => run$2(root, "git", "merge-base", "--is-ancestor", a, b).pipe(provide$2(succeed$2(CommandExecutor, executor)), map$4(() => true), catchAll(() => succeed$3(false))),
|
|
50113
50144
|
topLevel: () => exec("git", "rev-parse", "--show-toplevel").pipe(map$4((s) => s.trim())),
|
|
50114
50145
|
gitDir: () => exec("git", "rev-parse", "--absolute-git-dir").pipe(map$4((s) => s.trim())),
|
|
50115
50146
|
gitCommonDir: () => exec("git", "rev-parse", "--path-format=absolute", "--git-common-dir").pipe(map$4((s) => s.trim())),
|
|
@@ -50160,10 +50191,10 @@ const makeGitImpl = (executor, root) => {
|
|
|
50160
50191
|
},
|
|
50161
50192
|
commitAllWithPrefix: (prefix) => gen(function* () {
|
|
50162
50193
|
yield* exec("git", "add", "-A");
|
|
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$
|
|
50194
|
+
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$6(error)));
|
|
50164
50195
|
}).pipe(asVoid),
|
|
50165
50196
|
softResetTo: (ref) => exec("git", "reset", "--soft", ref).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$
|
|
50197
|
+
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$6(error))).pipe(asVoid),
|
|
50167
50198
|
discardPending: () => gen(function* () {
|
|
50168
50199
|
yield* exec("git", "add", "-A");
|
|
50169
50200
|
yield* exec("git", "reset", "--hard", "HEAD");
|
|
@@ -50643,6 +50674,15 @@ const modesJsonSchema = {
|
|
|
50643
50674
|
}
|
|
50644
50675
|
}
|
|
50645
50676
|
};
|
|
50677
|
+
/** The `skills:` shape: full step name -> its skill list (`compileSkillsMap`). An entry REPLACES the step's bundled list wholesale, never adds to it — and the schema can validate an entry's VALUE but never its KEY, since step names come from the workflow in play, not a fixed set. */
|
|
50678
|
+
const skillsJsonSchema = {
|
|
50679
|
+
type: "object",
|
|
50680
|
+
description: "Flat step full-name -> skill-name array map. Each entry REPLACES the named step's bundled skill list wholesale (never merges into it); [] means no skills at all for that step, and no preamble. A key naming a step the workflow in play does not declare is a load error listing the known names — the schema itself cannot validate a key, only a value's shape.",
|
|
50681
|
+
additionalProperties: {
|
|
50682
|
+
type: "array",
|
|
50683
|
+
items: { type: "string" }
|
|
50684
|
+
}
|
|
50685
|
+
};
|
|
50646
50686
|
/**
|
|
50647
50687
|
* A real (not `Unknown`) schema, unlike `vars`/`modes`: it is a flat settings
|
|
50648
50688
|
* struct with no per-mode map to compile, so its JSON Schema derives from the
|
|
@@ -50663,7 +50703,8 @@ const UiSchema = Struct({
|
|
|
50663
50703
|
const ConfigSchema = Struct({
|
|
50664
50704
|
vars: optional$1(Unknown.annotations({ jsonSchema: varsJsonSchema })),
|
|
50665
50705
|
modes: optional$1(Unknown.annotations({ jsonSchema: modesJsonSchema })),
|
|
50666
|
-
ui: optional$1(UiSchema)
|
|
50706
|
+
ui: optional$1(UiSchema),
|
|
50707
|
+
skills: optional$1(Unknown.annotations({ jsonSchema: skillsJsonSchema }))
|
|
50667
50708
|
});
|
|
50668
50709
|
//#endregion
|
|
50669
50710
|
//#region src/SteeringFormats.ts
|
|
@@ -50736,7 +50777,7 @@ const dedupeDiagnostics = (diagnostics) => {
|
|
|
50736
50777
|
};
|
|
50737
50778
|
//#endregion
|
|
50738
50779
|
//#region src/workflow/compile.ts
|
|
50739
|
-
const isPlainObject$
|
|
50780
|
+
const isPlainObject$3 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
50740
50781
|
const describeType = (v) => {
|
|
50741
50782
|
if (v === null) return "null";
|
|
50742
50783
|
if (Array.isArray(v)) return "array";
|
|
@@ -50756,7 +50797,7 @@ const compileVarsMap = (raw) => {
|
|
|
50756
50797
|
vars: {},
|
|
50757
50798
|
diagnostics
|
|
50758
50799
|
};
|
|
50759
|
-
if (!isPlainObject$
|
|
50800
|
+
if (!isPlainObject$3(raw)) {
|
|
50760
50801
|
diagnostics.push(err(["vars"], `"vars" must be a mapping of name -> scalar value, got ${describeType(raw)}`));
|
|
50761
50802
|
return {
|
|
50762
50803
|
vars: {},
|
|
@@ -50776,10 +50817,75 @@ const compileVarsMap = (raw) => {
|
|
|
50776
50817
|
diagnostics
|
|
50777
50818
|
};
|
|
50778
50819
|
};
|
|
50820
|
+
const isStringArray$1 = (v) => Array.isArray(v) && v.every((entry) => typeof entry === "string");
|
|
50821
|
+
/** A flat `step full name -> skill list` map; a malformed value is a load error and is dropped. */
|
|
50822
|
+
const compileSkillsMap = (raw) => {
|
|
50823
|
+
const diagnostics = [];
|
|
50824
|
+
if (raw === void 0) return {
|
|
50825
|
+
skills: {},
|
|
50826
|
+
diagnostics
|
|
50827
|
+
};
|
|
50828
|
+
if (!isPlainObject$3(raw)) {
|
|
50829
|
+
diagnostics.push(err(["skills"], `"skills" must be a mapping of step name -> array of skill names, got ${describeType(raw)}`));
|
|
50830
|
+
return {
|
|
50831
|
+
skills: {},
|
|
50832
|
+
diagnostics
|
|
50833
|
+
};
|
|
50834
|
+
}
|
|
50835
|
+
const skills = Object.create(null);
|
|
50836
|
+
for (const [key, value] of Object.entries(raw)) {
|
|
50837
|
+
if (!isStringArray$1(value)) {
|
|
50838
|
+
diagnostics.push(err(["skills", key], `"skills.${key}" must be an array of skill names (strings), got ${describeType(value)}`));
|
|
50839
|
+
continue;
|
|
50840
|
+
}
|
|
50841
|
+
skills[key] = value;
|
|
50842
|
+
}
|
|
50843
|
+
return {
|
|
50844
|
+
skills,
|
|
50845
|
+
diagnostics
|
|
50846
|
+
};
|
|
50847
|
+
};
|
|
50848
|
+
/**
|
|
50849
|
+
* The nine `*Skills` workflow vars this package deletes, each naming the
|
|
50850
|
+
* `.gtdrc` `skills:` step key(s) that replace it — four of the nine fan out to
|
|
50851
|
+
* several keys, because a var once shared between steps now addresses
|
|
50852
|
+
* them independently. Deliberately the only place gtd special-cases a var
|
|
50853
|
+
* name by string; meant to be deleted a major release after this ships.
|
|
50854
|
+
*/
|
|
50855
|
+
const DEAD_SKILLS_VARS = {
|
|
50856
|
+
triageSkills: ["design.triage"],
|
|
50857
|
+
architectureSkills: ["architecture.author"],
|
|
50858
|
+
decomposeSkills: ["architecture.decompose"],
|
|
50859
|
+
buildSkills: ["packages.item.building"],
|
|
50860
|
+
fixSkills: ["packages.item.fix-suite", "build.fix"],
|
|
50861
|
+
reviewFixSkills: [
|
|
50862
|
+
"packages.item.fix-spec",
|
|
50863
|
+
"build.fix-quality",
|
|
50864
|
+
"build.review.fix-nits"
|
|
50865
|
+
],
|
|
50866
|
+
reviewSkills: [
|
|
50867
|
+
"build.review.reviewing",
|
|
50868
|
+
"build.review.answer-review-questions",
|
|
50869
|
+
"build.review.collecting"
|
|
50870
|
+
],
|
|
50871
|
+
specReviewSkills: ["packages.item.spec.review"],
|
|
50872
|
+
escalateSkills: ["packages.item.health.describe", "build.health.describe"]
|
|
50873
|
+
};
|
|
50874
|
+
/** `vars:` entries naming one of the nine deleted `*Skills` vars — scoped to `.gtdrc` `vars:` only; there is no environment scan anywhere in this check, so a `GTD_BUILDSKILLS` gets neither this diagnostic nor any other. */
|
|
50875
|
+
const deadSkillsVarDiagnostics = (rawVars) => {
|
|
50876
|
+
if (!isPlainObject$3(rawVars)) return [];
|
|
50877
|
+
const diagnostics = [];
|
|
50878
|
+
for (const key of Object.keys(rawVars)) {
|
|
50879
|
+
const replacement = DEAD_SKILLS_VARS[key];
|
|
50880
|
+
if (replacement === void 0) continue;
|
|
50881
|
+
diagnostics.push(err(["vars", key], `"vars.${key}" was removed — skills are now configured per step, under the "skills:" key, addressed by: ${replacement.join(", ")}`));
|
|
50882
|
+
}
|
|
50883
|
+
return diagnostics;
|
|
50884
|
+
};
|
|
50779
50885
|
const MODE_COMMAND_KEYS = ["format", "validate"];
|
|
50780
50886
|
/** One `modes:` entry; malformed entries are load errors and are dropped. */
|
|
50781
50887
|
const compileMode = (name, entry, diagnostics) => {
|
|
50782
|
-
if (!isPlainObject$
|
|
50888
|
+
if (!isPlainObject$3(entry)) {
|
|
50783
50889
|
diagnostics.push(err(["modes", name], `mode "${name}": must be an object with "format" and/or "validate", got ${describeType(entry)}`));
|
|
50784
50890
|
return;
|
|
50785
50891
|
}
|
|
@@ -50809,7 +50915,7 @@ const compileModesMap = (raw) => {
|
|
|
50809
50915
|
modes: {},
|
|
50810
50916
|
diagnostics
|
|
50811
50917
|
};
|
|
50812
|
-
if (!isPlainObject$
|
|
50918
|
+
if (!isPlainObject$3(raw)) {
|
|
50813
50919
|
diagnostics.push(err(["modes"], `"modes" must be a mapping of mode name -> { format, validate }, got ${describeType(raw)}`));
|
|
50814
50920
|
return {
|
|
50815
50921
|
modes: {},
|
|
@@ -50838,7 +50944,7 @@ const mergeModes = (base, override) => {
|
|
|
50838
50944
|
};
|
|
50839
50945
|
/** Stamp a whole (possibly deeply nested) value with ONE origin, recursively — used when `inner` replaces `base` wholesale: every key inside still needs its own node, or a LATER layer partially overriding just one nested key would silently lose the rest of this subtree's origin. */
|
|
50840
50946
|
const uniformOrigin = (value, origin) => {
|
|
50841
|
-
if (!isPlainObject$
|
|
50947
|
+
if (!isPlainObject$3(value)) return { self: origin };
|
|
50842
50948
|
const children = {};
|
|
50843
50949
|
for (const [key, v] of Object.entries(value)) children[key] = uniformOrigin(v, origin);
|
|
50844
50950
|
return {
|
|
@@ -50856,7 +50962,7 @@ const uniformOrigin = (value, origin) => {
|
|
|
50856
50962
|
* findings, not one origin for the whole merged key.
|
|
50857
50963
|
*/
|
|
50858
50964
|
const mergeWithOrigin = (base, baseOrigin, inner, innerOrigin) => {
|
|
50859
|
-
if (!isPlainObject$
|
|
50965
|
+
if (!isPlainObject$3(base) || !isPlainObject$3(inner)) return {
|
|
50860
50966
|
value: inner,
|
|
50861
50967
|
origin: uniformOrigin(inner, innerOrigin)
|
|
50862
50968
|
};
|
|
@@ -50907,7 +51013,7 @@ const compileConfig = (layers) => {
|
|
|
50907
51013
|
let merged = {};
|
|
50908
51014
|
let originTree = { self: BUILT_IN_ORIGIN };
|
|
50909
51015
|
for (const layer of layers) {
|
|
50910
|
-
const value = isPlainObject$
|
|
51016
|
+
const value = isPlainObject$3(layer.value) ? layer.value : {};
|
|
50911
51017
|
const step = mergeWithOrigin(merged, originTree, value, layer.origin);
|
|
50912
51018
|
merged = step.value;
|
|
50913
51019
|
originTree = step.origin;
|
|
@@ -50917,17 +51023,91 @@ const compileConfig = (layers) => {
|
|
|
50917
51023
|
const ui = mergedConfig["ui"];
|
|
50918
51024
|
const { vars: rcVars, diagnostics: varsDiagnostics } = compileVarsMap(mergedConfig["vars"]);
|
|
50919
51025
|
diagnostics.push(...withOrigin(varsDiagnostics, lookupIn));
|
|
51026
|
+
diagnostics.push(...withOrigin(deadSkillsVarDiagnostics(mergedConfig["vars"]), lookupIn));
|
|
50920
51027
|
const { modes: rcModes, diagnostics: modesDiagnostics } = compileModesMap(mergedConfig["modes"]);
|
|
50921
51028
|
diagnostics.push(...withOrigin(modesDiagnostics, lookupIn));
|
|
51029
|
+
const skillsKeys = [];
|
|
51030
|
+
for (const layer of layers) {
|
|
51031
|
+
if (!isPlainObject$3(layer.value)) continue;
|
|
51032
|
+
const own = compileSkillsMap(layer.value["skills"]);
|
|
51033
|
+
diagnostics.push(...own.diagnostics.map((d) => ({
|
|
51034
|
+
...d,
|
|
51035
|
+
origin: layer.origin
|
|
51036
|
+
})));
|
|
51037
|
+
skillsKeys.push(...Object.keys(own.skills).map((key) => ({
|
|
51038
|
+
key,
|
|
51039
|
+
origin: layer.origin
|
|
51040
|
+
})));
|
|
51041
|
+
}
|
|
51042
|
+
const { skills: rcSkills } = compileSkillsMap(mergedConfig["skills"]);
|
|
50922
51043
|
const seeded = Object.fromEntries(BUILT_IN_MODE_NAMES.map((name) => [name, { validate: seededValidateCommand(name) }]));
|
|
50923
51044
|
return {
|
|
50924
51045
|
rcVars,
|
|
50925
51046
|
modes: mergeModes(seeded, rcModes),
|
|
50926
51047
|
...ui !== void 0 ? { ui } : {},
|
|
51048
|
+
rcSkills,
|
|
51049
|
+
skillsKeys,
|
|
50927
51050
|
diagnostics: dedupeDiagnostics(sortDiagnostics(diagnostics, layerOrder))
|
|
50928
51051
|
};
|
|
50929
51052
|
};
|
|
50930
51053
|
//#endregion
|
|
51054
|
+
//#region src/workflow/interpolate.ts
|
|
51055
|
+
const VAR_PATTERN = /\$\$|\$\{([A-Za-z_][A-Za-z0-9_]*)\}|\$([A-Za-z_][A-Za-z0-9_]*)/g;
|
|
51056
|
+
const isPlainObject$2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
51057
|
+
/**
|
|
51058
|
+
* `modes.*.format`, `modes.*.validate` and `ui.format` — gtd hands these
|
|
51059
|
+
* straight to bash, where `$` already means the shell's own expansion. The
|
|
51060
|
+
* predicate reads only the config PATH shape, never the value: sniffing for
|
|
51061
|
+
* `$GTD_FILE` would exempt whichever command happens not to name it, and
|
|
51062
|
+
* silently interpolate one that names something else instead.
|
|
51063
|
+
*/
|
|
51064
|
+
const isBashExemptPath = (path) => {
|
|
51065
|
+
if (path.length === 3 && path[0] === "modes" && (path[2] === "format" || path[2] === "validate")) return true;
|
|
51066
|
+
if (path.length === 2 && path[0] === "ui" && path[1] === "format") return true;
|
|
51067
|
+
return false;
|
|
51068
|
+
};
|
|
51069
|
+
const interpolateString = (value, path, env, diagnostics) => value.replace(VAR_PATTERN, (match, braced, bare) => {
|
|
51070
|
+
if (match === "$$") return "$";
|
|
51071
|
+
const name = braced ?? bare;
|
|
51072
|
+
if (name === void 0) return match;
|
|
51073
|
+
const resolved = env[name];
|
|
51074
|
+
if (resolved !== void 0) return resolved;
|
|
51075
|
+
diagnostics.push({
|
|
51076
|
+
severity: "error",
|
|
51077
|
+
path,
|
|
51078
|
+
message: `"${match}" references environment variable "${name}", which is not set`,
|
|
51079
|
+
origin: ""
|
|
51080
|
+
});
|
|
51081
|
+
return match;
|
|
51082
|
+
});
|
|
51083
|
+
const walk = (value, path, env, diagnostics) => {
|
|
51084
|
+
if (typeof value === "string") return isBashExemptPath(path) ? value : interpolateString(value, path, env, diagnostics);
|
|
51085
|
+
if (Array.isArray(value)) return value.map((v, i) => walk(v, [...path, i], env, diagnostics));
|
|
51086
|
+
if (isPlainObject$2(value)) {
|
|
51087
|
+
const out = {};
|
|
51088
|
+
for (const [key, v] of Object.entries(value)) out[key] = walk(v, [...path, key], env, diagnostics);
|
|
51089
|
+
return out;
|
|
51090
|
+
}
|
|
51091
|
+
return value;
|
|
51092
|
+
};
|
|
51093
|
+
/**
|
|
51094
|
+
* Expand `$NAME`/`${NAME}` from `env` over every string leaf of a decoded
|
|
51095
|
+
* `.gtdrc` layer, except the three paths gtd hands to bash. `$$` yields a
|
|
51096
|
+
* literal `$`; any other `$` not followed by a valid name (a trailing `$`,
|
|
51097
|
+
* `$1`, `$-`, `$ `) is left untouched. Exactly one pass: `String.replace`
|
|
51098
|
+
* never rescans a replacement's own text, so an environment variable's value
|
|
51099
|
+
* can never be read back as config syntax. An unset name is a load-error
|
|
51100
|
+
* `Diagnostic` naming the config path; the original `$NAME` text is left in
|
|
51101
|
+
* place rather than blanked.
|
|
51102
|
+
*/
|
|
51103
|
+
const interpolate = (config, env) => {
|
|
51104
|
+
const diagnostics = [];
|
|
51105
|
+
return {
|
|
51106
|
+
value: walk(config, [], env, diagnostics),
|
|
51107
|
+
diagnostics
|
|
51108
|
+
};
|
|
51109
|
+
};
|
|
51110
|
+
//#endregion
|
|
50931
51111
|
//#region src/workflow/vars.ts
|
|
50932
51112
|
const PREFIX = "GTD_";
|
|
50933
51113
|
/**
|
|
@@ -57718,7 +57898,7 @@ const dropOptionalUndefinedArtifacts = (all) => {
|
|
|
57718
57898
|
* findings surface together through `load`'s single sorted/deduped report,
|
|
57719
57899
|
* the same as every other producer in this package.
|
|
57720
57900
|
*/
|
|
57721
|
-
const decodeLevel = (level) => gen(function* () {
|
|
57901
|
+
const decodeLevel = (level, env) => gen(function* () {
|
|
57722
57902
|
if (!isPlainObject$1(level.config)) return {
|
|
57723
57903
|
layer: void 0,
|
|
57724
57904
|
diagnostics: [{
|
|
@@ -57739,13 +57919,17 @@ const decodeLevel = (level) => gen(function* () {
|
|
|
57739
57919
|
origin: level.filepath
|
|
57740
57920
|
}))
|
|
57741
57921
|
};
|
|
57922
|
+
const interpolated = interpolate(result.right, env);
|
|
57742
57923
|
return {
|
|
57743
57924
|
layer: {
|
|
57744
57925
|
origin: level.filepath,
|
|
57745
57926
|
dir: dirname(level.filepath),
|
|
57746
|
-
value:
|
|
57927
|
+
value: interpolated.value
|
|
57747
57928
|
},
|
|
57748
|
-
diagnostics:
|
|
57929
|
+
diagnostics: interpolated.diagnostics.map((d) => ({
|
|
57930
|
+
...d,
|
|
57931
|
+
origin: level.filepath
|
|
57932
|
+
}))
|
|
57749
57933
|
};
|
|
57750
57934
|
});
|
|
57751
57935
|
/**
|
|
@@ -57769,7 +57953,7 @@ const load = gen(function* () {
|
|
|
57769
57953
|
const discovery = yield* ConfigDiscovery;
|
|
57770
57954
|
const levels = yield* discovery.levels(host.root, host.home);
|
|
57771
57955
|
for (const level of levels) yield* narrator.narrate(`config: layer ${level.filepath}`);
|
|
57772
|
-
const decoded = yield* forEach$2(levels, decodeLevel);
|
|
57956
|
+
const decoded = yield* forEach$2(levels, (level) => decodeLevel(level, host.env));
|
|
57773
57957
|
const layers = decoded.flatMap((d) => d.layer !== void 0 ? [d.layer] : []);
|
|
57774
57958
|
const decodeDiagnostics = decoded.flatMap((d) => d.diagnostics);
|
|
57775
57959
|
const compiled = compileConfig(layers);
|
|
@@ -57779,11 +57963,22 @@ const load = gen(function* () {
|
|
|
57779
57963
|
catch: (e) => new GtdError(`gtd config:\n - ${module?.filepath ?? "(built-in default)"}: ${e instanceof Error ? e.message : String(e)}`)
|
|
57780
57964
|
});
|
|
57781
57965
|
const layerOrder = [...levels.map((level) => level.filepath), ...module ? [module.filepath] : []];
|
|
57782
|
-
const
|
|
57966
|
+
const knownSkillNames = Object.keys(loaded.skills).sort();
|
|
57967
|
+
const unknownSkillDiagnostics = compiled.skillsKeys.filter(({ key }) => !Object.hasOwn(loaded.skills, key)).map(({ key, origin }) => ({
|
|
57968
|
+
severity: "error",
|
|
57969
|
+
path: ["skills", key],
|
|
57970
|
+
message: `"skills.${key}" names a step this workflow does not declare — known step names: ${knownSkillNames.join(", ")}`,
|
|
57971
|
+
origin
|
|
57972
|
+
}));
|
|
57973
|
+
const diagnostics = dedupeDiagnostics(sortDiagnostics([
|
|
57974
|
+
...decodeDiagnostics,
|
|
57975
|
+
...compiled.diagnostics,
|
|
57976
|
+
...unknownSkillDiagnostics
|
|
57977
|
+
], layerOrder));
|
|
57783
57978
|
const fatal = diagnostics.filter((d) => d.severity === "error");
|
|
57784
57979
|
if (fatal.length > 0) {
|
|
57785
57980
|
const lines = fatal.map(formatDiagnostic);
|
|
57786
|
-
return yield* fail$
|
|
57981
|
+
return yield* fail$6(new GtdError(`gtd config:\n${lines.map((line) => ` - ${line}`).join("\n")}`));
|
|
57787
57982
|
}
|
|
57788
57983
|
const initial = yield* firstStep(loaded, resolveVars(loaded.defaults, compiled.rcVars, {}, host.env), headTree(yield* Workspace));
|
|
57789
57984
|
return {
|
|
@@ -57793,6 +57988,8 @@ const load = gen(function* () {
|
|
|
57793
57988
|
base: loaded.base,
|
|
57794
57989
|
steering: loaded.steering,
|
|
57795
57990
|
modes: compiled.modes,
|
|
57991
|
+
skills: loaded.skills,
|
|
57992
|
+
configuredSkills: compiled.rcSkills,
|
|
57796
57993
|
initial
|
|
57797
57994
|
},
|
|
57798
57995
|
workflowVars: { ...loaded.defaults },
|
|
@@ -57839,6 +58036,13 @@ const stringRecord = (exports, name) => {
|
|
|
57839
58036
|
if (typeof value !== "object" || value === null || Object.values(value).some((entry) => typeof entry !== "string")) throw new Error(`the "${name}" export is not a record of strings`);
|
|
57840
58037
|
return value;
|
|
57841
58038
|
};
|
|
58039
|
+
const isStringArray = (v) => Array.isArray(v) && v.every((entry) => typeof entry === "string");
|
|
58040
|
+
/** Read a module's optional `skills` export: full step name -> skill list, mirroring `stringRecord` for the vars-shaped exports. */
|
|
58041
|
+
const skillsRecord = (exports) => {
|
|
58042
|
+
const value = exports["skills"] ?? {};
|
|
58043
|
+
if (typeof value !== "object" || value === null || Object.values(value).some((entry) => !isStringArray(entry))) throw new Error(`the "skills" export is not a record of skill-name arrays`);
|
|
58044
|
+
return value;
|
|
58045
|
+
};
|
|
57842
58046
|
const optionalFunction = (exports, name) => {
|
|
57843
58047
|
const value = exports[name];
|
|
57844
58048
|
if (value === void 0) return void 0;
|
|
@@ -57857,6 +58061,7 @@ const fromModule = (exported, origin, dependencyFiles) => {
|
|
|
57857
58061
|
flow,
|
|
57858
58062
|
defaults: stringRecord(exports, "defaults"),
|
|
57859
58063
|
steering: stringRecord(exports, "steering"),
|
|
58064
|
+
skills: skillsRecord(exports),
|
|
57860
58065
|
summary: optionalFunction(exports, "summary"),
|
|
57861
58066
|
base: optionalFunction(exports, "base"),
|
|
57862
58067
|
origin,
|
|
@@ -57917,7 +58122,7 @@ const replayToFirstStep = (loaded, vars, tree) => flatMap$4(promise(() => replay
|
|
|
57917
58122
|
})), (outcome) => {
|
|
57918
58123
|
if (outcome.kind === "rest") return succeed$3(outcome.rest.name);
|
|
57919
58124
|
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";
|
|
57920
|
-
return fail$
|
|
58125
|
+
return fail$6(new GtdError(`gtd config:\n - ${loaded.origin}: ${problem}`));
|
|
57921
58126
|
});
|
|
57922
58127
|
/**
|
|
57923
58128
|
* The default entry's first step — where a finished process waits — found the
|
|
@@ -57932,7 +58137,7 @@ const firstStep = (loaded, vars, head) => gen(function* () {
|
|
|
57932
58137
|
if (!empty.read()) return name;
|
|
57933
58138
|
const atHead = yield* replayToFirstStep(loaded, vars, head);
|
|
57934
58139
|
if (atHead === name) return name;
|
|
57935
|
-
return yield* fail$
|
|
58140
|
+
return yield* fail$6(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`));
|
|
57936
58141
|
});
|
|
57937
58142
|
var ConfigService = class ConfigService extends Tag("ConfigService")() {
|
|
57938
58143
|
static Live = succeed$2(ConfigService, { load });
|
|
@@ -57952,7 +58157,7 @@ const renderInitScaffold = () => ({ config: JSON.stringify({
|
|
|
57952
58157
|
}, null, 2) + "\n" });
|
|
57953
58158
|
//#endregion
|
|
57954
58159
|
//#region src/judges/providers/fixed.ts
|
|
57955
|
-
const fail$
|
|
58160
|
+
const fail$3 = (message) => {
|
|
57956
58161
|
throw new Error(`gtd judge run: ${message}`);
|
|
57957
58162
|
};
|
|
57958
58163
|
const isAnswer = (v) => [
|
|
@@ -57963,9 +58168,9 @@ const isAnswer = (v) => [
|
|
|
57963
58168
|
const isProbability = (v) => typeof v === "number" && v >= 0 && v <= 1;
|
|
57964
58169
|
const validate = (entry, index) => {
|
|
57965
58170
|
const { id, answer, p } = typeof entry === "object" && entry !== null ? entry : {};
|
|
57966
|
-
if (typeof id !== "string") return fail$
|
|
57967
|
-
if (!isAnswer(answer)) return fail$
|
|
57968
|
-
if (!isProbability(p)) return fail$
|
|
58171
|
+
if (typeof id !== "string") return fail$3(`answers entry ${index} has no string "id"`);
|
|
58172
|
+
if (!isAnswer(answer)) return fail$3(`answers entry "${id}": "answer" must be a string, number or boolean`);
|
|
58173
|
+
if (!isProbability(p)) return fail$3(`answers entry "${id}": "p" must be a number in [0, 1]`);
|
|
57969
58174
|
return {
|
|
57970
58175
|
id,
|
|
57971
58176
|
answer,
|
|
@@ -57975,16 +58180,16 @@ const validate = (entry, index) => {
|
|
|
57975
58180
|
const fixed = ({ answersPath, env }) => async (questions) => {
|
|
57976
58181
|
const inline = env["GTD_JUDGE_ANSWERS"];
|
|
57977
58182
|
let raw;
|
|
57978
|
-
if (answersPath !== void 0) raw = await readFile(answersPath, "utf8").catch((e) => fail$
|
|
58183
|
+
if (answersPath !== void 0) raw = await readFile(answersPath, "utf8").catch((e) => fail$3(`cannot read --answers ${answersPath}: ${e instanceof Error ? e.message : String(e)}`));
|
|
57979
58184
|
else if (inline !== void 0 && inline !== "") raw = inline;
|
|
57980
|
-
else return fail$
|
|
58185
|
+
else return fail$3("provider \"fixed\" needs --answers <path> or GTD_JUDGE_ANSWERS");
|
|
57981
58186
|
let parsed;
|
|
57982
58187
|
try {
|
|
57983
58188
|
parsed = JSON.parse(raw);
|
|
57984
58189
|
} catch {
|
|
57985
|
-
return fail$
|
|
58190
|
+
return fail$3("the fixed answers are not valid JSON");
|
|
57986
58191
|
}
|
|
57987
|
-
if (!Array.isArray(parsed)) return fail$
|
|
58192
|
+
if (!Array.isArray(parsed)) return fail$3("the fixed answers must be a JSON array");
|
|
57988
58193
|
const asked = new Set(questions.map((q) => q.id));
|
|
57989
58194
|
return parsed.flatMap((entry, i) => {
|
|
57990
58195
|
const id = entry?.id;
|
|
@@ -57993,13 +58198,7 @@ const fixed = ({ answersPath, env }) => async (questions) => {
|
|
|
57993
58198
|
});
|
|
57994
58199
|
};
|
|
57995
58200
|
//#endregion
|
|
57996
|
-
//#region src/judges/
|
|
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
|
-
};
|
|
58201
|
+
//#region src/judges/criteria.ts
|
|
58003
58202
|
const LABEL = /(?:^|\. )([A-Za-z][A-Za-z0-9_-]*): /g;
|
|
58004
58203
|
/** Same splitter as gtd-build's `judge_request`: text before the first label is dropped. */
|
|
58005
58204
|
const splitLabels = (criteria) => {
|
|
@@ -58010,6 +58209,14 @@ const splitLabels = (criteria) => {
|
|
|
58010
58209
|
return [m[1], criteria.slice(start, end).replace(/^ /, "")];
|
|
58011
58210
|
});
|
|
58012
58211
|
};
|
|
58212
|
+
//#endregion
|
|
58213
|
+
//#region src/judges/providers/jev.ts
|
|
58214
|
+
const DEFAULT_URL = "https://api.typesafe.ai/v1/systemone";
|
|
58215
|
+
const MODEL = "jev-latest";
|
|
58216
|
+
const RETRIES = 3;
|
|
58217
|
+
const fail$2 = (message) => {
|
|
58218
|
+
throw new Error(`gtd judge run: ${message}`);
|
|
58219
|
+
};
|
|
58013
58220
|
const translate = (q) => {
|
|
58014
58221
|
if (q.primitive === "noul") return {
|
|
58015
58222
|
type: "noul",
|
|
@@ -58017,7 +58224,7 @@ const translate = (q) => {
|
|
|
58017
58224
|
};
|
|
58018
58225
|
const levels = splitLabels(q.criteria);
|
|
58019
58226
|
if (q.primitive === "choice") {
|
|
58020
|
-
if (levels.length < 2) return fail$
|
|
58227
|
+
if (levels.length < 2) return fail$2(`question "${q.id}": choice criteria need at least 2 labelled options`);
|
|
58021
58228
|
return {
|
|
58022
58229
|
type: "choice",
|
|
58023
58230
|
instructions: q.instructions,
|
|
@@ -58025,14 +58232,14 @@ const translate = (q) => {
|
|
|
58025
58232
|
};
|
|
58026
58233
|
}
|
|
58027
58234
|
if (q.primitive === "score") {
|
|
58028
|
-
if (levels.length < 2 || levels.length > 10) return fail$
|
|
58235
|
+
if (levels.length < 2 || levels.length > 10) return fail$2(`question "${q.id}": score criteria need 2 to 10 labelled levels, found ${levels.length}`);
|
|
58029
58236
|
return {
|
|
58030
58237
|
type: "score",
|
|
58031
58238
|
instructions: q.instructions,
|
|
58032
58239
|
criteria: levels.map(([, v]) => v)
|
|
58033
58240
|
};
|
|
58034
58241
|
}
|
|
58035
|
-
return fail$
|
|
58242
|
+
return fail$2(`question "${q.id}": unknown primitive "${String(q.primitive)}"`);
|
|
58036
58243
|
};
|
|
58037
58244
|
const toRequest = (questions, state) => ({
|
|
58038
58245
|
model: MODEL,
|
|
@@ -58040,15 +58247,15 @@ const toRequest = (questions, state) => ({
|
|
|
58040
58247
|
questions: Object.fromEntries(questions.map((q) => [q.id, translate(q)]))
|
|
58041
58248
|
});
|
|
58042
58249
|
const clamp = (n) => Math.min(1, Math.max(0, n));
|
|
58043
|
-
const unreadable = (why) => fail$
|
|
58044
|
-
const num = (v, what) => typeof v === "number" && Number.isFinite(v) ? v : unreadable(`${what} is not a finite number`);
|
|
58250
|
+
const unreadable$1 = (why) => fail$2(`unreadable jev response: ${why}`);
|
|
58251
|
+
const num = (v, what) => typeof v === "number" && Number.isFinite(v) ? v : unreadable$1(`${what} is not a finite number`);
|
|
58045
58252
|
const probs = (a, id) => {
|
|
58046
58253
|
const raw = a["probabilities"];
|
|
58047
|
-
if (typeof raw !== "object" || raw === null) return unreadable(`"${id}" has no probabilities`);
|
|
58254
|
+
if (typeof raw !== "object" || raw === null) return unreadable$1(`"${id}" has no probabilities`);
|
|
58048
58255
|
return Object.fromEntries(Object.entries(raw).map(([k, v]) => [k, num(v, `"${id}" probability "${k}"`)]));
|
|
58049
58256
|
};
|
|
58050
|
-
const toVerdict = (q, a) => {
|
|
58051
|
-
if (a["type"] !== q.primitive) return unreadable(`"${q.id}" answered as ${String(a["type"])}, asked ${q.primitive}`);
|
|
58257
|
+
const toVerdict$1 = (q, a) => {
|
|
58258
|
+
if (a["type"] !== q.primitive) return unreadable$1(`"${q.id}" answered as ${String(a["type"])}, asked ${q.primitive}`);
|
|
58052
58259
|
if (q.primitive === "noul") {
|
|
58053
58260
|
const n = num(a["noul"], `"${q.id}" noul`);
|
|
58054
58261
|
return n >= .5 ? {
|
|
@@ -58064,7 +58271,7 @@ const toVerdict = (q, a) => {
|
|
|
58064
58271
|
const p = probs(a, q.id);
|
|
58065
58272
|
if (q.primitive === "choice") {
|
|
58066
58273
|
const choice = a["choice"];
|
|
58067
|
-
if (typeof choice !== "string" || !(choice in p)) return unreadable(`"${q.id}" choice is absent from its probabilities`);
|
|
58274
|
+
if (typeof choice !== "string" || !(choice in p)) return unreadable$1(`"${q.id}" choice is absent from its probabilities`);
|
|
58068
58275
|
return {
|
|
58069
58276
|
id: q.id,
|
|
58070
58277
|
answer: choice,
|
|
@@ -58072,7 +58279,7 @@ const toVerdict = (q, a) => {
|
|
|
58072
58279
|
};
|
|
58073
58280
|
}
|
|
58074
58281
|
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`);
|
|
58282
|
+
if (levels.length === 0 || levels.some(([k]) => !Number.isFinite(k))) return unreadable$1(`"${q.id}" score probabilities are not numeric levels`);
|
|
58076
58283
|
const top = levels.reduce((best, cur) => cur[1] > best[1] || cur[1] === best[1] && cur[0] < best[0] ? cur : best);
|
|
58077
58284
|
return {
|
|
58078
58285
|
id: q.id,
|
|
@@ -58082,11 +58289,11 @@ const toVerdict = (q, a) => {
|
|
|
58082
58289
|
};
|
|
58083
58290
|
const toVerdicts = (questions, response) => {
|
|
58084
58291
|
const answers = response?.answers;
|
|
58085
|
-
if (typeof answers !== "object" || answers === null || Array.isArray(answers)) return unreadable("no \"answers\" object");
|
|
58292
|
+
if (typeof answers !== "object" || answers === null || Array.isArray(answers)) return unreadable$1("no \"answers\" object");
|
|
58086
58293
|
const map = answers;
|
|
58087
58294
|
const missing = questions.filter((q) => typeof map[q.id] !== "object" || map[q.id] === null);
|
|
58088
|
-
if (missing.length > 0) return fail$
|
|
58089
|
-
return questions.map((q) => toVerdict(q, map[q.id]));
|
|
58295
|
+
if (missing.length > 0) return fail$2(`jev answered ${questions.length - missing.length} of ${questions.length} questions; missing ${missing.map((q) => q.id).join(", ")}`);
|
|
58296
|
+
return questions.map((q) => toVerdict$1(q, map[q.id]));
|
|
58090
58297
|
};
|
|
58091
58298
|
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
58092
58299
|
const post = async (url, key, body, delayMs) => {
|
|
@@ -58099,41 +58306,165 @@ const post = async (url, key, body, delayMs) => {
|
|
|
58099
58306
|
},
|
|
58100
58307
|
body,
|
|
58101
58308
|
signal: AbortSignal.timeout(18e4)
|
|
58102
|
-
}).catch((e) => fail$
|
|
58309
|
+
}).catch((e) => fail$2(`jev request failed: ${e instanceof Error ? e.message : String(e)}`));
|
|
58103
58310
|
const text = await res.text();
|
|
58104
58311
|
if (res.status === 200) return text;
|
|
58105
58312
|
if ((res.status === 429 || res.status === 529) && attempt < RETRIES) {
|
|
58106
58313
|
await sleep(delayMs);
|
|
58107
58314
|
continue;
|
|
58108
58315
|
}
|
|
58109
|
-
return fail$
|
|
58316
|
+
return fail$2(`jev responded ${res.status}: ${text.slice(0, 2048)}`);
|
|
58110
58317
|
}
|
|
58111
58318
|
};
|
|
58112
58319
|
const parse = (text) => {
|
|
58113
58320
|
try {
|
|
58114
58321
|
return JSON.parse(text);
|
|
58115
58322
|
} catch {
|
|
58116
|
-
return unreadable("not JSON");
|
|
58323
|
+
return unreadable$1("not JSON");
|
|
58117
58324
|
}
|
|
58118
58325
|
};
|
|
58119
58326
|
const jev = ({ env, retryDelayMs = 2e3 }) => async (questions, state) => {
|
|
58120
58327
|
const key = env["TYPESAFE_API_KEY"];
|
|
58121
|
-
if (key === void 0 || key === "") return fail$
|
|
58328
|
+
if (key === void 0 || key === "") return fail$2("--provider jev needs TYPESAFE_API_KEY");
|
|
58122
58329
|
const url = env["JEV_BASE_URL"] || DEFAULT_URL;
|
|
58123
58330
|
const text = await post(url, key, JSON.stringify(toRequest(questions, state)), retryDelayMs);
|
|
58124
58331
|
return toVerdicts(questions, parse(text));
|
|
58125
58332
|
};
|
|
58126
58333
|
//#endregion
|
|
58334
|
+
//#region src/judges/providers/llm.ts
|
|
58335
|
+
const DEFAULT_MODEL = "haiku";
|
|
58336
|
+
const TIMEOUT_MS = 18e4;
|
|
58337
|
+
const SYSTEM_PROMPT = "You are a strict, impartial judge. Answer each question from the supplied evidence alone.\nReply only with the structured answer; never use tools or ask questions.";
|
|
58338
|
+
const fail$1 = (message) => {
|
|
58339
|
+
throw new Error(`gtd judge run: ${message}`);
|
|
58340
|
+
};
|
|
58341
|
+
const unreadable = (why) => fail$1(`unreadable claude response: ${why}`);
|
|
58342
|
+
/** Validated up front so a bad question throws before any spawn. */
|
|
58343
|
+
const levelsOf = (q) => {
|
|
58344
|
+
if (q.primitive === "noul") return [];
|
|
58345
|
+
if (q.primitive !== "choice" && q.primitive !== "score") return fail$1(`question "${q.id}": unknown primitive "${String(q.primitive)}"`);
|
|
58346
|
+
const levels = splitLabels(q.criteria);
|
|
58347
|
+
if (levels.length < 2) return fail$1(`question "${q.id}": ${q.primitive} criteria need at least 2 labelled ${q.primitive === "choice" ? "options" : "levels"}`);
|
|
58348
|
+
return levels;
|
|
58349
|
+
};
|
|
58350
|
+
const optionsOf = (q) => q.primitive === "noul" ? ["yes", "no"] : q.primitive === "choice" ? levelsOf(q).map(([label]) => label) : levelsOf(q).map((_, i) => i + 1);
|
|
58351
|
+
const describe = (q) => {
|
|
58352
|
+
const head = `<question id="${q.id}">\n${q.instructions}\n`;
|
|
58353
|
+
if (q.primitive === "noul") return `${head}Criteria: ${q.criteria}\nAnswer "yes" or "no".\n</question>`;
|
|
58354
|
+
const levels = levelsOf(q);
|
|
58355
|
+
return `${head}${q.primitive === "choice" ? levels.map(([label, text]) => `- ${label}: ${text}`).join("\n") : levels.map(([, text], i) => `${i + 1}. ${text}`).join("\n")}\n${q.primitive === "choice" ? "Answer with exactly one label." : "Answer with the number of one level."}\n</question>`;
|
|
58356
|
+
};
|
|
58357
|
+
const toPrompt = (questions, state) => [
|
|
58358
|
+
"Answer every question below from the evidence alone. For each, give your answer and p, your confidence between 0 and 1 that the given answer is correct.",
|
|
58359
|
+
...Object.entries(state).map(([key, body]) => `<evidence key="${key}">\n${body}\n</evidence>`),
|
|
58360
|
+
...questions.map(describe)
|
|
58361
|
+
].join("\n\n");
|
|
58362
|
+
const answerSchema = (q) => {
|
|
58363
|
+
return {
|
|
58364
|
+
type: "object",
|
|
58365
|
+
properties: {
|
|
58366
|
+
answer: { enum: optionsOf(q) },
|
|
58367
|
+
p: {
|
|
58368
|
+
type: "number",
|
|
58369
|
+
minimum: 0,
|
|
58370
|
+
maximum: 1
|
|
58371
|
+
}
|
|
58372
|
+
},
|
|
58373
|
+
required: ["answer", "p"],
|
|
58374
|
+
additionalProperties: false
|
|
58375
|
+
};
|
|
58376
|
+
};
|
|
58377
|
+
const toSchema = (questions) => ({
|
|
58378
|
+
type: "object",
|
|
58379
|
+
properties: Object.fromEntries(questions.map((q) => [q.id, answerSchema(q)])),
|
|
58380
|
+
required: questions.map((q) => q.id),
|
|
58381
|
+
additionalProperties: false
|
|
58382
|
+
});
|
|
58383
|
+
const isObject$2 = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
58384
|
+
const toVerdict = (q, raw) => {
|
|
58385
|
+
if (!isObject$2(raw)) return unreadable(`"${q.id}" is not an object`);
|
|
58386
|
+
const { answer, p } = raw;
|
|
58387
|
+
if (typeof p !== "number" || !Number.isFinite(p) || p < 0 || p > 1) return unreadable(`"${q.id}" p is not a number in [0, 1]`);
|
|
58388
|
+
if (!optionsOf(q).includes(answer)) return unreadable(`"${q.id}" answer is not one of its options`);
|
|
58389
|
+
return {
|
|
58390
|
+
id: q.id,
|
|
58391
|
+
answer,
|
|
58392
|
+
p
|
|
58393
|
+
};
|
|
58394
|
+
};
|
|
58395
|
+
const toLlmVerdicts = (questions, stdout) => {
|
|
58396
|
+
let envelope;
|
|
58397
|
+
try {
|
|
58398
|
+
envelope = JSON.parse(stdout);
|
|
58399
|
+
} catch {
|
|
58400
|
+
return unreadable("not JSON");
|
|
58401
|
+
}
|
|
58402
|
+
if (!isObject$2(envelope)) return unreadable("not an object");
|
|
58403
|
+
if (envelope["is_error"] === true) return fail$1(`claude failed: ${String(envelope["result"])}`);
|
|
58404
|
+
const out = envelope["structured_output"];
|
|
58405
|
+
if (!isObject$2(out)) return unreadable("no structured_output object");
|
|
58406
|
+
const missing = questions.filter((q) => !isObject$2(out[q.id]));
|
|
58407
|
+
if (missing.length > 0) return fail$1(`claude answered ${questions.length - missing.length} of ${questions.length} questions; missing ${missing.map((q) => q.id).join(", ")}`);
|
|
58408
|
+
return questions.map((q) => toVerdict(q, out[q.id]));
|
|
58409
|
+
};
|
|
58410
|
+
const run$1 = (argv, stdin, { env, cwd, timeoutMs }) => new Promise((resolve, reject) => {
|
|
58411
|
+
const child = execFile("claude", argv, {
|
|
58412
|
+
cwd,
|
|
58413
|
+
env,
|
|
58414
|
+
timeout: timeoutMs,
|
|
58415
|
+
killSignal: "SIGKILL",
|
|
58416
|
+
maxBuffer: 64 * 1024 * 1024
|
|
58417
|
+
}, (e, stdout, stderr) => {
|
|
58418
|
+
if (!e) return resolve(stdout);
|
|
58419
|
+
const { code, killed, message } = e;
|
|
58420
|
+
reject(/* @__PURE__ */ new Error(code === "ENOENT" ? "gtd judge run: --provider llm needs `claude` on PATH" : killed ? `gtd judge run: claude timed out after ${timeoutMs} ms` : typeof code === "number" ? `gtd judge run: claude exited ${code}: ${stderr.slice(0, 2048)}` : `gtd judge run: claude failed to start: ${message}`));
|
|
58421
|
+
});
|
|
58422
|
+
child.stdin?.on("error", () => {});
|
|
58423
|
+
child.stdin?.end(stdin);
|
|
58424
|
+
});
|
|
58425
|
+
const llm = ({ env, cwd, model = DEFAULT_MODEL, timeoutMs = TIMEOUT_MS }) => async (questions, state) => {
|
|
58426
|
+
const schema = JSON.stringify(toSchema(questions));
|
|
58427
|
+
const prompt = toPrompt(questions, state);
|
|
58428
|
+
const stdout = await run$1([
|
|
58429
|
+
"-p",
|
|
58430
|
+
"--model",
|
|
58431
|
+
model,
|
|
58432
|
+
"--output-format",
|
|
58433
|
+
"json",
|
|
58434
|
+
"--json-schema",
|
|
58435
|
+
schema,
|
|
58436
|
+
"--system-prompt",
|
|
58437
|
+
SYSTEM_PROMPT,
|
|
58438
|
+
"--tools",
|
|
58439
|
+
"",
|
|
58440
|
+
"--no-session-persistence",
|
|
58441
|
+
"--settings",
|
|
58442
|
+
"{\"disableAllHooks\":true}"
|
|
58443
|
+
], prompt, {
|
|
58444
|
+
env,
|
|
58445
|
+
cwd,
|
|
58446
|
+
timeoutMs
|
|
58447
|
+
});
|
|
58448
|
+
return toLlmVerdicts(questions, stdout);
|
|
58449
|
+
};
|
|
58450
|
+
//#endregion
|
|
58127
58451
|
//#region src/judges/run.ts
|
|
58128
58452
|
const fail = (message) => {
|
|
58129
58453
|
throw new Error(`gtd judge run: ${message}`);
|
|
58130
58454
|
};
|
|
58131
|
-
|
|
58455
|
+
/** The only place auto selection lives; it never falls back across providers. */
|
|
58456
|
+
const answererFor = ({ provider, answers, env, model, cwd }) => {
|
|
58457
|
+
if (model !== void 0 && provider !== void 0 && provider !== "llm") return fail(`--model only applies to --provider llm, not ${provider}`);
|
|
58132
58458
|
if (provider === "fixed") return fixed({
|
|
58133
58459
|
answersPath: answers,
|
|
58134
58460
|
env
|
|
58135
58461
|
});
|
|
58136
|
-
return jev({ env });
|
|
58462
|
+
if (provider === "jev" || provider === void 0 && model === void 0 && env["TYPESAFE_API_KEY"]) return jev({ env });
|
|
58463
|
+
return llm({
|
|
58464
|
+
env,
|
|
58465
|
+
cwd,
|
|
58466
|
+
model
|
|
58467
|
+
});
|
|
58137
58468
|
};
|
|
58138
58469
|
const runJudge = async (opts) => {
|
|
58139
58470
|
let doc;
|
|
@@ -62536,7 +62867,7 @@ const generateSelfSignedCert = (request) => gen(function* () {
|
|
|
62536
62867
|
`-addext "extendedKeyUsage=serverAuth"`,
|
|
62537
62868
|
`-addext "basicConstraints=critical,CA:FALSE"`
|
|
62538
62869
|
].join(" ");
|
|
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$
|
|
62870
|
+
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$6(new GtdError("gtd ui: openssl exited without issuing a certificate", [`exit status: ${outcome.status ?? "signal"}`, ...outcome.output.trim().split("\n").filter(Boolean)])) : try_({
|
|
62540
62871
|
try: () => ({
|
|
62541
62872
|
cert: readFileSync(certPath, "utf8"),
|
|
62542
62873
|
key: readFileSync(keyPath, "utf8")
|
|
@@ -62568,7 +62899,7 @@ const obtainTailscaleCert = (domain) => gen(function* () {
|
|
|
62568
62899
|
`--key-file ${shellQuote(keyPath)}`,
|
|
62569
62900
|
shellQuote(domain)
|
|
62570
62901
|
].join(" ");
|
|
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$
|
|
62902
|
+
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$6(new GtdError("gtd ui: tailscale cert exited without issuing a certificate", [`exit status: ${outcome.status ?? "signal"}`, ...outcome.output.trim().split("\n").filter(Boolean)])) : try_({
|
|
62572
62903
|
try: () => ({
|
|
62573
62904
|
cert: readFileSync(certPath, "utf8"),
|
|
62574
62905
|
key: readFileSync(keyPath, "utf8")
|
|
@@ -62605,7 +62936,7 @@ const TRPC_PATH_PREFIX = "/trpc";
|
|
|
62605
62936
|
*/
|
|
62606
62937
|
const resolveBindHost = (host, config, pickHost = () => pickBindHost(OS.networkInterfaces())) => {
|
|
62607
62938
|
const resolved = host ?? config?.host ?? pickHost();
|
|
62608
|
-
return resolved === void 0 ? fail$
|
|
62939
|
+
return resolved === void 0 ? fail$6(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);
|
|
62609
62940
|
};
|
|
62610
62941
|
/**
|
|
62611
62942
|
* `--self-signed`, then a configured pair, then a real `tailscale cert`, then
|
|
@@ -62622,11 +62953,11 @@ const resolveCertPair = (options, config, bindHost, displayHost, tailscaleStatus
|
|
|
62622
62953
|
if (config?.cert !== void 0 && config.key !== void 0) return loadCertPair(config.cert, config.key);
|
|
62623
62954
|
if (config?.cert !== void 0 || config?.key !== void 0) {
|
|
62624
62955
|
const missing = config.cert === void 0 ? "ui.cert" : "ui.key";
|
|
62625
|
-
return fail$
|
|
62956
|
+
return fail$6(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"]));
|
|
62626
62957
|
}
|
|
62627
62958
|
const certDomain = tailscaleStatus?.certDomains[0];
|
|
62628
62959
|
if (certDomain !== void 0) return obtainTailscaleCert(certDomain);
|
|
62629
|
-
return fail$
|
|
62960
|
+
return fail$6(new GtdError("gtd ui: HTTPS is mandatory and no certificate is configured", [
|
|
62630
62961
|
"pass --self-signed for a throwaway certificate",
|
|
62631
62962
|
"or configure ui.cert and ui.key",
|
|
62632
62963
|
"or join a tailnet with HTTPS certs enabled for an automatic one"
|
|
@@ -62647,7 +62978,7 @@ var UiListener = class UiListener extends Tag("UiListener")() {
|
|
|
62647
62978
|
key: tls.key
|
|
62648
62979
|
}, handler) : http.createServer(handler);
|
|
62649
62980
|
server.once("error", (err) => {
|
|
62650
|
-
resume(fail$
|
|
62981
|
+
resume(fail$6(err.code === "EADDRINUSE" ? new GtdError(`gtd ui: port ${port} is already in use`) : new GtdError(`gtd ui: could not start the server: ${err.message}`)));
|
|
62651
62982
|
});
|
|
62652
62983
|
server.listen(port, host, () => {
|
|
62653
62984
|
const address = server.address();
|
|
@@ -62706,7 +63037,7 @@ const readDevTemplate = (fs, root) => fs.readFileString(join(root, "src/web/inde
|
|
|
62706
63037
|
*/
|
|
62707
63038
|
const rebuildDevClientScript = (runner, fs, root) => gen(function* () {
|
|
62708
63039
|
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}`)));
|
|
62709
|
-
if (outcome.status !== 0) return yield* fail$
|
|
63040
|
+
if (outcome.status !== 0) return yield* fail$6(new GtdError("gtd ui --dev: rebuilding the client failed", outcome.output.trim().split("\n").filter(Boolean)));
|
|
62710
63041
|
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}`)));
|
|
62711
63042
|
});
|
|
62712
63043
|
/**
|
|
@@ -62717,7 +63048,7 @@ const rebuildDevClientScript = (runner, fs, root) => gen(function* () {
|
|
|
62717
63048
|
*/
|
|
62718
63049
|
const rebuildDevClientCss = (runner, fs, root) => gen(function* () {
|
|
62719
63050
|
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}`)));
|
|
62720
|
-
if (outcome.status !== 0) return yield* fail$
|
|
63051
|
+
if (outcome.status !== 0) return yield* fail$6(new GtdError("gtd ui --dev: rebuilding the stylesheet failed", outcome.output.trim().split("\n").filter(Boolean)));
|
|
62721
63052
|
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}`)));
|
|
62722
63053
|
});
|
|
62723
63054
|
/** 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. */
|
|
@@ -62985,7 +63316,7 @@ const resolveListener = (args) => gen(function* () {
|
|
|
62985
63316
|
const runUiCommand = (options, config, out) => gen(function* () {
|
|
62986
63317
|
const cwd = yield* Host;
|
|
62987
63318
|
const step = yield* promise(() => readStep({ path: cwd.root }, liveBeatDeps));
|
|
62988
|
-
if (step.status === "broken" || !isRenderable(step)) return yield* fail$
|
|
63319
|
+
if (step.status === "broken" || !isRenderable(step)) return yield* fail$6(refusalFor(step));
|
|
62989
63320
|
const servedState = step.state;
|
|
62990
63321
|
const servedLabel = step.label;
|
|
62991
63322
|
const runner = yield* CommandRunner;
|
|
@@ -63649,6 +63980,8 @@ const replayFor = (setup, pending) => replay({
|
|
|
63649
63980
|
start: setup.run.diffBase,
|
|
63650
63981
|
startTree: setup.run.diffBase === EMPTY_TREE$1 ? treeFromRecord({}) : commitTree(setup.workspace, setup.run.diffBase),
|
|
63651
63982
|
budgetBytes: setup.budget,
|
|
63983
|
+
skills: setup.def.skills,
|
|
63984
|
+
configuredSkills: setup.def.configuredSkills,
|
|
63652
63985
|
...pending !== void 0 ? { pending } : {}
|
|
63653
63986
|
});
|
|
63654
63987
|
const replayError = (outcome) => {
|
|
@@ -63817,11 +64150,11 @@ const restAt = (ref) => gen(function* () {
|
|
|
63817
64150
|
};
|
|
63818
64151
|
const outcome = yield* promise(() => replayFor(setup));
|
|
63819
64152
|
const error = replayError(outcome);
|
|
63820
|
-
if (error !== void 0 || outcome.kind !== "rest") return yield* fail$
|
|
64153
|
+
if (error !== void 0 || outcome.kind !== "rest") return yield* fail$6(error ?? /* @__PURE__ */ new Error("gtd: replay found no rest"));
|
|
63821
64154
|
const step = outcome.rest;
|
|
63822
64155
|
yield* (yield* Narrator).narrate(`rest resolved: ${step.name} (awaits ${step.actor})`);
|
|
63823
64156
|
const stepDef = stepDefOf(step);
|
|
63824
|
-
if (stepDef.mode !== void 0 && def.modes[stepDef.mode] === void 0) return yield* fail$
|
|
64157
|
+
if (stepDef.mode !== void 0 && def.modes[stepDef.mode] === void 0) return yield* fail$6(/* @__PURE__ */ new Error(`gtd config: step "${step.name}": mode "${stepDef.mode}" is not a mode this workflow knows (${knownModes(def).join(", ")})`));
|
|
63825
64158
|
const changes = ref === void 0 ? (yield* git.changedPaths()).map((e) => ({
|
|
63826
64159
|
status: normalizeStatus(e.status),
|
|
63827
64160
|
path: e.path
|
|
@@ -63870,7 +64203,9 @@ const entryRefusal = (rest, name, entryVars) => gen(function* () {
|
|
|
63870
64203
|
},
|
|
63871
64204
|
vars,
|
|
63872
64205
|
start: "",
|
|
63873
|
-
budgetBytes: rest.setup.budget
|
|
64206
|
+
budgetBytes: rest.setup.budget,
|
|
64207
|
+
skills: rest.def.skills,
|
|
64208
|
+
configuredSkills: rest.def.configuredSkills
|
|
63874
64209
|
}));
|
|
63875
64210
|
if (outcome.kind === "refused") return outcome.message;
|
|
63876
64211
|
if (outcome.kind === "rest") return outcome.entryRead ? void 0 : `"${name}" is not an enterable state — this workflow reads no entry`;
|
|
@@ -63935,7 +64270,7 @@ const decideLanding = (rest, verdicts) => gen(function* () {
|
|
|
63935
64270
|
kind: "refusal",
|
|
63936
64271
|
message: outcome.message
|
|
63937
64272
|
};
|
|
63938
|
-
if (outcome.kind === "divergence" || outcome.kind === "failed") return yield* fail$
|
|
64273
|
+
if (outcome.kind === "divergence" || outcome.kind === "failed") return yield* fail$6(new Error(outcome.message));
|
|
63939
64274
|
const to = outcome.kind === "rest" ? outcome.rest.name : rest.def.initial;
|
|
63940
64275
|
if (rest.changes.length === 0 && rest.stepDef.kind === "script" && to === rest.state) return {
|
|
63941
64276
|
kind: "noop",
|
|
@@ -75939,13 +76274,19 @@ while :; do
|
|
|
75939
76274
|
# you re-ran us resting here: you either edited something or accepted by
|
|
75940
76275
|
# editing nothing, so land the opening beat either way. Later beats are
|
|
75941
76276
|
# gates we just produced and you have not read yet — hand off. A judge
|
|
75942
|
-
# gate's own \`--json=judge\` is non-empty here
|
|
75943
|
-
#
|
|
75944
|
-
#
|
|
75945
|
-
#
|
|
75946
|
-
#
|
|
75947
|
-
# below).
|
|
76277
|
+
# gate's own \`--json=judge\` is non-empty here: pipe it through
|
|
76278
|
+
# \`gtd judge run\` and land the verdict via \`gtd judge answer\`. POSIX sh has
|
|
76279
|
+
# no pipefail, so each step is captured first and only piped on when it
|
|
76280
|
+
# succeeded; if \`gtd judge run\` fails or \`gtd judge answer\` rejects the
|
|
76281
|
+
# verdict, its stderr reaches you and we fall through to the human hand-off.
|
|
75948
76282
|
message)
|
|
76283
|
+
if [ -n "$(gtd next --json=judge)" ] &&
|
|
76284
|
+
verdict="$(gtd judge --json | gtd judge run)" &&
|
|
76285
|
+
script="$(printf '%s\\n' "$verdict" | gtd judge answer --json=script)"; then
|
|
76286
|
+
printf '%s\\n' "$script" | sh
|
|
76287
|
+
beat=$((beat + 1))
|
|
76288
|
+
continue
|
|
76289
|
+
fi
|
|
75949
76290
|
[ "$beat" = 1 ] || {
|
|
75950
76291
|
gtd next
|
|
75951
76292
|
exit 0
|
|
@@ -76569,7 +76910,7 @@ var SelectorUsageError = class extends Error {};
|
|
|
76569
76910
|
const writeSelection = (out, fields, path) => gen(function* () {
|
|
76570
76911
|
const selection = selectPath(fields, path);
|
|
76571
76912
|
if (selection.kind === "value") out.write(`${selection.text}\n`);
|
|
76572
|
-
else if (selection.kind === "unknown") return yield* fail$
|
|
76913
|
+
else if (selection.kind === "unknown") return yield* fail$6(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
|
|
76573
76914
|
});
|
|
76574
76915
|
/** `needs: "none"` skips the repo-root guard — the server is keyed on file name, not workflow state. */
|
|
76575
76916
|
const runLspCommand = () => startLspServer();
|
|
@@ -76589,7 +76930,7 @@ const runInitCommand = (out) => gen(function* () {
|
|
|
76589
76930
|
const git = yield* GitService;
|
|
76590
76931
|
const host = yield* Host;
|
|
76591
76932
|
const inRepo = yield* assertInitLocation(git, host);
|
|
76592
|
-
if (yield* configPresentAt(host.root)) return yield* fail$
|
|
76933
|
+
if (yield* configPresentAt(host.root)) return yield* fail$6(/* @__PURE__ */ new Error("gtd init: a gtd config already exists — remove it before re-initializing"));
|
|
76593
76934
|
const scaffold = renderInitScaffold();
|
|
76594
76935
|
yield* (yield* Workspace).write(".gtdrc.json", scaffold.config);
|
|
76595
76936
|
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";
|
|
@@ -76618,7 +76959,7 @@ const EMPTY_TREE = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
|
76618
76959
|
const planLanding = (opts = {}) => gen(function* () {
|
|
76619
76960
|
const rest = yield* currentRest;
|
|
76620
76961
|
const outcome = planStep(yield* snapshotFromRest(rest, opts.judge), opts);
|
|
76621
|
-
if (outcome.kind === "refusal") return yield* fail$
|
|
76962
|
+
if (outcome.kind === "refusal") return yield* fail$6(new Error(outcome.message));
|
|
76622
76963
|
if (outcome.kind === "noop") {
|
|
76623
76964
|
const required = ScriptSurface.render([{
|
|
76624
76965
|
kind: "outcome",
|
|
@@ -76657,13 +76998,13 @@ const planLanding = (opts = {}) => gen(function* () {
|
|
|
76657
76998
|
*/
|
|
76658
76999
|
const runSummaryCommand = (out) => gen(function* () {
|
|
76659
77000
|
const rendered = yield* summaryFor(yield* summaryRun);
|
|
76660
|
-
if (rendered === void 0) return yield* fail$
|
|
77001
|
+
if (rendered === void 0) return yield* fail$6(/* @__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"));
|
|
76661
77002
|
out.write(rendered.endsWith("\n") ? rendered : rendered + "\n");
|
|
76662
77003
|
});
|
|
76663
77004
|
/** 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. */
|
|
76664
77005
|
const runBaseCommand = (out) => gen(function* () {
|
|
76665
77006
|
const rest = yield* currentRest;
|
|
76666
|
-
if (rest.run.trace.length === 0) return yield* fail$
|
|
77007
|
+
if (rest.run.trace.length === 0) return yield* fail$6(/* @__PURE__ */ new Error("gtd base: refused — no process is underway at HEAD"));
|
|
76667
77008
|
const base = reviewBaseFor(rest);
|
|
76668
77009
|
out.write(`${base}\n`);
|
|
76669
77010
|
});
|
|
@@ -76671,7 +77012,7 @@ const runBaseCommand = (out) => gen(function* () {
|
|
|
76671
77012
|
const runJudgeCommand = (json, out) => gen(function* () {
|
|
76672
77013
|
const rest = yield* currentRest;
|
|
76673
77014
|
const rendered = yield* renderRest(rest);
|
|
76674
|
-
if (rendered.judge === void 0) return yield* fail$
|
|
77015
|
+
if (rendered.judge === void 0) return yield* fail$6(/* @__PURE__ */ new Error(`gtd judge: refused — the resolved rest ("${rest.state}") declares no "judge:"`));
|
|
76675
77016
|
const document = rendered.judge.endsWith("\n") ? rendered.judge : `${rendered.judge}\n`;
|
|
76676
77017
|
if (json.kind === "select") {
|
|
76677
77018
|
const selection = selectPath(yield* try_({
|
|
@@ -76679,7 +77020,7 @@ const runJudgeCommand = (json, out) => gen(function* () {
|
|
|
76679
77020
|
catch: () => new SelectorUsageError("gtd judge: the resolved rest's \"judge:\" template did not render valid JSON")
|
|
76680
77021
|
}), json.path);
|
|
76681
77022
|
if (selection.kind === "value") out.write(`${selection.text}\n`);
|
|
76682
|
-
else if (selection.kind === "unknown") return yield* fail$
|
|
77023
|
+
else if (selection.kind === "unknown") return yield* fail$6(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
|
|
76683
77024
|
return;
|
|
76684
77025
|
}
|
|
76685
77026
|
out.write(document);
|
|
@@ -76709,6 +77050,8 @@ const runJudgeRunCommand = (command, out) => gen(function* () {
|
|
|
76709
77050
|
try: () => runJudge({
|
|
76710
77051
|
provider: command.provider,
|
|
76711
77052
|
answers: command.answers,
|
|
77053
|
+
model: command.model,
|
|
77054
|
+
cwd: host.scratchDir,
|
|
76712
77055
|
env: host.env,
|
|
76713
77056
|
input
|
|
76714
77057
|
}),
|
|
@@ -76740,7 +77083,7 @@ const verdictSchemaFor = (ids) => Array$(Struct({
|
|
|
76740
77083
|
const runJudgeAnswerCommand = (json, out) => gen(function* () {
|
|
76741
77084
|
const rest = yield* currentRest;
|
|
76742
77085
|
const rendered = yield* renderRest(rest);
|
|
76743
|
-
if (rendered.judge === void 0) return yield* fail$
|
|
77086
|
+
if (rendered.judge === void 0) return yield* fail$6(/* @__PURE__ */ new Error(`gtd judge answer: refused — the resolved rest ("${rest.state}") declares no "judge:"`));
|
|
76744
77087
|
const ids = (yield* parseJudgeDocument(rendered.judge)).questions.map((q) => q.id);
|
|
76745
77088
|
const raw = yield* readStdin();
|
|
76746
77089
|
const parsed = yield* try_({
|
|
@@ -76786,7 +77129,7 @@ const runEntryCommand = (actor, entryState, varOverrides, out, commandLabel) =>
|
|
|
76786
77129
|
commandLabel,
|
|
76787
77130
|
vars: varOverrides
|
|
76788
77131
|
});
|
|
76789
|
-
if (plan.kind === "refusal") return yield* fail$
|
|
77132
|
+
if (plan.kind === "refusal") return yield* fail$6(new Error(plan.message));
|
|
76790
77133
|
out.write(landingScript(ScriptSurface.render(plan.steps)));
|
|
76791
77134
|
});
|
|
76792
77135
|
/**
|
|
@@ -76815,7 +77158,7 @@ const runAbandonCommand = (out) => gen(function* () {
|
|
|
76815
77158
|
return;
|
|
76816
77159
|
}
|
|
76817
77160
|
const restState = run.trace[run.trace.length - 1].state;
|
|
76818
|
-
if (run.startParentHash === EMPTY_TREE) return yield* fail$
|
|
77161
|
+
if (run.startParentHash === EMPTY_TREE) return yield* fail$6(/* @__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`));
|
|
76819
77162
|
const required = emitScripts([
|
|
76820
77163
|
{
|
|
76821
77164
|
kind: "gitWrite",
|
|
@@ -76841,13 +77184,13 @@ const runAbandonCommand = (out) => gen(function* () {
|
|
|
76841
77184
|
*/
|
|
76842
77185
|
const runRestoreCommand = (out) => gen(function* () {
|
|
76843
77186
|
const git = yield* GitService;
|
|
76844
|
-
if ((yield* currentRest).changes.length > 0) return yield* fail$
|
|
77187
|
+
if ((yield* currentRest).changes.length > 0) return yield* fail$6(/* @__PURE__ */ new Error("gtd restore: refuses on a dirty working tree — commit, stash, or discard your changes first."));
|
|
76845
77188
|
const retained = yield* readRetainedHistory(git);
|
|
76846
|
-
if (isNone(retained)) return yield* fail$
|
|
77189
|
+
if (isNone(retained)) return yield* fail$6(/* @__PURE__ */ new Error("gtd restore: no retained history to restore."));
|
|
76847
77190
|
const tip = retained.value;
|
|
76848
77191
|
const headHash = yield* git.resolveRef("HEAD");
|
|
76849
77192
|
const check = yield* restorability(git, headHash, tip);
|
|
76850
|
-
if (!check.ok) return yield* fail$
|
|
77193
|
+
if (!check.ok) return yield* fail$6(/* @__PURE__ */ new Error(`gtd restore: ${check.reason} — HEAD ${headHash.slice(0, 7)} is ahead of the retained tip ${tip.slice(0, 7)}.`));
|
|
76851
77194
|
const after = yield* restAt(tip);
|
|
76852
77195
|
const required = emitScripts([
|
|
76853
77196
|
{
|
|
@@ -76891,7 +77234,7 @@ const resolveValidateScript = (rest) => gen(function* () {
|
|
|
76891
77234
|
const mode = rest.stepDef.mode;
|
|
76892
77235
|
if (file === void 0 || mode === void 0) return void 0;
|
|
76893
77236
|
const resolved = resolveMode(rest.def, rest.state, mode);
|
|
76894
|
-
if (resolved.kind === "unknown") return yield* fail$
|
|
77237
|
+
if (resolved.kind === "unknown") return yield* fail$6(new Error(resolved.message));
|
|
76895
77238
|
const { script } = yield* validateScriptFor(resolved, file);
|
|
76896
77239
|
return {
|
|
76897
77240
|
file,
|
|
@@ -76947,23 +77290,23 @@ const formatFinding = (file, finding) => {
|
|
|
76947
77290
|
*/
|
|
76948
77291
|
const runCheckCommand = (mode, file, openQuestions, openThreadsFlag) => gen(function* () {
|
|
76949
77292
|
const format = steeringFormatFor(mode);
|
|
76950
|
-
if (format === void 0) return yield* fail$
|
|
77293
|
+
if (format === void 0) return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: unknown mode "${mode}" — known modes: ${BUILT_IN_MODE_NAMES.join(", ")}`));
|
|
76951
77294
|
if (openThreadsFlag) {
|
|
76952
|
-
if (openQuestions) return yield* fail$
|
|
77295
|
+
if (openQuestions) return yield* fail$6(/* @__PURE__ */ new Error("gtd check: --open-threads and --open-questions are mutually exclusive"));
|
|
76953
77296
|
if (format.openThreads === void 0) {
|
|
76954
77297
|
const accepted = BUILT_IN_MODE_NAMES.filter((name) => steeringFormatFor(name)?.openThreads !== void 0);
|
|
76955
|
-
return yield* fail$
|
|
77298
|
+
return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: --open-threads only applies to modes ${accepted.join(", ")} — got "${mode}"`));
|
|
76956
77299
|
}
|
|
76957
77300
|
return yield* runOpenThreadsCheckCommand(format, file);
|
|
76958
77301
|
}
|
|
76959
77302
|
if (openQuestions) {
|
|
76960
|
-
if (mode !== "qa") return yield* fail$
|
|
77303
|
+
if (mode !== "qa") return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: --open-questions only applies to mode "qa" — got "${mode}"`));
|
|
76961
77304
|
return yield* runOpenQuestionsCheckCommand(format, file);
|
|
76962
77305
|
}
|
|
76963
77306
|
const content = (yield* Workspace).atPath(file);
|
|
76964
77307
|
const errors = content !== void 0 ? format.validate(content).map((finding) => formatFinding(file, finding)) : [];
|
|
76965
77308
|
if (errors.length === 0) return;
|
|
76966
|
-
return yield* fail$
|
|
77309
|
+
return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: ${file} is not valid under mode "${mode}" (${errors.length} finding(s)):\n` + errors.join("\n")));
|
|
76967
77310
|
});
|
|
76968
77311
|
/**
|
|
76969
77312
|
* The bare `gtd check --open-threads`: code-comment threads in the files the
|
|
@@ -76980,15 +77323,15 @@ const runCodeThreadsCheckCommand = () => gen(function* () {
|
|
|
76980
77323
|
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}`)];
|
|
76981
77324
|
});
|
|
76982
77325
|
if (lines.length === 0) return;
|
|
76983
|
-
return yield* fail$
|
|
77326
|
+
return yield* fail$6(new Error(lines.join("\n")));
|
|
76984
77327
|
});
|
|
76985
77328
|
/** Prints one `file:line: [^name]: <first H entry>` line per open thread; a missing file fails, like `--open-questions`. */
|
|
76986
77329
|
const runOpenThreadsCheckCommand = (format, file) => gen(function* () {
|
|
76987
77330
|
const content = (yield* Workspace).atPath(file);
|
|
76988
|
-
if (content === void 0) return yield* fail$
|
|
77331
|
+
if (content === void 0) return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: ${file} does not exist`));
|
|
76989
77332
|
const errors = openThreads(format, content).map((t) => `${file}:${t.line + 1}: [^${t.name}]: ${t.firstMe}`);
|
|
76990
77333
|
if (errors.length === 0) return;
|
|
76991
|
-
return yield* fail$
|
|
77334
|
+
return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: ${errors.length} open thread(s) in ${file}:\n` + errors.join("\n")));
|
|
76992
77335
|
});
|
|
76993
77336
|
/**
|
|
76994
77337
|
* Runs the SAME `unansweredQuestions` predicate a flow's `openQuestions()`
|
|
@@ -76997,10 +77340,10 @@ const runOpenThreadsCheckCommand = (format, file) => gen(function* () {
|
|
|
76997
77340
|
*/
|
|
76998
77341
|
const runOpenQuestionsCheckCommand = (format, file) => gen(function* () {
|
|
76999
77342
|
const content = (yield* Workspace).atPath(file);
|
|
77000
|
-
if (content === void 0) return yield* fail$
|
|
77343
|
+
if (content === void 0) return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: ${file} does not exist`));
|
|
77001
77344
|
const errors = unansweredQuestions(format, content).map((q) => `${file}:${q.headingLine + 1}: ${q.question}`);
|
|
77002
77345
|
if (errors.length === 0) return;
|
|
77003
|
-
return yield* fail$
|
|
77346
|
+
return yield* fail$6(/* @__PURE__ */ new Error(`gtd check: ${errors.length} open question(s) unanswered in ${file}:\n` + errors.join("\n")));
|
|
77004
77347
|
});
|
|
77005
77348
|
/**
|
|
77006
77349
|
* Clears the `review` format's ticks in `<file>`, writing back only when the
|
|
@@ -77077,11 +77420,11 @@ const runUiCliCommand = (command, out) => gen(function* () {
|
|
|
77077
77420
|
*/
|
|
77078
77421
|
const assertRunningFromRepoRoot = (git, host) => gen(function* () {
|
|
77079
77422
|
const topLevel = yield* git.topLevel();
|
|
77080
|
-
if ((yield* host.realPath(topLevel)) !== (yield* host.realPath(host.root))) return yield* fail$
|
|
77423
|
+
if ((yield* host.realPath(topLevel)) !== (yield* host.realPath(host.root))) return yield* fail$6(/* @__PURE__ */ new Error(`gtd must be run from the repository root (${topLevel}); the current directory is ${host.root}`));
|
|
77081
77424
|
});
|
|
77082
77425
|
/** A command that derives workflow state needs at least one commit too — a commitless repository has no HEAD to resolve a `Rest` at. */
|
|
77083
77426
|
const assertRepositoryHasCommits = (git) => gen(function* () {
|
|
77084
|
-
if (!(yield* git.hasCommits())) return yield* fail$
|
|
77427
|
+
if (!(yield* git.hasCommits())) return yield* fail$6(/* @__PURE__ */ new Error("gtd requires a repository with at least one commit — make an initial commit, then run gtd again"));
|
|
77085
77428
|
});
|
|
77086
77429
|
/**
|
|
77087
77430
|
* `gtd init` may run either at a repository root or in a directory outside
|
|
@@ -77094,7 +77437,7 @@ const assertRepositoryHasCommits = (git) => gen(function* () {
|
|
|
77094
77437
|
const assertInitLocation = (git, host) => gen(function* () {
|
|
77095
77438
|
const topLevel = yield* either(git.topLevel());
|
|
77096
77439
|
if (topLevel._tag === "Left") return false;
|
|
77097
|
-
if ((yield* host.realPath(topLevel.right)) !== (yield* host.realPath(host.root))) return yield* fail$
|
|
77440
|
+
if ((yield* host.realPath(topLevel.right)) !== (yield* host.realPath(host.root))) return yield* fail$6(/* @__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}`));
|
|
77098
77441
|
return true;
|
|
77099
77442
|
});
|
|
77100
77443
|
/**
|
|
@@ -77270,10 +77613,10 @@ const FLAGS = [
|
|
|
77270
77613
|
arity: 1,
|
|
77271
77614
|
repeatable: false,
|
|
77272
77615
|
scope: (kind) => kind === "judgeRun",
|
|
77273
|
-
decode: ([raw]) => raw === "fixed" || raw === "jev" ? right(raw) : left(`gtd: --provider must be one of fixed, jev — got "${raw ?? ""}"`),
|
|
77616
|
+
decode: ([raw]) => raw === "fixed" || raw === "jev" || raw === "llm" ? right(raw) : left(`gtd: --provider must be one of fixed, jev, llm — got "${raw ?? ""}"`),
|
|
77274
77617
|
scopeError: "gtd: --provider is only valid for `gtd judge run`",
|
|
77275
77618
|
valueHint: "<name>",
|
|
77276
|
-
help: ["(gtd judge run only
|
|
77619
|
+
help: ["(gtd judge run only) the answerer: fixed | jev | llm;", "omitted: jev when TYPESAFE_API_KEY is set, else llm"]
|
|
77277
77620
|
},
|
|
77278
77621
|
{
|
|
77279
77622
|
name: "--answers",
|
|
@@ -77303,11 +77646,11 @@ const FLAGS = [
|
|
|
77303
77646
|
name: "--model",
|
|
77304
77647
|
arity: 1,
|
|
77305
77648
|
repeatable: false,
|
|
77306
|
-
scope: (kind) => kind === "land",
|
|
77649
|
+
scope: (kind) => kind === "land" || kind === "judgeRun",
|
|
77307
77650
|
decode: ([raw]) => raw === void 0 || raw.trim() === "" || /[\r\n]/.test(raw) ? left("gtd: --model must be a non-empty, single-line value") : right(raw),
|
|
77308
|
-
scopeError: "gtd: --model is only valid for `gtd land`
|
|
77651
|
+
scopeError: "gtd: --model is only valid for `gtd land` (with --cost) or `gtd judge run`",
|
|
77309
77652
|
valueHint: "<name>",
|
|
77310
|
-
help: ["(gtd land
|
|
77653
|
+
help: ["(gtd land, with --cost) tag that cost's model", "(gtd judge run, llm answerer) the claude model; default haiku"]
|
|
77311
77654
|
},
|
|
77312
77655
|
{
|
|
77313
77656
|
name: "--entry",
|
|
@@ -77663,9 +78006,13 @@ const COMMAND_ROWS = [
|
|
|
77663
78006
|
"stdin, write a verdict [{ id, answer, p }] on stdout — what",
|
|
77664
78007
|
"`gtd judge answer` decodes. --provider fixed answers from",
|
|
77665
78008
|
"--answers <path> or GTD_JUDGE_ANSWERS; questions the file",
|
|
77666
|
-
"does not cover are left out.
|
|
77667
|
-
"
|
|
77668
|
-
"on
|
|
78009
|
+
"does not cover are left out. --provider jev asks TypeSafe",
|
|
78010
|
+
"(TYPESAFE_API_KEY). --provider llm asks the `claude` CLI",
|
|
78011
|
+
"on PATH (Claude Code only), model haiku unless --model.",
|
|
78012
|
+
"No --provider: jev when TYPESAFE_API_KEY is set and no",
|
|
78013
|
+
"--model is given, else llm. Needs no repository. jev and",
|
|
78014
|
+
"llm exit 1 when they cannot answer every question, with",
|
|
78015
|
+
"nothing on stdout"
|
|
77669
78016
|
]
|
|
77670
78017
|
}
|
|
77671
78018
|
];
|
|
@@ -77927,14 +78274,16 @@ const parseArgv = (argv) => {
|
|
|
77927
78274
|
verbose
|
|
77928
78275
|
};
|
|
77929
78276
|
if (kind === "judgeRun") {
|
|
77930
|
-
|
|
77931
|
-
if (
|
|
78277
|
+
const provider = bag["--provider"];
|
|
78278
|
+
if (provider !== "fixed" && bag["--answers"] !== void 0) return usagePlan("gtd judge run: --answers is only valid with --provider fixed", jsonSeen);
|
|
78279
|
+
if ((provider === "fixed" || provider === "jev") && bag["--model"] !== void 0) return usagePlan("gtd judge run: --model is only valid with --provider llm (or when it is auto-selected)", jsonSeen);
|
|
77932
78280
|
return {
|
|
77933
78281
|
kind: "command",
|
|
77934
78282
|
command: {
|
|
77935
78283
|
kind: "judgeRun",
|
|
77936
|
-
provider:
|
|
77937
|
-
...bag["--answers"] !== void 0 ? { answers: bag["--answers"] } : {}
|
|
78284
|
+
...provider !== void 0 ? { provider } : {},
|
|
78285
|
+
...bag["--answers"] !== void 0 ? { answers: bag["--answers"] } : {},
|
|
78286
|
+
...bag["--model"] !== void 0 ? { model: bag["--model"] } : {}
|
|
77938
78287
|
},
|
|
77939
78288
|
json,
|
|
77940
78289
|
verbose
|