@pmelab/gtd 35.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 +45 -29
- 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-C8Fm3s72.mjs → reserved-zAfoJtR7.mjs} +62 -24
- package/dist/chunks/{tail-oaYewBN_.mjs → tail-BRC4DGdV.mjs} +1 -1
- package/dist/chunks/{wire-D3Rc5r22.mjs → wire-CSsa3Wxd.mjs} +117 -2
- package/dist/flows.mjs +15 -10
- package/dist/gtd.bundle.mjs +511 -64
- package/dist/testkit.mjs +158 -26
- package/dist/wire.mjs +2 -2
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +138 -38
- 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 +208 -66
- package/package.json +1 -1
- package/skills/authoring/SKILL.md +3 -3
- 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/flows/scripts.ts +31 -9
- package/src/replay/Replay.ts +51 -2
- package/src/testkit/FlowScripts.test.ts +58 -0
- package/src/testkit/FlowScripts.ts +61 -24
- 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/acceptance-criteria.feature +5 -1
- package/src/workflows/feature/context-limit.feature +37 -0
- package/src/workflows/feature/coverage.feature +6 -3
- package/src/workflows/feature/coverage.ts +8 -2
- package/src/workflows/feature/fast-path.feature +11 -19
- package/src/workflows/feature/feature.test.ts +24 -4
- package/src/workflows/feature/feature.ts +14 -10
- package/src/workflows/feature/flag-mode.feature +17 -9
- package/src/workflows/feature/lens-models.feature +7 -1
- package/src/workflows/feature/naive-acceptance.feature +2 -2
- package/src/workflows/feature/one-step-land.feature +10 -12
- package/src/workflows/feature/quality-unresolved.feature +7 -1
- 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/risk-tier.feature +12 -4
- package/src/workflows/feature/seam-rejection.feature +4 -9
- package/src/workflows/feature/seam.feature +29 -26
- package/src/workflows/feature/seam.test.ts +117 -6
- package/src/workflows/feature/seam.ts +158 -39
- package/src/workflows/review/review-door.feature +12 -4
- 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.test.ts +8 -0
- package/src/workflows/shared/text.ts +91 -22
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}`),
|
|
@@ -21865,26 +21955,22 @@ const checkScript = (command, options) => {
|
|
|
21865
21955
|
""
|
|
21866
21956
|
].join("\n");
|
|
21867
21957
|
};
|
|
21868
|
-
|
|
21869
|
-
|
|
21870
|
-
|
|
21871
|
-
|
|
21872
|
-
*/
|
|
21873
|
-
const revertScript = (commit, report, failure) => {
|
|
21874
|
-
const range = `${quote(`${commit}^`)} ${quote(commit)}`;
|
|
21875
|
-
const error = quote(`${report}.output`);
|
|
21958
|
+
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`);
|
|
21876
21962
|
return [
|
|
21877
21963
|
"#!/usr/bin/env sh",
|
|
21878
21964
|
"set +e",
|
|
21879
|
-
`if ! git diff --quiet ${range}
|
|
21880
|
-
` mkdir -p "$(dirname ${quote(report)})"`,
|
|
21881
|
-
` git diff --binary ${range}
|
|
21965
|
+
`if ! git diff --quiet ${range} --${paths}; then`,
|
|
21966
|
+
` mkdir -p "$(dirname ${quote$1(report)})"`,
|
|
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}`,
|
|
21882
21968
|
" code=$?",
|
|
21883
21969
|
" if [ \"$code\" -ne 0 ]; then",
|
|
21884
21970
|
" {",
|
|
21885
|
-
` printf '%s\\n\\n' ${quote(failure)}`,
|
|
21886
|
-
` if [ -s ${error} ]; then cat ${error}; else printf 'Reverting it exited %s and produced no output.\\n' "$code"; fi`,
|
|
21887
|
-
` } > ${quote(report)}`,
|
|
21971
|
+
` printf '%s\\n\\n' ${quote$1(failure)}`,
|
|
21972
|
+
` 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)}`,
|
|
21888
21974
|
" fi",
|
|
21889
21975
|
` rm -f ${error}`,
|
|
21890
21976
|
"fi",
|
|
@@ -21892,17 +21978,25 @@ const revertScript = (commit, report, failure) => {
|
|
|
21892
21978
|
].join("\n");
|
|
21893
21979
|
};
|
|
21894
21980
|
/**
|
|
21981
|
+
* Reverse-apply `commit`'s changes to the working tree. A failure — the
|
|
21982
|
+
* patch no longer applies — writes `failure` and git's error to `report`,
|
|
21983
|
+
* since a failed revert and one with nothing to undo both leave the tree clean.
|
|
21984
|
+
*/
|
|
21985
|
+
const revertScript = (commit, report, failure) => patchScript(commit, report, failure, true);
|
|
21986
|
+
/** Apply `commit`'s changes outside `exclude` to the working tree; a failure is reported as `revertScript`'s is. */
|
|
21987
|
+
const applyScript = (commit, report, failure, exclude = []) => patchScript(commit, report, failure, false, exclude);
|
|
21988
|
+
/**
|
|
21895
21989
|
* Undo the edits one commit made to `paths`: each goes back to its content
|
|
21896
21990
|
* before `commit` — or away, when `commit` added it — but only while it is
|
|
21897
21991
|
* still exactly as `commit` left it. A path changed since is left alone.
|
|
21898
21992
|
*/
|
|
21899
21993
|
const restoreScript = (commit, paths, source) => {
|
|
21900
|
-
const unchanged = (path) => `git diff --quiet ${quote(commit)} -- ${quote(path)}`;
|
|
21994
|
+
const unchanged = (path) => `git diff --quiet ${quote$1(commit)} -- ${quote$1(path)}`;
|
|
21901
21995
|
return [
|
|
21902
21996
|
"#!/usr/bin/env sh",
|
|
21903
21997
|
"set +e",
|
|
21904
|
-
...paths.restore.map((path) => `${unchanged(path)} && git restore --source=${quote(source ?? `${commit}~1`)} --worktree -- ${quote(path)}`),
|
|
21905
|
-
...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)}`),
|
|
21906
22000
|
""
|
|
21907
22001
|
].join("\n");
|
|
21908
22002
|
};
|
|
@@ -21916,15 +22010,15 @@ const removeScript = (paths) => [
|
|
|
21916
22010
|
const moveScript = (from, to) => [
|
|
21917
22011
|
"#!/usr/bin/env sh",
|
|
21918
22012
|
"set -e",
|
|
21919
|
-
`mkdir -p "$(dirname ${quote(to)})"`,
|
|
21920
|
-
`mv -- ${quote(from)} ${quote(to)}`,
|
|
22013
|
+
`mkdir -p "$(dirname ${quote$1(to)})"`,
|
|
22014
|
+
`mv -- ${quote$1(from)} ${quote$1(to)}`,
|
|
21921
22015
|
""
|
|
21922
22016
|
].join("\n");
|
|
21923
22017
|
/** Write `path` as committed at `ref` to `to`. */
|
|
21924
22018
|
const showScript = (ref, path, to) => [
|
|
21925
22019
|
"#!/usr/bin/env sh",
|
|
21926
22020
|
"set -e",
|
|
21927
|
-
`git show ${quote(`${ref}:${path}`)} > ${quote(to)}`,
|
|
22021
|
+
`git show ${quote$1(`${ref}:${path}`)} > ${quote$1(to)}`,
|
|
21928
22022
|
""
|
|
21929
22023
|
].join("\n");
|
|
21930
22024
|
//#endregion
|
|
@@ -22259,6 +22353,7 @@ var flows_exports = /* @__PURE__ */ __exportAll({
|
|
|
22259
22353
|
accessFor: () => accessFor,
|
|
22260
22354
|
agent: () => agent,
|
|
22261
22355
|
answered: () => answered,
|
|
22356
|
+
applyScript: () => applyScript,
|
|
22262
22357
|
changes: () => changes,
|
|
22263
22358
|
changesSince: () => changesSince,
|
|
22264
22359
|
check: () => check,
|
|
@@ -22286,7 +22381,7 @@ var flows_exports = /* @__PURE__ */ __exportAll({
|
|
|
22286
22381
|
numeric: () => numeric,
|
|
22287
22382
|
openQuestions: () => openQuestions,
|
|
22288
22383
|
protocolMismatch: () => protocolMismatch,
|
|
22289
|
-
quote: () => quote,
|
|
22384
|
+
quote: () => quote$1,
|
|
22290
22385
|
read: () => read,
|
|
22291
22386
|
refuse: () => refuse,
|
|
22292
22387
|
removeScript: () => removeScript,
|
|
@@ -37370,6 +37465,7 @@ var init_BeatStatus = __esmMin((() => {
|
|
|
37370
37465
|
initial,
|
|
37371
37466
|
model: rendered.model,
|
|
37372
37467
|
system: rendered.system !== void 0 && rendered.system !== "" ? rendered.system : void 0,
|
|
37468
|
+
context: rendered.context,
|
|
37373
37469
|
log,
|
|
37374
37470
|
state: rendered.state,
|
|
37375
37471
|
actor: rendered.actor,
|
|
@@ -37428,6 +37524,7 @@ var init_BeatDocument = __esmMin((() => {
|
|
|
37428
37524
|
session,
|
|
37429
37525
|
model: status.model,
|
|
37430
37526
|
system: status.system,
|
|
37527
|
+
context: status.context,
|
|
37431
37528
|
validate,
|
|
37432
37529
|
log: status.log,
|
|
37433
37530
|
state: status.state,
|
|
@@ -37669,6 +37766,91 @@ var init_Slices = __esmMin((() => {
|
|
|
37669
37766
|
renderSlicesJson = (document) => JSON.stringify(document) + "\n";
|
|
37670
37767
|
}));
|
|
37671
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
|
|
37672
37854
|
//#region src/wire/index.ts
|
|
37673
37855
|
var init_wire = __esmMin((() => {
|
|
37674
37856
|
init_constants();
|
|
@@ -37684,6 +37866,7 @@ var init_wire = __esmMin((() => {
|
|
|
37684
37866
|
init_Sessions();
|
|
37685
37867
|
init_Glob();
|
|
37686
37868
|
init_Slices();
|
|
37869
|
+
init_ContextLimit();
|
|
37687
37870
|
}));
|
|
37688
37871
|
//#endregion
|
|
37689
37872
|
//#region src/replay/RefName.ts
|
|
@@ -38013,6 +38196,15 @@ const budgeted = (evidence, budgetBytes) => {
|
|
|
38013
38196
|
truncated
|
|
38014
38197
|
};
|
|
38015
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);
|
|
38016
38208
|
const sameSkills = (a, b) => (a?.length ?? 0) === (b?.length ?? 0) && (a ?? []).every((skill, i) => skill === b?.[i]);
|
|
38017
38209
|
const samePersona = (a, b) => a.model === b.model && a.system === b.system && sameSkills(a.skills, b.skills) && sameAccess(a.access, b.access);
|
|
38018
38210
|
/**
|
|
@@ -38032,6 +38224,7 @@ const KNOWN_OPTIONS = {
|
|
|
38032
38224
|
...STEERING_OPTIONS,
|
|
38033
38225
|
"model",
|
|
38034
38226
|
"system",
|
|
38227
|
+
"context",
|
|
38035
38228
|
"allowEmpty",
|
|
38036
38229
|
"keep"
|
|
38037
38230
|
]),
|
|
@@ -38146,11 +38339,13 @@ const replay = async (input) => {
|
|
|
38146
38339
|
if (s.model !== void 0) persona.model = s.model;
|
|
38147
38340
|
if (s.system !== void 0) persona.system = s.system;
|
|
38148
38341
|
}
|
|
38342
|
+
const context = inheritedContext([...scopes.map((s) => s.context), request.options.context]);
|
|
38149
38343
|
return {
|
|
38150
38344
|
...request,
|
|
38151
38345
|
options: {
|
|
38152
38346
|
...persona,
|
|
38153
|
-
...request.options
|
|
38347
|
+
...request.options,
|
|
38348
|
+
...context === void 0 ? {} : { context }
|
|
38154
38349
|
}
|
|
38155
38350
|
};
|
|
38156
38351
|
}
|
|
@@ -38288,10 +38483,26 @@ const replay = async (input) => {
|
|
|
38288
38483
|
});
|
|
38289
38484
|
return landPending(step, input.pending);
|
|
38290
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
|
+
};
|
|
38291
38500
|
const requestFault = (request) => {
|
|
38292
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)`;
|
|
38293
38502
|
if (request.kind !== "agent") return void 0;
|
|
38294
38503
|
const name = scoped(request.name);
|
|
38504
|
+
const contextFault = resolvedContextFault(request);
|
|
38505
|
+
if (contextFault !== void 0) return `gtd: step "${name}": ${contextFault}`;
|
|
38295
38506
|
if (request.options.keep === true) {
|
|
38296
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`;
|
|
38297
38508
|
const refFault = name.includes("/") ? "it contains \"/\"" : refNameFault(name);
|
|
@@ -39912,6 +40123,10 @@ const commonOf = (step) => {
|
|
|
39912
40123
|
...optional$1("mode", options.mode)
|
|
39913
40124
|
};
|
|
39914
40125
|
};
|
|
40126
|
+
const stepContext = (context) => context === void 0 ? void 0 : {
|
|
40127
|
+
...optional$1("soft", context.soft),
|
|
40128
|
+
...optional$1("hard", context.hard)
|
|
40129
|
+
};
|
|
39915
40130
|
const promptDef = (common, request, skills, access) => ({
|
|
39916
40131
|
...common,
|
|
39917
40132
|
kind: "prompt",
|
|
@@ -39920,6 +40135,7 @@ const promptDef = (common, request, skills, access) => ({
|
|
|
39920
40135
|
...optional$1("system", request.options.system),
|
|
39921
40136
|
...optional$1("allowEmpty", request.options.allowEmpty),
|
|
39922
40137
|
...optional$1("keep", request.options.keep),
|
|
40138
|
+
...optional$1("context", stepContext(request.options.context)),
|
|
39923
40139
|
...optional$1("skills", skills),
|
|
39924
40140
|
...optional$1("access", access)
|
|
39925
40141
|
});
|
|
@@ -40005,7 +40221,8 @@ const hintsOf = (def) => ({
|
|
|
40005
40221
|
...optional$1("system", def.system),
|
|
40006
40222
|
...optional$1("mode", def.mode),
|
|
40007
40223
|
...optional$1("skills", def.skills),
|
|
40008
|
-
...optional$1("access", def.access)
|
|
40224
|
+
...optional$1("access", def.access),
|
|
40225
|
+
...optional$1("context", def.context)
|
|
40009
40226
|
});
|
|
40010
40227
|
const normalizeStatus = (raw) => raw === "A" ? "A" : raw === "D" ? "D" : "M";
|
|
40011
40228
|
/** Per-model token totals, highest-cost first (ties broken by model name). */
|
|
@@ -41287,6 +41504,17 @@ const readStdin = () => tryPromise({
|
|
|
41287
41504
|
},
|
|
41288
41505
|
catch: (e) => e instanceof Error ? e : new Error(String(e))
|
|
41289
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
|
+
});
|
|
41290
41518
|
/** Stdout is written once, after the answerer resolves — a rejection leaves it empty. */
|
|
41291
41519
|
const runJudgeRunCommand = (command, out) => gen(function* () {
|
|
41292
41520
|
const host = yield* Host;
|
|
@@ -41746,6 +41974,7 @@ const needsOf = (kind) => {
|
|
|
41746
41974
|
case "lsp":
|
|
41747
41975
|
case "install":
|
|
41748
41976
|
case "loop":
|
|
41977
|
+
case "contextHook":
|
|
41749
41978
|
case "judgeRun":
|
|
41750
41979
|
case "strays": return "none";
|
|
41751
41980
|
case "check":
|
|
@@ -41785,6 +42014,7 @@ const dispatchVoidCommand = (command, json, out) => {
|
|
|
41785
42014
|
case "uncheck": return runUncheckCommand(command.file);
|
|
41786
42015
|
case "install": return runInstallCommand(out);
|
|
41787
42016
|
case "loop": return runLoopCommand();
|
|
42017
|
+
case "contextHook": return runContextHookCommand(command, out);
|
|
41788
42018
|
case "summary": return runSummaryCommand(out, command.slice);
|
|
41789
42019
|
case "base": return runBaseCommand(out);
|
|
41790
42020
|
case "judge": return runJudgeCommand(json, out);
|
|
@@ -41828,6 +42058,10 @@ const nonNegativeNumber = (raw, flag) => {
|
|
|
41828
42058
|
if (raw.trim() === "" || !Number.isFinite(n) || n < 0) return left(`gtd: ${flag} must be a non-negative number — got "${raw}"`);
|
|
41829
42059
|
return right(n);
|
|
41830
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
|
+
};
|
|
41831
42065
|
const FLAGS = [
|
|
41832
42066
|
{
|
|
41833
42067
|
name: "--json",
|
|
@@ -41955,6 +42189,39 @@ const FLAGS = [
|
|
|
41955
42189
|
"GTD_JUDGE_MODEL, then judge.json, then sonnet"
|
|
41956
42190
|
]
|
|
41957
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
|
+
},
|
|
41958
42225
|
{
|
|
41959
42226
|
name: "--slice",
|
|
41960
42227
|
arity: 1,
|
|
@@ -42261,6 +42528,22 @@ const COMMAND_ROWS = [
|
|
|
42261
42528
|
"~/.config/gtd/loop.json); see docs/driver.md"
|
|
42262
42529
|
]
|
|
42263
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
|
+
},
|
|
42264
42547
|
{
|
|
42265
42548
|
token: "summary",
|
|
42266
42549
|
kind: "summary",
|
|
@@ -42739,6 +43022,17 @@ const parseArgv = (argv) => {
|
|
|
42739
43022
|
verbose
|
|
42740
43023
|
};
|
|
42741
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
|
+
};
|
|
42742
43036
|
if (kind === "summary") return {
|
|
42743
43037
|
kind: "command",
|
|
42744
43038
|
command: {
|
|
@@ -58417,8 +58711,9 @@ var init_lsp = __esmMin((() => {
|
|
|
58417
58711
|
}));
|
|
58418
58712
|
//#endregion
|
|
58419
58713
|
//#region src/loop/Agent.ts
|
|
58420
|
-
var optional, parseJson, field, costOf, claude, pi, agentCli;
|
|
58714
|
+
var optional, parseJson, field$1, costOf, claude, hookSettings, pi, agentCli;
|
|
58421
58715
|
var init_Agent = __esmMin((() => {
|
|
58716
|
+
init_wire();
|
|
58422
58717
|
optional = (flag, value) => value === void 0 || value === "" ? [] : [flag, value];
|
|
58423
58718
|
parseJson = (text) => {
|
|
58424
58719
|
try {
|
|
@@ -58427,7 +58722,7 @@ var init_Agent = __esmMin((() => {
|
|
|
58427
58722
|
return;
|
|
58428
58723
|
}
|
|
58429
58724
|
};
|
|
58430
|
-
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;
|
|
58431
58726
|
costOf = (value) => typeof value === "number" && value > 0 ? value : 0;
|
|
58432
58727
|
claude = {
|
|
58433
58728
|
command: "claude",
|
|
@@ -58437,19 +58732,45 @@ var init_Agent = __esmMin((() => {
|
|
|
58437
58732
|
turn.sessionId,
|
|
58438
58733
|
...optional("--model", turn.model),
|
|
58439
58734
|
...optional("--system-prompt", turn.system),
|
|
58735
|
+
"--settings",
|
|
58736
|
+
JSON.stringify(hookSettings(turn.hook)),
|
|
58440
58737
|
"--output-format",
|
|
58441
|
-
"json",
|
|
58738
|
+
"stream-json",
|
|
58739
|
+
"--verbose",
|
|
58442
58740
|
"--dangerously-skip-permissions"
|
|
58443
58741
|
],
|
|
58444
58742
|
read: (exit) => {
|
|
58445
|
-
const
|
|
58446
|
-
|
|
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";
|
|
58447
58751
|
return {
|
|
58448
|
-
ok: exit.code === 0 && field(envelope, "is_error") !== true,
|
|
58449
|
-
text: typeof result === "string" ? result :
|
|
58450
|
-
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
|
|
58451
58756
|
};
|
|
58452
|
-
}
|
|
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
|
+
} };
|
|
58453
58774
|
};
|
|
58454
58775
|
pi = {
|
|
58455
58776
|
command: "pi",
|
|
@@ -58465,13 +58786,14 @@ var init_Agent = __esmMin((() => {
|
|
|
58465
58786
|
],
|
|
58466
58787
|
read: (exit) => {
|
|
58467
58788
|
const events = exit.stdout.split("\n").map(parseJson).filter((event) => event !== void 0);
|
|
58468
|
-
const message = field(events.findLast((event) => field(event, "type") === "message_end" && field(field(event, "message"), "role") === "assistant"), "message");
|
|
58469
|
-
const content = field(message, "content");
|
|
58470
|
-
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");
|
|
58471
58792
|
return {
|
|
58472
|
-
ok: exit.code === 0 && !events.some((event) => field(event, "type") === "error"),
|
|
58793
|
+
ok: exit.code === 0 && !events.some((event) => field$1(event, "type") === "error"),
|
|
58473
58794
|
text: text === "" ? exit.stdout : text,
|
|
58474
|
-
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
|
|
58475
58797
|
};
|
|
58476
58798
|
}
|
|
58477
58799
|
};
|
|
@@ -58496,6 +58818,10 @@ var init_Documents = __esmMin((() => {
|
|
|
58496
58818
|
})),
|
|
58497
58819
|
model: optional$2(String$),
|
|
58498
58820
|
system: optional$2(String$),
|
|
58821
|
+
context: optional$2(Struct({
|
|
58822
|
+
soft: optionalWith(Number$, { exact: true }),
|
|
58823
|
+
hard: optionalWith(Number$, { exact: true })
|
|
58824
|
+
})),
|
|
58499
58825
|
validate: optional$2(String$),
|
|
58500
58826
|
label: optional$2(String$),
|
|
58501
58827
|
judge: optional$2(String$)
|
|
@@ -58543,9 +58869,30 @@ var init_Host = __esmMin((() => {
|
|
|
58543
58869
|
],
|
|
58544
58870
|
detached: true
|
|
58545
58871
|
});
|
|
58872
|
+
const killGroup = (signal) => {
|
|
58873
|
+
try {
|
|
58874
|
+
if (child.pid !== void 0) process.kill(-child.pid, signal);
|
|
58875
|
+
} catch {}
|
|
58876
|
+
};
|
|
58546
58877
|
let stdout = "";
|
|
58547
58878
|
let stderr = "";
|
|
58548
|
-
|
|
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
|
+
});
|
|
58549
58896
|
child.stderr?.setEncoding("utf-8").on("data", (chunk) => stderr += chunk);
|
|
58550
58897
|
child.stdin?.on("error", () => {});
|
|
58551
58898
|
child.stdin?.end(request.stdin);
|
|
@@ -58558,18 +58905,15 @@ var init_Host = __esmMin((() => {
|
|
|
58558
58905
|
};
|
|
58559
58906
|
child.on("error", (error) => settle(fail$7(/* @__PURE__ */ new Error(`could not run ${request.command}: ${error.message}`))));
|
|
58560
58907
|
child.on("close", (code, signal) => {
|
|
58908
|
+
clearTimeout(stopForce);
|
|
58561
58909
|
const exit = code ?? 128 + (signal === null ? 0 : constants.signals[signal] ?? 0);
|
|
58562
58910
|
settle(succeed$3({
|
|
58563
58911
|
code: exit,
|
|
58564
58912
|
stdout,
|
|
58565
|
-
stderr
|
|
58913
|
+
stderr,
|
|
58914
|
+
...stopped ? { stopped: true } : {}
|
|
58566
58915
|
}));
|
|
58567
58916
|
});
|
|
58568
|
-
const killGroup = (signal) => {
|
|
58569
|
-
try {
|
|
58570
|
-
if (child.pid !== void 0) process.kill(-child.pid, signal);
|
|
58571
|
-
} catch {}
|
|
58572
|
-
};
|
|
58573
58917
|
return async((done) => {
|
|
58574
58918
|
if (child.exitCode !== null || child.signalCode !== null || child.pid === void 0) {
|
|
58575
58919
|
killGroup("SIGTERM");
|
|
@@ -58613,9 +58957,10 @@ var init_Host = __esmMin((() => {
|
|
|
58613
58957
|
}));
|
|
58614
58958
|
//#endregion
|
|
58615
58959
|
//#region src/loop/Settings.ts
|
|
58616
|
-
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;
|
|
58617
58961
|
var init_Settings = __esmMin((() => {
|
|
58618
58962
|
init_esm();
|
|
58963
|
+
init_wire();
|
|
58619
58964
|
Agent = Literal("claude", "pi");
|
|
58620
58965
|
CLAUDE_MODELS = {
|
|
58621
58966
|
smart: "opus",
|
|
@@ -58627,7 +58972,8 @@ var init_Settings = __esmMin((() => {
|
|
|
58627
58972
|
models: optional$2(Record({
|
|
58628
58973
|
key: String$,
|
|
58629
58974
|
value: String$
|
|
58630
|
-
}))
|
|
58975
|
+
})),
|
|
58976
|
+
contextWindow: optional$2(Int.pipe(positive()))
|
|
58631
58977
|
});
|
|
58632
58978
|
settingsPath = (env) => {
|
|
58633
58979
|
const explicit = env["GTD_LOOP_CONFIG"];
|
|
@@ -58649,9 +58995,15 @@ var init_Settings = __esmMin((() => {
|
|
|
58649
58995
|
return decodeUnknownEither(SettingsFile, { onExcessProperty: "error" })(json).pipe(mapLeft((error) => `${path}: ${error.message}`));
|
|
58650
58996
|
};
|
|
58651
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
|
+
};
|
|
58652
59003
|
resolveSettings = (env, file) => gen$2(function* () {
|
|
58653
59004
|
const fromFile = file === void 0 ? {} : yield* decodeFile(file.path, file.text);
|
|
58654
59005
|
const envAgent = yield* decodeAgent(env["GTD_LOOP_AGENT"]);
|
|
59006
|
+
const envWindow = yield* decodeWindow(env["GTD_LOOP_CONTEXT_WINDOW"]);
|
|
58655
59007
|
const envModels = Object.fromEntries(Object.entries(env).filter((entry) => entry[0].startsWith(MODEL_ENV_PREFIX) && entry[1] !== void 0 && entry[1] !== ""));
|
|
58656
59008
|
const agent = envAgent ?? fromFile.agent ?? "claude";
|
|
58657
59009
|
return {
|
|
@@ -58660,7 +59012,8 @@ var init_Settings = __esmMin((() => {
|
|
|
58660
59012
|
...agent === "claude" ? CLAUDE_MODELS : {},
|
|
58661
59013
|
...fromFile.models
|
|
58662
59014
|
},
|
|
58663
|
-
envModels
|
|
59015
|
+
envModels,
|
|
59016
|
+
contextWindow: envWindow ?? fromFile.contextWindow
|
|
58664
59017
|
};
|
|
58665
59018
|
});
|
|
58666
59019
|
resolveModel = (settings, hint) => {
|
|
@@ -58670,9 +59023,10 @@ var init_Settings = __esmMin((() => {
|
|
|
58670
59023
|
}));
|
|
58671
59024
|
//#endregion
|
|
58672
59025
|
//#region src/loop/Loop.ts
|
|
58673
|
-
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;
|
|
58674
59027
|
var init_Loop = __esmMin((() => {
|
|
58675
59028
|
init_esm();
|
|
59029
|
+
init_wire();
|
|
58676
59030
|
init_Agent();
|
|
58677
59031
|
init_Documents();
|
|
58678
59032
|
init_Host();
|
|
@@ -58725,23 +59079,61 @@ var init_Loop = __esmMin((() => {
|
|
|
58725
59079
|
...exit.stderr.trim() === "" ? [] : [firstLines(exit.stderr)],
|
|
58726
59080
|
...result.text.trim() === "" ? [] : [firstLines(result.text)]
|
|
58727
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
|
+
});
|
|
58728
59109
|
agentTurn = (ctx, doc, model) => (prompt, sessionFlag) => gen(function* () {
|
|
58729
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);
|
|
58730
59115
|
const exit = yield* ctx.host.spawn({
|
|
58731
59116
|
command: cli.command,
|
|
58732
59117
|
args: cli.args({
|
|
58733
59118
|
sessionFlag,
|
|
58734
59119
|
sessionId: doc.session?.id ?? "",
|
|
58735
59120
|
model,
|
|
58736
|
-
system: doc.system
|
|
59121
|
+
system: doc.system,
|
|
59122
|
+
hook: guard.hook
|
|
58737
59123
|
}),
|
|
58738
59124
|
cwd: ctx.root,
|
|
58739
59125
|
stdin: prompt,
|
|
58740
|
-
env: {
|
|
58741
|
-
|
|
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 }
|
|
58742
59132
|
});
|
|
58743
59133
|
const result = cli.read(exit);
|
|
58744
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}`));
|
|
58745
59137
|
if (!result.ok) yield* agentFailed(ctx, exit, result);
|
|
58746
59138
|
return result;
|
|
58747
59139
|
});
|
|
@@ -58871,15 +59263,66 @@ var init_Loop = __esmMin((() => {
|
|
|
58871
59263
|
});
|
|
58872
59264
|
}));
|
|
58873
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
|
|
58874
59315
|
//#region src/loop/index.ts
|
|
58875
59316
|
var loop_exports = /* @__PURE__ */ __exportAll({
|
|
58876
59317
|
LoopHost: () => LoopHost,
|
|
58877
59318
|
liveLoopHost: () => liveLoopHost,
|
|
59319
|
+
runContextHook: () => runContextHook,
|
|
58878
59320
|
runLoop: () => runLoop
|
|
58879
59321
|
});
|
|
58880
59322
|
var init_loop = __esmMin((() => {
|
|
58881
59323
|
init_Loop();
|
|
58882
59324
|
init_Host();
|
|
59325
|
+
init_ContextHook();
|
|
58883
59326
|
}));
|
|
58884
59327
|
//#endregion
|
|
58885
59328
|
//#region src/judges/providers/io.ts
|
|
@@ -59368,6 +59811,10 @@ const liveToolCommands = effect$1(ToolCommands, gen(function* () {
|
|
|
59368
59811
|
const { runLoop, liveLoopHost } = await Promise.resolve().then(() => (init_loop(), loop_exports));
|
|
59369
59812
|
return () => runLoop({ gtd }).pipe(provide$1(liveLoopHost));
|
|
59370
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
|
+
}),
|
|
59371
59818
|
judge: async (request) => {
|
|
59372
59819
|
const { runJudge } = await Promise.resolve().then(() => (init_judges(), judges_exports)).catch((error) => {
|
|
59373
59820
|
throw loadFailure("judge")(error);
|