@pmelab/gtd 36.0.0 → 37.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +21 -9
- package/claude/hooks/context.ts +66 -0
- package/claude/hooks/drive.ts +3 -0
- package/claude/hooks/register.tsx +69 -6
- package/dist/chunks/{reserved-BAv71I4i.mjs → reserved-zAfoJtR7.mjs} +53 -16
- package/dist/chunks/{tail-kar1zhOb.mjs → tail-BRC4DGdV.mjs} +1 -1
- package/dist/chunks/{wire-D3Rc5r22.mjs → wire-CSsa3Wxd.mjs} +117 -2
- package/dist/gtd.bundle.mjs +498 -56
- package/dist/testkit.mjs +115 -3
- package/dist/wire.mjs +2 -2
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +126 -33
- package/dist/workflows/fix.mjs +2 -2
- package/dist/workflows/review.mjs +2 -2
- package/dist/workflows/rollout.mjs +1 -1
- package/dist/workflows.mjs +174 -44
- package/package.json +1 -1
- package/src/cli/Cli.test.ts +10 -3
- package/src/cli/Cli.ts +76 -1
- package/src/cli/Program.test.ts +1 -0
- package/src/cli/Program.ts +28 -0
- package/src/cli/ToolCommands.ts +3 -0
- package/src/edge/Edge.ts +11 -0
- package/src/flows/runtime.ts +11 -0
- package/src/replay/Replay.ts +51 -2
- package/src/testkit/Layers.ts +1 -0
- package/src/wire/BeatDocument.ts +12 -2
- package/src/wire/BeatStatus.ts +3 -0
- package/src/wire/ContextLimit.fixture.ts +30 -0
- package/src/wire/ContextLimit.test.ts +96 -0
- package/src/wire/ContextLimit.ts +169 -0
- package/src/wire/index.ts +1 -0
- package/src/wire/types.ts +7 -0
- package/src/workflow/Workflow.ts +9 -1
- package/src/workflows/feature/context-limit.feature +37 -0
- package/src/workflows/feature/coverage.ts +8 -2
- package/src/workflows/feature/feature.ts +6 -2
- package/src/workflows/feature/refactor-absorbs.feature +12 -5
- package/src/workflows/feature/refactor-first.feature +11 -2
- package/src/workflows/feature/refactor-lens-models.feature +4 -0
- package/src/workflows/feature/refactor-rebuild.feature +269 -0
- package/src/workflows/feature/refactor-review.feature +45 -1
- package/src/workflows/feature/refactor.ts +9 -3
- package/src/workflows/feature/seam.test.ts +108 -3
- package/src/workflows/feature/seam.ts +120 -19
- package/src/workflows/shared/options.test.ts +11 -2
- package/src/workflows/shared/options.ts +18 -4
- package/src/workflows/shared/steps.ts +1 -0
- package/src/workflows/shared/text.ts +80 -14
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -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, 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, isNotUndefined, isNotNull, 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,6 +181,8 @@ 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;
|
|
184
186
|
isNever = (_) => false;
|
|
185
187
|
isRecordOrArray = (input) => typeof input === "object" && input !== null;
|
|
186
188
|
isObject$3 = (input) => isRecordOrArray(input) || isFunction$1(input);
|
|
@@ -6826,7 +6828,7 @@ var init_label = __esmMin((() => {
|
|
|
6826
6828
|
}));
|
|
6827
6829
|
//#endregion
|
|
6828
6830
|
//#region node_modules/effect/dist/esm/internal/core-effect.js
|
|
6829
|
-
var annotateLogs$1, asSome, try_$1, catchTag$1, diffFiberRefs, bind, bindTo, match$4, fiberRefs, ignore$1, logWithLevel, logWarning$1, logError$1, mapErrorCause, negate$1, orElseSucceed$1, patchFiberRefs, promise$1, provideService$1, provideServiceEffect, sandbox$1, sleep$1, succeedNone, summarized, tapErrorCause$1, tryPromise$1, tryMap$1, updateFiberRefs, when$1, serviceOption$1;
|
|
6831
|
+
var annotateLogs$1, asSome, try_$1, catchAllDefect$1, catchTag$1, diffFiberRefs, bind, bindTo, match$4, fiberRefs, ignore$1, logWithLevel, logWarning$1, logError$1, mapErrorCause, negate$1, orElseSucceed$1, patchFiberRefs, promise$1, provideService$1, provideServiceEffect, sandbox$1, sleep$1, succeedNone, summarized, tapErrorCause$1, tryPromise$1, tryMap$1, updateFiberRefs, when$1, serviceOption$1;
|
|
6830
6832
|
var init_core_effect = __esmMin((() => {
|
|
6831
6833
|
init_Clock();
|
|
6832
6834
|
init_Context();
|
|
@@ -6861,6 +6863,13 @@ var init_core_effect = __esmMin((() => {
|
|
|
6861
6863
|
}
|
|
6862
6864
|
});
|
|
6863
6865
|
};
|
|
6866
|
+
catchAllDefect$1 = /*#__PURE__*/ dual(2, (self, f) => catchAllCause$1(self, (cause) => {
|
|
6867
|
+
const option = find(cause, (_) => isDieType$1(_) ? some(_) : none$4());
|
|
6868
|
+
switch (option._tag) {
|
|
6869
|
+
case "None": return failCause$6(cause);
|
|
6870
|
+
case "Some": return f(option.value.defect);
|
|
6871
|
+
}
|
|
6872
|
+
}));
|
|
6864
6873
|
catchTag$1 = /*#__PURE__*/ dual((args) => isEffect$1(args[0]), (self, ...args) => {
|
|
6865
6874
|
const f = args[args.length - 1];
|
|
6866
6875
|
let predicate;
|
|
@@ -11435,7 +11444,7 @@ var init_MutableQueue = __esmMin((() => {
|
|
|
11435
11444
|
}));
|
|
11436
11445
|
//#endregion
|
|
11437
11446
|
//#region node_modules/effect/dist/esm/Effect.js
|
|
11438
|
-
var isEffect, all$1, forEach$2, async, withFiberRuntime, fail$7, failCause$2, die, dieMessage, gen, promise, succeed$3, suspend$5, sync$1, _void, catchAll, catchAllCause, catchIf, catchTag, ignore, sandbox, retry, try_, tryMap, tryPromise, interrupt, interruptible, uninterruptible, uninterruptibleMask, as, asVoid, map$4, mapBoth$1, mapError$1, negate, acquireRelease, acquireUseRelease$2, addFinalizer, ensuring$2, onError, scope$1, scopeWith, scopedWith$1, scoped$3, fiberIdWith, forkDaemon, forkIn, forkScoped, timeout, provide$1, provideService, serviceOption, either, exit$1, intoDeferred, when, flatMap$4, andThen, flatten$5, race, raceWith, tap, tapErrorCause, repeat, match$2, matchCause, matchCauseEffect, matchEffect, logWarning, logError, annotateLogs, orDie, orElse$1, orElseSucceed, runtime, unsafeMakeSemaphore, makeSemaphore, unsafeMakeLatch, runFork$1, runPromise, runSync, zip$1, zipLeft, zipRight$1, zipWith, fnUntraced;
|
|
11447
|
+
var isEffect, all$1, forEach$2, async, withFiberRuntime, fail$7, failCause$2, die, dieMessage, gen, promise, succeed$3, suspend$5, sync$1, _void, catchAll, catchAllCause, catchAllDefect, catchIf, catchTag, ignore, sandbox, retry, try_, tryMap, tryPromise, interrupt, interruptible, uninterruptible, uninterruptibleMask, as, asVoid, map$4, mapBoth$1, mapError$1, negate, acquireRelease, acquireUseRelease$2, addFinalizer, ensuring$2, onError, scope$1, scopeWith, scopedWith$1, scoped$3, fiberIdWith, forkDaemon, forkIn, forkScoped, timeout, provide$1, provideService, serviceOption, either, exit$1, intoDeferred, when, flatMap$4, andThen, flatten$5, race, raceWith, tap, tapErrorCause, repeat, match$2, matchCause, matchCauseEffect, matchEffect, logWarning, logError, annotateLogs, orDie, orElse$1, orElseSucceed, runtime, unsafeMakeSemaphore, makeSemaphore, unsafeMakeLatch, runFork$1, runPromise, runSync, zip$1, zipLeft, zipRight$1, zipWith, fnUntraced;
|
|
11439
11448
|
var init_Effect = __esmMin((() => {
|
|
11440
11449
|
init_core_effect();
|
|
11441
11450
|
init_core();
|
|
@@ -11461,6 +11470,7 @@ var init_Effect = __esmMin((() => {
|
|
|
11461
11470
|
_void = void_$4;
|
|
11462
11471
|
catchAll = catchAll$1;
|
|
11463
11472
|
catchAllCause = catchAllCause$1;
|
|
11473
|
+
catchAllDefect = catchAllDefect$1;
|
|
11464
11474
|
catchIf = catchIf$1;
|
|
11465
11475
|
catchTag = catchTag$1;
|
|
11466
11476
|
ignore = ignore$1;
|
|
@@ -14278,7 +14288,7 @@ function getBrands(ast) {
|
|
|
14278
14288
|
onSome: (brands) => brands.map((brand) => ` & Brand<${formatUnknown(brand)}>`).join("")
|
|
14279
14289
|
});
|
|
14280
14290
|
}
|
|
14281
|
-
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, pickAnnotations, omitAnnotations, preserveTransformationAnnotations, typeAST, getTransformationFrom, encodedAST_, encodedAST, toJSONAnnotations, getEncodedParameter, formatKeyword, getOrElseExpected, getExpected;
|
|
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$1, pickAnnotations, omitAnnotations, preserveTransformationAnnotations, typeAST, getTransformationFrom, encodedAST_, encodedAST, toJSONAnnotations, getEncodedParameter, formatKeyword, getOrElseExpected, getExpected;
|
|
14282
14292
|
var init_SchemaAST = __esmMin((() => {
|
|
14283
14293
|
init_Array();
|
|
14284
14294
|
init_Function();
|
|
@@ -15242,7 +15252,7 @@ var init_SchemaAST = __esmMin((() => {
|
|
|
15242
15252
|
return pattern;
|
|
15243
15253
|
};
|
|
15244
15254
|
getTemplateLiteralRegExp = (ast) => new RegExp(`^${getTemplateLiteralPattern(ast, false, true)}$`);
|
|
15245
|
-
record = (key, value) => {
|
|
15255
|
+
record$1 = (key, value) => {
|
|
15246
15256
|
const propertySignatures = [];
|
|
15247
15257
|
const indexSignatures = [];
|
|
15248
15258
|
const go = (key) => {
|
|
@@ -16549,7 +16559,7 @@ function causeEncode(cause) {
|
|
|
16549
16559
|
};
|
|
16550
16560
|
}
|
|
16551
16561
|
}
|
|
16552
|
-
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, element, ElementImpl, getDefaultTupleTypeAST, Array$, formatPropertySignatureToken, PropertySignatureDeclaration, ToPropertySignature, formatPropertyKey, PropertySignatureTransformation, mergeSignatureAnnotations, PropertySignatureTypeId, isPropertySignature, PropertySignatureImpl, makePropertySignature, PropertySignatureWithFromImpl, propertySignature, withConstructorDefault, optional$2, 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$;
|
|
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$;
|
|
16553
16563
|
var init_Schema = __esmMin((() => {
|
|
16554
16564
|
init_Array();
|
|
16555
16565
|
init_BigDecimal();
|
|
@@ -16668,6 +16678,7 @@ var init_Schema = __esmMin((() => {
|
|
|
16668
16678
|
getDefaultUnionAST = (members) => Union$1.make(members.map((m) => m.ast));
|
|
16669
16679
|
NullOr = (self) => Union(self, Null);
|
|
16670
16680
|
UndefinedOr = (self) => Union(self, Undefined);
|
|
16681
|
+
NullishOr = (self) => Union(self, Null, Undefined);
|
|
16671
16682
|
element = (self) => new ElementImpl(new OptionalType(self.ast, false), self);
|
|
16672
16683
|
ElementImpl = class ElementImpl {
|
|
16673
16684
|
ast;
|
|
@@ -16712,6 +16723,15 @@ var init_Schema = __esmMin((() => {
|
|
|
16712
16723
|
return `PropertySignature<${token}, ${type}, never, ${token}, ${type}>`;
|
|
16713
16724
|
}
|
|
16714
16725
|
};
|
|
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
|
+
};
|
|
16715
16735
|
ToPropertySignature = class extends OptionalType {
|
|
16716
16736
|
isReadonly;
|
|
16717
16737
|
defaultValue;
|
|
@@ -16802,10 +16822,80 @@ var init_Schema = __esmMin((() => {
|
|
|
16802
16822
|
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));
|
|
16803
16823
|
}
|
|
16804
16824
|
});
|
|
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
|
+
};
|
|
16805
16892
|
optional$2 = (self) => {
|
|
16806
16893
|
const ast = self.ast === undefinedKeyword || self.ast === neverKeyword ? undefinedKeyword : UndefinedOr(self).ast;
|
|
16807
16894
|
return new PropertySignatureWithFromImpl(new PropertySignatureDeclaration(ast, true, true, {}, void 0), self);
|
|
16808
16895
|
};
|
|
16896
|
+
optionalWith = /*#__PURE__*/ dual((args) => isSchema(args[0]), (self, options) => {
|
|
16897
|
+
return new PropertySignatureWithFromImpl(optionalPropertySignatureAST(self, options), self);
|
|
16898
|
+
});
|
|
16809
16899
|
preserveMissingMessageAnnotation = /*#__PURE__*/ pickAnnotations([MissingMessageAnnotationId]);
|
|
16810
16900
|
getDefaultTypeLiteralAST = (fields, records) => {
|
|
16811
16901
|
const ownKeys = Reflect.ownKeys(fields);
|
|
@@ -16847,7 +16937,7 @@ var init_Schema = __esmMin((() => {
|
|
|
16847
16937
|
const issFrom = [];
|
|
16848
16938
|
const issTo = [];
|
|
16849
16939
|
for (const r of records) {
|
|
16850
|
-
const { indexSignatures, propertySignatures } = record(r.key.ast, r.value.ast);
|
|
16940
|
+
const { indexSignatures, propertySignatures } = record$1(r.key.ast, r.value.ast);
|
|
16851
16941
|
propertySignatures.forEach((ps) => {
|
|
16852
16942
|
from.push(ps);
|
|
16853
16943
|
to.push(new PropertySignature(ps.name, typeAST(ps.type), ps.isOptional, ps.isReadonly, ps.annotations));
|
|
@@ -16862,7 +16952,7 @@ var init_Schema = __esmMin((() => {
|
|
|
16862
16952
|
}
|
|
16863
16953
|
const iss = [];
|
|
16864
16954
|
for (const r of records) {
|
|
16865
|
-
const { indexSignatures, propertySignatures } = record(r.key.ast, r.value.ast);
|
|
16955
|
+
const { indexSignatures, propertySignatures } = record$1(r.key.ast, r.value.ast);
|
|
16866
16956
|
propertySignatures.forEach((ps) => pss.push(ps));
|
|
16867
16957
|
indexSignatures.forEach((is) => iss.push(is));
|
|
16868
16958
|
}
|
|
@@ -21831,15 +21921,15 @@ const openQuestions = (text) => ctx().openQuestions(text);
|
|
|
21831
21921
|
//#endregion
|
|
21832
21922
|
//#region src/flows/scripts.ts
|
|
21833
21923
|
/** POSIX single-quoting: `value` survives the shell as one word, verbatim. */
|
|
21834
|
-
const quote = (value) => `'${value.replace(/'/g, "'\\''")}'`;
|
|
21835
|
-
const removal = (paths) => paths.length === 0 ? [] : [`rm -rf -- ${paths.map(quote).join(" ")}`];
|
|
21924
|
+
const quote$1 = (value) => `'${value.replace(/'/g, "'\\''")}'`;
|
|
21925
|
+
const removal = (paths) => paths.length === 0 ? [] : [`rm -rf -- ${paths.map(quote$1).join(" ")}`];
|
|
21836
21926
|
/**
|
|
21837
21927
|
* Run `command` and keep its outcome in the tree: on failure its output (or
|
|
21838
21928
|
* a note that there was none) lands in `report`, on success `report` goes.
|
|
21839
21929
|
*/
|
|
21840
21930
|
const checkScript = (command, options) => {
|
|
21841
|
-
const report = quote(options.report);
|
|
21842
|
-
const output = quote(`${options.report}.output`);
|
|
21931
|
+
const report = quote$1(options.report);
|
|
21932
|
+
const output = quote$1(`${options.report}.output`);
|
|
21843
21933
|
return [
|
|
21844
21934
|
"#!/usr/bin/env sh",
|
|
21845
21935
|
"set +e",
|
|
@@ -21857,7 +21947,7 @@ const checkScript = (command, options) => {
|
|
|
21857
21947
|
` rm -f ${output}`,
|
|
21858
21948
|
` printf 'the test command failed with exit code %s and produced no output.' "$code" > ${report}`,
|
|
21859
21949
|
" fi",
|
|
21860
|
-
` printf '\\n<!-- gtd check %s -->\\n' ${quote(options.stamp)} >> ${report}`,
|
|
21950
|
+
` printf '\\n<!-- gtd check %s -->\\n' ${quote$1(options.stamp)} >> ${report}`,
|
|
21861
21951
|
"else",
|
|
21862
21952
|
` rm -f ${output} ${report}`,
|
|
21863
21953
|
...removal(options.sweepOnGreen ?? []).map((line) => ` ${line}`),
|
|
@@ -21866,21 +21956,21 @@ const checkScript = (command, options) => {
|
|
|
21866
21956
|
].join("\n");
|
|
21867
21957
|
};
|
|
21868
21958
|
const patchScript = (commit, report, failure, reverse, exclude = []) => {
|
|
21869
|
-
const paths = exclude.length === 0 ? "" : ` . ${exclude.map((p) => quote(`:(exclude,literal)${p}`)).join(" ")}`;
|
|
21870
|
-
const range = `${quote(`${commit}^`)} ${quote(commit)}`;
|
|
21871
|
-
const error = quote(`${report}.output`);
|
|
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`);
|
|
21872
21962
|
return [
|
|
21873
21963
|
"#!/usr/bin/env sh",
|
|
21874
21964
|
"set +e",
|
|
21875
21965
|
`if ! git diff --quiet ${range} --${paths}; then`,
|
|
21876
|
-
` mkdir -p "$(dirname ${quote(report)})"`,
|
|
21966
|
+
` mkdir -p "$(dirname ${quote$1(report)})"`,
|
|
21877
21967
|
` 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}`,
|
|
21878
21968
|
" code=$?",
|
|
21879
21969
|
" if [ \"$code\" -ne 0 ]; then",
|
|
21880
21970
|
" {",
|
|
21881
|
-
` printf '%s\\n\\n' ${quote(failure)}`,
|
|
21971
|
+
` printf '%s\\n\\n' ${quote$1(failure)}`,
|
|
21882
21972
|
` if [ -s ${error} ]; then cat ${error}; else printf '${reverse ? "Reverting" : "Applying"} it exited %s and produced no output.\\n' "$code"; fi`,
|
|
21883
|
-
` } > ${quote(report)}`,
|
|
21973
|
+
` } > ${quote$1(report)}`,
|
|
21884
21974
|
" fi",
|
|
21885
21975
|
` rm -f ${error}`,
|
|
21886
21976
|
"fi",
|
|
@@ -21901,12 +21991,12 @@ const applyScript = (commit, report, failure, exclude = []) => patchScript(commi
|
|
|
21901
21991
|
* still exactly as `commit` left it. A path changed since is left alone.
|
|
21902
21992
|
*/
|
|
21903
21993
|
const restoreScript = (commit, paths, source) => {
|
|
21904
|
-
const unchanged = (path) => `git diff --quiet ${quote(commit)} -- ${quote(path)}`;
|
|
21994
|
+
const unchanged = (path) => `git diff --quiet ${quote$1(commit)} -- ${quote$1(path)}`;
|
|
21905
21995
|
return [
|
|
21906
21996
|
"#!/usr/bin/env sh",
|
|
21907
21997
|
"set +e",
|
|
21908
|
-
...paths.restore.map((path) => `${unchanged(path)} && git restore --source=${quote(source ?? `${commit}~1`)} --worktree -- ${quote(path)}`),
|
|
21909
|
-
...paths.remove.map((path) => `${unchanged(path)} && rm -f -- ${quote(path)}`),
|
|
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)}`),
|
|
21910
22000
|
""
|
|
21911
22001
|
].join("\n");
|
|
21912
22002
|
};
|
|
@@ -21920,15 +22010,15 @@ const removeScript = (paths) => [
|
|
|
21920
22010
|
const moveScript = (from, to) => [
|
|
21921
22011
|
"#!/usr/bin/env sh",
|
|
21922
22012
|
"set -e",
|
|
21923
|
-
`mkdir -p "$(dirname ${quote(to)})"`,
|
|
21924
|
-
`mv -- ${quote(from)} ${quote(to)}`,
|
|
22013
|
+
`mkdir -p "$(dirname ${quote$1(to)})"`,
|
|
22014
|
+
`mv -- ${quote$1(from)} ${quote$1(to)}`,
|
|
21925
22015
|
""
|
|
21926
22016
|
].join("\n");
|
|
21927
22017
|
/** Write `path` as committed at `ref` to `to`. */
|
|
21928
22018
|
const showScript = (ref, path, to) => [
|
|
21929
22019
|
"#!/usr/bin/env sh",
|
|
21930
22020
|
"set -e",
|
|
21931
|
-
`git show ${quote(`${ref}:${path}`)} > ${quote(to)}`,
|
|
22021
|
+
`git show ${quote$1(`${ref}:${path}`)} > ${quote$1(to)}`,
|
|
21932
22022
|
""
|
|
21933
22023
|
].join("\n");
|
|
21934
22024
|
//#endregion
|
|
@@ -22291,7 +22381,7 @@ var flows_exports = /* @__PURE__ */ __exportAll({
|
|
|
22291
22381
|
numeric: () => numeric,
|
|
22292
22382
|
openQuestions: () => openQuestions,
|
|
22293
22383
|
protocolMismatch: () => protocolMismatch,
|
|
22294
|
-
quote: () => quote,
|
|
22384
|
+
quote: () => quote$1,
|
|
22295
22385
|
read: () => read,
|
|
22296
22386
|
refuse: () => refuse,
|
|
22297
22387
|
removeScript: () => removeScript,
|
|
@@ -37375,6 +37465,7 @@ var init_BeatStatus = __esmMin((() => {
|
|
|
37375
37465
|
initial,
|
|
37376
37466
|
model: rendered.model,
|
|
37377
37467
|
system: rendered.system !== void 0 && rendered.system !== "" ? rendered.system : void 0,
|
|
37468
|
+
context: rendered.context,
|
|
37378
37469
|
log,
|
|
37379
37470
|
state: rendered.state,
|
|
37380
37471
|
actor: rendered.actor,
|
|
@@ -37433,6 +37524,7 @@ var init_BeatDocument = __esmMin((() => {
|
|
|
37433
37524
|
session,
|
|
37434
37525
|
model: status.model,
|
|
37435
37526
|
system: status.system,
|
|
37527
|
+
context: status.context,
|
|
37436
37528
|
validate,
|
|
37437
37529
|
log: status.log,
|
|
37438
37530
|
state: status.state,
|
|
@@ -37674,6 +37766,91 @@ var init_Slices = __esmMin((() => {
|
|
|
37674
37766
|
renderSlicesJson = (document) => JSON.stringify(document) + "\n";
|
|
37675
37767
|
}));
|
|
37676
37768
|
//#endregion
|
|
37769
|
+
//#region src/wire/ContextLimit.ts
|
|
37770
|
+
var DEFAULT_CONTEXT_LIMIT, DEFAULT_WINDOW, LONG_WINDOW, contextWindowFor, parseContextWindow, CONTEXT_STOP_FILE_ENV, contextShapeFault, contextLimitFault, record, count, usageTokens, transcriptTokens, CONTEXT_LIMIT_MARKER, percent, contextHook, hookOutput;
|
|
37771
|
+
var init_ContextLimit = __esmMin((() => {
|
|
37772
|
+
DEFAULT_CONTEXT_LIMIT = {
|
|
37773
|
+
soft: .6,
|
|
37774
|
+
hard: .7
|
|
37775
|
+
};
|
|
37776
|
+
DEFAULT_WINDOW = 2e5;
|
|
37777
|
+
LONG_WINDOW = 1e6;
|
|
37778
|
+
contextWindowFor = (model) => model !== void 0 && /\[1m\]/i.test(model) ? LONG_WINDOW : DEFAULT_WINDOW;
|
|
37779
|
+
parseContextWindow = (raw) => {
|
|
37780
|
+
const n = Number(raw);
|
|
37781
|
+
return raw !== void 0 && raw.trim() !== "" && Number.isInteger(n) && n > 0 ? n : void 0;
|
|
37782
|
+
};
|
|
37783
|
+
CONTEXT_STOP_FILE_ENV = "GTD_LOOP_CONTEXT_STOP_FILE";
|
|
37784
|
+
contextShapeFault = (limit) => {
|
|
37785
|
+
if (typeof limit !== "object" || limit === null || Array.isArray(limit)) return `context must be an object { soft, hard }, got ${JSON.stringify(limit)}`;
|
|
37786
|
+
const unknown = Object.keys(limit).filter((key) => key !== "soft" && key !== "hard");
|
|
37787
|
+
if (unknown.length > 0) return `unknown key(s) ${unknown.join(", ")} in context`;
|
|
37788
|
+
const shares = limit;
|
|
37789
|
+
for (const key of ["soft", "hard"]) {
|
|
37790
|
+
const value = shares[key];
|
|
37791
|
+
if (value === void 0) continue;
|
|
37792
|
+
if (typeof value !== "number" || !(value > 0 && value <= 1)) return `context.${key} must be a share of the context window in (0, 1], got ${JSON.stringify(value)}`;
|
|
37793
|
+
}
|
|
37794
|
+
};
|
|
37795
|
+
contextLimitFault = (limit) => {
|
|
37796
|
+
const shape = contextShapeFault(limit);
|
|
37797
|
+
if (shape !== void 0) return shape;
|
|
37798
|
+
const shares = limit;
|
|
37799
|
+
const soft = shares.soft ?? DEFAULT_CONTEXT_LIMIT.soft;
|
|
37800
|
+
const hard = shares.hard ?? DEFAULT_CONTEXT_LIMIT.hard;
|
|
37801
|
+
return soft < hard ? void 0 : `context.soft (${soft}) must be below context.hard (${hard})`;
|
|
37802
|
+
};
|
|
37803
|
+
record = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
37804
|
+
count = (value) => typeof value === "number" && value > 0 ? value : 0;
|
|
37805
|
+
usageTokens = (usage) => {
|
|
37806
|
+
const u = record(usage);
|
|
37807
|
+
if (u === void 0) return void 0;
|
|
37808
|
+
return count(u["input_tokens"]) + count(u["cache_read_input_tokens"]) + count(u["cache_creation_input_tokens"]);
|
|
37809
|
+
};
|
|
37810
|
+
transcriptTokens = (transcript) => {
|
|
37811
|
+
const lines = transcript.split("\n");
|
|
37812
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
37813
|
+
const line = lines[i].trim();
|
|
37814
|
+
if (line === "") continue;
|
|
37815
|
+
let entry;
|
|
37816
|
+
try {
|
|
37817
|
+
entry = JSON.parse(line);
|
|
37818
|
+
} catch {
|
|
37819
|
+
continue;
|
|
37820
|
+
}
|
|
37821
|
+
if (record(entry)?.["type"] !== "assistant") continue;
|
|
37822
|
+
const tokens = usageTokens(record(record(entry)?.["message"])?.["usage"]);
|
|
37823
|
+
if (tokens !== void 0) return tokens;
|
|
37824
|
+
}
|
|
37825
|
+
};
|
|
37826
|
+
CONTEXT_LIMIT_MARKER = "gtd: context limit";
|
|
37827
|
+
percent = (share) => `${Math.round(share * 100)}%`;
|
|
37828
|
+
contextHook = (input) => {
|
|
37829
|
+
const { event, tokens, window, limit } = input;
|
|
37830
|
+
if (event === "PreCompact") return {
|
|
37831
|
+
kind: "hard",
|
|
37832
|
+
stopReason: `${CONTEXT_LIMIT_MARKER}: the context is about to be compacted — the run is too big for one turn`
|
|
37833
|
+
};
|
|
37834
|
+
if (tokens === void 0) return void 0;
|
|
37835
|
+
const used = `${tokens} of ${window} tokens`;
|
|
37836
|
+
if (tokens >= limit.hard * window) return {
|
|
37837
|
+
kind: "hard",
|
|
37838
|
+
stopReason: `${CONTEXT_LIMIT_MARKER}: ${used}, past the ${percent(limit.hard)} hard limit`
|
|
37839
|
+
};
|
|
37840
|
+
if (tokens >= limit.soft * window) return {
|
|
37841
|
+
kind: "soft",
|
|
37842
|
+
reason: `Context limit: ${used} used, past the ${percent(limit.soft)} soft limit. Stop working now. Do not start anything new; end your turn with a short handoff note as your answer: what you touched, and what was next.`
|
|
37843
|
+
};
|
|
37844
|
+
};
|
|
37845
|
+
hookOutput = (decision) => decision.kind === "soft" ? {
|
|
37846
|
+
decision: "block",
|
|
37847
|
+
reason: decision.reason
|
|
37848
|
+
} : {
|
|
37849
|
+
continue: false,
|
|
37850
|
+
stopReason: decision.stopReason
|
|
37851
|
+
};
|
|
37852
|
+
}));
|
|
37853
|
+
//#endregion
|
|
37677
37854
|
//#region src/wire/index.ts
|
|
37678
37855
|
var init_wire = __esmMin((() => {
|
|
37679
37856
|
init_constants();
|
|
@@ -37689,6 +37866,7 @@ var init_wire = __esmMin((() => {
|
|
|
37689
37866
|
init_Sessions();
|
|
37690
37867
|
init_Glob();
|
|
37691
37868
|
init_Slices();
|
|
37869
|
+
init_ContextLimit();
|
|
37692
37870
|
}));
|
|
37693
37871
|
//#endregion
|
|
37694
37872
|
//#region src/replay/RefName.ts
|
|
@@ -38018,6 +38196,15 @@ const budgeted = (evidence, budgetBytes) => {
|
|
|
38018
38196
|
truncated
|
|
38019
38197
|
};
|
|
38020
38198
|
};
|
|
38199
|
+
const scopeLabel = (chain) => {
|
|
38200
|
+
const path = chain.flatMap((o) => o.name === void 0 ? [] : [o.name]).join(".");
|
|
38201
|
+
if (chain.at(-1)?.name !== void 0) return `scope "${path}"`;
|
|
38202
|
+
return path === "" ? "an unnamed scope" : `an unnamed scope inside "${path}"`;
|
|
38203
|
+
};
|
|
38204
|
+
const inheritedContext = (layers) => layers.reduce((merged, layer) => layer === void 0 ? merged : {
|
|
38205
|
+
...merged,
|
|
38206
|
+
...Object.fromEntries(Object.entries(layer).filter(([, value]) => value !== void 0))
|
|
38207
|
+
}, void 0);
|
|
38021
38208
|
const sameSkills = (a, b) => (a?.length ?? 0) === (b?.length ?? 0) && (a ?? []).every((skill, i) => skill === b?.[i]);
|
|
38022
38209
|
const samePersona = (a, b) => a.model === b.model && a.system === b.system && sameSkills(a.skills, b.skills) && sameAccess(a.access, b.access);
|
|
38023
38210
|
/**
|
|
@@ -38037,6 +38224,7 @@ const KNOWN_OPTIONS = {
|
|
|
38037
38224
|
...STEERING_OPTIONS,
|
|
38038
38225
|
"model",
|
|
38039
38226
|
"system",
|
|
38227
|
+
"context",
|
|
38040
38228
|
"allowEmpty",
|
|
38041
38229
|
"keep"
|
|
38042
38230
|
]),
|
|
@@ -38151,11 +38339,13 @@ const replay = async (input) => {
|
|
|
38151
38339
|
if (s.model !== void 0) persona.model = s.model;
|
|
38152
38340
|
if (s.system !== void 0) persona.system = s.system;
|
|
38153
38341
|
}
|
|
38342
|
+
const context = inheritedContext([...scopes.map((s) => s.context), request.options.context]);
|
|
38154
38343
|
return {
|
|
38155
38344
|
...request,
|
|
38156
38345
|
options: {
|
|
38157
38346
|
...persona,
|
|
38158
|
-
...request.options
|
|
38347
|
+
...request.options,
|
|
38348
|
+
...context === void 0 ? {} : { context }
|
|
38159
38349
|
}
|
|
38160
38350
|
};
|
|
38161
38351
|
}
|
|
@@ -38293,10 +38483,26 @@ const replay = async (input) => {
|
|
|
38293
38483
|
});
|
|
38294
38484
|
return landPending(step, input.pending);
|
|
38295
38485
|
};
|
|
38486
|
+
const scopeContextFault = () => {
|
|
38487
|
+
for (const [i, s] of scopes.entries()) {
|
|
38488
|
+
const fault = s.context === void 0 ? void 0 : contextShapeFault(s.context);
|
|
38489
|
+
if (fault !== void 0) return `the context of ${scopeLabel(scopes.slice(0, i + 1))}: ${fault}`;
|
|
38490
|
+
}
|
|
38491
|
+
};
|
|
38492
|
+
const resolvedContextFault = (request) => {
|
|
38493
|
+
const own = request.options.context;
|
|
38494
|
+
const layered = scopeContextFault() ?? (own === void 0 ? void 0 : contextShapeFault(own));
|
|
38495
|
+
if (layered !== void 0) return layered;
|
|
38496
|
+
const resolved = resolve(request);
|
|
38497
|
+
const context = resolved.kind === "agent" ? resolved.options.context : void 0;
|
|
38498
|
+
return context === void 0 ? void 0 : contextLimitFault(context);
|
|
38499
|
+
};
|
|
38296
38500
|
const requestFault = (request) => {
|
|
38297
38501
|
if (request.kind === "run" && typeof request.body !== "string") return `gtd: step "${scoped(request.name)}": a run() body is a shell script string — decide in flow code, then render the script (see checkScript and friends)`;
|
|
38298
38502
|
if (request.kind !== "agent") return void 0;
|
|
38299
38503
|
const name = scoped(request.name);
|
|
38504
|
+
const contextFault = resolvedContextFault(request);
|
|
38505
|
+
if (contextFault !== void 0) return `gtd: step "${name}": ${contextFault}`;
|
|
38300
38506
|
if (request.options.keep === true) {
|
|
38301
38507
|
if (request.options.allowEmpty === true) return `gtd: step "${name}": keep: true cannot be combined with allowEmpty — a turn that changes nothing has nothing to keep`;
|
|
38302
38508
|
const refFault = name.includes("/") ? "it contains \"/\"" : refNameFault(name);
|
|
@@ -39917,6 +40123,10 @@ const commonOf = (step) => {
|
|
|
39917
40123
|
...optional$1("mode", options.mode)
|
|
39918
40124
|
};
|
|
39919
40125
|
};
|
|
40126
|
+
const stepContext = (context) => context === void 0 ? void 0 : {
|
|
40127
|
+
...optional$1("soft", context.soft),
|
|
40128
|
+
...optional$1("hard", context.hard)
|
|
40129
|
+
};
|
|
39920
40130
|
const promptDef = (common, request, skills, access) => ({
|
|
39921
40131
|
...common,
|
|
39922
40132
|
kind: "prompt",
|
|
@@ -39925,6 +40135,7 @@ const promptDef = (common, request, skills, access) => ({
|
|
|
39925
40135
|
...optional$1("system", request.options.system),
|
|
39926
40136
|
...optional$1("allowEmpty", request.options.allowEmpty),
|
|
39927
40137
|
...optional$1("keep", request.options.keep),
|
|
40138
|
+
...optional$1("context", stepContext(request.options.context)),
|
|
39928
40139
|
...optional$1("skills", skills),
|
|
39929
40140
|
...optional$1("access", access)
|
|
39930
40141
|
});
|
|
@@ -40010,7 +40221,8 @@ const hintsOf = (def) => ({
|
|
|
40010
40221
|
...optional$1("system", def.system),
|
|
40011
40222
|
...optional$1("mode", def.mode),
|
|
40012
40223
|
...optional$1("skills", def.skills),
|
|
40013
|
-
...optional$1("access", def.access)
|
|
40224
|
+
...optional$1("access", def.access),
|
|
40225
|
+
...optional$1("context", def.context)
|
|
40014
40226
|
});
|
|
40015
40227
|
const normalizeStatus = (raw) => raw === "A" ? "A" : raw === "D" ? "D" : "M";
|
|
40016
40228
|
/** Per-model token totals, highest-cost first (ties broken by model name). */
|
|
@@ -41292,6 +41504,17 @@ const readStdin = () => tryPromise({
|
|
|
41292
41504
|
},
|
|
41293
41505
|
catch: (e) => e instanceof Error ? e : new Error(String(e))
|
|
41294
41506
|
});
|
|
41507
|
+
/** Stdout is written once: a hook reads one JSON document, or none. */
|
|
41508
|
+
const runContextHookCommand = (command, out) => gen(function* () {
|
|
41509
|
+
const tools = yield* ToolCommands;
|
|
41510
|
+
const input = yield* readStdin();
|
|
41511
|
+
out.write(yield* tools.contextHook({
|
|
41512
|
+
input,
|
|
41513
|
+
...command.soft !== void 0 ? { soft: command.soft } : {},
|
|
41514
|
+
...command.hard !== void 0 ? { hard: command.hard } : {},
|
|
41515
|
+
...command.window !== void 0 ? { window: command.window } : {}
|
|
41516
|
+
}));
|
|
41517
|
+
});
|
|
41295
41518
|
/** Stdout is written once, after the answerer resolves — a rejection leaves it empty. */
|
|
41296
41519
|
const runJudgeRunCommand = (command, out) => gen(function* () {
|
|
41297
41520
|
const host = yield* Host;
|
|
@@ -41751,6 +41974,7 @@ const needsOf = (kind) => {
|
|
|
41751
41974
|
case "lsp":
|
|
41752
41975
|
case "install":
|
|
41753
41976
|
case "loop":
|
|
41977
|
+
case "contextHook":
|
|
41754
41978
|
case "judgeRun":
|
|
41755
41979
|
case "strays": return "none";
|
|
41756
41980
|
case "check":
|
|
@@ -41790,6 +42014,7 @@ const dispatchVoidCommand = (command, json, out) => {
|
|
|
41790
42014
|
case "uncheck": return runUncheckCommand(command.file);
|
|
41791
42015
|
case "install": return runInstallCommand(out);
|
|
41792
42016
|
case "loop": return runLoopCommand();
|
|
42017
|
+
case "contextHook": return runContextHookCommand(command, out);
|
|
41793
42018
|
case "summary": return runSummaryCommand(out, command.slice);
|
|
41794
42019
|
case "base": return runBaseCommand(out);
|
|
41795
42020
|
case "judge": return runJudgeCommand(json, out);
|
|
@@ -41833,6 +42058,10 @@ const nonNegativeNumber = (raw, flag) => {
|
|
|
41833
42058
|
if (raw.trim() === "" || !Number.isFinite(n) || n < 0) return left(`gtd: ${flag} must be a non-negative number — got "${raw}"`);
|
|
41834
42059
|
return right(n);
|
|
41835
42060
|
};
|
|
42061
|
+
const share = (raw, flag) => {
|
|
42062
|
+
const n = Number(raw);
|
|
42063
|
+
return raw.trim() !== "" && n > 0 && n <= 1 ? right(n) : left(`gtd: ${flag} must be a share of the context window in (0, 1] — got "${raw}"`);
|
|
42064
|
+
};
|
|
41836
42065
|
const FLAGS = [
|
|
41837
42066
|
{
|
|
41838
42067
|
name: "--json",
|
|
@@ -41960,6 +42189,39 @@ const FLAGS = [
|
|
|
41960
42189
|
"GTD_JUDGE_MODEL, then judge.json, then sonnet"
|
|
41961
42190
|
]
|
|
41962
42191
|
},
|
|
42192
|
+
{
|
|
42193
|
+
name: "--soft",
|
|
42194
|
+
arity: 1,
|
|
42195
|
+
repeatable: false,
|
|
42196
|
+
scope: (kind) => kind === "contextHook",
|
|
42197
|
+
decode: ([raw]) => share(raw ?? "", "--soft"),
|
|
42198
|
+
scopeError: "gtd: --soft is only valid for `gtd context-hook`",
|
|
42199
|
+
valueHint: "<share>",
|
|
42200
|
+
help: ["(gtd context-hook only) the soft limit; default 0.6"]
|
|
42201
|
+
},
|
|
42202
|
+
{
|
|
42203
|
+
name: "--hard",
|
|
42204
|
+
arity: 1,
|
|
42205
|
+
repeatable: false,
|
|
42206
|
+
scope: (kind) => kind === "contextHook",
|
|
42207
|
+
decode: ([raw]) => share(raw ?? "", "--hard"),
|
|
42208
|
+
scopeError: "gtd: --hard is only valid for `gtd context-hook`",
|
|
42209
|
+
valueHint: "<share>",
|
|
42210
|
+
help: ["(gtd context-hook only) the hard limit; default 0.7"]
|
|
42211
|
+
},
|
|
42212
|
+
{
|
|
42213
|
+
name: "--window",
|
|
42214
|
+
arity: 1,
|
|
42215
|
+
repeatable: false,
|
|
42216
|
+
scope: (kind) => kind === "contextHook",
|
|
42217
|
+
decode: ([raw]) => {
|
|
42218
|
+
const window = parseContextWindow(raw);
|
|
42219
|
+
return window !== void 0 ? right(window) : left(`gtd: --window must be a positive integer — got "${raw ?? ""}"`);
|
|
42220
|
+
},
|
|
42221
|
+
scopeError: "gtd: --window is only valid for `gtd context-hook`",
|
|
42222
|
+
valueHint: "<tokens>",
|
|
42223
|
+
help: ["(gtd context-hook only) the model's context window in", "tokens; default 200000"]
|
|
42224
|
+
},
|
|
41963
42225
|
{
|
|
41964
42226
|
name: "--slice",
|
|
41965
42227
|
arity: 1,
|
|
@@ -42266,6 +42528,22 @@ const COMMAND_ROWS = [
|
|
|
42266
42528
|
"~/.config/gtd/loop.json); see docs/driver.md"
|
|
42267
42529
|
]
|
|
42268
42530
|
},
|
|
42531
|
+
{
|
|
42532
|
+
token: "context-hook",
|
|
42533
|
+
kind: "contextHook",
|
|
42534
|
+
arity: "none",
|
|
42535
|
+
details: [
|
|
42536
|
+
"A Claude Code PostToolUse and PreCompact hook that stops an",
|
|
42537
|
+
"agent turn at a share of its context window. Reads the",
|
|
42538
|
+
"hook's input on stdin and the context the transcript's",
|
|
42539
|
+
"latest assistant message used. Past --soft it blocks with a",
|
|
42540
|
+
"request to end the turn with a handoff note; past --hard,",
|
|
42541
|
+
"or at PreCompact, it stops the turn with a stopReason",
|
|
42542
|
+
"starting \"gtd: context limit\". Prints nothing otherwise,",
|
|
42543
|
+
"and for a subagent's tool call. Always exits 0 on valid",
|
|
42544
|
+
"input; see docs/driver.md"
|
|
42545
|
+
]
|
|
42546
|
+
},
|
|
42269
42547
|
{
|
|
42270
42548
|
token: "summary",
|
|
42271
42549
|
kind: "summary",
|
|
@@ -42744,6 +43022,17 @@ const parseArgv = (argv) => {
|
|
|
42744
43022
|
verbose
|
|
42745
43023
|
};
|
|
42746
43024
|
}
|
|
43025
|
+
if (kind === "contextHook") return {
|
|
43026
|
+
kind: "command",
|
|
43027
|
+
command: {
|
|
43028
|
+
kind: "contextHook",
|
|
43029
|
+
...bag["--soft"] !== void 0 ? { soft: bag["--soft"] } : {},
|
|
43030
|
+
...bag["--hard"] !== void 0 ? { hard: bag["--hard"] } : {},
|
|
43031
|
+
...bag["--window"] !== void 0 ? { window: bag["--window"] } : {}
|
|
43032
|
+
},
|
|
43033
|
+
json,
|
|
43034
|
+
verbose
|
|
43035
|
+
};
|
|
42747
43036
|
if (kind === "summary") return {
|
|
42748
43037
|
kind: "command",
|
|
42749
43038
|
command: {
|
|
@@ -58422,8 +58711,9 @@ var init_lsp = __esmMin((() => {
|
|
|
58422
58711
|
}));
|
|
58423
58712
|
//#endregion
|
|
58424
58713
|
//#region src/loop/Agent.ts
|
|
58425
|
-
var optional, parseJson, field, costOf, claude, pi, agentCli;
|
|
58714
|
+
var optional, parseJson, field$1, costOf, claude, hookSettings, pi, agentCli;
|
|
58426
58715
|
var init_Agent = __esmMin((() => {
|
|
58716
|
+
init_wire();
|
|
58427
58717
|
optional = (flag, value) => value === void 0 || value === "" ? [] : [flag, value];
|
|
58428
58718
|
parseJson = (text) => {
|
|
58429
58719
|
try {
|
|
@@ -58432,7 +58722,7 @@ var init_Agent = __esmMin((() => {
|
|
|
58432
58722
|
return;
|
|
58433
58723
|
}
|
|
58434
58724
|
};
|
|
58435
|
-
field = (value, key) => typeof value === "object" && value !== null ? value[key] : void 0;
|
|
58725
|
+
field$1 = (value, key) => typeof value === "object" && value !== null ? value[key] : void 0;
|
|
58436
58726
|
costOf = (value) => typeof value === "number" && value > 0 ? value : 0;
|
|
58437
58727
|
claude = {
|
|
58438
58728
|
command: "claude",
|
|
@@ -58442,19 +58732,45 @@ var init_Agent = __esmMin((() => {
|
|
|
58442
58732
|
turn.sessionId,
|
|
58443
58733
|
...optional("--model", turn.model),
|
|
58444
58734
|
...optional("--system-prompt", turn.system),
|
|
58735
|
+
"--settings",
|
|
58736
|
+
JSON.stringify(hookSettings(turn.hook)),
|
|
58445
58737
|
"--output-format",
|
|
58446
|
-
"json",
|
|
58738
|
+
"stream-json",
|
|
58739
|
+
"--verbose",
|
|
58447
58740
|
"--dangerously-skip-permissions"
|
|
58448
58741
|
],
|
|
58449
58742
|
read: (exit) => {
|
|
58450
|
-
const
|
|
58451
|
-
|
|
58743
|
+
const lines = exit.stdout.split("\n");
|
|
58744
|
+
let envelope;
|
|
58745
|
+
for (let i = lines.length - 1; i >= 0 && envelope === void 0; i--) {
|
|
58746
|
+
const event = parseJson(lines[i]);
|
|
58747
|
+
if (field$1(event, "type") === "result" || field$1(event, "result") !== void 0) envelope = event;
|
|
58748
|
+
}
|
|
58749
|
+
const result = field$1(envelope, "result");
|
|
58750
|
+
const hookStopped = field$1(envelope, "terminal_reason") === "hook_stopped";
|
|
58452
58751
|
return {
|
|
58453
|
-
ok: exit.code === 0 && field(envelope, "is_error") !== true,
|
|
58454
|
-
text: typeof result === "string" ? result :
|
|
58455
|
-
cost: costOf(field(envelope, "total_cost_usd"))
|
|
58752
|
+
ok: exit.code === 0 && field$1(envelope, "is_error") !== true && !hookStopped,
|
|
58753
|
+
text: typeof result === "string" ? result : lines.slice(-5).join("\n"),
|
|
58754
|
+
cost: costOf(field$1(envelope, "total_cost_usd")),
|
|
58755
|
+
hookStopped
|
|
58456
58756
|
};
|
|
58457
|
-
}
|
|
58757
|
+
},
|
|
58758
|
+
contextTokens: (line) => {
|
|
58759
|
+
const event = parseJson(line);
|
|
58760
|
+
if (field$1(event, "type") !== "assistant") return void 0;
|
|
58761
|
+
if (field$1(event, "parent_tool_use_id") != null) return void 0;
|
|
58762
|
+
return usageTokens(field$1(field$1(event, "message"), "usage"));
|
|
58763
|
+
}
|
|
58764
|
+
};
|
|
58765
|
+
hookSettings = (command) => {
|
|
58766
|
+
const hook = [{ hooks: [{
|
|
58767
|
+
type: "command",
|
|
58768
|
+
command
|
|
58769
|
+
}] }];
|
|
58770
|
+
return { hooks: {
|
|
58771
|
+
PostToolUse: hook,
|
|
58772
|
+
PreCompact: hook
|
|
58773
|
+
} };
|
|
58458
58774
|
};
|
|
58459
58775
|
pi = {
|
|
58460
58776
|
command: "pi",
|
|
@@ -58470,13 +58786,14 @@ var init_Agent = __esmMin((() => {
|
|
|
58470
58786
|
],
|
|
58471
58787
|
read: (exit) => {
|
|
58472
58788
|
const events = exit.stdout.split("\n").map(parseJson).filter((event) => event !== void 0);
|
|
58473
|
-
const message = field(events.findLast((event) => field(event, "type") === "message_end" && field(field(event, "message"), "role") === "assistant"), "message");
|
|
58474
|
-
const content = field(message, "content");
|
|
58475
|
-
const text = (Array.isArray(content) ? content : []).filter((part) => field(part, "type") === "text").map((part) => String(field(part, "text"))).join("\n");
|
|
58789
|
+
const message = field$1(events.findLast((event) => field$1(event, "type") === "message_end" && field$1(field$1(event, "message"), "role") === "assistant"), "message");
|
|
58790
|
+
const content = field$1(message, "content");
|
|
58791
|
+
const text = (Array.isArray(content) ? content : []).filter((part) => field$1(part, "type") === "text").map((part) => String(field$1(part, "text"))).join("\n");
|
|
58476
58792
|
return {
|
|
58477
|
-
ok: exit.code === 0 && !events.some((event) => field(event, "type") === "error"),
|
|
58793
|
+
ok: exit.code === 0 && !events.some((event) => field$1(event, "type") === "error"),
|
|
58478
58794
|
text: text === "" ? exit.stdout : text,
|
|
58479
|
-
cost: costOf(field(field(field(message, "usage"), "cost"), "total"))
|
|
58795
|
+
cost: costOf(field$1(field$1(field$1(message, "usage"), "cost"), "total")),
|
|
58796
|
+
hookStopped: false
|
|
58480
58797
|
};
|
|
58481
58798
|
}
|
|
58482
58799
|
};
|
|
@@ -58501,6 +58818,10 @@ var init_Documents = __esmMin((() => {
|
|
|
58501
58818
|
})),
|
|
58502
58819
|
model: optional$2(String$),
|
|
58503
58820
|
system: optional$2(String$),
|
|
58821
|
+
context: optional$2(Struct({
|
|
58822
|
+
soft: optionalWith(Number$, { exact: true }),
|
|
58823
|
+
hard: optionalWith(Number$, { exact: true })
|
|
58824
|
+
})),
|
|
58504
58825
|
validate: optional$2(String$),
|
|
58505
58826
|
label: optional$2(String$),
|
|
58506
58827
|
judge: optional$2(String$)
|
|
@@ -58548,9 +58869,30 @@ var init_Host = __esmMin((() => {
|
|
|
58548
58869
|
],
|
|
58549
58870
|
detached: true
|
|
58550
58871
|
});
|
|
58872
|
+
const killGroup = (signal) => {
|
|
58873
|
+
try {
|
|
58874
|
+
if (child.pid !== void 0) process.kill(-child.pid, signal);
|
|
58875
|
+
} catch {}
|
|
58876
|
+
};
|
|
58551
58877
|
let stdout = "";
|
|
58552
58878
|
let stderr = "";
|
|
58553
|
-
|
|
58879
|
+
let stopped = false;
|
|
58880
|
+
let stopForce;
|
|
58881
|
+
let scanned = 0;
|
|
58882
|
+
child.stdout?.setEncoding("utf-8").on("data", (chunk) => {
|
|
58883
|
+
stdout += chunk;
|
|
58884
|
+
if (request.stopAt === void 0 || stopped) return;
|
|
58885
|
+
for (let end = stdout.indexOf("\n", scanned); end !== -1; end = stdout.indexOf("\n", scanned)) {
|
|
58886
|
+
const line = stdout.slice(scanned, end);
|
|
58887
|
+
scanned = end + 1;
|
|
58888
|
+
if (request.stopAt(line)) {
|
|
58889
|
+
stopped = true;
|
|
58890
|
+
killGroup("SIGTERM");
|
|
58891
|
+
stopForce = setTimeout(() => killGroup("SIGKILL"), KILL_GRACE_MS);
|
|
58892
|
+
return;
|
|
58893
|
+
}
|
|
58894
|
+
}
|
|
58895
|
+
});
|
|
58554
58896
|
child.stderr?.setEncoding("utf-8").on("data", (chunk) => stderr += chunk);
|
|
58555
58897
|
child.stdin?.on("error", () => {});
|
|
58556
58898
|
child.stdin?.end(request.stdin);
|
|
@@ -58563,18 +58905,15 @@ var init_Host = __esmMin((() => {
|
|
|
58563
58905
|
};
|
|
58564
58906
|
child.on("error", (error) => settle(fail$7(/* @__PURE__ */ new Error(`could not run ${request.command}: ${error.message}`))));
|
|
58565
58907
|
child.on("close", (code, signal) => {
|
|
58908
|
+
clearTimeout(stopForce);
|
|
58566
58909
|
const exit = code ?? 128 + (signal === null ? 0 : constants.signals[signal] ?? 0);
|
|
58567
58910
|
settle(succeed$3({
|
|
58568
58911
|
code: exit,
|
|
58569
58912
|
stdout,
|
|
58570
|
-
stderr
|
|
58913
|
+
stderr,
|
|
58914
|
+
...stopped ? { stopped: true } : {}
|
|
58571
58915
|
}));
|
|
58572
58916
|
});
|
|
58573
|
-
const killGroup = (signal) => {
|
|
58574
|
-
try {
|
|
58575
|
-
if (child.pid !== void 0) process.kill(-child.pid, signal);
|
|
58576
|
-
} catch {}
|
|
58577
|
-
};
|
|
58578
58917
|
return async((done) => {
|
|
58579
58918
|
if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
|
|
58580
58919
|
killGroup("SIGTERM");
|
|
@@ -58618,9 +58957,10 @@ var init_Host = __esmMin((() => {
|
|
|
58618
58957
|
}));
|
|
58619
58958
|
//#endregion
|
|
58620
58959
|
//#region src/loop/Settings.ts
|
|
58621
|
-
var Agent, CLAUDE_MODELS, BUNDLED_HINTS, SettingsFile, settingsPath, MODEL_ENV_PREFIX, modelEnvName, decodeFile, decodeAgent, resolveSettings, resolveModel;
|
|
58960
|
+
var Agent, CLAUDE_MODELS, BUNDLED_HINTS, SettingsFile, settingsPath, MODEL_ENV_PREFIX, modelEnvName, decodeFile, decodeAgent, decodeWindow, resolveSettings, resolveModel;
|
|
58622
58961
|
var init_Settings = __esmMin((() => {
|
|
58623
58962
|
init_esm();
|
|
58963
|
+
init_wire();
|
|
58624
58964
|
Agent = Literal("claude", "pi");
|
|
58625
58965
|
CLAUDE_MODELS = {
|
|
58626
58966
|
smart: "opus",
|
|
@@ -58632,7 +58972,8 @@ var init_Settings = __esmMin((() => {
|
|
|
58632
58972
|
models: optional$2(Record({
|
|
58633
58973
|
key: String$,
|
|
58634
58974
|
value: String$
|
|
58635
|
-
}))
|
|
58975
|
+
})),
|
|
58976
|
+
contextWindow: optional$2(Int.pipe(positive()))
|
|
58636
58977
|
});
|
|
58637
58978
|
settingsPath = (env) => {
|
|
58638
58979
|
const explicit = env["GTD_LOOP_CONFIG"];
|
|
@@ -58654,9 +58995,15 @@ var init_Settings = __esmMin((() => {
|
|
|
58654
58995
|
return decodeUnknownEither(SettingsFile, { onExcessProperty: "error" })(json).pipe(mapLeft((error) => `${path}: ${error.message}`));
|
|
58655
58996
|
};
|
|
58656
58997
|
decodeAgent = (value) => value === void 0 || value === "" ? right(void 0) : decodeUnknownEither(Agent)(value).pipe(mapLeft(() => `GTD_LOOP_AGENT must be "claude" or "pi" — got "${value}"`));
|
|
58998
|
+
decodeWindow = (value) => {
|
|
58999
|
+
if (value === void 0 || value === "") return right(void 0);
|
|
59000
|
+
const window = parseContextWindow(value);
|
|
59001
|
+
return window !== void 0 ? right(window) : left(`GTD_LOOP_CONTEXT_WINDOW must be a positive integer — got "${value}"`);
|
|
59002
|
+
};
|
|
58657
59003
|
resolveSettings = (env, file) => gen$2(function* () {
|
|
58658
59004
|
const fromFile = file === void 0 ? {} : yield* decodeFile(file.path, file.text);
|
|
58659
59005
|
const envAgent = yield* decodeAgent(env["GTD_LOOP_AGENT"]);
|
|
59006
|
+
const envWindow = yield* decodeWindow(env["GTD_LOOP_CONTEXT_WINDOW"]);
|
|
58660
59007
|
const envModels = Object.fromEntries(Object.entries(env).filter((entry) => entry[0].startsWith(MODEL_ENV_PREFIX) && entry[1] !== void 0 && entry[1] !== ""));
|
|
58661
59008
|
const agent = envAgent ?? fromFile.agent ?? "claude";
|
|
58662
59009
|
return {
|
|
@@ -58665,7 +59012,8 @@ var init_Settings = __esmMin((() => {
|
|
|
58665
59012
|
...agent === "claude" ? CLAUDE_MODELS : {},
|
|
58666
59013
|
...fromFile.models
|
|
58667
59014
|
},
|
|
58668
|
-
envModels
|
|
59015
|
+
envModels,
|
|
59016
|
+
contextWindow: envWindow ?? fromFile.contextWindow
|
|
58669
59017
|
};
|
|
58670
59018
|
});
|
|
58671
59019
|
resolveModel = (settings, hint) => {
|
|
@@ -58675,9 +59023,10 @@ var init_Settings = __esmMin((() => {
|
|
|
58675
59023
|
}));
|
|
58676
59024
|
//#endregion
|
|
58677
59025
|
//#region src/loop/Loop.ts
|
|
58678
|
-
var MAX_VALIDATION_FIXES, FAILURE_LINES, LAND, fromEither, paint, firstLines, loadSettings, gitRoot, gtd, readBeat, clock, header, rest, agentFailed, agentTurn, sessionFlags, validateOnce, promptBeat, runScript, stop, judgeGate, messageBeat, kindBeat, runBeat, costFlags, land, runLoop;
|
|
59026
|
+
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;
|
|
58679
59027
|
var init_Loop = __esmMin((() => {
|
|
58680
59028
|
init_esm();
|
|
59029
|
+
init_wire();
|
|
58681
59030
|
init_Agent();
|
|
58682
59031
|
init_Documents();
|
|
58683
59032
|
init_Host();
|
|
@@ -58730,23 +59079,61 @@ var init_Loop = __esmMin((() => {
|
|
|
58730
59079
|
...exit.stderr.trim() === "" ? [] : [firstLines(exit.stderr)],
|
|
58731
59080
|
...result.text.trim() === "" ? [] : [firstLines(result.text)]
|
|
58732
59081
|
].join("\n") + "\n");
|
|
59082
|
+
quote = (arg) => `'${arg.replaceAll("'", "'\\''")}'`;
|
|
59083
|
+
contextGuard = (ctx, doc, model) => {
|
|
59084
|
+
const limit = {
|
|
59085
|
+
...DEFAULT_CONTEXT_LIMIT,
|
|
59086
|
+
...doc.context
|
|
59087
|
+
};
|
|
59088
|
+
const window = ctx.settings.contextWindow ?? contextWindowFor(model);
|
|
59089
|
+
return {
|
|
59090
|
+
limit,
|
|
59091
|
+
window,
|
|
59092
|
+
hook: [...ctx.gtd, "context-hook"].concat([
|
|
59093
|
+
"--soft",
|
|
59094
|
+
String(limit.soft),
|
|
59095
|
+
"--hard",
|
|
59096
|
+
String(limit.hard),
|
|
59097
|
+
"--window",
|
|
59098
|
+
String(window)
|
|
59099
|
+
]).map(quote).join(" "),
|
|
59100
|
+
kill: (limit.hard + 1) / 2
|
|
59101
|
+
};
|
|
59102
|
+
};
|
|
59103
|
+
contextStop = (ctx, exit, guard, stopFile) => map$4(ctx.host.readFile(stopFile), (recorded) => {
|
|
59104
|
+
const reason = recorded?.trim().split("\n")[0];
|
|
59105
|
+
if (reason !== void 0 && reason !== "") return reason;
|
|
59106
|
+
if (exit.stopped !== true) return void 0;
|
|
59107
|
+
return `${CONTEXT_LIMIT_MARKER}: the stream passed ${Math.round(guard.kill * 100)}% of ${guard.window} tokens with no hook stopping it`;
|
|
59108
|
+
});
|
|
58733
59109
|
agentTurn = (ctx, doc, model) => (prompt, sessionFlag) => gen(function* () {
|
|
58734
59110
|
const cli = agentCli(ctx.settings.agent);
|
|
59111
|
+
const guard = contextGuard(ctx, doc, model);
|
|
59112
|
+
const tokensOf = cli.contextTokens;
|
|
59113
|
+
const stopFile = `${ctx.log}.context-stop`;
|
|
59114
|
+
yield* ctx.host.resetLog(stopFile);
|
|
58735
59115
|
const exit = yield* ctx.host.spawn({
|
|
58736
59116
|
command: cli.command,
|
|
58737
59117
|
args: cli.args({
|
|
58738
59118
|
sessionFlag,
|
|
58739
59119
|
sessionId: doc.session?.id ?? "",
|
|
58740
59120
|
model,
|
|
58741
|
-
system: doc.system
|
|
59121
|
+
system: doc.system,
|
|
59122
|
+
hook: guard.hook
|
|
58742
59123
|
}),
|
|
58743
59124
|
cwd: ctx.root,
|
|
58744
59125
|
stdin: prompt,
|
|
58745
|
-
env: {
|
|
58746
|
-
|
|
59126
|
+
env: {
|
|
59127
|
+
CLAUDE_CODE_DISABLE_BACKGROUND_TASKS: "1",
|
|
59128
|
+
[CONTEXT_STOP_FILE_ENV]: stopFile
|
|
59129
|
+
},
|
|
59130
|
+
output: "capture",
|
|
59131
|
+
...tokensOf === void 0 ? {} : { stopAt: (line) => (tokensOf(line) ?? 0) >= guard.kill * guard.window }
|
|
58747
59132
|
});
|
|
58748
59133
|
const result = cli.read(exit);
|
|
58749
59134
|
yield* ctx.host.appendLog(ctx.log, `${exit.stderr}${result.text}\n`);
|
|
59135
|
+
const why = yield* contextStop(ctx, exit, guard, stopFile);
|
|
59136
|
+
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}`));
|
|
58750
59137
|
if (!result.ok) yield* agentFailed(ctx, exit, result);
|
|
58751
59138
|
return result;
|
|
58752
59139
|
});
|
|
@@ -58876,15 +59263,66 @@ var init_Loop = __esmMin((() => {
|
|
|
58876
59263
|
});
|
|
58877
59264
|
}));
|
|
58878
59265
|
//#endregion
|
|
59266
|
+
//#region src/loop/ContextHook.ts
|
|
59267
|
+
var field, limitOf, parseInput, tokensOf, recordStop, runContextHook;
|
|
59268
|
+
var init_ContextHook = __esmMin((() => {
|
|
59269
|
+
init_esm();
|
|
59270
|
+
init_wire();
|
|
59271
|
+
init_Host();
|
|
59272
|
+
field = (value, key) => typeof value === "object" && value !== null ? value[key] : void 0;
|
|
59273
|
+
limitOf = (request) => {
|
|
59274
|
+
const limit = {
|
|
59275
|
+
soft: request.soft ?? DEFAULT_CONTEXT_LIMIT.soft,
|
|
59276
|
+
hard: request.hard ?? DEFAULT_CONTEXT_LIMIT.hard
|
|
59277
|
+
};
|
|
59278
|
+
const fault = contextLimitFault(limit);
|
|
59279
|
+
return fault === void 0 ? succeed$3(limit) : fail$7(/* @__PURE__ */ new Error(`gtd context-hook: ${fault}`));
|
|
59280
|
+
};
|
|
59281
|
+
parseInput = (text) => try_({
|
|
59282
|
+
try: () => JSON.parse(text),
|
|
59283
|
+
catch: () => /* @__PURE__ */ new Error("gtd context-hook: stdin is not a hook's JSON input")
|
|
59284
|
+
}).pipe(map$4((input) => {
|
|
59285
|
+
const event = field(input, "hook_event_name");
|
|
59286
|
+
if (event !== "PostToolUse" && event !== "PreCompact") return void 0;
|
|
59287
|
+
if (field(input, "agent_id") !== void 0) return void 0;
|
|
59288
|
+
const path = field(input, "transcript_path");
|
|
59289
|
+
return {
|
|
59290
|
+
event,
|
|
59291
|
+
transcript: typeof path === "string" && path !== "" ? path : void 0
|
|
59292
|
+
};
|
|
59293
|
+
}));
|
|
59294
|
+
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);
|
|
59295
|
+
recordStop = (stopReason) => flatMap$4(LoopHost, (host) => {
|
|
59296
|
+
const file = host.env[CONTEXT_STOP_FILE_ENV];
|
|
59297
|
+
return file === void 0 || file === "" ? _void : host.appendLog(file, `${stopReason}\n`).pipe(catchAllDefect(() => _void));
|
|
59298
|
+
});
|
|
59299
|
+
runContextHook = (request) => gen(function* () {
|
|
59300
|
+
const limit = yield* limitOf(request);
|
|
59301
|
+
const input = yield* parseInput(request.input);
|
|
59302
|
+
if (input === void 0) return "";
|
|
59303
|
+
const decision = contextHook({
|
|
59304
|
+
event: input.event,
|
|
59305
|
+
tokens: yield* tokensOf(input),
|
|
59306
|
+
window: request.window ?? contextWindowFor(void 0),
|
|
59307
|
+
limit
|
|
59308
|
+
});
|
|
59309
|
+
if (decision === void 0) return "";
|
|
59310
|
+
if (decision.kind === "hard") yield* recordStop(decision.stopReason);
|
|
59311
|
+
return `${JSON.stringify(hookOutput(decision))}\n`;
|
|
59312
|
+
});
|
|
59313
|
+
}));
|
|
59314
|
+
//#endregion
|
|
58879
59315
|
//#region src/loop/index.ts
|
|
58880
59316
|
var loop_exports = /* @__PURE__ */ __exportAll({
|
|
58881
59317
|
LoopHost: () => LoopHost,
|
|
58882
59318
|
liveLoopHost: () => liveLoopHost,
|
|
59319
|
+
runContextHook: () => runContextHook,
|
|
58883
59320
|
runLoop: () => runLoop
|
|
58884
59321
|
});
|
|
58885
59322
|
var init_loop = __esmMin((() => {
|
|
58886
59323
|
init_Loop();
|
|
58887
59324
|
init_Host();
|
|
59325
|
+
init_ContextHook();
|
|
58888
59326
|
}));
|
|
58889
59327
|
//#endregion
|
|
58890
59328
|
//#region src/judges/providers/io.ts
|
|
@@ -59373,6 +59811,10 @@ const liveToolCommands = effect$1(ToolCommands, gen(function* () {
|
|
|
59373
59811
|
const { runLoop, liveLoopHost } = await Promise.resolve().then(() => (init_loop(), loop_exports));
|
|
59374
59812
|
return () => runLoop({ gtd }).pipe(provide$1(liveLoopHost));
|
|
59375
59813
|
}),
|
|
59814
|
+
contextHook: (request) => lazy("loop", async () => {
|
|
59815
|
+
const { runContextHook, liveLoopHost } = await Promise.resolve().then(() => (init_loop(), loop_exports));
|
|
59816
|
+
return () => runContextHook(request).pipe(provide$1(liveLoopHost));
|
|
59817
|
+
}),
|
|
59376
59818
|
judge: async (request) => {
|
|
59377
59819
|
const { runJudge } = await Promise.resolve().then(() => (init_judges(), judges_exports)).catch((error) => {
|
|
59378
59820
|
throw loadFailure("judge")(error);
|