@pmelab/gtd 38.0.0 → 38.2.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 +36 -3
- package/dist/chunks/{Schema-DO5ttJaI.mjs → Schema-C6fLlQzx.mjs} +1 -1
- package/dist/chunks/{reserved-sfMdy7v7.mjs → reserved-C3PgP7XB.mjs} +56 -12
- package/dist/chunks/{tail-Cgca5Gp-.mjs → tail-Bkxki2nK.mjs} +1 -1
- package/dist/chunks/{wire-CSsa3Wxd.mjs → wire-BJuZWR3C.mjs} +1 -1
- package/dist/gtd.bundle.mjs +292 -53
- package/dist/testkit.mjs +257 -21
- package/dist/wire.mjs +1 -1
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +158 -42
- 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 +230 -70
- package/package.json +1 -1
- package/src/cli/Cli.test.ts +15 -3
- package/src/cli/Cli.ts +61 -28
- package/src/cli/History.ts +1 -19
- package/src/cli/Metrics.test.ts +224 -0
- package/src/cli/Metrics.ts +310 -0
- package/src/cli/Output.ts +13 -0
- package/src/cli/Program.test.ts +3 -1
- package/src/cli/Program.ts +4 -0
- package/src/testkit/steps.ts +4 -0
- package/src/wire/ContextLimit.ts +1 -1
- package/src/workflows/feature/continuation-cap.feature +65 -0
- package/src/workflows/feature/continuation-rebuild.feature +88 -0
- package/src/workflows/feature/continuation-slices.feature +64 -0
- package/src/workflows/feature/continuation.feature +205 -0
- package/src/workflows/feature/criteria.ts +11 -0
- package/src/workflows/feature/refactor.ts +64 -30
- package/src/workflows/feature/seam.ts +102 -30
- package/src/workflows/shared/continuation.ts +92 -0
- package/src/workflows/shared/options.ts +2 -0
- package/src/workflows/shared/steps.ts +1 -0
- package/src/workflows/shared/text.test.ts +6 -2
- package/src/workflows/shared/text.ts +104 -8
- package/src/workflows/shared/vars.ts +5 -0
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -2137,7 +2137,7 @@ var init_hashMap = __esmMin((() => {
|
|
|
2137
2137
|
}));
|
|
2138
2138
|
//#endregion
|
|
2139
2139
|
//#region node_modules/effect/dist/esm/internal/hashSet.js
|
|
2140
|
-
var HashSetSymbolKey, HashSetTypeId, HashSetProto, makeImpl, isHashSet, _empty$4, empty$23, fromIterable$3, make$44, has$2, size$6, beginMutation, endMutation, mutate, add$
|
|
2140
|
+
var HashSetSymbolKey, HashSetTypeId, HashSetProto, makeImpl, isHashSet, _empty$4, empty$23, fromIterable$3, make$44, has$2, size$6, beginMutation, endMutation, mutate, add$4, remove$3, difference$1, union$1, forEach$4, reduce$4;
|
|
2141
2141
|
var init_hashSet = __esmMin((() => {
|
|
2142
2142
|
init_Equal();
|
|
2143
2143
|
init_Function();
|
|
@@ -2186,12 +2186,12 @@ var init_hashSet = __esmMin((() => {
|
|
|
2186
2186
|
empty$23 = () => _empty$4;
|
|
2187
2187
|
fromIterable$3 = (elements) => {
|
|
2188
2188
|
const set = beginMutation(empty$23());
|
|
2189
|
-
for (const value of elements) add$
|
|
2189
|
+
for (const value of elements) add$4(set, value);
|
|
2190
2190
|
return endMutation(set);
|
|
2191
2191
|
};
|
|
2192
2192
|
make$44 = (...elements) => {
|
|
2193
2193
|
const set = beginMutation(empty$23());
|
|
2194
|
-
for (const value of elements) add$
|
|
2194
|
+
for (const value of elements) add$4(set, value);
|
|
2195
2195
|
return endMutation(set);
|
|
2196
2196
|
};
|
|
2197
2197
|
has$2 = /*#__PURE__*/ dual(2, (self, value) => has$3(self._keyMap, value));
|
|
@@ -2206,21 +2206,21 @@ var init_hashSet = __esmMin((() => {
|
|
|
2206
2206
|
f(transient);
|
|
2207
2207
|
return endMutation(transient);
|
|
2208
2208
|
});
|
|
2209
|
-
add$
|
|
2209
|
+
add$4 = /*#__PURE__*/ dual(2, (self, value) => self._keyMap._editable ? (set$5(value, true)(self._keyMap), self) : makeImpl(set$5(value, true)(self._keyMap)));
|
|
2210
2210
|
remove$3 = /*#__PURE__*/ dual(2, (self, value) => self._keyMap._editable ? (remove$4(value)(self._keyMap), self) : makeImpl(remove$4(value)(self._keyMap)));
|
|
2211
2211
|
difference$1 = /*#__PURE__*/ dual(2, (self, that) => mutate(self, (set) => {
|
|
2212
2212
|
for (const value of that) remove$3(set, value);
|
|
2213
2213
|
}));
|
|
2214
2214
|
union$1 = /*#__PURE__*/ dual(2, (self, that) => mutate(empty$23(), (set) => {
|
|
2215
|
-
forEach$4(self, (value) => add$
|
|
2216
|
-
for (const value of that) add$
|
|
2215
|
+
forEach$4(self, (value) => add$4(set, value));
|
|
2216
|
+
for (const value of that) add$4(set, value);
|
|
2217
2217
|
}));
|
|
2218
2218
|
forEach$4 = /*#__PURE__*/ dual(2, (self, f) => forEach$5(self._keyMap, (_, k) => f(k)));
|
|
2219
2219
|
reduce$4 = /*#__PURE__*/ dual(3, (self, zero, f) => reduce$5(self._keyMap, zero, (z, _, a) => f(z, a)));
|
|
2220
2220
|
}));
|
|
2221
2221
|
//#endregion
|
|
2222
2222
|
//#region node_modules/effect/dist/esm/HashSet.js
|
|
2223
|
-
var empty$22, fromIterable$2, make$43, has$1, size$5, add$
|
|
2223
|
+
var empty$22, fromIterable$2, make$43, has$1, size$5, add$3, remove$2, difference, union, reduce$3;
|
|
2224
2224
|
var init_HashSet = __esmMin((() => {
|
|
2225
2225
|
init_hashSet();
|
|
2226
2226
|
empty$22 = empty$23;
|
|
@@ -2228,7 +2228,7 @@ var init_HashSet = __esmMin((() => {
|
|
|
2228
2228
|
make$43 = make$44;
|
|
2229
2229
|
has$1 = has$2;
|
|
2230
2230
|
size$5 = size$6;
|
|
2231
|
-
add$
|
|
2231
|
+
add$3 = add$4;
|
|
2232
2232
|
remove$2 = remove$3;
|
|
2233
2233
|
difference = difference$1;
|
|
2234
2234
|
union = union$1;
|
|
@@ -2369,7 +2369,7 @@ _E: (_) => _ };
|
|
|
2369
2369
|
isInterruptedOnly$1 = (self) => reduceWithContext$1(void 0, IsInterruptedOnlyCauseReducer)(self);
|
|
2370
2370
|
failures = (self) => reverse$1(reduce$2(self, empty$25(), (list, cause) => cause._tag === "Fail" ? some(pipe(list, prepend$1(cause.error))) : none$4()));
|
|
2371
2371
|
defects = (self) => reverse$1(reduce$2(self, empty$25(), (list, cause) => cause._tag === "Die" ? some(pipe(list, prepend$1(cause.defect))) : none$4()));
|
|
2372
|
-
interruptors$1 = (self) => reduce$2(self, empty$22(), (set, cause) => cause._tag === "Interrupt" ? some(pipe(set, add$
|
|
2372
|
+
interruptors$1 = (self) => reduce$2(self, empty$22(), (set, cause) => cause._tag === "Interrupt" ? some(pipe(set, add$3(cause.fiberId))) : none$4());
|
|
2373
2373
|
failureOption = (self) => find(self, (cause) => cause._tag === "Fail" ? some(cause.error) : none$4());
|
|
2374
2374
|
failureOrCause$1 = (self) => {
|
|
2375
2375
|
const option = failureOption(self);
|
|
@@ -2485,17 +2485,17 @@ _E: (_) => _ };
|
|
|
2485
2485
|
cause = stack.pop();
|
|
2486
2486
|
break;
|
|
2487
2487
|
case OP_FAIL$2:
|
|
2488
|
-
_parallel = add$
|
|
2488
|
+
_parallel = add$3(_parallel, make$46(cause._tag, cause.error));
|
|
2489
2489
|
if (stack.length === 0) return [_parallel, _sequential];
|
|
2490
2490
|
cause = stack.pop();
|
|
2491
2491
|
break;
|
|
2492
2492
|
case "Die":
|
|
2493
|
-
_parallel = add$
|
|
2493
|
+
_parallel = add$3(_parallel, make$46(cause._tag, cause.defect));
|
|
2494
2494
|
if (stack.length === 0) return [_parallel, _sequential];
|
|
2495
2495
|
cause = stack.pop();
|
|
2496
2496
|
break;
|
|
2497
2497
|
case OP_INTERRUPT:
|
|
2498
|
-
_parallel = add$
|
|
2498
|
+
_parallel = add$3(_parallel, make$46(cause._tag, cause.fiberId));
|
|
2499
2499
|
if (stack.length === 0) return [_parallel, _sequential];
|
|
2500
2500
|
cause = stack.pop();
|
|
2501
2501
|
break;
|
|
@@ -2721,7 +2721,7 @@ _E: (_) => _ };
|
|
|
2721
2721
|
}));
|
|
2722
2722
|
//#endregion
|
|
2723
2723
|
//#region node_modules/effect/dist/esm/internal/context.js
|
|
2724
|
-
var TagTypeId, ReferenceTypeId, STMSymbolKey, STMTypeId, TagProto, ReferenceProto, makeGenericTag, Tag$1, Reference$1, TypeId$21, ContextProto, makeContext, serviceNotFoundError, isContext$1, isTag$1, isReference, _empty$3, empty$20, make$42, add$
|
|
2724
|
+
var TagTypeId, ReferenceTypeId, STMSymbolKey, STMTypeId, TagProto, ReferenceProto, makeGenericTag, Tag$1, Reference$1, TypeId$21, ContextProto, makeContext, serviceNotFoundError, isContext$1, isTag$1, isReference, _empty$3, empty$20, make$42, add$2, defaultValueCache, getDefaultValue, unsafeGetReference, unsafeGet$1, get$9, getOption$1, merge$2, mergeAll$4, omit$2;
|
|
2725
2725
|
var init_context = __esmMin((() => {
|
|
2726
2726
|
init_Equal();
|
|
2727
2727
|
init_Function();
|
|
@@ -2865,7 +2865,7 @@ var init_context = __esmMin((() => {
|
|
|
2865
2865
|
_empty$3 = /*#__PURE__*/ makeContext(/*#__PURE__*/ new Map());
|
|
2866
2866
|
empty$20 = () => _empty$3;
|
|
2867
2867
|
make$42 = (tag, service) => makeContext(/* @__PURE__ */ new Map([[tag.key, service]]));
|
|
2868
|
-
add$
|
|
2868
|
+
add$2 = /*#__PURE__*/ dual(3, (self, tag, service) => {
|
|
2869
2869
|
const map = new Map(self.unsafeMap);
|
|
2870
2870
|
map.set(tag.key, service);
|
|
2871
2871
|
return makeContext(map);
|
|
@@ -2912,7 +2912,7 @@ var init_context = __esmMin((() => {
|
|
|
2912
2912
|
}));
|
|
2913
2913
|
//#endregion
|
|
2914
2914
|
//#region node_modules/effect/dist/esm/Context.js
|
|
2915
|
-
var GenericTag, isContext, isTag, empty$19, make$41, add, get$8, unsafeGet, getOption, merge$1, mergeAll$3, omit$1, Tag, Reference;
|
|
2915
|
+
var GenericTag, isContext, isTag, empty$19, make$41, add$1, get$8, unsafeGet, getOption, merge$1, mergeAll$3, omit$1, Tag, Reference;
|
|
2916
2916
|
var init_Context = __esmMin((() => {
|
|
2917
2917
|
init_context();
|
|
2918
2918
|
GenericTag = makeGenericTag;
|
|
@@ -2920,7 +2920,7 @@ var init_Context = __esmMin((() => {
|
|
|
2920
2920
|
isTag = isTag$1;
|
|
2921
2921
|
empty$19 = empty$20;
|
|
2922
2922
|
make$41 = make$42;
|
|
2923
|
-
add = add$
|
|
2923
|
+
add$1 = add$2;
|
|
2924
2924
|
get$8 = get$9;
|
|
2925
2925
|
unsafeGet = unsafeGet$1;
|
|
2926
2926
|
getOption = getOption$1;
|
|
@@ -2932,7 +2932,7 @@ var init_Context = __esmMin((() => {
|
|
|
2932
2932
|
}));
|
|
2933
2933
|
//#endregion
|
|
2934
2934
|
//#region node_modules/effect/dist/esm/Duration.js
|
|
2935
|
-
var TypeId$20, bigint0$2, bigint24, bigint60, bigint1e3, bigint1e6, bigint1e9, DURATION_REGEX, decode$2, zeroValue, infinityValue, DurationProto, make$40, isDuration, isFinite, isZero$1, zero$1, infinity, nanos, micros, millis, seconds, minutes, hours, days, weeks, toMillis, toNanos, unsafeToNanos, toHrTime, match$6, matchWith, Equivalence$3, sum, lessThanOrEqualTo$1, greaterThanOrEqualTo$1, equals$1, parts, format$3;
|
|
2935
|
+
var TypeId$20, bigint0$2, bigint24, bigint60, bigint1e3, bigint1e6, bigint1e9, DURATION_REGEX, decode$2, zeroValue, infinityValue, DurationProto, make$40, isDuration, isFinite, isZero$1, zero$1, infinity, nanos, micros, millis, seconds, minutes, hours, days, weeks, toMillis, toNanos, unsafeToNanos, toHrTime, match$6, matchWith, Equivalence$3, sum$1, lessThanOrEqualTo$1, greaterThanOrEqualTo$1, equals$1, parts, format$3;
|
|
2936
2936
|
var init_Duration = __esmMin((() => {
|
|
2937
2937
|
init_Equal();
|
|
2938
2938
|
init_Function();
|
|
@@ -3114,7 +3114,7 @@ var init_Duration = __esmMin((() => {
|
|
|
3114
3114
|
onMillis: (self, that) => self === that,
|
|
3115
3115
|
onNanos: (self, that) => self === that
|
|
3116
3116
|
});
|
|
3117
|
-
sum = /*#__PURE__*/ dual(2, (self, that) => matchWith(self, that, {
|
|
3117
|
+
sum$1 = /*#__PURE__*/ dual(2, (self, that) => matchWith(self, that, {
|
|
3118
3118
|
onMillis: (self, that) => make$40(self + that),
|
|
3119
3119
|
onNanos: (self, that) => make$40(self + that)
|
|
3120
3120
|
}));
|
|
@@ -3718,7 +3718,7 @@ var init_hashSetPatch = __esmMin((() => {
|
|
|
3718
3718
|
patches = prepend$1(head.first)(prepend$1(head.second)(tail));
|
|
3719
3719
|
break;
|
|
3720
3720
|
case "Add":
|
|
3721
|
-
set = add$
|
|
3721
|
+
set = add$3(head.value)(set);
|
|
3722
3722
|
patches = tail;
|
|
3723
3723
|
break;
|
|
3724
3724
|
case "Remove":
|
|
@@ -5725,7 +5725,7 @@ var init_defaultServices = __esmMin((() => {
|
|
|
5725
5725
|
init_console();
|
|
5726
5726
|
init_random();
|
|
5727
5727
|
init_tracer();
|
|
5728
|
-
liveServices = /*#__PURE__*/ pipe(/*#__PURE__*/ empty$19(), /*#__PURE__*/ add(clockTag, /*#__PURE__*/ make$32()), /*#__PURE__*/ add(consoleTag, defaultConsole), /*#__PURE__*/ add(randomTag, /*#__PURE__*/ make$30(/*#__PURE__*/ Math.random())), /*#__PURE__*/ add(configProviderTag, /*#__PURE__*/ fromEnv()), /*#__PURE__*/ add(tracerTag, nativeTracer));
|
|
5728
|
+
liveServices = /*#__PURE__*/ pipe(/*#__PURE__*/ empty$19(), /*#__PURE__*/ add$1(clockTag, /*#__PURE__*/ make$32()), /*#__PURE__*/ add$1(consoleTag, defaultConsole), /*#__PURE__*/ add$1(randomTag, /*#__PURE__*/ make$30(/*#__PURE__*/ Math.random())), /*#__PURE__*/ add$1(configProviderTag, /*#__PURE__*/ fromEnv()), /*#__PURE__*/ add$1(tracerTag, nativeTracer));
|
|
5729
5729
|
currentServices = /*#__PURE__*/ globalValue(/*#__PURE__*/ Symbol.for("effect/DefaultServices/currentServices"), () => fiberRefUnsafeMakeContext(liveServices));
|
|
5730
5730
|
sleep$3 = (duration) => {
|
|
5731
5731
|
const decodedDuration = decode$2(duration);
|
|
@@ -6934,8 +6934,8 @@ var init_core_effect = __esmMin((() => {
|
|
|
6934
6934
|
resolve(die$3(e));
|
|
6935
6935
|
}
|
|
6936
6936
|
});
|
|
6937
|
-
provideService$1 = /*#__PURE__*/ dual(3, (self, tag, service) => contextWithEffect((env) => provideContext$1(self, add(env, tag, service))));
|
|
6938
|
-
provideServiceEffect = /*#__PURE__*/ dual(3, (self, tag, effect) => contextWithEffect((env) => flatMap$6(effect, (service) => provideContext$1(self, pipe(env, add(tag, service))))));
|
|
6937
|
+
provideService$1 = /*#__PURE__*/ dual(3, (self, tag, service) => contextWithEffect((env) => provideContext$1(self, add$1(env, tag, service))));
|
|
6938
|
+
provideServiceEffect = /*#__PURE__*/ dual(3, (self, tag, effect) => contextWithEffect((env) => flatMap$6(effect, (service) => provideContext$1(self, pipe(env, add$1(tag, service))))));
|
|
6939
6939
|
sandbox$1 = (self) => matchCauseEffect$2(self, {
|
|
6940
6940
|
onFailure: fail$12,
|
|
6941
6941
|
onSuccess: succeed$8
|
|
@@ -11093,7 +11093,7 @@ var init_schedule = __esmMin((() => {
|
|
|
11093
11093
|
};
|
|
11094
11094
|
makeWithState = (initial, step) => new ScheduleImpl(initial, step);
|
|
11095
11095
|
addDelay = /*#__PURE__*/ dual(2, (self, f) => addDelayEffect(self, (out) => sync$2(() => f(out))));
|
|
11096
|
-
addDelayEffect = /*#__PURE__*/ dual(2, (self, f) => modifyDelayEffect(self, (out, duration) => map$8(f(out), (delay) => sum(duration, decode$2(delay)))));
|
|
11096
|
+
addDelayEffect = /*#__PURE__*/ dual(2, (self, f) => modifyDelayEffect(self, (out, duration) => map$8(f(out), (delay) => sum$1(duration, decode$2(delay)))));
|
|
11097
11097
|
check$1 = /*#__PURE__*/ dual(2, (self, test) => checkEffect(self, (input, out) => sync$2(() => test(input, out))));
|
|
11098
11098
|
checkEffect = /*#__PURE__*/ dual(2, (self, test) => makeWithState(self.initial, (now, input, state) => flatMap$6(self.step(now, input, state), ([state, out, decision]) => {
|
|
11099
11099
|
if (isDone(decision)) return succeed$8([
|
|
@@ -13618,7 +13618,7 @@ var init_rcRef = __esmMin((() => {
|
|
|
13618
13618
|
case "Acquired":
|
|
13619
13619
|
self.state.refCount++;
|
|
13620
13620
|
return self.state.fiber ? as$1(interruptFiber(self.state.fiber), self.state) : succeed$8(self.state);
|
|
13621
|
-
case "Empty": return scopeMake().pipe(bindTo("scope"), bind("value", ({ scope }) => restore(fiberRefLocally(self.acquire, currentContext$1, add(self.context, scopeTag, scope)))), map$8(({ scope, value }) => {
|
|
13621
|
+
case "Empty": return scopeMake().pipe(bindTo("scope"), bind("value", ({ scope }) => restore(fiberRefLocally(self.acquire, currentContext$1, add$1(self.context, scopeTag, scope)))), map$8(({ scope, value }) => {
|
|
13622
13622
|
const state = {
|
|
13623
13623
|
_tag: "Acquired",
|
|
13624
13624
|
value,
|
|
@@ -14288,7 +14288,7 @@ function getBrands(ast) {
|
|
|
14288
14288
|
onSome: (brands) => brands.map((brand) => ` & Brand<${formatUnknown(brand)}>`).join("")
|
|
14289
14289
|
});
|
|
14290
14290
|
}
|
|
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$
|
|
14291
|
+
var TypeConstructorAnnotationId, BrandAnnotationId, SchemaIdAnnotationId, MessageAnnotationId, MissingMessageAnnotationId, IdentifierAnnotationId, TitleAnnotationId, AutoTitleAnnotationId, DescriptionAnnotationId, ExamplesAnnotationId, DefaultAnnotationId, JSONSchemaAnnotationId, ArbitraryAnnotationId, PrettyAnnotationId, EquivalenceAnnotationId, DocumentationAnnotationId, ConcurrencyAnnotationId, BatchingAnnotationId, ParseIssueTitleAnnotationId, ParseOptionsAnnotationId, DecodingFallbackAnnotationId, SurrogateAnnotationId, StableFilterAnnotationId, getAnnotation, getBrandAnnotation, getMessageAnnotation, getMissingMessageAnnotation, getTitleAnnotation, getAutoTitleAnnotation, getIdentifierAnnotation, getDescriptionAnnotation, getConcurrencyAnnotation, getBatchingAnnotation, getParseIssueTitleAnnotation$1, getParseOptionsAnnotation, getDecodingFallbackAnnotation, getSurrogateAnnotation, getStableFilterAnnotation, hasStableFilter, JSONIdentifierAnnotationId, getJSONIdentifierAnnotation, getJSONIdentifier, Declaration, createASTGuard, Literal$1, isLiteral, $null, UniqueSymbol, UndefinedKeyword, undefinedKeyword, NeverKeyword, neverKeyword, UnknownKeyword, unknownKeyword, AnyKeyword, anyKeyword, StringKeyword, stringKeyword, isStringKeyword, NumberKeyword, numberKeyword, isNumberKeyword, BooleanKeyword, booleanKeyword, isBooleanKeyword, BigIntKeyword, bigIntKeyword, SymbolKeyword, symbolKeyword, isSymbolKeyword, Type$1, OptionalType, getRestASTs, TupleType, formatTuple, PropertySignature, isParameter, IndexSignature, TypeLiteral, formatIndexSignatures, formatTypeLiteral, isTypeLiteral, sortCandidates, literalMap, flatten$2, unify, Union$1, mapMembers, isMembers, isUnion, toJSONMemoMap, Suspend, Refinement$1, isRefinement$1, defaultParseOption, Transformation$1, isTransformation$1, FinalTransformation, createTransformationGuard, ComposeTransformation, composeTransformation, PropertySignatureTransformation$1, TypeLiteralTransformation, isTypeLiteralTransformation, annotations, STRING_KEYWORD_PATTERN, NUMBER_KEYWORD_PATTERN, getTemplateLiteralSpanTypePattern, handleTemplateLiteralSpanTypeParens, getTemplateLiteralPattern, getTemplateLiteralRegExp, record$2, pickAnnotations, omitAnnotations, preserveTransformationAnnotations, typeAST, getTransformationFrom, encodedAST_, encodedAST, toJSONAnnotations, getEncodedParameter, formatKeyword, getOrElseExpected, getExpected;
|
|
14292
14292
|
var init_SchemaAST = __esmMin((() => {
|
|
14293
14293
|
init_Array();
|
|
14294
14294
|
init_Function();
|
|
@@ -15252,7 +15252,7 @@ var init_SchemaAST = __esmMin((() => {
|
|
|
15252
15252
|
return pattern;
|
|
15253
15253
|
};
|
|
15254
15254
|
getTemplateLiteralRegExp = (ast) => new RegExp(`^${getTemplateLiteralPattern(ast, false, true)}$`);
|
|
15255
|
-
record$
|
|
15255
|
+
record$2 = (key, value) => {
|
|
15256
15256
|
const propertySignatures = [];
|
|
15257
15257
|
const indexSignatures = [];
|
|
15258
15258
|
const go = (key) => {
|
|
@@ -16937,7 +16937,7 @@ var init_Schema = __esmMin((() => {
|
|
|
16937
16937
|
const issFrom = [];
|
|
16938
16938
|
const issTo = [];
|
|
16939
16939
|
for (const r of records) {
|
|
16940
|
-
const { indexSignatures, propertySignatures } = record$
|
|
16940
|
+
const { indexSignatures, propertySignatures } = record$2(r.key.ast, r.value.ast);
|
|
16941
16941
|
propertySignatures.forEach((ps) => {
|
|
16942
16942
|
from.push(ps);
|
|
16943
16943
|
to.push(new PropertySignature(ps.name, typeAST(ps.type), ps.isOptional, ps.isReadonly, ps.annotations));
|
|
@@ -16952,7 +16952,7 @@ var init_Schema = __esmMin((() => {
|
|
|
16952
16952
|
}
|
|
16953
16953
|
const iss = [];
|
|
16954
16954
|
for (const r of records) {
|
|
16955
|
-
const { indexSignatures, propertySignatures } = record$
|
|
16955
|
+
const { indexSignatures, propertySignatures } = record$2(r.key.ast, r.value.ast);
|
|
16956
16956
|
propertySignatures.forEach((ps) => pss.push(ps));
|
|
16957
16957
|
indexSignatures.forEach((is) => iss.push(is));
|
|
16958
16958
|
}
|
|
@@ -18875,7 +18875,7 @@ var init_Runtime = __esmMin((() => {
|
|
|
18875
18875
|
return updateAs(refs, {
|
|
18876
18876
|
fiberId,
|
|
18877
18877
|
fiberRef: currentLoggers,
|
|
18878
|
-
value: loggers.pipe(remove$2(defaultLogger), add$
|
|
18878
|
+
value: loggers.pipe(remove$2(defaultLogger), add$3(prettyLoggerDefault))
|
|
18879
18879
|
});
|
|
18880
18880
|
};
|
|
18881
18881
|
makeRunMain = (f) => dual((args) => isEffect(args[0]), (effect, options) => {
|
|
@@ -37767,7 +37767,7 @@ var init_Slices = __esmMin((() => {
|
|
|
37767
37767
|
}));
|
|
37768
37768
|
//#endregion
|
|
37769
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;
|
|
37770
|
+
var DEFAULT_CONTEXT_LIMIT, DEFAULT_WINDOW, LONG_WINDOW, contextWindowFor, parseContextWindow, CONTEXT_STOP_FILE_ENV, contextShapeFault, contextLimitFault, record$1, count, usageTokens, transcriptTokens, CONTEXT_LIMIT_MARKER, percent, contextHook, hookOutput;
|
|
37771
37771
|
var init_ContextLimit = __esmMin((() => {
|
|
37772
37772
|
DEFAULT_CONTEXT_LIMIT = {
|
|
37773
37773
|
soft: .6,
|
|
@@ -37800,10 +37800,10 @@ var init_ContextLimit = __esmMin((() => {
|
|
|
37800
37800
|
const hard = shares.hard ?? DEFAULT_CONTEXT_LIMIT.hard;
|
|
37801
37801
|
return soft < hard ? void 0 : `context.soft (${soft}) must be below context.hard (${hard})`;
|
|
37802
37802
|
};
|
|
37803
|
-
record = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
37803
|
+
record$1 = (value) => typeof value === "object" && value !== null ? value : void 0;
|
|
37804
37804
|
count = (value) => typeof value === "number" && value > 0 ? value : 0;
|
|
37805
37805
|
usageTokens = (usage) => {
|
|
37806
|
-
const u = record(usage);
|
|
37806
|
+
const u = record$1(usage);
|
|
37807
37807
|
if (u === void 0) return void 0;
|
|
37808
37808
|
return count(u["input_tokens"]) + count(u["cache_read_input_tokens"]) + count(u["cache_creation_input_tokens"]);
|
|
37809
37809
|
};
|
|
@@ -37818,8 +37818,8 @@ var init_ContextLimit = __esmMin((() => {
|
|
|
37818
37818
|
} catch {
|
|
37819
37819
|
continue;
|
|
37820
37820
|
}
|
|
37821
|
-
if (record(entry)?.["type"] !== "assistant") continue;
|
|
37822
|
-
const tokens = usageTokens(record(record(entry)?.["message"])?.["usage"]);
|
|
37821
|
+
if (record$1(entry)?.["type"] !== "assistant") continue;
|
|
37822
|
+
const tokens = usageTokens(record$1(record$1(entry)?.["message"])?.["usage"]);
|
|
37823
37823
|
if (tokens !== void 0) return tokens;
|
|
37824
37824
|
}
|
|
37825
37825
|
};
|
|
@@ -37839,7 +37839,7 @@ var init_ContextLimit = __esmMin((() => {
|
|
|
37839
37839
|
};
|
|
37840
37840
|
if (tokens >= limit.soft * window) return {
|
|
37841
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.`
|
|
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. Where your instructions name a file for that note, write it there too.`
|
|
37843
37843
|
};
|
|
37844
37844
|
};
|
|
37845
37845
|
hookOutput = (decision) => decision.kind === "soft" ? {
|
|
@@ -41263,6 +41263,13 @@ const writeSelection = (out, fields, path) => gen(function* () {
|
|
|
41263
41263
|
if (selection.kind === "value") out.write(`${selection.text}\n`);
|
|
41264
41264
|
else if (selection.kind === "unknown") return yield* fail$7(new SelectorUsageError(`gtd: unknown --json selector "${selection.path}" — see \`gtd --help\``));
|
|
41265
41265
|
});
|
|
41266
|
+
/** Writes `document` per `json` (bare → whole, `=path` → one value); returns false for `off`. */
|
|
41267
|
+
const writeJson = (json, out, document) => gen(function* () {
|
|
41268
|
+
if (json.kind === "off") return false;
|
|
41269
|
+
if (json.kind === "document") out.write(`${JSON.stringify(document)}\n`);
|
|
41270
|
+
else yield* writeSelection(out, document, json.path);
|
|
41271
|
+
return true;
|
|
41272
|
+
});
|
|
41266
41273
|
//#endregion
|
|
41267
41274
|
//#region src/cli/Strays.ts
|
|
41268
41275
|
init_esm();
|
|
@@ -41324,13 +41331,6 @@ const resolveHistoryRef = (arg, entries) => {
|
|
|
41324
41331
|
return fail$7(/* @__PURE__ */ new Error(`gtd history: no history ref matches "${arg}"`));
|
|
41325
41332
|
};
|
|
41326
41333
|
const seven = (hash) => hash.slice(0, 7);
|
|
41327
|
-
/** Writes `document` per `json` (bare → whole, `=path` → one value); returns false for `off`. */
|
|
41328
|
-
const writeJson = (json, out, document) => gen(function* () {
|
|
41329
|
-
if (json.kind === "off") return false;
|
|
41330
|
-
if (json.kind === "document") out.write(`${JSON.stringify(document)}\n`);
|
|
41331
|
-
else yield* writeSelection(out, document, json.path);
|
|
41332
|
-
return true;
|
|
41333
|
-
});
|
|
41334
41334
|
const runHistoryListCommand = (json, out) => gen(function* () {
|
|
41335
41335
|
const entries = yield* historyEntries;
|
|
41336
41336
|
if (yield* writeJson(json, out, entries)) return;
|
|
@@ -41343,13 +41343,12 @@ const runHistoryListCommand = (json, out) => gen(function* () {
|
|
|
41343
41343
|
const runHistoryShowCommand = (ref, json, out) => gen(function* () {
|
|
41344
41344
|
const entry = yield* resolveHistoryRef(ref, yield* historyEntries);
|
|
41345
41345
|
const trail = yield* historyTrail(entry.tip);
|
|
41346
|
-
|
|
41346
|
+
if (yield* writeJson(json, out, {
|
|
41347
41347
|
ref: entry.ref,
|
|
41348
41348
|
entry: entry.entry,
|
|
41349
41349
|
branch: entry.branch,
|
|
41350
41350
|
...trail
|
|
41351
|
-
};
|
|
41352
|
-
if (yield* writeJson(json, out, document)) return;
|
|
41351
|
+
})) return;
|
|
41353
41352
|
if (trail.versionWarning !== void 0) yield* (yield* Narrator).warn(trail.versionWarning);
|
|
41354
41353
|
const lines = [`${entry.ref} (branch ${entry.branch ?? "-"}, tip ${seven(entry.tip)})`];
|
|
41355
41354
|
for (const step of trail.steps) {
|
|
@@ -41365,6 +41364,203 @@ const runHistoryFetchCommand = (remote, out) => sync$1(() => {
|
|
|
41365
41364
|
out.write(`${combinedScript(fetchHistoryRefs(remote), "")}\n`);
|
|
41366
41365
|
});
|
|
41367
41366
|
//#endregion
|
|
41367
|
+
//#region src/cli/Metrics.ts
|
|
41368
|
+
init_esm();
|
|
41369
|
+
init_wire();
|
|
41370
|
+
const QUALITY = ".gtd/QUALITY.md";
|
|
41371
|
+
const LENS = /^((?:.*\.)?quality\.[^.]+)\.reviewing$/;
|
|
41372
|
+
const CONTINUE = /(^|\.)continue\./;
|
|
41373
|
+
const inSeam = (step) => step.startsWith("seam.");
|
|
41374
|
+
const phaseOf = (step) => {
|
|
41375
|
+
const scope = step.split(".")[0];
|
|
41376
|
+
if (inSeam(step) && step.endsWith(".naive")) return "naive";
|
|
41377
|
+
if (step === "seam.note" || scope === "refactor") return "refactor";
|
|
41378
|
+
if (scope === "implement") return "implement";
|
|
41379
|
+
return "other";
|
|
41380
|
+
};
|
|
41381
|
+
const round = (n, places = 6) => {
|
|
41382
|
+
const f = 10 ** places;
|
|
41383
|
+
return Math.round(n * f) / f;
|
|
41384
|
+
};
|
|
41385
|
+
const record = () => Object.create(null);
|
|
41386
|
+
const add = (into, key, n) => {
|
|
41387
|
+
into[key] = (into[key] ?? 0) + n;
|
|
41388
|
+
};
|
|
41389
|
+
const roundAll = (record) => Object.fromEntries(Object.entries(record).map(([k, v]) => [k, round(v)]));
|
|
41390
|
+
const emptyTally = () => ({
|
|
41391
|
+
slices: {
|
|
41392
|
+
decided: 0,
|
|
41393
|
+
landed: 0,
|
|
41394
|
+
rebuilt: 0,
|
|
41395
|
+
refactored: 0
|
|
41396
|
+
},
|
|
41397
|
+
continuations: record(),
|
|
41398
|
+
byModel: record(),
|
|
41399
|
+
byPhase: {
|
|
41400
|
+
naive: 0,
|
|
41401
|
+
refactor: 0,
|
|
41402
|
+
implement: 0,
|
|
41403
|
+
other: 0
|
|
41404
|
+
},
|
|
41405
|
+
doubleWork: {
|
|
41406
|
+
naive: 0,
|
|
41407
|
+
rebuild: 0
|
|
41408
|
+
},
|
|
41409
|
+
byLens: record()
|
|
41410
|
+
});
|
|
41411
|
+
const sum = (record) => Object.values(record).reduce((a, b) => a + b, 0);
|
|
41412
|
+
const finish = (t) => ({
|
|
41413
|
+
slices: t.slices,
|
|
41414
|
+
refactorFirstRate: t.slices.decided === 0 ? null : round(t.slices.rebuilt / t.slices.decided, 3),
|
|
41415
|
+
continuations: t.continuations,
|
|
41416
|
+
cost: {
|
|
41417
|
+
total: round(sum(t.byModel)),
|
|
41418
|
+
byModel: roundAll(t.byModel),
|
|
41419
|
+
byPhase: roundAll(t.byPhase),
|
|
41420
|
+
doubleWork: {
|
|
41421
|
+
naive: round(t.doubleWork.naive),
|
|
41422
|
+
rebuild: round(t.doubleWork.rebuild),
|
|
41423
|
+
total: round(t.doubleWork.naive + t.doubleWork.rebuild)
|
|
41424
|
+
}
|
|
41425
|
+
},
|
|
41426
|
+
findings: {
|
|
41427
|
+
total: sum(t.byLens),
|
|
41428
|
+
byLens: t.byLens
|
|
41429
|
+
}
|
|
41430
|
+
});
|
|
41431
|
+
const tallyCost = (t, open, costs, phase) => {
|
|
41432
|
+
for (const { cost, model } of costs) {
|
|
41433
|
+
add(t.byModel, model ?? "unspecified", cost);
|
|
41434
|
+
t.byPhase[phase] += cost;
|
|
41435
|
+
if (phase === "naive") open.naive += cost;
|
|
41436
|
+
if (phase === "implement" && open.rebuilding) t.doubleWork.rebuild += cost;
|
|
41437
|
+
}
|
|
41438
|
+
};
|
|
41439
|
+
/** A slice is decided where its turns leave the seam: for `implement.applying` the naive pass landed — unless it fails to apply and is built afresh — anywhere else it is rebuilt. */
|
|
41440
|
+
const tallyDecision = (t, open, at, to) => {
|
|
41441
|
+
if (at === "implement.closing") open.rebuilding = false;
|
|
41442
|
+
if (open.applying !== void 0 && at === "implement.applying") {
|
|
41443
|
+
const naive = open.applying;
|
|
41444
|
+
open.applying = void 0;
|
|
41445
|
+
if (to !== "implement.building") return;
|
|
41446
|
+
t.slices.landed--;
|
|
41447
|
+
rebuild(t, open, naive);
|
|
41448
|
+
return;
|
|
41449
|
+
}
|
|
41450
|
+
if (!inSeam(at) || inSeam(to)) return;
|
|
41451
|
+
t.slices.decided++;
|
|
41452
|
+
const naive = open.naive;
|
|
41453
|
+
open.naive = 0;
|
|
41454
|
+
if (to === "implement.applying") {
|
|
41455
|
+
open.applying = naive;
|
|
41456
|
+
open.rebuilding = false;
|
|
41457
|
+
t.slices.landed++;
|
|
41458
|
+
return;
|
|
41459
|
+
}
|
|
41460
|
+
rebuild(t, open, naive);
|
|
41461
|
+
if (at === "seam.note") t.slices.refactored++;
|
|
41462
|
+
};
|
|
41463
|
+
const rebuild = (t, open, naive) => {
|
|
41464
|
+
open.rebuilding = true;
|
|
41465
|
+
t.slices.rebuilt++;
|
|
41466
|
+
t.doubleWork.naive += naive;
|
|
41467
|
+
};
|
|
41468
|
+
/** Oldest first; a commit gtd did not write is skipped. */
|
|
41469
|
+
const processMetrics = (commits) => {
|
|
41470
|
+
const t = emptyTally();
|
|
41471
|
+
const open = {
|
|
41472
|
+
naive: 0,
|
|
41473
|
+
rebuilding: false,
|
|
41474
|
+
applying: void 0
|
|
41475
|
+
};
|
|
41476
|
+
for (const commit of commits) {
|
|
41477
|
+
const message = parseCommitMessage(commit.message);
|
|
41478
|
+
const subject = message.parsed;
|
|
41479
|
+
if (subject === void 0) continue;
|
|
41480
|
+
const at = subject.from ?? subject.to;
|
|
41481
|
+
tallyCost(t, open, message.cost, phaseOf(at));
|
|
41482
|
+
if (subject.actor === "agent" && CONTINUE.test(at)) add(t.continuations, at.replace(CONTINUE, "$1"), 1);
|
|
41483
|
+
const lens = LENS.exec(at)?.[1];
|
|
41484
|
+
if (lens !== void 0 && commit.findings > 0) add(t.byLens, lens, commit.findings);
|
|
41485
|
+
tallyDecision(t, open, at, subject.to);
|
|
41486
|
+
}
|
|
41487
|
+
return finish(t);
|
|
41488
|
+
};
|
|
41489
|
+
const totalMetrics = (all) => {
|
|
41490
|
+
const t = emptyTally();
|
|
41491
|
+
for (const m of all) {
|
|
41492
|
+
for (const key of Object.keys(t.slices)) t.slices[key] += m.slices[key];
|
|
41493
|
+
for (const [k, v] of Object.entries(m.continuations)) add(t.continuations, k, v);
|
|
41494
|
+
for (const [k, v] of Object.entries(m.cost.byModel)) add(t.byModel, k, v);
|
|
41495
|
+
for (const key of Object.keys(t.byPhase)) t.byPhase[key] += m.cost.byPhase[key];
|
|
41496
|
+
t.doubleWork.naive += m.cost.doubleWork.naive;
|
|
41497
|
+
t.doubleWork.rebuild += m.cost.doubleWork.rebuild;
|
|
41498
|
+
for (const [k, v] of Object.entries(m.findings.byLens)) add(t.byLens, k, v);
|
|
41499
|
+
}
|
|
41500
|
+
return {
|
|
41501
|
+
processes: all.length,
|
|
41502
|
+
...finish(t)
|
|
41503
|
+
};
|
|
41504
|
+
};
|
|
41505
|
+
const chunks = (content) => content === void 0 ? 0 : (content.match(/^## /gm) ?? []).length;
|
|
41506
|
+
const readProcessMetrics = (entry) => gen(function* () {
|
|
41507
|
+
const git = yield* GitService;
|
|
41508
|
+
const base = getOrUndefined(yield* git.readRefOption(`${entry.entry}^`));
|
|
41509
|
+
const commits = yield* git.commitHistory(base, entry.tip);
|
|
41510
|
+
const quality = (hash) => git.readFileAtRef(hash, QUALITY).pipe(map$4((content) => content), orElseSucceed(() => void 0));
|
|
41511
|
+
let count = chunks(base === void 0 ? void 0 : yield* quality(base));
|
|
41512
|
+
const read = [];
|
|
41513
|
+
for (const { hash, message, touched } of commits) {
|
|
41514
|
+
const before = count;
|
|
41515
|
+
if (touched.includes(QUALITY)) count = chunks(yield* quality(hash));
|
|
41516
|
+
read.push({
|
|
41517
|
+
message,
|
|
41518
|
+
findings: Math.max(0, count - before)
|
|
41519
|
+
});
|
|
41520
|
+
}
|
|
41521
|
+
return {
|
|
41522
|
+
workflow: (commits[0] === void 0 ? void 0 : parseCommitMessage(commits[0].message).workflow) ?? null,
|
|
41523
|
+
...processMetrics(read)
|
|
41524
|
+
};
|
|
41525
|
+
});
|
|
41526
|
+
const printable = (s) => s.replace(/[\x00-\x1f\x7f-\x9f\u2028\u2029]/g, "?");
|
|
41527
|
+
const listed = (record) => Object.entries(record).map(([k, v]) => `${printable(k)} ${v}`).join(", ");
|
|
41528
|
+
const line = (label, m) => {
|
|
41529
|
+
const { slices, cost } = m;
|
|
41530
|
+
const percent = m.refactorFirstRate === null ? "-" : `${Math.round(m.refactorFirstRate * 100)}%`;
|
|
41531
|
+
const continued = sum(m.continuations);
|
|
41532
|
+
return [
|
|
41533
|
+
`${label}: ${slices.decided} slices, ${slices.rebuilt} rebuilt (refactor-first ${percent}), ${slices.refactored} refactored`,
|
|
41534
|
+
`${continued} continuations${continued > 0 ? ` (${listed(m.continuations)})` : ""}`,
|
|
41535
|
+
`cost ${cost.total} (${listed(cost.byPhase)}; by model ${listed(cost.byModel) || "-"}), double work ${cost.doubleWork.total}`,
|
|
41536
|
+
`${m.findings.total} findings${m.findings.total > 0 ? ` (${listed(m.findings.byLens)})` : ""}`
|
|
41537
|
+
].join("; ");
|
|
41538
|
+
};
|
|
41539
|
+
const runHistoryMetricsCommand = (refs, json, out) => gen(function* () {
|
|
41540
|
+
const entries = yield* historyEntries;
|
|
41541
|
+
const chosen = refs.length === 0 ? entries : (yield* forEach$2(refs, (ref) => resolveHistoryRef(ref, entries).pipe(map$4((hit) => hit.branch === ref ? entries.filter((e) => e.branch === ref) : [hit])))).flat();
|
|
41542
|
+
const unique = chosen.filter((e, i) => chosen.findIndex((o) => o.ref === e.ref) === i);
|
|
41543
|
+
const processes = yield* forEach$2(unique, (e) => readProcessMetrics(e).pipe(map$4((metrics) => ({
|
|
41544
|
+
ref: e.ref,
|
|
41545
|
+
entry: e.entry,
|
|
41546
|
+
branch: e.branch,
|
|
41547
|
+
tip: e.tip,
|
|
41548
|
+
...metrics
|
|
41549
|
+
}))), { concurrency: 4 });
|
|
41550
|
+
const document = {
|
|
41551
|
+
processes,
|
|
41552
|
+
total: totalMetrics(processes)
|
|
41553
|
+
};
|
|
41554
|
+
if (yield* writeJson(json, out, document)) return;
|
|
41555
|
+
if (processes.length === 0) {
|
|
41556
|
+
out.write("no history refs; run gtd history fetch | sh to pull them\n");
|
|
41557
|
+
return;
|
|
41558
|
+
}
|
|
41559
|
+
const lines = processes.map((p) => line(`${p.entry.slice(0, 7)} ${printable(p.branch ?? "-")}${p.workflow === null ? "" : ` (${printable(p.workflow)})`}`, p));
|
|
41560
|
+
lines.push(line(`total (${processes.length} processes)`, document.total));
|
|
41561
|
+
out.write(`${lines.join("\n")}\n`);
|
|
41562
|
+
});
|
|
41563
|
+
//#endregion
|
|
41368
41564
|
//#region src/cli/Program.ts
|
|
41369
41565
|
init_esm();
|
|
41370
41566
|
init_wire();
|
|
@@ -42022,6 +42218,7 @@ const dispatchVoidCommand = (command, json, out) => {
|
|
|
42022
42218
|
case "judgeRun": return runJudgeRunCommand(command, out);
|
|
42023
42219
|
case "historyList": return runHistoryListCommand(json, out);
|
|
42024
42220
|
case "historyShow": return runHistoryShowCommand(command.ref, json, out);
|
|
42221
|
+
case "historyMetrics": return runHistoryMetricsCommand(command.refs, json, out);
|
|
42025
42222
|
case "historyFetch": return runHistoryFetchCommand(command.remote, out);
|
|
42026
42223
|
}
|
|
42027
42224
|
};
|
|
@@ -42062,18 +42259,30 @@ const share = (raw, flag) => {
|
|
|
42062
42259
|
const n = Number(raw);
|
|
42063
42260
|
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
42261
|
};
|
|
42262
|
+
const JSON_KINDS = /* @__PURE__ */ new Set([
|
|
42263
|
+
"next",
|
|
42264
|
+
"land",
|
|
42265
|
+
"judge",
|
|
42266
|
+
"judgeAnswer",
|
|
42267
|
+
"doors",
|
|
42268
|
+
"slices",
|
|
42269
|
+
"historyList",
|
|
42270
|
+
"historyShow",
|
|
42271
|
+
"historyMetrics",
|
|
42272
|
+
"strays"
|
|
42273
|
+
]);
|
|
42065
42274
|
const FLAGS = [
|
|
42066
42275
|
{
|
|
42067
42276
|
name: "--json",
|
|
42068
42277
|
arity: "optional",
|
|
42069
42278
|
repeatable: false,
|
|
42070
|
-
scope: (kind) => kind
|
|
42279
|
+
scope: (kind) => JSON_KINDS.has(kind),
|
|
42071
42280
|
decode: ([raw]) => right(raw ?? ""),
|
|
42072
|
-
scopeError: "gtd: --json is only valid for `gtd next`/`gtd land`/`gtd judge`/`gtd judge answer`/`gtd doors`/`gtd slices`/`gtd history list`/`gtd history show`/`gtd strays` — every other command prints plain text; see `gtd install` for the driver protocol briefing",
|
|
42281
|
+
scopeError: "gtd: --json is only valid for `gtd next`/`gtd land`/`gtd judge`/`gtd judge answer`/`gtd doors`/`gtd slices`/`gtd history list`/`gtd history show`/`gtd history metrics`/`gtd strays` — every other command prints plain text; see `gtd install` for the driver protocol briefing",
|
|
42073
42282
|
valueHint: "<path>",
|
|
42074
42283
|
help: [
|
|
42075
42284
|
"(gtd next/gtd land/gtd judge/gtd judge answer/gtd doors/gtd slices/gtd history",
|
|
42076
|
-
"list/gtd history show/gtd strays only) output structured JSON. Bare --json prints the whole document;",
|
|
42285
|
+
"list/gtd history show/gtd history metrics/gtd strays only) output structured JSON. Bare --json prints the whole document;",
|
|
42077
42286
|
"--json=<path> (a dotted key path into that document, e.g.",
|
|
42078
42287
|
"kind, content, session.id) prints just that value: a",
|
|
42079
42288
|
"scalar raw and unquoted, a boolean as true/false, a list",
|
|
@@ -42723,6 +42932,25 @@ const COMMAND_ROWS = [
|
|
|
42723
42932
|
"prints the trail as one document; writes nothing"
|
|
42724
42933
|
]
|
|
42725
42934
|
},
|
|
42935
|
+
{
|
|
42936
|
+
token: "history metrics",
|
|
42937
|
+
kind: "historyMetrics",
|
|
42938
|
+
arity: {
|
|
42939
|
+
name: "ref",
|
|
42940
|
+
many: true
|
|
42941
|
+
},
|
|
42942
|
+
details: [
|
|
42943
|
+
"Report how the kept processes went: slices whose naive pass",
|
|
42944
|
+
"landed or was rebuilt (the refactor-first rate), continuations",
|
|
42945
|
+
"per phase, Gtd-Cost by model and phase with the double work of",
|
|
42946
|
+
"a rebuild, and quality-lap findings per lens — per process and",
|
|
42947
|
+
"in total. Each <ref> is read as by history show, but a branch",
|
|
42948
|
+
"name means every process kept from it; none means every ref.",
|
|
42949
|
+
"Reads commit subjects and trailers, never replays, so a",
|
|
42950
|
+
"changed config is no refusal. --json prints { processes, total",
|
|
42951
|
+
"} as one document; writes nothing"
|
|
42952
|
+
]
|
|
42953
|
+
},
|
|
42726
42954
|
{
|
|
42727
42955
|
token: "history fetch",
|
|
42728
42956
|
kind: "historyFetch",
|
|
@@ -42754,7 +42982,7 @@ const flagHeader = (row) => {
|
|
|
42754
42982
|
};
|
|
42755
42983
|
const renderHelp = () => {
|
|
42756
42984
|
const commandBlocks = COMMAND_ROWS.map((row) => {
|
|
42757
|
-
const header = row.arity === "none" ? row.token : "names" in row.arity ? `${row.token} <${row.arity.names[0]}> <${row.arity.names[1]}>` : "variadic" in row.arity ? `${row.token} <${row.arity.name}> [${row.arity.variadic}...]` : "optional" in row.arity ? `${row.token} [${row.arity.name}]` : `${row.token} <${row.arity.name}>`;
|
|
42985
|
+
const header = row.arity === "none" ? row.token : "names" in row.arity ? `${row.token} <${row.arity.names[0]}> <${row.arity.names[1]}>` : "variadic" in row.arity ? `${row.token} <${row.arity.name}> [${row.arity.variadic}...]` : "optional" in row.arity ? `${row.token} [${row.arity.name}]` : "many" in row.arity ? `${row.token} [${row.arity.name}...]` : `${row.token} <${row.arity.name}>`;
|
|
42758
42986
|
return renderBlock(header, row.details);
|
|
42759
42987
|
});
|
|
42760
42988
|
return `Usage: gtd [command] [options]\n\nCommands:\n${[
|
|
@@ -42862,12 +43090,14 @@ const conflictViolation = (present) => {
|
|
|
42862
43090
|
for (const other of row.conflicts ?? []) if (present.has(other)) return `gtd: ${row.name} and ${other} are mutually exclusive`;
|
|
42863
43091
|
}
|
|
42864
43092
|
};
|
|
43093
|
+
const tooMany = (cmd, rest, expected, max) => rest.length > max ? `gtd ${cmd}: too many arguments — expected ${expected}, got: ${rest.join(", ")}` : void 0;
|
|
42865
43094
|
const arityError = (cmd, rest, arity) => {
|
|
42866
|
-
if (arity === "none") return
|
|
43095
|
+
if (arity === "none") return tooMany(cmd, rest, "none", 0);
|
|
42867
43096
|
if ("names" in arity) return pairArityError(cmd, rest, arity.names);
|
|
42868
|
-
if ("
|
|
43097
|
+
if ("many" in arity) return void 0;
|
|
43098
|
+
if ("optional" in arity) return tooMany(cmd, rest, `at most one ${arity.name}`, 1);
|
|
42869
43099
|
if (rest.length === 0) return `gtd ${cmd}: missing ${arity.name} argument`;
|
|
42870
|
-
|
|
43100
|
+
return "variadic" in arity ? void 0 : tooMany(cmd, rest, `one ${arity.name}`, 1);
|
|
42871
43101
|
};
|
|
42872
43102
|
const pairArityError = (cmd, rest, [first, second]) => {
|
|
42873
43103
|
if (rest.length === 0) return `gtd ${cmd}: missing ${first} and ${second} arguments`;
|
|
@@ -42918,7 +43148,7 @@ const parseArgv = (argv) => {
|
|
|
42918
43148
|
};
|
|
42919
43149
|
const isHistory = first === "history";
|
|
42920
43150
|
const row = first === void 0 ? void 0 : commandByToken(isHistory ? `history ${positionals[1] ?? ""}` : first);
|
|
42921
|
-
if (isHistory && row === void 0) return usagePlan("gtd history: expected a subcommand — list, show <ref
|
|
43151
|
+
if (isHistory && row === void 0) return usagePlan("gtd history: expected a subcommand — list, show <ref>, metrics [ref...] or fetch [remote]", jsonSeen);
|
|
42922
43152
|
const judgeAnswer = row?.kind === "judge" && positionals[1] === "answer";
|
|
42923
43153
|
const selectsStart = workflowPresent && first === void 0;
|
|
42924
43154
|
const judgeRun = row?.kind === "judge" && positionals[1] === "run";
|
|
@@ -43051,6 +43281,15 @@ const parseArgv = (argv) => {
|
|
|
43051
43281
|
json,
|
|
43052
43282
|
verbose
|
|
43053
43283
|
};
|
|
43284
|
+
if (kind === "historyMetrics") return {
|
|
43285
|
+
kind: "command",
|
|
43286
|
+
command: {
|
|
43287
|
+
kind: "historyMetrics",
|
|
43288
|
+
refs: restPositionals
|
|
43289
|
+
},
|
|
43290
|
+
json,
|
|
43291
|
+
verbose
|
|
43292
|
+
};
|
|
43054
43293
|
if (kind === "historyFetch") return {
|
|
43055
43294
|
kind: "command",
|
|
43056
43295
|
command: {
|