@pmelab/gtd 46.0.0 → 48.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.
Files changed (34) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +21 -19
  3. package/dist/chunks/{reserved-BENPy6IJ.mjs → reserved-DF1HD6jL.mjs} +41 -22
  4. package/dist/chunks/{review-DcbgUwr7.mjs → review-Bv40kZu9.mjs} +5 -8
  5. package/dist/chunks/{tail-CDNMZ-2E.mjs → tail-D89fU_wf.mjs} +68 -39
  6. package/dist/gtd.bundle.mjs +203 -867
  7. package/dist/testkit.mjs +89 -53
  8. package/dist/workflows/cleanup.mjs +2 -2
  9. package/dist/workflows/feature.mjs +26 -22
  10. package/dist/workflows/fix.mjs +2 -2
  11. package/dist/workflows/review.mjs +3 -3
  12. package/dist/workflows/rollout.mjs +1 -1
  13. package/dist/workflows.mjs +257 -205
  14. package/package.json +1 -1
  15. package/src/cli/Cli.test.ts +0 -2
  16. package/src/cli/Cli.ts +0 -15
  17. package/src/cli/Program.test.ts +0 -1
  18. package/src/cli/Program.ts +0 -8
  19. package/src/cli/ToolCommands.ts +1 -2
  20. package/src/install/Install.ts +89 -35
  21. package/src/testkit/Layers.ts +0 -1
  22. package/src/wire/ContextLimit.ts +1 -1
  23. package/src/workflows/cleanup/cleanup.test.ts +11 -9
  24. package/src/workflows/feature/feature.ts +38 -28
  25. package/src/workflows/feature/lens-review.feature +3 -1
  26. package/src/workflows/feature/slice-findings.feature +198 -0
  27. package/src/workflows/fix/fix-lens-origin.feature +101 -0
  28. package/src/workflows/fix/fix-quality.feature +131 -0
  29. package/src/workflows/index.ts +0 -1
  30. package/src/workflows/shared/lenses.ts +30 -5
  31. package/src/workflows/shared/review.ts +3 -8
  32. package/src/workflows/shared/tail.ts +74 -57
  33. package/src/workflows/shared/text.ts +85 -29
  34. package/src/workflows/feature/quality-unresolved.feature +0 -121
@@ -7,16 +7,16 @@ import { isIP } from "node:net";
7
7
  import * as Crypto from "node:crypto";
8
8
  import { createHash, randomUUID } from "node:crypto";
9
9
  import * as NFS from "node:fs";
10
- import { appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, mkdtempSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
10
+ import { appendFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
11
11
  import * as OS from "node:os";
12
- import { constants, homedir, networkInterfaces, tmpdir } from "node:os";
12
+ import { homedir, networkInterfaces, tmpdir } from "node:os";
13
13
  import * as Path from "node:path";
14
14
  import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
15
15
  import * as https from "node:https";
16
16
  import { Readable } from "node:stream";
17
17
  import { mkdir, readFile, writeFile } from "node:fs/promises";
18
18
  import * as ChildProcess from "node:child_process";
19
- import { execFile, execFileSync, spawn } from "node:child_process";
19
+ import { execFile, execFileSync } from "node:child_process";
20
20
  import * as NodeUrl from "node:url";
21
21
  import { fileURLToPath, pathToFileURL } from "node:url";
22
22
  import * as readline from "node:readline";
@@ -170,7 +170,7 @@ var init_GlobalValue = __esmMin((() => {
170
170
  }));
171
171
  //#endregion
172
172
  //#region node_modules/effect/dist/esm/Predicate.js
173
- var isTruthy, isString, isNumber, isBoolean, isBigInt, isSymbol, isFunction$1, isUndefined, isNotUndefined, isNotNull, isNever, isRecordOrArray, isObject$3, hasProperty, isTagged, isNullable, isNotNullable, isUint8Array, isDate, isIterable, isRecord$2, isPromiseLike;
173
+ var isTruthy, isString, isNumber, isBoolean, isBigInt, isSymbol, isFunction$1, isUndefined, isNever, isRecordOrArray, isObject$3, hasProperty, isTagged, isNullable, isNotNullable, isUint8Array, isDate, isIterable, isRecord$2, isPromiseLike;
174
174
  var init_Predicate = __esmMin((() => {
175
175
  init_Function();
176
176
  isTruthy = (input) => !!input;
@@ -181,8 +181,6 @@ var init_Predicate = __esmMin((() => {
181
181
  isSymbol = (input) => typeof input === "symbol";
182
182
  isFunction$1 = isFunction$2;
183
183
  isUndefined = (input) => input === void 0;
184
- isNotUndefined = (input) => input !== void 0;
185
- isNotNull = (input) => input !== null;
186
184
  isNever = (_) => false;
187
185
  isRecordOrArray = (input) => typeof input === "object" && input !== null;
188
186
  isObject$3 = (input) => isRecordOrArray(input) || isFunction$1(input);
@@ -234,54 +232,11 @@ function yieldWrapGet(self) {
234
232
  if (typeof self === "object" && self !== null && YieldWrapTypeId in self) return self[YieldWrapTypeId]();
235
233
  throw new Error(getBugErrorMessage("yieldWrapGet"));
236
234
  }
237
- var GenKindTypeId, isGenKind, GenKindImpl, SingleShotGen$1, adapter$1, defaultIncHi, defaultIncLo, MUL_HI, MUL_LO, BIT_53, BIT_27, PCGRandom, YieldWrapTypeId, YieldWrap, structuralRegionState, standard, forced, isNotOptimizedAway, internalCall;
235
+ var SingleShotGen$1, defaultIncHi, defaultIncLo, MUL_HI, MUL_LO, BIT_53, BIT_27, PCGRandom, YieldWrapTypeId, YieldWrap, structuralRegionState, standard, forced, isNotOptimizedAway, internalCall;
238
236
  var init_Utils = __esmMin((() => {
239
- init_Function();
240
237
  init_GlobalValue();
241
238
  init_errors$1();
242
239
  init_Predicate();
243
- GenKindTypeId = /*#__PURE__*/ Symbol.for("effect/Gen/GenKind");
244
- isGenKind = (u) => isObject$3(u) && GenKindTypeId in u;
245
- GenKindImpl = class {
246
- value;
247
- constructor(value) {
248
- this.value = value;
249
- }
250
- /**
251
- * @since 2.0.0
252
- */
253
- get _F() {
254
- return identity$1;
255
- }
256
- /**
257
- * @since 2.0.0
258
- */
259
- get _R() {
260
- return (_) => _;
261
- }
262
- /**
263
- * @since 2.0.0
264
- */
265
- get _O() {
266
- return (_) => _;
267
- }
268
- /**
269
- * @since 2.0.0
270
- */
271
- get _E() {
272
- return (_) => _;
273
- }
274
- /**
275
- * @since 2.0.0
276
- */
277
- [GenKindTypeId] = GenKindTypeId;
278
- /**
279
- * @since 2.0.0
280
- */
281
- [Symbol.iterator]() {
282
- return new SingleShotGen$1(this);
283
- }
284
- };
285
240
  SingleShotGen$1 = class SingleShotGen$1 {
286
241
  self;
287
242
  called = false;
@@ -322,11 +277,6 @@ var init_Utils = __esmMin((() => {
322
277
  return new SingleShotGen$1(this.self);
323
278
  }
324
279
  };
325
- adapter$1 = () => function() {
326
- let x = arguments[0];
327
- for (let i = 1; i < arguments.length; i++) x = arguments[i](x);
328
- return new GenKindImpl(x);
329
- };
330
280
  defaultIncHi = 335903614;
331
281
  defaultIncLo = 4150755663;
332
282
  MUL_HI = 1481765933;
@@ -997,12 +947,11 @@ var init_either = __esmMin((() => {
997
947
  }));
998
948
  //#endregion
999
949
  //#region node_modules/effect/dist/esm/Either.js
1000
- var right, left, fromOption$1, try_$2, isEither$1, isLeft, isRight, mapBoth$4, mapLeft, map$15, match$9, merge$3, getOrThrowWith$1, getOrThrow$1, adapter, gen$2;
950
+ var right, left, fromOption$1, try_$2, isEither$1, isLeft, isRight, mapBoth$4, mapLeft, map$15, match$9, merge$3, getOrThrowWith$1, getOrThrow$1;
1001
951
  var init_Either = __esmMin((() => {
1002
952
  init_Function();
1003
953
  init_either();
1004
954
  init_Predicate();
1005
- init_Utils();
1006
955
  right = right$1;
1007
956
  left = left$1;
1008
957
  fromOption$1 = fromOption$2;
@@ -1034,17 +983,6 @@ var init_Either = __esmMin((() => {
1034
983
  throw onLeft(self.left);
1035
984
  });
1036
985
  getOrThrow$1 = /*#__PURE__*/ getOrThrowWith$1(() => /* @__PURE__ */ new Error("getOrThrow called on a Left"));
1037
- adapter = /*#__PURE__*/ adapter$1();
1038
- gen$2 = (...args) => {
1039
- const iterator = (args.length === 1 ? args[0] : args[1].bind(args[0]))(adapter);
1040
- let state = iterator.next();
1041
- while (!state.done) {
1042
- const current = isGenKind(state.value) ? state.value.value : yieldWrapGet(state.value);
1043
- if (isLeft(current)) return current;
1044
- state = iterator.next(current.right);
1045
- }
1046
- return right(state.value);
1047
- };
1048
986
  }));
1049
987
  //#endregion
1050
988
  //#region node_modules/effect/dist/esm/internal/array.js
@@ -2932,7 +2870,7 @@ var init_Context = __esmMin((() => {
2932
2870
  }));
2933
2871
  //#endregion
2934
2872
  //#region node_modules/effect/dist/esm/Duration.js
2935
- var TypeId$20, bigint0$2, bigint24, bigint60, bigint1e3, bigint1e6, bigint1e9, DURATION_REGEX, decode$2, zeroValue, infinityValue, DurationProto, make$40, isDuration, isFinite, isZero$1, zero$1, infinity, nanos, micros, millis, seconds, minutes, hours, days, weeks, toMillis, toNanos, unsafeToNanos, toHrTime, match$6, matchWith, Equivalence$3, sum$1, lessThanOrEqualTo$1, greaterThanOrEqualTo$1, equals$1, parts, format$3;
2873
+ var TypeId$20, bigint0$2, bigint24, bigint60, bigint1e3, bigint1e6, bigint1e9, DURATION_REGEX, decode$1, zeroValue, infinityValue, DurationProto, make$40, isDuration, isFinite, isZero$1, zero$1, infinity, nanos, micros, millis, seconds, minutes, hours, days, weeks, toMillis, toNanos, unsafeToNanos, toHrTime, match$6, matchWith, Equivalence$3, sum$1, lessThanOrEqualTo$1, greaterThanOrEqualTo$1, equals$1, parts, format$3;
2936
2874
  var init_Duration = __esmMin((() => {
2937
2875
  init_Equal();
2938
2876
  init_Function();
@@ -2949,7 +2887,7 @@ var init_Duration = __esmMin((() => {
2949
2887
  bigint1e6 = /*#__PURE__*/ BigInt(1e6);
2950
2888
  bigint1e9 = /*#__PURE__*/ BigInt(1e9);
2951
2889
  DURATION_REGEX = /^(-?\d+(?:\.\d+)?)\s+(nanos?|micros?|millis?|seconds?|minutes?|hours?|days?|weeks?)$/;
2952
- decode$2 = (input) => {
2890
+ decode$1 = (input) => {
2953
2891
  if (isDuration(input)) return input;
2954
2892
  else if (isNumber(input)) return millis(input);
2955
2893
  else if (isBigInt(input)) return nanos(input);
@@ -3068,7 +3006,7 @@ var init_Duration = __esmMin((() => {
3068
3006
  onNanos: (nanos) => Number(nanos) / 1e6
3069
3007
  });
3070
3008
  toNanos = (self) => {
3071
- const _self = decode$2(self);
3009
+ const _self = decode$1(self);
3072
3010
  switch (_self.value._tag) {
3073
3011
  case "Infinity": return none$4();
3074
3012
  case "Nanos": return some(_self.value.nanos);
@@ -3076,7 +3014,7 @@ var init_Duration = __esmMin((() => {
3076
3014
  }
3077
3015
  };
3078
3016
  unsafeToNanos = (self) => {
3079
- const _self = decode$2(self);
3017
+ const _self = decode$1(self);
3080
3018
  switch (_self.value._tag) {
3081
3019
  case "Infinity": throw new Error("Cannot convert infinite duration to nanos");
3082
3020
  case "Nanos": return _self.value.nanos;
@@ -3084,7 +3022,7 @@ var init_Duration = __esmMin((() => {
3084
3022
  }
3085
3023
  };
3086
3024
  toHrTime = (self) => {
3087
- const _self = decode$2(self);
3025
+ const _self = decode$1(self);
3088
3026
  switch (_self.value._tag) {
3089
3027
  case "Infinity": return [Infinity, 0];
3090
3028
  case "Nanos": return [Number(_self.value.nanos / bigint1e9), Number(_self.value.nanos % bigint1e9)];
@@ -3092,7 +3030,7 @@ var init_Duration = __esmMin((() => {
3092
3030
  }
3093
3031
  };
3094
3032
  match$6 = /*#__PURE__*/ dual(2, (self, options) => {
3095
- const _self = decode$2(self);
3033
+ const _self = decode$1(self);
3096
3034
  switch (_self.value._tag) {
3097
3035
  case "Nanos": return options.onNanos(_self.value.nanos);
3098
3036
  case "Infinity": return options.onMillis(Infinity);
@@ -3100,8 +3038,8 @@ var init_Duration = __esmMin((() => {
3100
3038
  }
3101
3039
  });
3102
3040
  matchWith = /*#__PURE__*/ dual(3, (self, that, options) => {
3103
- const _self = decode$2(self);
3104
- const _that = decode$2(that);
3041
+ const _self = decode$1(self);
3042
+ const _that = decode$1(that);
3105
3043
  if (_self.value._tag === "Infinity" || _that.value._tag === "Infinity") return options.onMillis(toMillis(_self), toMillis(_that));
3106
3044
  else if (_self.value._tag === "Nanos" || _that.value._tag === "Nanos") {
3107
3045
  const selfNanos = _self.value._tag === "Nanos" ? _self.value.nanos : BigInt(Math.round(_self.value.millis * 1e6));
@@ -3126,9 +3064,9 @@ var init_Duration = __esmMin((() => {
3126
3064
  onMillis: (self, that) => self >= that,
3127
3065
  onNanos: (self, that) => self >= that
3128
3066
  }));
3129
- equals$1 = /*#__PURE__*/ dual(2, (self, that) => Equivalence$3(decode$2(self), decode$2(that)));
3067
+ equals$1 = /*#__PURE__*/ dual(2, (self, that) => Equivalence$3(decode$1(self), decode$1(that)));
3130
3068
  parts = (self) => {
3131
- const duration = decode$2(self);
3069
+ const duration = decode$1(self);
3132
3070
  if (duration.value._tag === "Infinity") return {
3133
3071
  days: Infinity,
3134
3072
  hours: Infinity,
@@ -3153,7 +3091,7 @@ var init_Duration = __esmMin((() => {
3153
3091
  };
3154
3092
  };
3155
3093
  format$3 = (self) => {
3156
- const duration = decode$2(self);
3094
+ const duration = decode$1(self);
3157
3095
  if (duration.value._tag === "Infinity") return "Infinity";
3158
3096
  if (isZero$1(duration)) return "0";
3159
3097
  const fragments = parts(duration);
@@ -5728,7 +5666,7 @@ var init_defaultServices = __esmMin((() => {
5728
5666
  liveServices = /*#__PURE__*/ pipe(/*#__PURE__*/ empty$19(), /*#__PURE__*/ add$1(clockTag, /*#__PURE__*/ make$32()), /*#__PURE__*/ add$1(consoleTag, defaultConsole), /*#__PURE__*/ add$1(randomTag, /*#__PURE__*/ make$30(/*#__PURE__*/ Math.random())), /*#__PURE__*/ add$1(configProviderTag, /*#__PURE__*/ fromEnv()), /*#__PURE__*/ add$1(tracerTag, nativeTracer));
5729
5667
  currentServices = /*#__PURE__*/ globalValue(/*#__PURE__*/ Symbol.for("effect/DefaultServices/currentServices"), () => fiberRefUnsafeMakeContext(liveServices));
5730
5668
  sleep$3 = (duration) => {
5731
- const decodedDuration = decode$2(duration);
5669
+ const decodedDuration = decode$1(duration);
5732
5670
  return clockWith((clock) => clock.sleep(decodedDuration));
5733
5671
  };
5734
5672
  defaultServicesWith = (f) => withFiberRuntime$1((fiber) => f(fiber.currentDefaultServices));
@@ -7718,7 +7656,7 @@ _A: (_) => _ };
7718
7656
  //#endregion
7719
7657
  //#region node_modules/effect/dist/esm/internal/metric/hook.js
7720
7658
  var MetricHookSymbolKey, MetricHookTypeId, metricHookVariance, make$25, bigint0$1, counter$1, frequency, gauge, histogram$1, summary, calculateQuantiles, resolveQuantile;
7721
- var init_hook = __esmMin((() => {
7659
+ var init_hook$1 = __esmMin((() => {
7722
7660
  init_Array();
7723
7661
  init_Duration();
7724
7662
  init_Function();
@@ -8015,7 +7953,7 @@ var init_registry = __esmMin((() => {
8015
7953
  init_Function();
8016
7954
  init_MutableHashMap();
8017
7955
  init_Option();
8018
- init_hook();
7956
+ init_hook$1();
8019
7957
  init_keyType();
8020
7958
  init_pair();
8021
7959
  MetricRegistrySymbolKey = "effect/MetricRegistry";
@@ -11093,7 +11031,7 @@ var init_schedule = __esmMin((() => {
11093
11031
  };
11094
11032
  makeWithState = (initial, step) => new ScheduleImpl(initial, step);
11095
11033
  addDelay = /*#__PURE__*/ dual(2, (self, f) => addDelayEffect(self, (out) => sync$2(() => f(out))));
11096
- addDelayEffect = /*#__PURE__*/ dual(2, (self, f) => modifyDelayEffect(self, (out, duration) => map$8(f(out), (delay) => sum$1(duration, decode$2(delay)))));
11034
+ addDelayEffect = /*#__PURE__*/ dual(2, (self, f) => modifyDelayEffect(self, (out, duration) => map$8(f(out), (delay) => sum$1(duration, decode$1(delay)))));
11097
11035
  check$1 = /*#__PURE__*/ dual(2, (self, test) => checkEffect(self, (input, out) => sync$2(() => test(input, out))));
11098
11036
  checkEffect = /*#__PURE__*/ dual(2, (self, test) => makeWithState(self.initial, (now, input, state) => flatMap$6(self.step(now, input, state), ([state, out, decision]) => {
11099
11037
  if (isDone(decision)) return succeed$8([
@@ -11160,7 +11098,7 @@ var init_schedule = __esmMin((() => {
11160
11098
  const intervals = decision.intervals;
11161
11099
  const delay = size$2(make$20(now, start$1(intervals)));
11162
11100
  return map$8(f(out, delay), (durationInput) => {
11163
- const duration = decode$2(durationInput);
11101
+ const duration = decode$1(durationInput);
11164
11102
  const oldStart = start$1(intervals);
11165
11103
  const newStart = now + toMillis(duration);
11166
11104
  const delta = newStart - oldStart;
@@ -13602,7 +13540,7 @@ var init_rcRef = __esmMin((() => {
13602
13540
  make$12 = (options) => withFiberRuntime$1((fiber) => {
13603
13541
  const context = fiber.getFiberRef(currentContext$1);
13604
13542
  const scope = get$8(context, scopeTag);
13605
- const ref = new RcRefImpl(options.acquire, context, scope, options.idleTimeToLive ? decode$2(options.idleTimeToLive) : void 0);
13543
+ const ref = new RcRefImpl(options.acquire, context, scope, options.idleTimeToLive ? decode$1(options.idleTimeToLive) : void 0);
13606
13544
  return as$1(scope.addFinalizer(() => ref.semaphore.withPermits(1)(suspend$7(() => {
13607
13545
  const close = ref.state._tag === "Acquired" ? scopeClose(ref.state.scope, exitVoid$1) : void_$4;
13608
13546
  ref.state = stateClosed;
@@ -14288,7 +14226,7 @@ function getBrands(ast) {
14288
14226
  onSome: (brands) => brands.map((brand) => ` & Brand<${formatUnknown(brand)}>`).join("")
14289
14227
  });
14290
14228
  }
14291
- var TypeConstructorAnnotationId, BrandAnnotationId, SchemaIdAnnotationId, MessageAnnotationId, MissingMessageAnnotationId, IdentifierAnnotationId, TitleAnnotationId, AutoTitleAnnotationId, DescriptionAnnotationId, ExamplesAnnotationId, DefaultAnnotationId, JSONSchemaAnnotationId, ArbitraryAnnotationId, PrettyAnnotationId, EquivalenceAnnotationId, DocumentationAnnotationId, ConcurrencyAnnotationId, BatchingAnnotationId, ParseIssueTitleAnnotationId, ParseOptionsAnnotationId, DecodingFallbackAnnotationId, SurrogateAnnotationId, StableFilterAnnotationId, getAnnotation, getBrandAnnotation, getMessageAnnotation, getMissingMessageAnnotation, getTitleAnnotation, getAutoTitleAnnotation, getIdentifierAnnotation, getDescriptionAnnotation, getConcurrencyAnnotation, getBatchingAnnotation, getParseIssueTitleAnnotation$1, getParseOptionsAnnotation, getDecodingFallbackAnnotation, getSurrogateAnnotation, getStableFilterAnnotation, hasStableFilter, JSONIdentifierAnnotationId, getJSONIdentifierAnnotation, getJSONIdentifier, Declaration, createASTGuard, Literal$1, isLiteral, $null, UniqueSymbol, UndefinedKeyword, undefinedKeyword, NeverKeyword, neverKeyword, UnknownKeyword, unknownKeyword, AnyKeyword, anyKeyword, StringKeyword, stringKeyword, isStringKeyword, NumberKeyword, numberKeyword, isNumberKeyword, BooleanKeyword, booleanKeyword, isBooleanKeyword, BigIntKeyword, bigIntKeyword, SymbolKeyword, symbolKeyword, isSymbolKeyword, Type$1, OptionalType, getRestASTs, TupleType, formatTuple, PropertySignature, isParameter, IndexSignature, TypeLiteral, formatIndexSignatures, formatTypeLiteral, isTypeLiteral, sortCandidates, literalMap, flatten$2, unify, Union$1, mapMembers, isMembers, isUnion, toJSONMemoMap, Suspend, Refinement$1, isRefinement$1, defaultParseOption, Transformation$1, isTransformation$1, FinalTransformation, createTransformationGuard, ComposeTransformation, composeTransformation, PropertySignatureTransformation$1, TypeLiteralTransformation, isTypeLiteralTransformation, annotations, STRING_KEYWORD_PATTERN, NUMBER_KEYWORD_PATTERN, getTemplateLiteralSpanTypePattern, handleTemplateLiteralSpanTypeParens, getTemplateLiteralPattern, getTemplateLiteralRegExp, record$2, pickAnnotations, omitAnnotations, preserveTransformationAnnotations, typeAST, getTransformationFrom, encodedAST_, encodedAST, toJSONAnnotations, getEncodedParameter, formatKeyword, getOrElseExpected, getExpected;
14229
+ var TypeConstructorAnnotationId, BrandAnnotationId, SchemaIdAnnotationId, MessageAnnotationId, MissingMessageAnnotationId, IdentifierAnnotationId, TitleAnnotationId, AutoTitleAnnotationId, DescriptionAnnotationId, ExamplesAnnotationId, DefaultAnnotationId, JSONSchemaAnnotationId, ArbitraryAnnotationId, PrettyAnnotationId, EquivalenceAnnotationId, DocumentationAnnotationId, ConcurrencyAnnotationId, BatchingAnnotationId, ParseIssueTitleAnnotationId, ParseOptionsAnnotationId, DecodingFallbackAnnotationId, SurrogateAnnotationId, StableFilterAnnotationId, getAnnotation, getBrandAnnotation, getMessageAnnotation, getMissingMessageAnnotation, getTitleAnnotation, getAutoTitleAnnotation, getIdentifierAnnotation, getDescriptionAnnotation, getConcurrencyAnnotation, getBatchingAnnotation, getParseIssueTitleAnnotation$1, getParseOptionsAnnotation, getDecodingFallbackAnnotation, getSurrogateAnnotation, getStableFilterAnnotation, hasStableFilter, JSONIdentifierAnnotationId, getJSONIdentifierAnnotation, getJSONIdentifier, Declaration, createASTGuard, Literal$1, isLiteral, UniqueSymbol, UndefinedKeyword, undefinedKeyword, NeverKeyword, neverKeyword, UnknownKeyword, unknownKeyword, AnyKeyword, anyKeyword, StringKeyword, stringKeyword, isStringKeyword, NumberKeyword, numberKeyword, isNumberKeyword, BooleanKeyword, booleanKeyword, isBooleanKeyword, BigIntKeyword, bigIntKeyword, SymbolKeyword, symbolKeyword, isSymbolKeyword, Type$1, OptionalType, getRestASTs, TupleType, formatTuple, PropertySignature, isParameter, IndexSignature, TypeLiteral, formatIndexSignatures, formatTypeLiteral, isTypeLiteral, sortCandidates, literalMap, flatten$2, unify, Union$1, mapMembers, isMembers, isUnion, toJSONMemoMap, Suspend, Refinement$1, isRefinement$1, defaultParseOption, Transformation$1, isTransformation$1, FinalTransformation, createTransformationGuard, ComposeTransformation, composeTransformation, PropertySignatureTransformation$1, TypeLiteralTransformation, isTypeLiteralTransformation, annotations, STRING_KEYWORD_PATTERN, NUMBER_KEYWORD_PATTERN, getTemplateLiteralSpanTypePattern, handleTemplateLiteralSpanTypeParens, getTemplateLiteralPattern, getTemplateLiteralRegExp, record$2, pickAnnotations, omitAnnotations, preserveTransformationAnnotations, typeAST, getTransformationFrom, encodedAST_, encodedAST, toJSONAnnotations, getEncodedParameter, formatKeyword, getOrElseExpected, getExpected;
14292
14230
  var init_SchemaAST = __esmMin((() => {
14293
14231
  init_Array();
14294
14232
  init_Function();
@@ -14405,7 +14343,6 @@ var init_SchemaAST = __esmMin((() => {
14405
14343
  }
14406
14344
  };
14407
14345
  isLiteral = /*#__PURE__*/ createASTGuard("Literal");
14408
- $null = /*#__PURE__*/ new Literal$1(null);
14409
14346
  UniqueSymbol = class {
14410
14347
  symbol;
14411
14348
  annotations;
@@ -15438,7 +15375,7 @@ function getDefaultTypeMessage(issue) {
15438
15375
  if (issue.message !== void 0) return issue.message;
15439
15376
  return `Expected ${isRefinement$1(issue.ast) ? getRefinementExpected(issue.ast) : String(issue.ast)}, actual ${formatUnknown(issue.actual)}`;
15440
15377
  }
15441
- var Pointer, Unexpected, Missing, Composite, Refinement, Transformation, Type, Forbidden, ParseErrorTypeId, ParseError, parseError, succeed, fail$5, _try, fromOption, isEither, flatMap, map, mapError, mapBoth, orElse, mergeInternalOptions, getEither, getSync, getEffect, decodeUnknownSync, decodeUnknownEither$1, decodeUnknown$1, encodeUnknownSync, encodeUnknown, decodeSync, validateSync, is, encodeSync, decodeMemoMap, encodeMemoMap, goMemo, getConcurrency, getBatching, go, fromRefinement, getLiterals, getSearchTree, dropRightRefinement, handleForbidden, compare, getFinalTransformation, makeTree, TreeFormatter, drawTree, draw, formatTransformationKind, formatRefinementKind, getAnnotated, Either_void, getCurrentMessage, createParseIssueGuard, isComposite, isRefinement, isTransformation, getMessage$1, getParseIssueTitleAnnotation, formatTypeMessage, getParseIssueTitle, formatForbiddenMessage, formatUnexpectedMessage, formatMissingMessage, formatTree;
15378
+ var Pointer, Unexpected, Missing, Composite, Refinement, Transformation, Type, Forbidden, ParseErrorTypeId, ParseError, parseError, succeed, fail$5, _try, fromOption, isEither, flatMap, map, mapError, mapBoth, orElse, mergeInternalOptions, getEither, getSync, getEffect, decodeUnknownSync, decodeUnknown$1, encodeUnknownSync, encodeUnknown, decodeSync, validateSync, is, encodeSync, decodeMemoMap, encodeMemoMap, goMemo, getConcurrency, getBatching, go, fromRefinement, getLiterals, getSearchTree, dropRightRefinement, handleForbidden, compare, getFinalTransformation, makeTree, TreeFormatter, drawTree, draw, formatTransformationKind, formatRefinementKind, getAnnotated, Either_void, getCurrentMessage, createParseIssueGuard, isComposite, isRefinement, isTransformation, getMessage$1, getParseIssueTitleAnnotation, formatTypeMessage, getParseIssueTitle, formatForbiddenMessage, formatUnexpectedMessage, formatMissingMessage, formatTree;
15442
15379
  var init_ParseResult = __esmMin((() => {
15443
15380
  init_Array();
15444
15381
  init_Cause();
@@ -15657,7 +15594,6 @@ var init_ParseResult = __esmMin((() => {
15657
15594
  });
15658
15595
  };
15659
15596
  decodeUnknownSync = (schema, options) => getSync(schema.ast, true, options);
15660
- decodeUnknownEither$1 = (schema, options) => getEither(schema.ast, true, options);
15661
15597
  decodeUnknown$1 = (schema, options) => getEffect(schema.ast, true, options);
15662
15598
  encodeUnknownSync = (schema, options) => getSync(schema.ast, false, options);
15663
15599
  encodeUnknown = (schema, options) => getEffect(schema.ast, false, options);
@@ -16457,18 +16393,6 @@ function makeTypeLiteralClass(fields, records, ast = getDefaultTypeLiteralAST(fi
16457
16393
  function Struct(fields, ...records) {
16458
16394
  return makeTypeLiteralClass(fields, records);
16459
16395
  }
16460
- function makeRecordClass(key, value, ast) {
16461
- return class RecordClass extends makeTypeLiteralClass({}, [{
16462
- key,
16463
- value
16464
- }], ast) {
16465
- static annotations(annotations) {
16466
- return makeRecordClass(key, value, mergeSchemaAnnotations(this.ast, annotations));
16467
- }
16468
- static key = key;
16469
- static value = value;
16470
- };
16471
- }
16472
16396
  function makeRefineClass(from, filter, ast) {
16473
16397
  return class RefineClass extends make$8(ast) {
16474
16398
  static annotations(annotations) {
@@ -16559,7 +16483,7 @@ function causeEncode(cause) {
16559
16483
  };
16560
16484
  }
16561
16485
  }
16562
- var TypeId$7, variance, builtInAnnotations, toASTAnnotations, mergeSchemaAnnotations, format, encodedSchema, typeSchema, decodeUnknown, decodeUnknownEither, isSchema, declareConstructor, declarePrimitive, declare, InstanceOfSchemaId, instanceOf, Undefined, Null, Never, Unknown, BigIntFromSelf, SymbolFromSelf, String$, Number$, Boolean$, getDefaultUnionAST, NullOr, UndefinedOr, NullishOr, element, ElementImpl, getDefaultTupleTypeAST, Array$, formatPropertySignatureToken, PropertySignatureDeclaration, FromPropertySignature, ToPropertySignature, formatPropertyKey, PropertySignatureTransformation, mergeSignatureAnnotations, PropertySignatureTypeId, isPropertySignature, PropertySignatureImpl, makePropertySignature, PropertySignatureWithFromImpl, propertySignature, withConstructorDefault, optionalToRequired, optionalToOptional, optionalPropertySignatureAST, optional$2, optionalWith, preserveMissingMessageAnnotation, getDefaultTypeLiteralAST, lazilyMergeDefaults, tag$2, TaggedStruct, Record, intersectTypeLiterals, preserveRefinementAnnotations, addRefinementToMembers, extendAST, getTypes, intersectUnionMembers, extend, suspend, RefineSchemaId, fromFilterPredicateReturnTypeItem, toFilterParseIssue, transformOrFail, transform$1, TrimmedSchemaId, trimmed, MinLengthSchemaId, minLength, LengthSchemaId, length, PatternSchemaId, pattern, LowercasedSchemaId, lowercased, Lowercased, UppercasedSchemaId, uppercased, Uppercased, CapitalizedSchemaId, capitalized, Capitalized, UncapitalizedSchemaId, uncapitalized, Uncapitalized, nonEmptyString, Trimmed, NonEmptyTrimmedString, getErrorMessage, UUIDSchemaId, uuidRegexp, ULIDSchemaId, ulidRegexp, URLFromSelf, FiniteSchemaId, finite, GreaterThanSchemaId, greaterThan, GreaterThanOrEqualToSchemaId, greaterThanOrEqualTo, IntSchemaId, int, LessThanSchemaId, lessThan, LessThanOrEqualToSchemaId, lessThanOrEqualTo, BetweenSchemaId, between, NonNaNSchemaId, nonNaN, positive, negative, nonPositive, nonNegative, Int, NonNegative, JsonNumberSchemaId, encodeSymbol, decodeSymbol, GreaterThanOrEqualToBigIntSchemaId, greaterThanOrEqualToBigInt, BetweenBigIntSchemaId, betweenBigInt, nonNegativeBigInt, BigInt$, NonNegativeBigIntFromSelf, toComposite, DurationFromSelf, NonNegativeInt, DurationValueMillis, DurationValueNanos, DurationValueInfinity, durationValueInfinity, DurationValue, HRTime, isDurationValue, Uint8ArrayFromSelf, Uint8, ValidDateSchemaId, validDate, DateFromSelfSchemaId, DateFromSelf, DateFromString, DateTimeUtcFromSelf, decodeDateTimeUtc, timeZoneOffsetArbitrary, TimeZoneOffsetFromSelf, timeZoneNamedArbitrary, TimeZoneNamedFromSelf, TimeZoneFromSelf, timeZoneArbitrary, DateTimeZonedFromSelf, optionDecode, optionArbitrary, optionPretty, optionParse, OptionFromSelf_, OptionFromSelf, bigDecimalPretty, bigDecimalArbitrary, BigDecimalFromSelf, isField, isFields, getFields, getSchemaFromFieldsOr, getFieldsFromFieldsOr, getClassTag, TaggedError, extendFields, astCache, getClassAnnotations, makeClass, FiberIdEncoded, fiberIdArbitrary, fiberIdPretty, FiberIdFromSelf, fiberIdDecode, fiberIdEncode, causeDieEncoded, CauseEmptyEncoded, causeFailEncoded, CauseInterruptEncoded, causeEncodedId, causeEncoded, causeArbitrary, causePretty, causeParse, CauseFromSelf, Cause, Defect, SymbolStruct, SymbolFromStruct, PropertyKey$;
16486
+ var TypeId$7, variance, builtInAnnotations, toASTAnnotations, mergeSchemaAnnotations, format, encodedSchema, typeSchema, decodeUnknown, isSchema, declareConstructor, declarePrimitive, declare, InstanceOfSchemaId, instanceOf, Undefined, Never, Unknown, BigIntFromSelf, SymbolFromSelf, String$, Number$, Boolean$, getDefaultUnionAST, UndefinedOr, element, ElementImpl, getDefaultTupleTypeAST, Array$, formatPropertySignatureToken, PropertySignatureDeclaration, ToPropertySignature, formatPropertyKey, PropertySignatureTransformation, mergeSignatureAnnotations, PropertySignatureTypeId, isPropertySignature, PropertySignatureImpl, makePropertySignature, PropertySignatureWithFromImpl, propertySignature, withConstructorDefault, optional$1, preserveMissingMessageAnnotation, getDefaultTypeLiteralAST, lazilyMergeDefaults, tag$2, TaggedStruct, intersectTypeLiterals, preserveRefinementAnnotations, addRefinementToMembers, extendAST, getTypes, intersectUnionMembers, extend, suspend, RefineSchemaId, fromFilterPredicateReturnTypeItem, toFilterParseIssue, transformOrFail, transform$1, TrimmedSchemaId, trimmed, MinLengthSchemaId, minLength, LengthSchemaId, length, PatternSchemaId, pattern, LowercasedSchemaId, lowercased, Lowercased, UppercasedSchemaId, uppercased, Uppercased, CapitalizedSchemaId, capitalized, Capitalized, UncapitalizedSchemaId, uncapitalized, Uncapitalized, nonEmptyString, Trimmed, NonEmptyTrimmedString, getErrorMessage, UUIDSchemaId, uuidRegexp, ULIDSchemaId, ulidRegexp, URLFromSelf, FiniteSchemaId, finite, GreaterThanSchemaId, greaterThan, GreaterThanOrEqualToSchemaId, greaterThanOrEqualTo, IntSchemaId, int, LessThanSchemaId, lessThan, LessThanOrEqualToSchemaId, lessThanOrEqualTo, BetweenSchemaId, between, NonNaNSchemaId, nonNaN, positive, negative, nonPositive, nonNegative, Int, NonNegative, JsonNumberSchemaId, encodeSymbol, decodeSymbol, GreaterThanOrEqualToBigIntSchemaId, greaterThanOrEqualToBigInt, BetweenBigIntSchemaId, betweenBigInt, nonNegativeBigInt, BigInt$, NonNegativeBigIntFromSelf, toComposite, DurationFromSelf, NonNegativeInt, DurationValueMillis, DurationValueNanos, DurationValueInfinity, durationValueInfinity, DurationValue, HRTime, isDurationValue, Uint8ArrayFromSelf, Uint8, ValidDateSchemaId, validDate, DateFromSelfSchemaId, DateFromSelf, DateFromString, DateTimeUtcFromSelf, decodeDateTimeUtc, timeZoneOffsetArbitrary, TimeZoneOffsetFromSelf, timeZoneNamedArbitrary, TimeZoneNamedFromSelf, TimeZoneFromSelf, timeZoneArbitrary, DateTimeZonedFromSelf, optionDecode, optionArbitrary, optionPretty, optionParse, OptionFromSelf_, OptionFromSelf, bigDecimalPretty, bigDecimalArbitrary, BigDecimalFromSelf, isField, isFields, getFields, getSchemaFromFieldsOr, getFieldsFromFieldsOr, getClassTag, TaggedError, extendFields, astCache, getClassAnnotations, makeClass, FiberIdEncoded, fiberIdArbitrary, fiberIdPretty, FiberIdFromSelf, fiberIdDecode, fiberIdEncode, causeDieEncoded, CauseEmptyEncoded, causeFailEncoded, CauseInterruptEncoded, causeEncodedId, causeEncoded, causeArbitrary, causePretty, causeParse, CauseFromSelf, Cause, Defect, SymbolStruct, SymbolFromStruct, PropertyKey$;
16563
16487
  var init_Schema = __esmMin((() => {
16564
16488
  init_Array();
16565
16489
  init_BigDecimal();
@@ -16569,7 +16493,6 @@ var init_Schema = __esmMin((() => {
16569
16493
  init_Data();
16570
16494
  init_DateTime();
16571
16495
  init_Duration();
16572
- init_Either();
16573
16496
  init_Equal();
16574
16497
  init_Equivalence();
16575
16498
  init_FiberId();
@@ -16636,10 +16559,6 @@ var init_Schema = __esmMin((() => {
16636
16559
  const decodeUnknown = decodeUnknown$1(schema, options);
16637
16560
  return (u, overrideOptions) => mapError(decodeUnknown(u, overrideOptions), parseError);
16638
16561
  };
16639
- decodeUnknownEither = (schema, options) => {
16640
- const decodeUnknownEither = decodeUnknownEither$1(schema, options);
16641
- return (u, overrideOptions) => mapLeft(decodeUnknownEither(u, overrideOptions), parseError);
16642
- };
16643
16562
  isSchema = (u) => hasProperty(u, TypeId$7) && isObject$3(u[TypeId$7]);
16644
16563
  declareConstructor = (typeParameters, options, annotations) => makeDeclareClass(typeParameters, new Declaration(typeParameters.map((tp) => tp.ast), (...typeParameters) => options.decode(...typeParameters.map(make$8)), (...typeParameters) => options.encode(...typeParameters.map(make$8)), toASTAnnotations(annotations)));
16645
16564
  declarePrimitive = (is, annotations) => {
@@ -16667,7 +16586,6 @@ var init_Schema = __esmMin((() => {
16667
16586
  ...annotations
16668
16587
  });
16669
16588
  Undefined = class extends make$8(undefinedKeyword) {};
16670
- Null = class extends make$8($null) {};
16671
16589
  Never = class extends make$8(neverKeyword) {};
16672
16590
  Unknown = class extends make$8(unknownKeyword) {};
16673
16591
  BigIntFromSelf = class extends make$8(bigIntKeyword) {};
@@ -16676,9 +16594,7 @@ var init_Schema = __esmMin((() => {
16676
16594
  Number$ = class extends make$8(numberKeyword) {};
16677
16595
  Boolean$ = class extends make$8(booleanKeyword) {};
16678
16596
  getDefaultUnionAST = (members) => Union$1.make(members.map((m) => m.ast));
16679
- NullOr = (self) => Union(self, Null);
16680
16597
  UndefinedOr = (self) => Union(self, Undefined);
16681
- NullishOr = (self) => Union(self, Null, Undefined);
16682
16598
  element = (self) => new ElementImpl(new OptionalType(self.ast, false), self);
16683
16599
  ElementImpl = class ElementImpl {
16684
16600
  ast;
@@ -16723,15 +16639,6 @@ var init_Schema = __esmMin((() => {
16723
16639
  return `PropertySignature<${token}, ${type}, never, ${token}, ${type}>`;
16724
16640
  }
16725
16641
  };
16726
- FromPropertySignature = class extends OptionalType {
16727
- isReadonly;
16728
- fromKey;
16729
- constructor(type, isOptional, isReadonly, annotations, fromKey) {
16730
- super(type, isOptional, annotations);
16731
- this.isReadonly = isReadonly;
16732
- this.fromKey = fromKey;
16733
- }
16734
- };
16735
16642
  ToPropertySignature = class extends OptionalType {
16736
16643
  isReadonly;
16737
16644
  defaultValue;
@@ -16822,80 +16729,10 @@ var init_Schema = __esmMin((() => {
16822
16729
  case "PropertySignatureTransformation": return makePropertySignature(new PropertySignatureTransformation(ast.from, new ToPropertySignature(ast.to.type, ast.to.isOptional, ast.to.isReadonly, ast.to.annotations, defaultValue), ast.decode, ast.encode));
16823
16730
  }
16824
16731
  });
16825
- optionalToRequired = (from, to, options) => makePropertySignature(new PropertySignatureTransformation(new FromPropertySignature(from.ast, true, true, {}, void 0), new ToPropertySignature(to.ast, false, true, {}, void 0), (o) => some(options.decode(o)), flatMap$9(options.encode)));
16826
- optionalToOptional = (from, to, options) => makePropertySignature(new PropertySignatureTransformation(new FromPropertySignature(from.ast, true, true, {}, void 0), new ToPropertySignature(to.ast, true, true, {}, void 0), options.decode, options.encode));
16827
- optionalPropertySignatureAST = (self, options) => {
16828
- const isExact = options?.exact;
16829
- const defaultValue = options?.default;
16830
- const isNullable = options?.nullable;
16831
- const asOption = options?.as == "Option";
16832
- const asOptionEncode = options?.onNoneEncoding ? orElse$3(options.onNoneEncoding) : identity$1;
16833
- if (isExact) if (defaultValue) if (isNullable) return withConstructorDefault(optionalToRequired(NullOr(self), typeSchema(self), {
16834
- decode: match$8({
16835
- onNone: defaultValue,
16836
- onSome: (a) => a === null ? defaultValue() : a
16837
- }),
16838
- encode: some
16839
- }), defaultValue).ast;
16840
- else return withConstructorDefault(optionalToRequired(self, typeSchema(self), {
16841
- decode: match$8({
16842
- onNone: defaultValue,
16843
- onSome: identity$1
16844
- }),
16845
- encode: some
16846
- }), defaultValue).ast;
16847
- else if (asOption) {
16848
- const to = OptionFromSelf_(typeSchema(self));
16849
- if (isNullable) return optionalToRequired(NullOr(self), to, {
16850
- decode: filter$3(isNotNull),
16851
- encode: asOptionEncode
16852
- }).ast;
16853
- else return optionalToRequired(self, to, {
16854
- decode: identity$1,
16855
- encode: identity$1
16856
- }).ast;
16857
- } else if (isNullable) return optionalToOptional(NullOr(self), typeSchema(self), {
16858
- decode: filter$3(isNotNull),
16859
- encode: identity$1
16860
- }).ast;
16861
- else return new PropertySignatureDeclaration(self.ast, true, true, {}, void 0);
16862
- else if (defaultValue) if (isNullable) return withConstructorDefault(optionalToRequired(NullishOr(self), typeSchema(self), {
16863
- decode: match$8({
16864
- onNone: defaultValue,
16865
- onSome: (a) => a == null ? defaultValue() : a
16866
- }),
16867
- encode: some
16868
- }), defaultValue).ast;
16869
- else return withConstructorDefault(optionalToRequired(UndefinedOr(self), typeSchema(self), {
16870
- decode: match$8({
16871
- onNone: defaultValue,
16872
- onSome: (a) => a === void 0 ? defaultValue() : a
16873
- }),
16874
- encode: some
16875
- }), defaultValue).ast;
16876
- else if (asOption) {
16877
- const to = OptionFromSelf_(typeSchema(self));
16878
- if (isNullable) return optionalToRequired(NullishOr(self), to, {
16879
- decode: filter$3((a) => a != null),
16880
- encode: asOptionEncode
16881
- }).ast;
16882
- else return optionalToRequired(UndefinedOr(self), to, {
16883
- decode: filter$3(isNotUndefined),
16884
- encode: asOptionEncode
16885
- }).ast;
16886
- } else if (isNullable) return optionalToOptional(NullishOr(self), UndefinedOr(typeSchema(self)), {
16887
- decode: filter$3(isNotNull),
16888
- encode: identity$1
16889
- }).ast;
16890
- else return new PropertySignatureDeclaration(UndefinedOr(self).ast, true, true, {}, void 0);
16891
- };
16892
- optional$2 = (self) => {
16732
+ optional$1 = (self) => {
16893
16733
  const ast = self.ast === undefinedKeyword || self.ast === neverKeyword ? undefinedKeyword : UndefinedOr(self).ast;
16894
16734
  return new PropertySignatureWithFromImpl(new PropertySignatureDeclaration(ast, true, true, {}, void 0), self);
16895
16735
  };
16896
- optionalWith = /*#__PURE__*/ dual((args) => isSchema(args[0]), (self, options) => {
16897
- return new PropertySignatureWithFromImpl(optionalPropertySignatureAST(self, options), self);
16898
- });
16899
16736
  preserveMissingMessageAnnotation = /*#__PURE__*/ pickAnnotations([MissingMessageAnnotationId]);
16900
16737
  getDefaultTypeLiteralAST = (fields, records) => {
16901
16738
  const ownKeys = Reflect.ownKeys(fields);
@@ -16975,7 +16812,6 @@ var init_Schema = __esmMin((() => {
16975
16812
  _tag: tag$2(value),
16976
16813
  ...fields
16977
16814
  });
16978
- Record = (options) => makeRecordClass(options.key, options.value);
16979
16815
  intersectTypeLiterals = (x, y, path) => {
16980
16816
  if (isTypeLiteral(x) && isTypeLiteral(y)) {
16981
16817
  const propertySignatures = [...x.propertySignatures];
@@ -18256,8 +18092,8 @@ var init_Error = __esmMin((() => {
18256
18092
  BadArgument = class extends TaggedError("@effect/platform/Error/BadArgument")("BadArgument", {
18257
18093
  module: Module,
18258
18094
  method: String$,
18259
- description: /*#__PURE__*/ optional$2(String$),
18260
- cause: /*#__PURE__*/ optional$2(Defect)
18095
+ description: /*#__PURE__*/ optional$1(String$),
18096
+ cause: /*#__PURE__*/ optional$1(Defect)
18261
18097
  }) {
18262
18098
  /**
18263
18099
  * @since 1.0.0
@@ -18275,10 +18111,10 @@ var init_Error = __esmMin((() => {
18275
18111
  reason: SystemErrorReason,
18276
18112
  module: Module,
18277
18113
  method: String$,
18278
- description: /*#__PURE__*/ optional$2(String$),
18279
- syscall: /*#__PURE__*/ optional$2(String$),
18280
- pathOrDescriptor: /*#__PURE__*/ optional$2(/*#__PURE__*/ Union(String$, Number$)),
18281
- cause: /*#__PURE__*/ optional$2(Defect)
18114
+ description: /*#__PURE__*/ optional$1(String$),
18115
+ syscall: /*#__PURE__*/ optional$1(String$),
18116
+ pathOrDescriptor: /*#__PURE__*/ optional$1(/*#__PURE__*/ Union(String$, Number$)),
18117
+ cause: /*#__PURE__*/ optional$1(Defect)
18282
18118
  }) {
18283
18119
  /**
18284
18120
  * @since 1.0.0
@@ -20126,7 +19962,7 @@ var init_esm = __esmMin((() => {
20126
19962
  init_mergeStrategy();
20127
19963
  init_metric();
20128
19964
  init_boundaries();
20129
- init_hook();
19965
+ init_hook$1();
20130
19966
  init_key();
20131
19967
  init_keyType();
20132
19968
  init_label();
@@ -21117,8 +20953,15 @@ export CLAUDE_CODE_DISABLE_BACKGROUND_TASKS=1
21117
20953
  export BASH_DEFAULT_TIMEOUT_MS=1800000
21118
20954
  export BASH_MAX_TIMEOUT_MS=7200000
21119
20955
 
20956
+ # gtd's paths, scripts and checks are relative to the repository root.
20957
+ cd "$(git rev-parse --show-toplevel)"
20958
+
21120
20959
  beat=1
21121
20960
  while :; do
20961
+ cost=
20962
+ model=
20963
+ judged_before="\${judged:-}"
20964
+ judged=
21122
20965
  # One value per invocation: \`gtd next --json=<path>\` is a pure read (peek
21123
20966
  # or dispatch, indistinguishable, always safe to call again), so nothing is
21124
20967
  # lost by reading \`kind\`/\`idle\` as two separate calls rather than one
@@ -21146,14 +20989,22 @@ while :; do
21146
20989
  # \`gtd judge run\` and land the verdict via \`gtd judge answer\`. POSIX sh has
21147
20990
  # no pipefail, so each step is captured first and only piped on when it
21148
20991
  # succeeded; if \`gtd judge run\` fails or \`gtd judge answer\` rejects the
21149
- # verdict, its stderr reaches you and we fall through to the human hand-off.
20992
+ # verdict, its stderr reaches you and the gate is handed to you — on the
20993
+ # opening beat too, so it never lands unanswered — as it is when the gate
20994
+ # we just answered comes straight back.
21150
20995
  message)
21151
- if [ -n "$(gtd next --json=judge)" ] &&
21152
- verdict="$(gtd judge --json | gtd judge run)" &&
21153
- script="$(printf '%s\\n' "$verdict" | gtd judge answer --json=script)"; then
21154
- printf '%s\\n' "$script" | sh
21155
- beat=$((beat + 1))
21156
- continue
20996
+ if [ -n "$(gtd next --json=judge)" ]; then
20997
+ state="$(gtd next --json=state)"
20998
+ if [ "$state" != "$judged_before" ] &&
20999
+ verdict="$(gtd judge --json | gtd judge run)" &&
21000
+ script="$(printf '%s\\n' "$verdict" | gtd judge answer --json=script)"; then
21001
+ printf '%s\\n' "$script" | sh
21002
+ judged="$state"
21003
+ beat=$((beat + 1))
21004
+ continue
21005
+ fi
21006
+ gtd next
21007
+ exit 0
21157
21008
  fi
21158
21009
  [ "$beat" = 1 ] || {
21159
21010
  gtd next
@@ -21172,45 +21023,83 @@ while :; do
21172
21023
  model="$(gtd next --json=model)"
21173
21024
  system="$(gtd next --json=system)"
21174
21025
  validate="$(gtd next --json=validate)"
21026
+ context="$(gtd next --json=context)"
21175
21027
  log="$(gtd next --json=log)"
21028
+ # Absolute, since the hook runs wherever the agent last cd'ed to.
21029
+ case "$log" in /*) ;; *) log="$(git rev-parse --show-toplevel)/$log" ;; esac
21176
21030
  # \`model\` is a hint, not a model name — the bundled workflow ships
21177
21031
  # \`smart\` and \`base\`, which \`claude --model\` rejects. Resolve them
21178
- # with the variables \`gtd loop\` reads; unset, the hint is dropped and
21179
- # the agent runs its own default. Any other value is a real model name.
21032
+ # from your environment; unset, the hint is dropped and the agent runs
21033
+ # its own default. Any other value is a real model name.
21180
21034
  case "$model" in
21181
21035
  smart) model="\${GTD_LOOP_MODEL_SMART:-}" ;;
21182
21036
  base) model="\${GTD_LOOP_MODEL_BASE:-}" ;;
21183
21037
  esac
21184
- # The prompt embeds a full diff, so it goes to the agent over stdin,
21185
- # never as an argv positional — argv is capped (~1 MB on macOS, and
21186
- # POSIX guarantees only 4 KB, ARG_MAX), and a diff crosses that far
21187
- # sooner than you'd expect. Piping plain \`gtd next\` (not
21188
- # --json=content) means the diff is rendered once, for this input,
21189
- # rather than twice.
21190
- agent_turn() { gtd next | claude -p "$1" "$session_id" \\
21191
- \${model:+--model "$model"} \\
21192
- \${system:+--system-prompt "$system"} \\
21193
- --dangerously-skip-permissions >>"$log" 2>&1; }
21038
+ # The step's context limit, as a Claude Code hook after every tool
21039
+ # call and before compacting. Past \`hard\` it stops the turn and
21040
+ # appends why to the stop file, so we land nothing and stop too.
21041
+ soft="$(printf '%s' "$context" | sed -n 's/.*"soft":\\([0-9.]*\\).*/\\1/p')"
21042
+ hard="$(printf '%s' "$context" | sed -n 's/.*"hard":\\([0-9.]*\\).*/\\1/p')"
21043
+ window="\${GTD_LOOP_CONTEXT_WINDOW:-}"
21044
+ case "$model" in *'[1m]'* | *'[1M]'*) window="\${window:-1000000}" ;; esac
21045
+ hook="gtd context-hook\${soft:+ --soft $soft}\${hard:+ --hard $hard}\${window:+ --window $window}"
21046
+ hooks="[{\\"hooks\\":[{\\"type\\":\\"command\\",\\"command\\":\\"$hook\\"}]}]"
21047
+ settings="{\\"hooks\\":{\\"PostToolUse\\":$hooks,\\"PreCompact\\":$hooks}}"
21048
+ stop="$log.context-stop"
21049
+ rm -f "$stop"
21050
+ # One turn, its prompt on stdin. The prompt embeds a full diff, so it
21051
+ # never goes on argv — argv is capped (~1 MB on macOS, and POSIX
21052
+ # guarantees only 4 KB, ARG_MAX), and a diff crosses that far sooner
21053
+ # than you'd expect. Every turn passes the same $model/$system:
21054
+ # whether \`claude --resume\` re-applies the original session's is a
21055
+ # harness detail gtd cannot verify from outside. Its JSON envelope
21056
+ # goes to the log, and its \`total_cost_usd\` adds up into $cost. An
21057
+ # \`is_error\` envelope (max turns, an error mid-turn) or one another
21058
+ # hook stopped fails the turn even at exit 0: landing it would land
21059
+ # the failure as work. Only a turn that never ran (no envelope: the
21060
+ # session flag was refused) is worth retrying under the other flag.
21061
+ turn() {
21062
+ out="$(GTD_LOOP_CONTEXT_STOP_FILE="$stop" claude -p "$@" \\
21063
+ \${model:+--model "$model"} \\
21064
+ \${system:+--system-prompt "$system"} \\
21065
+ --settings "$settings" --output-format json \\
21066
+ --dangerously-skip-permissions 2>>"$log")" && ok=0 || ok=$?
21067
+ printf '%s\\n' "$out" >>"$log"
21068
+ case "$out" in *'"type":"result"'*) ran=true ;; *) ran=false ;; esac
21069
+ case "$out" in
21070
+ *'"is_error":true'* | *'"terminal_reason":"hook_stopped"'*) ok=1 ;;
21071
+ esac
21072
+ usd="$(printf '%s\\n' "$out" | sed -n 's/.*"total_cost_usd":\\([0-9.eE+-]*\\).*/\\1/p' | tail -n 1)"
21073
+ [ -z "$usd" ] || cost="$(awk -v a="\${cost:-0}" -v b="$usd" 'BEGIN { printf "%.6f", a + b }')"
21074
+ [ "\${cost:-}" != 0.000000 ] || cost=
21075
+ if [ -s "$stop" ]; then
21076
+ cat "$stop" >&2
21077
+ exit 1
21078
+ fi
21079
+ return "$ok"
21080
+ }
21081
+ # Plain \`gtd next\` (not --json=content) renders the diff once.
21082
+ gtd next >"$log.prompt"
21194
21083
  if [ "\${resume:-}" = true ]
21195
- then agent_turn --resume || agent_turn --session-id
21196
- else agent_turn --session-id || agent_turn --resume
21084
+ then first=--resume second=--session-id
21085
+ else first=--session-id second=--resume
21197
21086
  fi
21087
+ turn "$first" "$session_id" <"$log.prompt" ||
21088
+ { [ "$ran" = false ] && turn "$second" "$session_id" <"$log.prompt"; } || {
21089
+ echo "agent turn failed — see $log" >&2
21090
+ exit 1
21091
+ }
21198
21092
  n=0
21199
21093
  while [ -n "\${validate:-}" ] && ! fix="$(sh -c "$validate" 2>&1)"; do
21200
21094
  n=$((n + 1)) && [ "$n" -gt 3 ] && { printf '%s\\n' "$fix" >&2; exit 1; }
21201
- # $fix IS the fix prompt, verbatim — piped for the same reason the
21202
- # agent's own turn above is. Whether \`claude --resume\` re-applies the
21203
- # original session's model/system prompt is a harness detail gtd
21204
- # cannot verify from outside, so this passes the identical
21205
- # $model/$system on both calls rather than assume it does —
21206
- # otherwise this fix turn might silently fall back to Claude Code's
21207
- # own defaults while the turn that produced the file ran under the
21208
- # workflow's own model and persona.
21209
- printf '%s' "$fix" | claude -p --resume "$session_id" \\
21210
- \${model:+--model "$model"} \\
21211
- \${system:+--system-prompt "$system"} \\
21212
- --dangerously-skip-permissions >>"$log" 2>&1
21213
- done ;;
21095
+ # $fix IS the fix prompt, verbatim.
21096
+ printf '%s' "$fix" >"$log.prompt"
21097
+ turn --resume "$session_id" <"$log.prompt" || {
21098
+ echo "fix turn failed — see $log" >&2
21099
+ exit 1
21100
+ }
21101
+ done
21102
+ rm -f "$log.prompt" ;;
21214
21103
  esac
21215
21104
 
21216
21105
  # Read every value the landing needs BEFORE piping the script to \`sh\`:
@@ -21220,7 +21109,8 @@ while :; do
21220
21109
  # before the script runs and changes the tree out from under them.
21221
21110
  settled="$(gtd land --json=settled)"
21222
21111
  idle="$(gtd land --json=idle)"
21223
- gtd land --json=script | sh
21112
+ # A prompt beat's turns record their cost, tagged with the model that ran.
21113
+ gtd land --json=script \${cost:+--cost="$cost"} \${cost:+\${model:+--model="$model"}} | sh
21224
21114
  if [ "\${settled:-}" = true ]; then
21225
21115
  [ "\${idle:-}" = true ] && gtd next
21226
21116
  exit 0
@@ -21921,15 +21811,15 @@ const openQuestions = (text) => ctx().openQuestions(text);
21921
21811
  //#endregion
21922
21812
  //#region src/flows/scripts.ts
21923
21813
  /** POSIX single-quoting: `value` survives the shell as one word, verbatim. */
21924
- const quote$1 = (value) => `'${value.replace(/'/g, "'\\''")}'`;
21925
- const removal = (paths) => paths.length === 0 ? [] : [`rm -rf -- ${paths.map(quote$1).join(" ")}`];
21814
+ const quote = (value) => `'${value.replace(/'/g, "'\\''")}'`;
21815
+ const removal = (paths) => paths.length === 0 ? [] : [`rm -rf -- ${paths.map(quote).join(" ")}`];
21926
21816
  /**
21927
21817
  * Run `command` and keep its outcome in the tree: on failure its output (or
21928
21818
  * a note that there was none) lands in `report`, on success `report` goes.
21929
21819
  */
21930
21820
  const checkScript = (command, options) => {
21931
- const report = quote$1(options.report);
21932
- const output = quote$1(`${options.report}.output`);
21821
+ const report = quote(options.report);
21822
+ const output = quote(`${options.report}.output`);
21933
21823
  return [
21934
21824
  "#!/usr/bin/env sh",
21935
21825
  "set +e",
@@ -21947,7 +21837,7 @@ const checkScript = (command, options) => {
21947
21837
  ` rm -f ${output}`,
21948
21838
  ` printf 'the test command failed with exit code %s and produced no output.' "$code" > ${report}`,
21949
21839
  " fi",
21950
- ` printf '\\n<!-- gtd check %s -->\\n' ${quote$1(options.stamp)} >> ${report}`,
21840
+ ` printf '\\n<!-- gtd check %s -->\\n' ${quote(options.stamp)} >> ${report}`,
21951
21841
  "else",
21952
21842
  ` rm -f ${output} ${report}`,
21953
21843
  ...removal(options.sweepOnGreen ?? []).map((line) => ` ${line}`),
@@ -21956,21 +21846,21 @@ const checkScript = (command, options) => {
21956
21846
  ].join("\n");
21957
21847
  };
21958
21848
  const patchScript = (commit, report, failure, reverse, exclude = []) => {
21959
- const paths = exclude.length === 0 ? "" : ` . ${exclude.map((p) => quote$1(`:(exclude,literal)${p}`)).join(" ")}`;
21960
- const range = `${quote$1(`${commit}^`)} ${quote$1(commit)}`;
21961
- const error = quote$1(`${report}.output`);
21849
+ const paths = exclude.length === 0 ? "" : ` . ${exclude.map((p) => quote(`:(exclude,literal)${p}`)).join(" ")}`;
21850
+ const range = `${quote(`${commit}^`)} ${quote(commit)}`;
21851
+ const error = quote(`${report}.output`);
21962
21852
  return [
21963
21853
  "#!/usr/bin/env sh",
21964
21854
  "set +e",
21965
21855
  `if ! git diff --quiet ${range} --${paths}; then`,
21966
- ` mkdir -p "$(dirname ${quote$1(report)})"`,
21856
+ ` mkdir -p "$(dirname ${quote(report)})"`,
21967
21857
  ` git diff --binary --no-color --no-ext-diff --no-textconv --src-prefix=a/ --dst-prefix=b/ ${range} --${paths} | git apply --whitespace=nowarn${reverse ? " -R" : ""} 2> ${error}`,
21968
21858
  " code=$?",
21969
21859
  " if [ \"$code\" -ne 0 ]; then",
21970
21860
  " {",
21971
- ` printf '%s\\n\\n' ${quote$1(failure)}`,
21861
+ ` printf '%s\\n\\n' ${quote(failure)}`,
21972
21862
  ` if [ -s ${error} ]; then cat ${error}; else printf '${reverse ? "Reverting" : "Applying"} it exited %s and produced no output.\\n' "$code"; fi`,
21973
- ` } > ${quote$1(report)}`,
21863
+ ` } > ${quote(report)}`,
21974
21864
  " fi",
21975
21865
  ` rm -f ${error}`,
21976
21866
  "fi",
@@ -21991,12 +21881,12 @@ const applyScript = (commit, report, failure, exclude = []) => patchScript(commi
21991
21881
  * still exactly as `commit` left it. A path changed since is left alone.
21992
21882
  */
21993
21883
  const restoreScript = (commit, paths, source) => {
21994
- const unchanged = (path) => `git diff --quiet ${quote$1(commit)} -- ${quote$1(path)}`;
21884
+ const unchanged = (path) => `git diff --quiet ${quote(commit)} -- ${quote(path)}`;
21995
21885
  return [
21996
21886
  "#!/usr/bin/env sh",
21997
21887
  "set +e",
21998
- ...paths.restore.map((path) => `${unchanged(path)} && git restore --source=${quote$1(source ?? `${commit}~1`)} --worktree -- ${quote$1(path)}`),
21999
- ...paths.remove.map((path) => `${unchanged(path)} && rm -f -- ${quote$1(path)}`),
21888
+ ...paths.restore.map((path) => `${unchanged(path)} && git restore --source=${quote(source ?? `${commit}~1`)} --worktree -- ${quote(path)}`),
21889
+ ...paths.remove.map((path) => `${unchanged(path)} && rm -f -- ${quote(path)}`),
22000
21890
  ""
22001
21891
  ].join("\n");
22002
21892
  };
@@ -22010,8 +21900,8 @@ const removeScript = (paths) => [
22010
21900
  const writeScript = (path, content, remove = []) => [
22011
21901
  "#!/usr/bin/env sh",
22012
21902
  "set -e",
22013
- `mkdir -p "$(dirname ${quote$1(path)})"`,
22014
- `printf '%s' ${quote$1(content)} > ${quote$1(path)}`,
21903
+ `mkdir -p "$(dirname ${quote(path)})"`,
21904
+ `printf '%s' ${quote(content)} > ${quote(path)}`,
22015
21905
  ...removal(remove),
22016
21906
  ""
22017
21907
  ].join("\n");
@@ -22019,15 +21909,15 @@ const writeScript = (path, content, remove = []) => [
22019
21909
  const moveScript = (from, to) => [
22020
21910
  "#!/usr/bin/env sh",
22021
21911
  "set -e",
22022
- `mkdir -p "$(dirname ${quote$1(to)})"`,
22023
- `mv -- ${quote$1(from)} ${quote$1(to)}`,
21912
+ `mkdir -p "$(dirname ${quote(to)})"`,
21913
+ `mv -- ${quote(from)} ${quote(to)}`,
22024
21914
  ""
22025
21915
  ].join("\n");
22026
21916
  /** Write `path` as committed at `ref` to `to`. */
22027
21917
  const showScript = (ref, path, to) => [
22028
21918
  "#!/usr/bin/env sh",
22029
21919
  "set -e",
22030
- `git show ${quote$1(`${ref}:${path}`)} > ${quote$1(to)}`,
21920
+ `git show ${quote(`${ref}:${path}`)} > ${quote(to)}`,
22031
21921
  ""
22032
21922
  ].join("\n");
22033
21923
  //#endregion
@@ -22390,7 +22280,7 @@ var flows_exports = /* @__PURE__ */ __exportAll({
22390
22280
  numeric: () => numeric,
22391
22281
  openQuestions: () => openQuestions,
22392
22282
  protocolMismatch: () => protocolMismatch,
22393
- quote: () => quote$1,
22283
+ quote: () => quote,
22394
22284
  read: () => read,
22395
22285
  refuse: () => refuse,
22396
22286
  removeScript: () => removeScript,
@@ -31643,7 +31533,7 @@ var init_micromark = __esmMin((() => {
31643
31533
  * Decoded value.
31644
31534
  */
31645
31535
  function decodeString(value) {
31646
- return value.replace(characterEscapeOrReference, decode$1);
31536
+ return value.replace(characterEscapeOrReference, decode);
31647
31537
  }
31648
31538
  /**
31649
31539
  * @param {string} $0
@@ -31655,7 +31545,7 @@ function decodeString(value) {
31655
31545
  * @returns {string}
31656
31546
  * Decoded value
31657
31547
  */
31658
- function decode$1($0, $1, $2) {
31548
+ function decode($0, $1, $2) {
31659
31549
  if ($1) return $1;
31660
31550
  if ($2.charCodeAt(0) === 35) {
31661
31551
  const head = $2.charCodeAt(1);
@@ -38021,7 +37911,7 @@ const isVerdict = (value) => {
38021
37911
  "boolean"
38022
37912
  ].includes(typeof v.answer) && typeof v.p === "number";
38023
37913
  };
38024
- const parseJson$1 = (raw) => {
37914
+ const parseJson = (raw) => {
38025
37915
  try {
38026
37916
  return JSON.parse(raw);
38027
37917
  } catch {
@@ -38035,11 +37925,11 @@ const CONFIG_RE = /^([0-9a-f]{16}) (.+)$/;
38035
37925
  const CONTROL_CHARACTER$1 = /[\x00-\x1f\x7f-\x9f\u2028\u2029]/;
38036
37926
  const encodePath = (path) => path.trim() !== path || path.startsWith("\"") || CONTROL_CHARACTER$1.test(path) ? JSON.stringify(path) : path;
38037
37927
  const decodePath = (raw) => {
38038
- const path = raw.startsWith("\"") ? parseJson$1(raw) : raw;
37928
+ const path = raw.startsWith("\"") ? parseJson(raw) : raw;
38039
37929
  return typeof path === "string" && path !== "" && !CONTROL_CHARACTER$1.test(path) ? path : void 0;
38040
37930
  };
38041
37931
  const decodeApproval = (raw) => {
38042
- const parsed = parseJson$1(raw);
37932
+ const parsed = parseJson(raw);
38043
37933
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return void 0;
38044
37934
  const { step, name, email } = parsed;
38045
37935
  if (typeof step !== "string" || typeof name !== "string" || typeof email !== "string") return void 0;
@@ -38075,7 +37965,7 @@ const TRAILER_READERS = {
38075
37965
  if (value !== "") into.workflow ??= value;
38076
37966
  },
38077
37967
  "Gtd-Judge": (value, into) => {
38078
- const parsed = parseJson$1(value);
37968
+ const parsed = parseJson(value);
38079
37969
  if (isVerdict(parsed)) into.judge.push(parsed);
38080
37970
  },
38081
37971
  "Gtd-Mark": (value, into) => {
@@ -40146,31 +40036,31 @@ const judgeDocument = (step) => step.request.kind === "judge" ? judgeJson(step.r
40146
40036
  */
40147
40037
  const TRUNCATION_NOTICE = "Note: some evidence above was truncated to fit the judge's payload budget.";
40148
40038
  const DEFAULT_JUDGE_MESSAGE = "A judgment is pending. Run `gtd judge answer` and pipe a verdict, or land to take the conservative default with no verdict recorded.";
40149
- const optional$1 = (key, value) => value === void 0 ? {} : { [key]: value };
40039
+ const optional = (key, value) => value === void 0 ? {} : { [key]: value };
40150
40040
  const commonOf = (step) => {
40151
40041
  const options = step.request.options;
40152
40042
  return {
40153
40043
  actor: step.actor,
40154
- ...optional$1("label", options.label),
40155
- ...optional$1("file", options.file),
40156
- ...optional$1("mode", options.mode)
40044
+ ...optional("label", options.label),
40045
+ ...optional("file", options.file),
40046
+ ...optional("mode", options.mode)
40157
40047
  };
40158
40048
  };
40159
40049
  const stepContext = (context) => context === void 0 ? void 0 : {
40160
- ...optional$1("soft", context.soft),
40161
- ...optional$1("hard", context.hard)
40050
+ ...optional("soft", context.soft),
40051
+ ...optional("hard", context.hard)
40162
40052
  };
40163
40053
  const promptDef = (common, request, skills, access) => ({
40164
40054
  ...common,
40165
40055
  kind: "prompt",
40166
40056
  content: request.prompt,
40167
- ...optional$1("model", request.options.model),
40168
- ...optional$1("system", request.options.system),
40169
- ...optional$1("allowEmpty", request.options.allowEmpty),
40170
- ...optional$1("keep", request.options.keep),
40171
- ...optional$1("context", stepContext(request.options.context)),
40172
- ...optional$1("skills", skills),
40173
- ...optional$1("access", access)
40057
+ ...optional("model", request.options.model),
40058
+ ...optional("system", request.options.system),
40059
+ ...optional("allowEmpty", request.options.allowEmpty),
40060
+ ...optional("keep", request.options.keep),
40061
+ ...optional("context", stepContext(request.options.context)),
40062
+ ...optional("skills", skills),
40063
+ ...optional("access", access)
40174
40064
  });
40175
40065
  const scriptDef = (common, request) => ({
40176
40066
  ...common,
@@ -40183,15 +40073,15 @@ const judgeDef = (common, request, step) => {
40183
40073
  ...common,
40184
40074
  kind: "message",
40185
40075
  content: step.truncated ? `${message}\n\n${TRUNCATION_NOTICE}` : message,
40186
- ...optional$1("judge", judgeDocument(step))
40076
+ ...optional("judge", judgeDocument(step))
40187
40077
  };
40188
40078
  };
40189
40079
  const messageDef = (common, request, step) => ({
40190
40080
  ...common,
40191
40081
  kind: "message",
40192
40082
  content: request.options.message ?? request.options.label ?? step.name,
40193
- ...optional$1("acceptClean", request.options.approve === true || request.options.acceptClean),
40194
- ...optional$1("approve", request.options.approve)
40083
+ ...optional("acceptClean", request.options.approve === true || request.options.acceptClean),
40084
+ ...optional("approve", request.options.approve)
40195
40085
  });
40196
40086
  const stepDefOf = (step) => {
40197
40087
  const request = step.request;
@@ -40247,15 +40137,15 @@ const memoryOf = (trace, run) => {
40247
40137
  };
40248
40138
  };
40249
40139
  const hintsOf = (def) => ({
40250
- ...optional$1("model", def.model),
40251
- ...optional$1("label", def.label),
40252
- ...optional$1("file", def.file),
40253
- ...optional$1("judge", def.judge),
40254
- ...optional$1("system", def.system),
40255
- ...optional$1("mode", def.mode),
40256
- ...optional$1("skills", def.skills),
40257
- ...optional$1("access", def.access),
40258
- ...optional$1("context", def.context)
40140
+ ...optional("model", def.model),
40141
+ ...optional("label", def.label),
40142
+ ...optional("file", def.file),
40143
+ ...optional("judge", def.judge),
40144
+ ...optional("system", def.system),
40145
+ ...optional("mode", def.mode),
40146
+ ...optional("skills", def.skills),
40147
+ ...optional("access", def.access),
40148
+ ...optional("context", def.context)
40259
40149
  });
40260
40150
  const normalizeStatus = (raw) => raw === "A" ? "A" : raw === "D" ? "D" : "M";
40261
40151
  /** Per-model token totals, highest-cost first (ties broken by model name). */
@@ -40747,7 +40637,7 @@ const historySteps = (run) => {
40747
40637
  from: message.parsed?.from,
40748
40638
  to: entry.state,
40749
40639
  verdicts: message.judge,
40750
- ...optional$1("approval", approvalEntryOf(entry.hash, message)[0])
40640
+ ...optional("approval", approvalEntryOf(entry.hash, message)[0])
40751
40641
  };
40752
40642
  });
40753
40643
  };
@@ -41775,7 +41665,7 @@ const processJudgments = (commits) => {
41775
41665
  });
41776
41666
  };
41777
41667
  const NOT_COMPARABLE = { tailsNotComparable: "true" };
41778
- const field$2 = (key, value) => value === void 0 ? {} : { [key]: value };
41668
+ const field$1 = (key, value) => value === void 0 ? {} : { [key]: value };
41779
41669
  const JUDGES = {
41780
41670
  retry: ({ reads, i, scope }, v) => {
41781
41671
  const reports = reportsBefore(reads, i, scope);
@@ -41785,8 +41675,8 @@ const JUDGES = {
41785
41675
  const known = previous !== void 0 && current !== void 0;
41786
41676
  return {
41787
41677
  state: comparable ? {
41788
- ...field$2("previous", previous),
41789
- ...field$2("current", current)
41678
+ ...field$1("previous", previous),
41679
+ ...field$1("current", current)
41790
41680
  } : NOT_COMPARABLE,
41791
41681
  outcome: known && comparable && answerOf(v.answer) === "identical" ? retryOutcome(reads, i, scope) : null
41792
41682
  };
@@ -41794,12 +41684,12 @@ const JUDGES = {
41794
41684
  triage: ({ reads, i }, v) => {
41795
41685
  const finding = reads[i].commit.findings?.find((f) => f.id === v.id);
41796
41686
  return {
41797
- state: field$2(v.id, finding && `## ${finding.title}\n\n${finding.body}`),
41687
+ state: field$1(v.id, finding && `## ${finding.title}\n\n${finding.body}`),
41798
41688
  outcome: triageOutcome(reads, i, answerOf(v.answer), finding)
41799
41689
  };
41800
41690
  },
41801
41691
  clear: ({ reads, i, sketch }, v) => ({
41802
- state: field$2("sketch", sketch),
41692
+ state: field$1("sketch", sketch),
41803
41693
  outcome: clearOutcome(reads, i, v)
41804
41694
  })
41805
41695
  };
@@ -42011,7 +41901,6 @@ const runInstallCommand = (out) => gen(function* () {
42011
41901
  yield* (yield* Workspace).write(WORKFLOW_MODULE, CONFIG_SCAFFOLD);
42012
41902
  yield* (yield* Narrator).warn(`gtd install: wrote ${WORKFLOW_MODULE}, importing gtd's shipped workflows — commit it before your first \`gtd land\``);
42013
41903
  });
42014
- const runLoopCommand = () => flatMap$4(ToolCommands, (tools) => tools.loop(selfGtd()));
42015
41904
  /**
42016
41905
  * Exactly one trailing newline — duplicated from `Cli.ts`'s own
42017
41906
  * `normalizeTrailingNewline` rather than imported, to avoid a circular value
@@ -42592,7 +42481,6 @@ const needsOf = (kind) => {
42592
42481
  switch (kind) {
42593
42482
  case "lsp":
42594
42483
  case "install":
42595
- case "loop":
42596
42484
  case "contextHook":
42597
42485
  case "judgeRun":
42598
42486
  case "strays": return "none";
@@ -42632,7 +42520,6 @@ const dispatchVoidCommand = (command, json, out) => {
42632
42520
  return runCheckCommand(command.mode, command.file, command.openQuestions ?? false, command.openThreads ?? false);
42633
42521
  case "uncheck": return runUncheckCommand(command.file);
42634
42522
  case "install": return runInstallCommand(out);
42635
- case "loop": return runLoopCommand();
42636
42523
  case "contextHook": return runContextHookCommand(command, out);
42637
42524
  case "summary": return runSummaryCommand(out, command.slice);
42638
42525
  case "base": return runBaseCommand(out);
@@ -43161,20 +43048,6 @@ const COMMAND_ROWS = [
43161
43048
  "else it writes nothing."
43162
43049
  ]
43163
43050
  },
43164
- {
43165
- token: "loop",
43166
- kind: "loop",
43167
- arity: "none",
43168
- details: [
43169
- "Drive this worktree's process until it rests on you: read",
43170
- "each beat, run the agent turn or script it demands, and",
43171
- "land the result. Exits 0 at a human gate, at idle and when",
43172
- "a landing settles; exits 1 on a stall or a failed turn or",
43173
- "landing. The agent CLI and the model each workflow hint",
43174
- "maps to are per-machine settings (GTD_LOOP_* variables, or",
43175
- "~/.config/gtd/loop.json); see docs/driver.md"
43176
- ]
43177
- },
43178
43051
  {
43179
43052
  token: "context-hook",
43180
43053
  kind: "contextHook",
@@ -48004,7 +47877,7 @@ var init_Server = __esmMin((() => {
48004
47877
  //#endregion
48005
47878
  //#region src/ui/Host.ts
48006
47879
  var liveUiHost;
48007
- var init_Host$1 = __esmMin((() => {
47880
+ var init_Host = __esmMin((() => {
48008
47881
  init_esm();
48009
47882
  init_Beat();
48010
47883
  init_Ports();
@@ -48059,7 +47932,7 @@ var ui_exports = /* @__PURE__ */ __exportAll({
48059
47932
  var init_ui = __esmMin((() => {
48060
47933
  init_Server();
48061
47934
  init_Ports();
48062
- init_Host$1();
47935
+ init_Host();
48063
47936
  init_Write();
48064
47937
  init_Serve();
48065
47938
  init_Bind();
@@ -59426,229 +59299,13 @@ var init_lsp = __esmMin((() => {
59426
59299
  init_Lsp();
59427
59300
  }));
59428
59301
  //#endregion
59429
- //#region src/loop/Agent.ts
59430
- var optional, parseJson, field$1, costOf, claude, hookSettings, pi, agentCli;
59431
- var init_Agent = __esmMin((() => {
59432
- init_wire();
59433
- optional = (flag, value) => value === void 0 || value === "" ? [] : [flag, value];
59434
- parseJson = (text) => {
59435
- try {
59436
- return JSON.parse(text);
59437
- } catch {
59438
- return;
59439
- }
59440
- };
59441
- field$1 = (value, key) => typeof value === "object" && value !== null ? value[key] : void 0;
59442
- costOf = (value) => typeof value === "number" && value > 0 ? value : 0;
59443
- claude = {
59444
- command: "claude",
59445
- args: (turn) => [
59446
- "-p",
59447
- turn.sessionFlag,
59448
- turn.sessionId,
59449
- ...optional("--model", turn.model),
59450
- ...optional("--system-prompt", turn.system),
59451
- "--settings",
59452
- JSON.stringify(hookSettings(turn.hook)),
59453
- "--output-format",
59454
- "stream-json",
59455
- "--verbose",
59456
- "--dangerously-skip-permissions"
59457
- ],
59458
- read: (exit) => {
59459
- const lines = exit.stdout.split("\n");
59460
- let envelope;
59461
- for (let i = lines.length - 1; i >= 0 && envelope === void 0; i--) {
59462
- const event = parseJson(lines[i]);
59463
- if (field$1(event, "type") === "result" || field$1(event, "result") !== void 0) envelope = event;
59464
- }
59465
- const result = field$1(envelope, "result");
59466
- const hookStopped = field$1(envelope, "terminal_reason") === "hook_stopped";
59467
- return {
59468
- ok: exit.code === 0 && field$1(envelope, "is_error") !== true && !hookStopped,
59469
- text: typeof result === "string" ? result : lines.slice(-5).join("\n"),
59470
- cost: costOf(field$1(envelope, "total_cost_usd")),
59471
- hookStopped
59472
- };
59473
- },
59474
- contextTokens: (line) => {
59475
- const event = parseJson(line);
59476
- if (field$1(event, "type") !== "assistant") return void 0;
59477
- if (field$1(event, "parent_tool_use_id") != null) return void 0;
59478
- return usageTokens(field$1(field$1(event, "message"), "usage"));
59479
- }
59480
- };
59481
- hookSettings = (command) => {
59482
- const hook = [{ hooks: [{
59483
- type: "command",
59484
- command
59485
- }] }];
59486
- return { hooks: {
59487
- PostToolUse: hook,
59488
- PreCompact: hook
59489
- } };
59490
- };
59491
- pi = {
59492
- command: "pi",
59493
- args: (turn) => [
59494
- "-p",
59495
- turn.sessionFlag,
59496
- turn.sessionId,
59497
- ...optional("--model", turn.model),
59498
- ...optional("--system-prompt", turn.system),
59499
- "--mode",
59500
- "json",
59501
- "--no-approve"
59502
- ],
59503
- read: (exit) => {
59504
- const events = exit.stdout.split("\n").map(parseJson).filter((event) => event !== void 0);
59505
- const message = field$1(events.findLast((event) => field$1(event, "type") === "message_end" && field$1(field$1(event, "message"), "role") === "assistant"), "message");
59506
- const content = field$1(message, "content");
59507
- const text = (Array.isArray(content) ? content : []).filter((part) => field$1(part, "type") === "text").map((part) => String(field$1(part, "text"))).join("\n");
59508
- return {
59509
- ok: exit.code === 0 && !events.some((event) => field$1(event, "type") === "error"),
59510
- text: text === "" ? exit.stdout : text,
59511
- cost: costOf(field$1(field$1(field$1(message, "usage"), "cost"), "total")),
59512
- hookStopped: false
59513
- };
59514
- }
59515
- };
59516
- agentCli = (name) => name === "pi" ? pi : claude;
59517
- }));
59518
- //#endregion
59519
- //#region src/loop/Documents.ts
59520
- var Beat, Land, decode, decodeBeat, decodeLand;
59521
- var init_Documents = __esmMin((() => {
59302
+ //#region src/hook/HookHost.ts
59303
+ var HookHost, liveHookHost;
59304
+ var init_HookHost = __esmMin((() => {
59522
59305
  init_esm();
59523
- init_wire();
59524
- Beat = Struct({
59525
- schema: Number$,
59526
- kind: String$,
59527
- content: String$,
59528
- idle: Boolean$,
59529
- log: String$,
59530
- state: String$,
59531
- session: optional$2(Struct({
59532
- id: String$,
59533
- resume: Boolean$
59534
- })),
59535
- model: optional$2(String$),
59536
- system: optional$2(String$),
59537
- context: optional$2(Struct({
59538
- soft: optionalWith(Number$, { exact: true }),
59539
- hard: optionalWith(Number$, { exact: true })
59540
- })),
59541
- validate: optional$2(String$),
59542
- label: optional$2(String$),
59543
- judge: optional$2(String$)
59544
- });
59545
- Land = Struct({
59546
- schema: Number$,
59547
- script: String$,
59548
- settled: Boolean$,
59549
- idle: Boolean$,
59550
- subject: NullOr(String$)
59551
- });
59552
- decode = (schema, name) => (stdout) => {
59553
- let json;
59554
- try {
59555
- json = JSON.parse(stdout);
59556
- } catch {
59557
- return left(`${name} is not JSON:\n${stdout}`);
59558
- }
59559
- const version = typeof json === "object" && json !== null ? json.schema : void 0;
59560
- if (version !== 1) return left(`${name} has schema ${JSON.stringify(version)}, but this loop reads schema 1 only — upgrade the loop's gtd`);
59561
- return decodeUnknownEither(schema)(json).pipe(mapLeft((error) => `${name} did not decode: ${error.message}`));
59562
- };
59563
- decodeBeat = decode(Beat, "`gtd next --json`");
59564
- decodeLand = decode(Land, "`gtd land --json`");
59565
- }));
59566
- //#endregion
59567
- //#region src/loop/Host.ts
59568
- var LoopHost, KILL_GRACE_MS, spawnLive, liveLoopHost;
59569
- var init_Host = __esmMin((() => {
59570
- init_esm();
59571
- LoopHost = class extends Tag("LoopHost")() {};
59572
- KILL_GRACE_MS = 5e3;
59573
- spawnLive = (request) => async((resume) => {
59574
- const logFd = request.output === "capture" ? void 0 : openSync(request.output.log, "a");
59575
- const child = spawn(request.command, [...request.args], {
59576
- cwd: request.cwd,
59577
- env: {
59578
- ...process.env,
59579
- ...request.env
59580
- },
59581
- stdio: [
59582
- request.stdin === void 0 ? "ignore" : "pipe",
59583
- logFd ?? "pipe",
59584
- logFd ?? "pipe"
59585
- ],
59586
- detached: true
59587
- });
59588
- const killGroup = (signal) => {
59589
- try {
59590
- if (child.pid !== void 0) process.kill(-child.pid, signal);
59591
- } catch {}
59592
- };
59593
- let stdout = "";
59594
- let stderr = "";
59595
- let stopped = false;
59596
- let stopForce;
59597
- let scanned = 0;
59598
- child.stdout?.setEncoding("utf-8").on("data", (chunk) => {
59599
- stdout += chunk;
59600
- if (request.stopAt === void 0 || stopped) return;
59601
- for (let end = stdout.indexOf("\n", scanned); end !== -1; end = stdout.indexOf("\n", scanned)) {
59602
- const line = stdout.slice(scanned, end);
59603
- scanned = end + 1;
59604
- if (request.stopAt(line)) {
59605
- stopped = true;
59606
- killGroup("SIGTERM");
59607
- stopForce = setTimeout(() => killGroup("SIGKILL"), KILL_GRACE_MS);
59608
- return;
59609
- }
59610
- }
59611
- });
59612
- child.stderr?.setEncoding("utf-8").on("data", (chunk) => stderr += chunk);
59613
- child.stdin?.on("error", () => {});
59614
- child.stdin?.end(request.stdin);
59615
- let settled = false;
59616
- const settle = (exit) => {
59617
- if (settled) return;
59618
- settled = true;
59619
- if (logFd !== void 0) closeSync(logFd);
59620
- resume(exit);
59621
- };
59622
- child.on("error", (error) => settle(fail$7(/* @__PURE__ */ new Error(`could not run ${request.command}: ${error.message}`))));
59623
- child.on("close", (code, signal) => {
59624
- clearTimeout(stopForce);
59625
- const exit = code ?? 128 + (signal === null ? 0 : constants.signals[signal] ?? 0);
59626
- settle(succeed$3({
59627
- code: exit,
59628
- stdout,
59629
- stderr,
59630
- ...stopped ? { stopped: true } : {}
59631
- }));
59632
- });
59633
- return async((done) => {
59634
- if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
59635
- killGroup("SIGTERM");
59636
- done(_void);
59637
- return;
59638
- }
59639
- const force = setTimeout(() => killGroup("SIGKILL"), KILL_GRACE_MS);
59640
- child.once("exit", () => {
59641
- clearTimeout(force);
59642
- killGroup("SIGKILL");
59643
- done(_void);
59644
- });
59645
- killGroup("SIGTERM");
59646
- });
59647
- });
59648
- liveLoopHost = succeed$2(LoopHost, {
59306
+ HookHost = class extends Tag("HookHost")() {};
59307
+ liveHookHost = succeed$2(HookHost, {
59649
59308
  env: process.env,
59650
- color: process.stderr.isTTY === true && process.env["NO_COLOR"] === void 0,
59651
- spawn: spawnLive,
59652
59309
  readFile: (path) => try_({
59653
59310
  try: () => {
59654
59311
  try {
@@ -59660,331 +59317,16 @@ var init_Host = __esmMin((() => {
59660
59317
  },
59661
59318
  catch: (error) => /* @__PURE__ */ new Error(`could not read ${path}: ${String(error)}`)
59662
59319
  }),
59663
- resetLog: (path) => try_({
59664
- try: () => {
59665
- mkdirSync(dirname(path), { recursive: true });
59666
- writeFileSync(path, "");
59667
- },
59668
- catch: (error) => /* @__PURE__ */ new Error(`could not reset the loop log ${path}: ${String(error)}`)
59669
- }),
59670
- appendLog: (path, text) => sync$1(() => appendFileSync(path, text)),
59671
- say: (text) => sync$1(() => process.stderr.write(text))
59672
- });
59673
- }));
59674
- //#endregion
59675
- //#region src/loop/Settings.ts
59676
- var Agent, CLAUDE_MODELS, BUNDLED_HINTS, SettingsFile, settingsPath, MODEL_ENV_PREFIX, modelEnvName, decodeFile, decodeAgent, decodeWindow, resolveSettings, resolveModel;
59677
- var init_Settings = __esmMin((() => {
59678
- init_esm();
59679
- init_wire();
59680
- Agent = Literal("claude", "pi");
59681
- CLAUDE_MODELS = {
59682
- smart: "opus",
59683
- base: "sonnet"
59684
- };
59685
- BUNDLED_HINTS = new Set(Object.keys(CLAUDE_MODELS));
59686
- SettingsFile = Struct({
59687
- agent: optional$2(Agent),
59688
- models: optional$2(Record({
59689
- key: String$,
59690
- value: String$
59691
- })),
59692
- contextWindow: optional$2(Int.pipe(positive()))
59693
- });
59694
- settingsPath = (env) => {
59695
- const explicit = env["GTD_LOOP_CONFIG"];
59696
- if (explicit) return explicit;
59697
- const xdg = env["XDG_CONFIG_HOME"];
59698
- if (xdg) return `${xdg}/gtd/loop.json`;
59699
- const home = env["HOME"];
59700
- return home ? `${home}/.config/gtd/loop.json` : void 0;
59701
- };
59702
- MODEL_ENV_PREFIX = "GTD_LOOP_MODEL_";
59703
- modelEnvName = (hint) => `${MODEL_ENV_PREFIX}${hint.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`;
59704
- decodeFile = (path, text) => {
59705
- let json;
59706
- try {
59707
- json = JSON.parse(text);
59708
- } catch (error) {
59709
- return left(`${path}: not JSON (${error.message})`);
59710
- }
59711
- return decodeUnknownEither(SettingsFile, { onExcessProperty: "error" })(json).pipe(mapLeft((error) => `${path}: ${error.message}`));
59712
- };
59713
- decodeAgent = (value) => value === void 0 || value === "" ? right(void 0) : decodeUnknownEither(Agent)(value).pipe(mapLeft(() => `GTD_LOOP_AGENT must be "claude" or "pi" — got "${value}"`));
59714
- decodeWindow = (value) => {
59715
- if (value === void 0 || value === "") return right(void 0);
59716
- const window = parseContextWindow(value);
59717
- return window !== void 0 ? right(window) : left(`GTD_LOOP_CONTEXT_WINDOW must be a positive integer — got "${value}"`);
59718
- };
59719
- resolveSettings = (env, file) => gen$2(function* () {
59720
- const fromFile = file === void 0 ? {} : yield* decodeFile(file.path, file.text);
59721
- const envAgent = yield* decodeAgent(env["GTD_LOOP_AGENT"]);
59722
- const envWindow = yield* decodeWindow(env["GTD_LOOP_CONTEXT_WINDOW"]);
59723
- const envModels = Object.fromEntries(Object.entries(env).filter((entry) => entry[0].startsWith(MODEL_ENV_PREFIX) && entry[1] !== void 0 && entry[1] !== ""));
59724
- const agent = envAgent ?? fromFile.agent ?? "claude";
59725
- return {
59726
- agent,
59727
- models: {
59728
- ...agent === "claude" ? CLAUDE_MODELS : {},
59729
- ...fromFile.models
59730
- },
59731
- envModels,
59732
- contextWindow: envWindow ?? fromFile.contextWindow
59733
- };
59734
- });
59735
- resolveModel = (settings, hint) => {
59736
- if (hint === void 0 || hint === "") return void 0;
59737
- return settings.envModels[modelEnvName(hint)] ?? settings.models[hint] ?? (BUNDLED_HINTS.has(hint) ? void 0 : hint);
59738
- };
59739
- }));
59740
- //#endregion
59741
- //#region src/loop/Loop.ts
59742
- var MAX_VALIDATION_FIXES, FAILURE_LINES, LAND, fromEither, paint, firstLines, loadSettings, gitRoot, gtd, readBeat, clock, header, rest, agentFailed, quote, contextGuard, contextStop, agentTurn, sessionFlags, validateOnce, promptBeat, runScript, stop, judgeGate, messageBeat, kindBeat, runBeat, costFlags, land, runLoop;
59743
- var init_Loop = __esmMin((() => {
59744
- init_esm();
59745
- init_wire();
59746
- init_Agent();
59747
- init_Documents();
59748
- init_Host();
59749
- init_Settings();
59750
- MAX_VALIDATION_FIXES = 3;
59751
- FAILURE_LINES = 40;
59752
- LAND = {
59753
- cost: 0,
59754
- model: void 0
59755
- };
59756
- fromEither = (either) => mapError$1(either, (message) => new Error(message));
59757
- paint = (host, sgr, text) => host.color ? `\x1b[${sgr}m${text}\x1b[0m` : text;
59758
- firstLines = (text) => text.trimEnd().split("\n").slice(0, FAILURE_LINES).join("\n");
59759
- loadSettings = gen(function* () {
59760
- const host = yield* LoopHost;
59761
- const path = settingsPath(host.env);
59762
- const text = path === void 0 ? void 0 : yield* host.readFile(path);
59763
- return yield* fromEither(resolveSettings(host.env, path !== void 0 && text !== void 0 ? {
59764
- path,
59765
- text
59766
- } : void 0));
59767
- });
59768
- gitRoot = gen(function* () {
59769
- const exit = yield* (yield* LoopHost).spawn({
59770
- command: "git",
59771
- args: ["rev-parse", "--show-toplevel"],
59772
- output: "capture"
59773
- });
59774
- if (exit.code !== 0) return yield* fail$7(/* @__PURE__ */ new Error("not inside a git repository"));
59775
- return exit.stdout.trim();
59776
- });
59777
- gtd = (ctx, args, stdin) => flatMap$4(ctx.host.spawn({
59778
- command: ctx.gtd[0],
59779
- args: [...ctx.gtd.slice(1), ...args],
59780
- cwd: ctx.root,
59781
- ...stdin === void 0 ? {} : { stdin },
59782
- output: "capture"
59783
- }), (exit) => exit.code === 0 ? succeed$3(exit.stdout) : fail$7(/* @__PURE__ */ new Error(`\`gtd ${args.join(" ")}\` failed (exit ${exit.code})\n${exit.stderr.trimEnd()}`)));
59784
- readBeat = (ctx) => flatMap$4(gtd(ctx, ["next", "--json"]), (stdout) => fromEither(decodeBeat(stdout)));
59785
- clock = () => (/* @__PURE__ */ new Date()).toTimeString().slice(0, 8);
59786
- header = (ctx, beat, doc) => gen(function* () {
59787
- const time = clock();
59788
- yield* ctx.host.appendLog(ctx.log, `\n─── beat #${beat} ${time} ${doc.kind}: ${doc.state} ───\n`);
59789
- const state = paint(ctx.host, doc.idle ? "32" : "33", doc.state);
59790
- yield* ctx.host.say(`\n${paint(ctx.host, "1;36", `─── beat #${beat} ${time} ${doc.kind}:`)} ${state} ${paint(ctx.host, "1;36", "───")}\n`);
59791
- });
59792
- rest = (ctx, sgr, headline) => ctx.host.say(`\n${paint(ctx.host, `1;${sgr}`, `● ${headline}`)}\n`);
59793
- agentFailed = (ctx, exit, result) => ctx.host.say([
59794
- `\n${paint(ctx.host, "1;31", `✘ agent turn failed (exit ${exit.code})`)}`,
59795
- ...exit.stderr.trim() === "" ? [] : [firstLines(exit.stderr)],
59796
- ...result.text.trim() === "" ? [] : [firstLines(result.text)]
59797
- ].join("\n") + "\n");
59798
- quote = (arg) => `'${arg.replaceAll("'", "'\\''")}'`;
59799
- contextGuard = (ctx, doc, model) => {
59800
- const limit = {
59801
- ...DEFAULT_CONTEXT_LIMIT,
59802
- ...doc.context
59803
- };
59804
- const window = ctx.settings.contextWindow ?? contextWindowFor(model);
59805
- return {
59806
- limit,
59807
- window,
59808
- hook: [...ctx.gtd, "context-hook"].concat([
59809
- "--soft",
59810
- String(limit.soft),
59811
- "--hard",
59812
- String(limit.hard),
59813
- "--window",
59814
- String(window)
59815
- ]).map(quote).join(" "),
59816
- kill: (limit.hard + 1) / 2
59817
- };
59818
- };
59819
- contextStop = (ctx, exit, guard, stopFile) => map$4(ctx.host.readFile(stopFile), (recorded) => {
59820
- const reason = recorded?.trim().split("\n")[0];
59821
- if (reason !== void 0 && reason !== "") return reason;
59822
- if (exit.stopped !== true) return void 0;
59823
- return `${CONTEXT_LIMIT_MARKER}: the stream passed ${Math.round(guard.kill * 100)}% of ${guard.window} tokens with no hook stopping it`;
59824
- });
59825
- agentTurn = (ctx, doc, model) => (prompt, sessionFlag) => gen(function* () {
59826
- const cli = agentCli(ctx.settings.agent);
59827
- const guard = contextGuard(ctx, doc, model);
59828
- const tokensOf = cli.contextTokens;
59829
- const stopFile = `${ctx.log}.context-stop`;
59830
- yield* ctx.host.resetLog(stopFile);
59831
- const exit = yield* ctx.host.spawn({
59832
- command: cli.command,
59833
- args: cli.args({
59834
- sessionFlag,
59835
- sessionId: doc.session?.id ?? "",
59836
- model,
59837
- system: doc.system,
59838
- hook: guard.hook
59839
- }),
59840
- cwd: ctx.root,
59841
- stdin: prompt,
59842
- env: {
59843
- CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1",
59844
- [CONTEXT_STOP_FILE_ENV]: stopFile
59845
- },
59846
- output: "capture",
59847
- ...tokensOf === void 0 ? {} : { stopAt: (line) => (tokensOf(line) ?? 0) >= guard.kill * guard.window }
59848
- });
59849
- const result = cli.read(exit);
59850
- yield* ctx.host.appendLog(ctx.log, `${exit.stderr}${result.text}\n`);
59851
- const why = yield* contextStop(ctx, exit, guard, stopFile);
59852
- if (why !== void 0) return yield* fail$7(/* @__PURE__ */ new Error(`${why} — the turn at "${doc.state}" was stopped and nothing landed; see ${ctx.log}`));
59853
- if (!result.ok) yield* agentFailed(ctx, exit, result);
59854
- return result;
59855
- });
59856
- sessionFlags = (doc) => doc.session?.resume === true ? ["--resume", "--session-id"] : ["--session-id", "--resume"];
59857
- validateOnce = (ctx, script) => ctx.host.spawn({
59858
- command: "sh",
59859
- args: [
59860
- "-c",
59861
- "sh -c \"$1\" 2>&1",
59862
- "sh",
59863
- script
59864
- ],
59865
- cwd: ctx.root,
59866
- output: "capture"
59867
- });
59868
- promptBeat = (ctx, doc) => gen(function* () {
59869
- if (doc.session === void 0) return yield* fail$7(/* @__PURE__ */ new Error(`prompt beat at "${doc.state}" carries no session`));
59870
- const model = resolveModel(ctx.settings, doc.model);
59871
- const turn = agentTurn(ctx, doc, model);
59872
- let cost = 0;
59873
- const run = (prompt, flag) => map$4(turn(prompt, flag), (result) => {
59874
- cost += result.cost;
59875
- return result.ok;
59876
- });
59877
- const content = yield* gtd(ctx, ["next"]);
59878
- const [first, second] = sessionFlags(doc);
59879
- if (!(yield* run(content, first)) && !(yield* run(content, second))) return yield* fail$7(/* @__PURE__ */ new Error("agent turn failed on both session flags"));
59880
- for (let fixes = 0; doc.validate !== void 0 && doc.validate !== "";) {
59881
- const check = yield* validateOnce(ctx, doc.validate);
59882
- if (check.code === 0) break;
59883
- yield* ctx.host.appendLog(ctx.log, check.stdout);
59884
- if (++fixes > MAX_VALIDATION_FIXES) {
59885
- yield* ctx.host.say(check.stdout);
59886
- return yield* fail$7(/* @__PURE__ */ new Error(`validation still failing after ${MAX_VALIDATION_FIXES} fixes`));
59887
- }
59888
- if (!(yield* run(check.stdout, "--resume"))) return yield* fail$7(/* @__PURE__ */ new Error("agent turn failed while fixing validation"));
59889
- }
59890
- return {
59891
- cost,
59892
- model
59893
- };
59894
- });
59895
- runScript = (ctx, content) => as(ctx.host.spawn({
59896
- command: "sh",
59897
- args: ["-c", content],
59898
- cwd: ctx.root,
59899
- output: { log: ctx.log }
59900
- }), LAND);
59901
- stop = (ctx, sgr, headline, prose) => as(zipRight$1(ctx.host.appendLog(ctx.log, prose), rest(ctx, sgr, headline)), "stop");
59902
- judgeGate = (ctx, doc) => gtd(ctx, ["judge", "run"], doc.judge).pipe(flatMap$4((verdict) => gtd(ctx, [
59903
- "judge",
59904
- "answer",
59905
- "--json"
59906
- ], verdict)), tap(() => ctx.host.say(` ${paint(ctx.host, "2", "⚖ judged")}\n`)), catchAll((error) => as(ctx.host.appendLog(ctx.log, `${error.message}\n`), void 0)));
59907
- messageBeat = (ctx, beat, doc, judged) => gen(function* () {
59908
- const isJudge = doc.judge !== void 0 && doc.judge !== "";
59909
- const landing = isJudge && judged !== doc.state ? yield* judgeGate(ctx, doc) : void 0;
59910
- if (landing !== void 0) return {
59911
- ...LAND,
59912
- landing
59913
- };
59914
- if (beat === 1 && !isJudge) return LAND;
59915
- const label = doc.label === void 0 ? "" : ` (${doc.label})`;
59916
- return yield* stop(ctx, "33", `your turn — ${doc.state}${label}`, doc.content);
59917
- });
59918
- kindBeat = (ctx, beat, doc, judged) => {
59919
- switch (doc.kind) {
59920
- case "stalled": return zipRight$1(ctx.host.appendLog(ctx.log, doc.content), fail$7(new Error(doc.content.trimEnd())));
59921
- case "message": return messageBeat(ctx, beat, doc, judged);
59922
- case "capture": return succeed$3(LAND);
59923
- case "script": return runScript(ctx, doc.content);
59924
- case "prompt": return promptBeat(ctx, doc);
59925
- default: return fail$7(/* @__PURE__ */ new Error(`unknown beat kind "${doc.kind}"`));
59926
- }
59927
- };
59928
- runBeat = (ctx, beat, doc, judged) => beat > 1 && doc.idle ? flatMap$4(gtd(ctx, ["next"]), (message) => stop(ctx, "32", `done — ${doc.state}`, message)) : kindBeat(ctx, beat, doc, judged);
59929
- costFlags = (outcome) => outcome.cost > 0 ? [`--cost=${outcome.cost.toFixed(6)}`, ...outcome.model === void 0 ? [] : [`--model=${outcome.model}`]] : [];
59930
- land = (ctx, outcome) => gen(function* () {
59931
- const landed = outcome.landing ?? (yield* gtd(ctx, [
59932
- "land",
59933
- "--json",
59934
- ...costFlags(outcome)
59935
- ]));
59936
- const doc = yield* fromEither(decodeLand(landed));
59937
- const exit = yield* ctx.host.spawn({
59938
- command: "sh",
59939
- args: [],
59940
- cwd: ctx.root,
59941
- stdin: doc.script,
59942
- output: { log: ctx.log }
59943
- });
59944
- if (exit.code !== 0) return yield* fail$7(/* @__PURE__ */ new Error(`the landing script failed (exit ${exit.code}) — see ${ctx.log}`));
59945
- if (doc.subject !== null) yield* ctx.host.say(` ${paint(ctx.host, "2", `↳ ${doc.subject}`)}\n`);
59946
- if (!doc.settled) return false;
59947
- yield* ctx.host.say(`${paint(ctx.host, "32", "✔ settled — nothing owed")}\n`);
59948
- if (doc.idle) {
59949
- const message = yield* gtd(ctx, ["next"]);
59950
- yield* ctx.host.appendLog(ctx.log, message);
59951
- yield* ctx.host.say(message);
59952
- }
59953
- return true;
59954
- });
59955
- runLoop = (options) => gen(function* () {
59956
- const host = yield* LoopHost;
59957
- const settings = yield* loadSettings;
59958
- const root = yield* gitRoot;
59959
- const base = {
59960
- host,
59961
- settings,
59962
- root,
59963
- gtd: options.gtd
59964
- };
59965
- let doc = yield* readBeat(base);
59966
- const ctx = {
59967
- ...base,
59968
- log: resolve(root, doc.log)
59969
- };
59970
- yield* host.resetLog(ctx.log);
59971
- let judged;
59972
- for (let beat = 1;; beat++) {
59973
- if (beat > 1) doc = yield* readBeat(ctx);
59974
- yield* header(ctx, beat, doc);
59975
- const outcome = yield* runBeat(ctx, beat, doc, judged);
59976
- if (outcome === "stop" || (yield* land(ctx, outcome))) return;
59977
- judged = outcome.landing === void 0 ? void 0 : doc.state;
59978
- }
59320
+ appendFile: (path, text) => sync$1(() => appendFileSync(path, text))
59979
59321
  });
59980
59322
  }));
59981
59323
  //#endregion
59982
- //#region src/loop/ContextHook.ts
59324
+ //#region src/hook/ContextHook.ts
59983
59325
  var field, limitOf, parseInput, tokensOf, recordStop, runContextHook;
59984
59326
  var init_ContextHook = __esmMin((() => {
59985
59327
  init_esm();
59986
59328
  init_wire();
59987
- init_Host();
59329
+ init_HookHost();
59988
59330
  field = (value, key) => typeof value === "object" && value !== null ? value[key] : void 0;
59989
59331
  limitOf = (request) => {
59990
59332
  const limit = {
@@ -60007,10 +59349,10 @@ var init_ContextHook = __esmMin((() => {
60007
59349
  transcript: typeof path === "string" && path !== "" ? path : void 0
60008
59350
  };
60009
59351
  }));
60010
- tokensOf = (input) => input.event === "PostToolUse" && input.transcript !== void 0 ? flatMap$4(LoopHost, (host) => host.readFile(input.transcript)).pipe(map$4((text) => text === void 0 ? void 0 : transcriptTokens(text))) : succeed$3(void 0);
60011
- recordStop = (stopReason) => flatMap$4(LoopHost, (host) => {
59352
+ tokensOf = (input) => input.event === "PostToolUse" && input.transcript !== void 0 ? flatMap$4(HookHost, (host) => host.readFile(input.transcript)).pipe(map$4((text) => text === void 0 ? void 0 : transcriptTokens(text))) : succeed$3(void 0);
59353
+ recordStop = (stopReason) => flatMap$4(HookHost, (host) => {
60012
59354
  const file = host.env[CONTEXT_STOP_FILE_ENV];
60013
- return file === void 0 || file === "" ? _void : host.appendLog(file, `${stopReason}\n`).pipe(catchAllDefect(() => _void));
59355
+ return file === void 0 || file === "" ? _void : host.appendFile(file, `${stopReason}\n`).pipe(catchAllDefect(() => _void));
60014
59356
  });
60015
59357
  runContextHook = (request) => gen(function* () {
60016
59358
  const limit = yield* limitOf(request);
@@ -60028,16 +59370,14 @@ var init_ContextHook = __esmMin((() => {
60028
59370
  });
60029
59371
  }));
60030
59372
  //#endregion
60031
- //#region src/loop/index.ts
60032
- var loop_exports = /* @__PURE__ */ __exportAll({
60033
- LoopHost: () => LoopHost,
60034
- liveLoopHost: () => liveLoopHost,
60035
- runContextHook: () => runContextHook,
60036
- runLoop: () => runLoop
59373
+ //#region src/hook/index.ts
59374
+ var hook_exports = /* @__PURE__ */ __exportAll({
59375
+ HookHost: () => HookHost,
59376
+ liveHookHost: () => liveHookHost,
59377
+ runContextHook: () => runContextHook
60037
59378
  });
60038
- var init_loop = __esmMin((() => {
60039
- init_Loop();
60040
- init_Host();
59379
+ var init_hook = __esmMin((() => {
59380
+ init_HookHost();
60041
59381
  init_ContextHook();
60042
59382
  }));
60043
59383
  //#endregion
@@ -60523,13 +59863,9 @@ const liveToolCommands = effect$1(ToolCommands, gen(function* () {
60523
59863
  const { startLspServer } = await Promise.resolve().then(() => (init_lsp(), lsp_exports));
60524
59864
  return () => startLspServer({ gtd });
60525
59865
  }),
60526
- loop: (gtd) => lazy("loop", async () => {
60527
- const { runLoop, liveLoopHost } = await Promise.resolve().then(() => (init_loop(), loop_exports));
60528
- return () => runLoop({ gtd }).pipe(provide$1(liveLoopHost));
60529
- }),
60530
- contextHook: (request) => lazy("loop", async () => {
60531
- const { runContextHook, liveLoopHost } = await Promise.resolve().then(() => (init_loop(), loop_exports));
60532
- return () => runContextHook(request).pipe(provide$1(liveLoopHost));
59866
+ contextHook: (request) => lazy("context-hook", async () => {
59867
+ const { runContextHook, liveHookHost } = await Promise.resolve().then(() => (init_hook(), hook_exports));
59868
+ return () => runContextHook(request).pipe(provide$1(liveHookHost));
60533
59869
  }),
60534
59870
  judge: async (request) => {
60535
59871
  const { runJudge } = await Promise.resolve().then(() => (init_judges(), judges_exports)).catch((error) => {