@pmelab/gtd 37.0.0 → 38.1.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 +15 -0
- package/dist/chunks/{reserved-zAfoJtR7.mjs → reserved-CfQ8eurM.mjs} +85 -17
- package/dist/chunks/{tail-BRC4DGdV.mjs → tail-C7yaWvaS.mjs} +1 -1
- package/dist/chunks/{wire-CSsa3Wxd.mjs → wire-BJuZWR3C.mjs} +1 -1
- package/dist/gtd.bundle.mjs +1 -1
- package/dist/testkit.mjs +1 -1
- package/dist/wire.mjs +1 -1
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +318 -76
- 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 +419 -109
- package/package.json +1 -1
- package/src/testkit/steps.ts +39 -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/coverage.ts +14 -6
- package/src/workflows/feature/criteria.test.ts +17 -1
- package/src/workflows/feature/criteria.ts +37 -3
- package/src/workflows/feature/feature.ts +64 -15
- package/src/workflows/feature/index.ts +1 -0
- package/src/workflows/feature/refactor.ts +64 -30
- package/src/workflows/feature/seam.ts +157 -48
- package/src/workflows/feature/slicing-cap.feature +14 -0
- package/src/workflows/feature/slicing.feature +225 -0
- package/src/workflows/feature/slicing.test.ts +49 -0
- package/src/workflows/feature/slicing.ts +105 -0
- package/src/workflows/index.ts +1 -0
- package/src/workflows/shared/continuation.ts +92 -0
- package/src/workflows/shared/fences.ts +5 -0
- package/src/workflows/shared/options.ts +3 -0
- package/src/workflows/shared/steps.ts +2 -0
- package/src/workflows/shared/text.test.ts +6 -2
- package/src/workflows/shared/text.ts +153 -22
- package/src/workflows/shared/vars.ts +6 -0
- package/src/workflows/shared/workflows.steps.ts +13 -0
package/README.md
CHANGED
|
@@ -313,6 +313,12 @@ note, past 70% (or when the context is about to be compacted) the turn stops and
|
|
|
313
313
|
nothing lands. A step's `context` option, or the bundled workflows'
|
|
314
314
|
`contextLimit` option, moves the two limits — see
|
|
315
315
|
[Context limits](https://github.com/pmelab/gtd/blob/main/docs/driver.md#context-limits).
|
|
316
|
+
In `feature`, a naive pass, refactor or build turn that wrapped up that way is a
|
|
317
|
+
snapshot: a fresh turn picks up from it with the handoff note and the criteria
|
|
318
|
+
still open, up to 3 times per phase, across its retries (`continuations`), and a
|
|
319
|
+
phase whose continuations keep stopping, or close nothing twice in a row
|
|
320
|
+
(`continuationStall`), rests for a person — see
|
|
321
|
+
[Continuations](https://github.com/pmelab/gtd/blob/main/docs/configuration.md#continuations).
|
|
316
322
|
|
|
317
323
|
### Or drive it from inside Claude Code
|
|
318
324
|
|
|
@@ -638,6 +644,15 @@ out is `gtd abandon`. A process from 27.5.0 or later whose judge ruled
|
|
|
638
644
|
that slice. Details in
|
|
639
645
|
[the naive-pass path](docs/configuration.md#the-naive-pass-path).
|
|
640
646
|
|
|
647
|
+
**Coarse slices (`sliceMaxCriteria`, default 8).** A change with more acceptance
|
|
648
|
+
criteria than the cap is built in slices: after design an agent groups related
|
|
649
|
+
criteria (same flow or subsystem) into `.gtd/SLICES.md`, as few slices as the
|
|
650
|
+
cap allows, and each slice — naive pass, refactor and rebuild when judged so,
|
|
651
|
+
health loop, quality lap — runs in order from where the previous one landed.
|
|
652
|
+
`gtd slices` lists them as `feature-1`, `feature-2`, … (`refactor-<n>` ahead of
|
|
653
|
+
a refactored one). A change within the cap is one `feature` slice, as before.
|
|
654
|
+
See [Coarse slices](docs/configuration.md#coarse-slices).
|
|
655
|
+
|
|
641
656
|
**Flag mode (`flagMode`, on by default).** On, the naive pass's judge runs as
|
|
642
657
|
above and a rebuilt implementation is asked for a new release flag (none at a
|
|
643
658
|
`low` risk tier); a pass the judge lets land is not asked for one. A project
|
|
@@ -133,9 +133,12 @@ const defaults = {
|
|
|
133
133
|
refactorFlagPattern: "\\bGTD_FLAG_\\w+",
|
|
134
134
|
seamAllow: [...testFileGlobs, ".gtd/**"].join(", "),
|
|
135
135
|
flagMode: "true",
|
|
136
|
+
sliceMaxCriteria: "8",
|
|
136
137
|
flag_risk_tier: "0",
|
|
137
138
|
qualityReviews: "correctness, owasp-security, ponytail-review, test-audit, conventions, spec-challenge",
|
|
138
|
-
refactorQualityReviews: "correctness, ponytail-review, conventions"
|
|
139
|
+
refactorQualityReviews: "correctness, ponytail-review, conventions",
|
|
140
|
+
continuations: "3",
|
|
141
|
+
continuationStall: "2"
|
|
139
142
|
};
|
|
140
143
|
/** Environment settings. */
|
|
141
144
|
const envDefaults = {
|
|
@@ -592,6 +595,24 @@ printf '%s\\n' ${[
|
|
|
592
595
|
].map(quote).join(" ")} > ${quote(".gtd/REQUIREMENTS.md")}
|
|
593
596
|
`;
|
|
594
597
|
};
|
|
598
|
+
const slicingPrompt = (cap) => `${stateFileRules}
|
|
599
|
+
- Read \`.gtd/REQUIREMENTS.md\`: its \`## Acceptance Criteria\` are settled
|
|
600
|
+
and more than ${cap}, too many to build in one slice
|
|
601
|
+
- Group them into slices in \`.gtd/SLICES.md\`, one \`## <title>\` heading per
|
|
602
|
+
slice over a \`- AC-<n>\` list item per criterion it builds. Put criteria of
|
|
603
|
+
the same flow or subsystem together; every criterion in exactly one slice,
|
|
604
|
+
at most ${cap} per slice
|
|
605
|
+
- Keep it coarse: as few slices as the cap allows, never one per criterion
|
|
606
|
+
- Order the slices so each builds on the ones before: they run in that order,
|
|
607
|
+
each from where the previous one landed
|
|
608
|
+
- Change nothing but \`.gtd/SLICES.md\` — leave the criteria as they are
|
|
609
|
+
- Leave everything uncommitted and finish your turn — do not commit
|
|
610
|
+
`;
|
|
611
|
+
/** The line telling a slice's turn which criteria are its own; empty for a single slice. */
|
|
612
|
+
const sliceLine = (ids) => ids === void 0 ? "" : `- This slice builds ${ids.join(", ")} only: every rule here about the criteria
|
|
613
|
+
means these. The others are for other slices, before or after it — leave
|
|
614
|
+
them unbuilt and untested
|
|
615
|
+
`;
|
|
595
616
|
const designSystem = () => `${designPersona}
|
|
596
617
|
|
|
597
618
|
${agentConduct}`;
|
|
@@ -635,7 +656,7 @@ ${strays.map((path) => ` - \`${displayPath(path)}\``).join("\n")}
|
|
|
635
656
|
- Introduce no new flag read and add no second read of an existing one:
|
|
636
657
|
every match of \`${pattern}\` may move, never increase in number`;
|
|
637
658
|
const withRules = (rules) => rules === void 0 ? "" : `${rules}\n`;
|
|
638
|
-
const refactorBuildingPrompt = ({ pkg, strays, pattern, reference, feedback = false, note = false }) => `${stateFileRules}
|
|
659
|
+
const refactorBuildingPrompt = ({ pkg, strays, pattern, reference, feedback = false, note = false, from }) => `${stateFileRules}
|
|
639
660
|
- The package to implement is \`${pkg}\`; never delete it
|
|
640
661
|
${note ? `- The package's \`## Refactor note\` section names the seams to open and the
|
|
641
662
|
shape each takes, written from the whole naive pass: build exactly those
|
|
@@ -650,8 +671,9 @@ ${reference === void 0 ? "" : `- Reference only: \`git show ${reference} -- ${st
|
|
|
650
671
|
restructuring afresh here, minus the feature's own behaviour. A
|
|
651
672
|
refactor that touches none of it is wrong, however clean — never
|
|
652
673
|
swap in an unrelated tidy-up
|
|
653
|
-
`}
|
|
654
|
-
|
|
674
|
+
`}${handoffRule()}
|
|
675
|
+
- Leave everything uncommitted and finish your turn — do not commit
|
|
676
|
+
${from === void 0 ? "" : continuationLines(from)}`;
|
|
655
677
|
const refactorFixPrompt = (strays, pattern) => `${stateFileRules}
|
|
656
678
|
${fixFeedbackPrompt}
|
|
657
679
|
${refactorRules(strays, pattern)}
|
|
@@ -1219,7 +1241,7 @@ Print the closing message and stop — this writes nothing itself.
|
|
|
1219
1241
|
const listed = (paths, unreadable = []) => paths.map((path) => ` - \`${displayPath(path)}\`${unreadable.includes(path) ? " (unreadable)" : ""}`).join("\n");
|
|
1220
1242
|
const isRed = (retry) => "red" in retry;
|
|
1221
1243
|
const isFault = (retry) => "fault" in retry;
|
|
1222
|
-
const pickUp = (hash) => `Pick it up — \`git diff --binary ${hash}^ ${hash} | git apply\``;
|
|
1244
|
+
const pickUp = (hash, exclude) => `Pick it up — \`git diff --binary --no-color --no-ext-diff --no-textconv ${hash}^ ${hash}${exclude === void 0 ? "" : ` -- ${quote(":(top)")} ${quote(`:(top,exclude)${exclude}`)}`} | git apply\``;
|
|
1223
1245
|
const criteriaBinding = (refused) => `- Its \`## Acceptance Criteria\` (\`AC-<n>\`) bind this turn: re-read them from
|
|
1224
1246
|
the file, never from memory, and stop only when each one holds. They are
|
|
1225
1247
|
settled — ${refused ? "a turn that changes them is refused" : "leave them as they are"}`;
|
|
@@ -1238,9 +1260,35 @@ re-implement. It changed these files outside the expected set:
|
|
|
1238
1260
|
${listed(retry.strays)}
|
|
1239
1261
|
Start over and choose a different approach; do not rebuild the same diff.
|
|
1240
1262
|
`;
|
|
1241
|
-
const
|
|
1263
|
+
const quoted = (text) => text.trimEnd().split("\n").map((line) => line === "" ? "" : ` > ${line}`).join("\n");
|
|
1264
|
+
/** Every turn a continuation may pick up tells its agent where the note goes. */
|
|
1265
|
+
const handoffRule = () => `- Should you be told to stop at a context limit, write the handoff note to
|
|
1266
|
+
\`.gtd/HANDOFF.md\` — what you touched, what was next — and finish your turn:
|
|
1267
|
+
a fresh turn picks up from what you leave, broken or not. That file is the one
|
|
1268
|
+
exception to any path rule here; write it at no other time`;
|
|
1269
|
+
/** `pickUp`: how the snapshot gets into the tree — absent when it already is. */
|
|
1270
|
+
const continuationLines = (from, pickUp) => `
|
|
1271
|
+
Your previous turn stopped at its context limit; this fresh turn picks up from
|
|
1272
|
+
its snapshot (\`${from.snapshot}\`). ${pickUp === void 0 ? "Its work is already in the tree." : `${pickUp}.`} Its handoff note:
|
|
1273
|
+
|
|
1274
|
+
${quoted(from.note === "" ? "(empty)" : from.note)}
|
|
1275
|
+
|
|
1276
|
+
Still open: ${from.open.length === 0 ? "nothing the workflow can count — finish what the note says is next" : from.open.join(", ")}.
|
|
1277
|
+
${pickUp === void 0 ? "Delete `.gtd/HANDOFF.md` once you are done; rewrite it should you be stopped again.\n" : ""}`;
|
|
1278
|
+
const oversizedMessage = (phase, from, why, narrowable = true) => `The ${phase} keeps outgrowing its context: ${"cap" in why ? why.cap === 0 ? "continuations are off (`continuations` is 0) and the turn stopped at its context limit" : `${why.cap} continuation${why.cap === 1 ? "" : "s"} ran and the last still stopped at its context limit` : `the last ${why.stall} continuation${why.stall === 1 ? "" : "s"} closed nothing still open`}. The last snapshot is \`${from.snapshot}\`; still open: ${from.open.length === 0 ? "nothing countable" : from.open.join(", ")}.
|
|
1279
|
+
|
|
1280
|
+
Its handoff note:
|
|
1281
|
+
|
|
1282
|
+
${quoted(from.note === "" ? "(empty)" : from.note)}
|
|
1283
|
+
|
|
1284
|
+
Land to go on: a fresh round of continuations picks up from that snapshot${narrowable ? ` — narrow
|
|
1285
|
+
\`.gtd/REQUIREMENTS.md\` first if the change is too big, or raise the context limit` : ` — raise
|
|
1286
|
+
the context limit first if the refactor is too big`}. \`gtd abandon\` gives the change up.
|
|
1287
|
+
`;
|
|
1288
|
+
/** `from`: a continuation of a pass that stopped at its context limit, in place of `retry`'s pick-up. */
|
|
1289
|
+
const naivePassPrompt = (retry, slice, from) => `${stateFileRules}
|
|
1242
1290
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
1243
|
-
${criteriaBinding(false)}
|
|
1291
|
+
${sliceLine(slice)}${criteriaBinding(false)}
|
|
1244
1292
|
- Implement them the quickest way that works — the naive version. Do not
|
|
1245
1293
|
restructure, abstract or refactor around the change; it may land exactly as
|
|
1246
1294
|
you leave it, and a reviewer makes it fit
|
|
@@ -1255,9 +1303,20 @@ ${criteriaBinding(false)}
|
|
|
1255
1303
|
- Run \`${env.testCommand}\` and finish only once it is green with every
|
|
1256
1304
|
criterion's test passing: the next step runs it on your diff and sends a red
|
|
1257
1305
|
pass back
|
|
1258
|
-
- Leave \`.gtd/\` untouched
|
|
1306
|
+
- Leave \`.gtd/\` untouched, a handoff note excepted
|
|
1307
|
+
${handoffRule()}
|
|
1259
1308
|
- Leave everything uncommitted and finish your turn — do not commit
|
|
1260
|
-
${retry === void 0 ? "" :
|
|
1309
|
+
${from !== void 0 ? `${continuationLines(from, pickUp(from.snapshot, ".gtd/HANDOFF.md"))}${retry === void 0 ? "" : isFault(retry) ? `
|
|
1310
|
+
The pass this continues was a retry: its tests fell short, and still must not:
|
|
1311
|
+
${retry.fault}
|
|
1312
|
+
` : isRed(retry) ? `
|
|
1313
|
+
The pass this continues was a retry after a red suite (\`.gtd/FEEDBACK.md\`
|
|
1314
|
+
holds the output): finish only once the suite is green.
|
|
1315
|
+
` : `
|
|
1316
|
+
The pass this continues was a retry after a \`reject\`: keep away from the
|
|
1317
|
+
approach that changed these files outside the expected set:
|
|
1318
|
+
${listed(retry.strays)}
|
|
1319
|
+
`}` : retry === void 0 ? "" : naiveRetry(retry)}`;
|
|
1261
1320
|
const carries = (rebuild) => (rebuild.acceptance?.ids.length ?? 0) > 0;
|
|
1262
1321
|
const rebuildLines = ({ note, acceptance }) => `${note === void 0 ? "" : `- The refactor note (\`.gtd/REFACTOR-NOTE.md\`) named the seams the refactor
|
|
1263
1322
|
opened; plug the change into them:
|
|
@@ -1290,9 +1349,13 @@ const afterRefactorLine = (rebuild) => `- A reviewed refactor has just landed an
|
|
|
1290
1349
|
though never a release flag. Build only what is still missing, held to every
|
|
1291
1350
|
rule below; if nothing is, ${carries(rebuild) ? "carry over the acceptance tests below and change nothing else" : "change nothing and finish your turn"}
|
|
1292
1351
|
`;
|
|
1293
|
-
const
|
|
1352
|
+
const flagLine = (flagMode, tier, amend, sliced) => !flagMode ? "- Add no release flag — this project ships without release flags" : tier === "low" ? "- Add no release flag — this change is low risk tier" : amend === true ? "- Keep the release flag the earlier lap added, if it added one; otherwise put\n the behaviour behind a new release flag" : sliced ? `- Put the new behaviour behind the release flag an earlier slice of this
|
|
1353
|
+
change added; only when none did, behind a new one, following the
|
|
1354
|
+
repository's flag conventions` : `- Put the new behaviour behind a new release flag, following the
|
|
1355
|
+
repository's flag conventions`;
|
|
1356
|
+
const implementBuildingPrompt = (reference, tier, amend, afterRefactor, flagMode = true, rebuild = {}, slice, from) => `${stateFileRules}
|
|
1294
1357
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
1295
|
-
${criteriaBinding(true)}
|
|
1358
|
+
${sliceLine(slice)}${criteriaBinding(true)}
|
|
1296
1359
|
${afterRefactor === true ? afterRefactorLine(rebuild) : ""}${amend === true ? `- The change already exists in the tree from an earlier lap; amend it to meet
|
|
1297
1360
|
the re-derived requirements instead of rewriting it
|
|
1298
1361
|
` : flagMode ? `- Implement them properly, fitting the codebase's seams and conventions
|
|
@@ -1301,14 +1364,14 @@ ${afterRefactor === true ? afterRefactorLine(rebuild) : ""}${amend === true ? `-
|
|
|
1301
1364
|
`}${reference === void 0 || amend === true ? "" : `- Reference only: \`git show ${reference}\` shows an earlier naive attempt.
|
|
1302
1365
|
Read it for ideas; never apply, cherry-pick or check it out — write
|
|
1303
1366
|
the change fresh${carries(rebuild) ? ", its acceptance tests excepted (below)" : ""}
|
|
1304
|
-
`}${rebuildLines(rebuild)}${
|
|
1305
|
-
repository's flag conventions`}
|
|
1367
|
+
`}${rebuildLines(rebuild)}${flagLine(flagMode, tier, amend, slice !== void 0)}
|
|
1306
1368
|
- Write the tests first, then the code that makes them pass. Name each
|
|
1307
1369
|
criterion's ID in the test that covers it (\`[AC-3] …\`): once the suite is
|
|
1308
1370
|
green a judge checks every ID has a passing test, and sends uncovered ones back
|
|
1371
|
+
${handoffRule()}
|
|
1309
1372
|
- Leave \`.gtd/REQUIREMENTS.md\` in place and everything uncommitted, then
|
|
1310
1373
|
finish your turn
|
|
1311
|
-
`;
|
|
1374
|
+
${from === void 0 ? "" : continuationLines(from)}`;
|
|
1312
1375
|
const implementFixPrompt = () => `${stateFileRules}
|
|
1313
1376
|
${fixFeedbackPrompt}
|
|
1314
1377
|
- Leave everything uncommitted and finish your turn — do not commit
|
|
@@ -1383,9 +1446,9 @@ const coverageMessage = () => `Judging acceptance-criteria coverage. Run \`gtd j
|
|
|
1383
1446
|
\`yes\`/\`no\` verdict per criterion ID — or land without a verdict, which
|
|
1384
1447
|
counts every criterion as uncovered.
|
|
1385
1448
|
`;
|
|
1386
|
-
const coveringPrompt = (uncovered) => `${stateFileRules}
|
|
1449
|
+
const coveringPrompt = (uncovered, slice) => `${stateFileRules}
|
|
1387
1450
|
- Read \`.gtd/REQUIREMENTS.md\`: the settled requirements for this change
|
|
1388
|
-
${criteriaBinding(true)}
|
|
1451
|
+
${sliceLine(slice)}${criteriaBinding(true)}
|
|
1389
1452
|
- A judge found no passing test in this change that covers ${uncovered.join(", ")}.
|
|
1390
1453
|
Write a behaviour-level test for each, naming its ID in the test or scenario
|
|
1391
1454
|
name (\`[${uncovered[0]}] …\`), and fix the code if the test shows it falls short
|
|
@@ -1412,6 +1475,8 @@ const REVIEW = ".gtd/REVIEW.md";
|
|
|
1412
1475
|
const REFACTOR = ".gtd/REFACTOR.md";
|
|
1413
1476
|
const REFACTOR_NOTE = ".gtd/REFACTOR-NOTE.md";
|
|
1414
1477
|
const QUALITY = ".gtd/QUALITY.md";
|
|
1478
|
+
const SLICES = ".gtd/SLICES.md";
|
|
1479
|
+
const HANDOFF = ".gtd/HANDOFF.md";
|
|
1415
1480
|
const planner = () => env.plannerModel ?? "";
|
|
1416
1481
|
const coder = () => env.coderModel ?? "";
|
|
1417
1482
|
const fixCheck = (rules) => agentWithSkills("fix", buildFixPrompt(rules), {
|
|
@@ -1605,8 +1670,11 @@ const ShippedOptions = Struct({
|
|
|
1605
1670
|
reviewSeverityMinP: setting,
|
|
1606
1671
|
refactorFlagPattern: setting,
|
|
1607
1672
|
seamAllow: setting,
|
|
1673
|
+
sliceMaxCriteria: setting,
|
|
1608
1674
|
qualityReviews: setting,
|
|
1609
1675
|
refactorQualityReviews: setting,
|
|
1676
|
+
continuations: setting,
|
|
1677
|
+
continuationStall: setting,
|
|
1610
1678
|
testCommand: setting,
|
|
1611
1679
|
plannerModel: setting,
|
|
1612
1680
|
coderModel: setting,
|
|
@@ -1710,4 +1778,4 @@ const steering = {
|
|
|
1710
1778
|
[REVIEW]: "review"
|
|
1711
1779
|
};
|
|
1712
1780
|
//#endregion
|
|
1713
|
-
export {
|
|
1781
|
+
export { naiveApplyFailure as $, agentWithSkills as A, coverageQuestion as B, fixCheck as C, testFileGlobs as Ct, reviewMissing as D, registryEntry as Dt, planner as E, flipProblems as Et, buildReviewTriageMessage as F, designSystem as G, criterionLine as H, builderSystem as I, fixReviewNotesPrompt as J, designTriagePrompt as K, clearCriteriaMessage as L, buildReviewAwaitAfterDeferMessage as M, buildReviewCollectingPrompt as N, reviewQuality as O, requireFlag as Ot, buildReviewFixNitsPrompt as P, implementFixPrompt as Q, clearCriteriaQuestion as R, coder as S, envDefaults as St, fixRisks as T, flagReferences as Tt, deferNotesScript as U, coveringPrompt as V, designGateAnswerMessage as W, idleMessage as X, handOffAwaitReviewMessage as Y, implementBuildingPrompt as Z, REFACTOR_NOTE as _, startGateBlockedMessage as _t, flagModeOn as a, refactorDroppedRefusal as at, SLICES as b, unwindFailure as bt, baseline as c, refactorRules as ct, guarded as d, reviewGateBlockedMessage as dt, naivePassPrompt as et, healthy as f, reviewNotesCapture as ft, REFACTOR as g, slicingPrompt as gt, QUALITY as h, seamSteerMessage as ht, skills as i, refactorBuildingPrompt as it, buildReviewAnswerQuestionsPrompt as j, reviewing as k, escalation as l, reviewEditNotesCapture as lt, HANDOFF as m, seamByHandMessage as mt, summary as n, oversizedMessage as nt, flagShipped as o, refactorFixPrompt as ot, FEEDBACK as p, reviewerSystem as pt, finisherSystem as q, access as r, qualityUnresolvedMessage as rt, shipped as s, refactorNotePrompt as st, steering as t, normaliseCriteriaScript as tt, gate as u, reviewEditsCapture as ut, REQUIREMENTS as v, uncoveredMessage as vt, fixQuality as w, flagMentions as wt, awaitReview as x, defaults as xt, REVIEW as y, unwindFailedMessage as yt, coverageMessage as z };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { read, refuse, removeScript, run, scope, showScript, vars } from "../flows.mjs";
|
|
2
2
|
import { fixFindings, lensEntriesOf, lensOf, qualityLap as qualityLap$1, reviewToHandOff } from "../workflow-kit.mjs";
|
|
3
|
-
import { C as
|
|
3
|
+
import { C as fixCheck, D as reviewMissing, O as reviewQuality, T as fixRisks, Y as handOffAwaitReviewMessage, d as guarded, f as healthy, h as QUALITY, k as reviewing, l as escalation, w as fixQuality, x as awaitReview, y as REVIEW } from "./reserved-CfQ8eurM.mjs";
|
|
4
4
|
//#region src/workflows/shared/tail.ts
|
|
5
5
|
/** The reviewer's own `.gtd/REVIEW.md`, kept beside the human's notes so `fix` can tell them apart. */
|
|
6
6
|
const REVIEW_ORIG = ".gtd/REVIEW.orig.md";
|
|
@@ -591,7 +591,7 @@ const contextHook = (input) => {
|
|
|
591
591
|
};
|
|
592
592
|
if (tokens >= limit.soft * window) return {
|
|
593
593
|
kind: "soft",
|
|
594
|
-
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.`
|
|
594
|
+
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.`
|
|
595
595
|
};
|
|
596
596
|
};
|
|
597
597
|
/** A decision as Claude Code's settings-hook JSON output. */
|
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -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" ? {
|
package/dist/testkit.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { applyScript, checkScript, configProblems, configure, installContext, isFactoryWorkflow, moveScript, protocolMismatch, removeScript, restoreScript, revertScript, showScript, t as flows_exports } from "./flows.mjs";
|
|
2
|
-
import { A as beatKindOf, B as ACCESS_REFUSAL, C as renderLandPlain, D as renderBeatJson, E as beatDocument, O as statusOf, S as renderLandJson, T as renderBeatPlain, U as renderFormat, _ as selectPath, a as contextLimitFault, g as resolveSession, h as globMatches, j as demandOf, l as parseContextWindow, m as slicesDocument, o as contextShapeFault, p as renderSlicesJson, v as judgeJson, x as noopText, y as landFields } from "./chunks/wire-
|
|
2
|
+
import { A as beatKindOf, B as ACCESS_REFUSAL, C as renderLandPlain, D as renderBeatJson, E as beatDocument, O as statusOf, S as renderLandJson, T as renderBeatPlain, U as renderFormat, _ as selectPath, a as contextLimitFault, g as resolveSession, h as globMatches, j as demandOf, l as parseContextWindow, m as slicesDocument, o as contextShapeFault, p as renderSlicesJson, v as judgeJson, x as noopText, y as landFields } from "./chunks/wire-BJuZWR3C.mjs";
|
|
3
3
|
import { C as headingSections, S as headingSectionBodies, a as unansweredQuestions, b as parseThreadsWithFindings, n as openThreads, r as steeringFormatFor, s as parseCodeThreads, t as BUILT_IN_MODE_NAMES, w as formatFinding } from "./chunks/steering-DVILanVf.mjs";
|
|
4
4
|
import { $ as logWarning, $i as NodeInspectSymbol, $n as map$5, $r as make$19, $t as provide$1, A as catchIf, Ai as add, An as scopeMake, Ar as flatMap$3, At as suspend$5, B as flatMap$4, Bi as getOrElse, Bn as get$3, Br as sync$1, Bt as unsafeMakeLatch, C as all$1, Ci as toArray, Cn as isInterrupted, Cr as exitFail, Ct as sandbox, D as async, Di as GenericTag, Dn as squash, Dr as exitZipRight, Dt as scopedWith$1, E as asVoid$1, Ei as unsafeHead, En as reduceWithContext, Er as exitVoid, Et as scoped$4, F as ensuring$2, Fi as fromIterable, Fn as join$3, Fr as map$3, Ft as tryMap, G as forkIn, Gi as none, Gn as TypeId$10, Gr as whenEffect, Gt as zipLeft, H as fnUntraced, Hi as isSome, Hn as modify$1, Hr as uninterruptible, Ht as when, I as exit, Ii as splitAt, In as sequential, Ir as onInterrupt, It as tryPromise, J as ignore, Ji as left, Jn as all, Jr as DeferredTypeId$1, Jt as spaced$1, K as forkScoped, Ki as some, Kn as Class, Kr as withFiberRuntime, Kt as zipRight$3, L as fail$5, Li as filter$1, Ln as bind, Lr as scopeClose, Lt as try_, M as die$2, Mi as getOption, Mn as _await$2, Mr as interruptAsFiber, Mt as tap, N as dieMessage, Ni as omit, Nn as inheritAll$1, Nr as interruptFiber, Nt as tapErrorCause, O as catchAll$1, Oi as Reference, On as ensuring$3, Or as fiberId, Ot as serviceOption, P as either, Pi as empty$5, Pn as interruptAllAs$1, Pr as interruptible$1, Pt as timeout, Q as isEffect, Qi as BaseProto, Qn as isFailure, Qr as ids, Qt as mergeAll$2, R as failCause$4, Ri as flatMap$5, Rn as bindTo, Rr as succeed$4, Rt as uninterruptible$1, S as addFinalizer$1, Si as takeRight, Sn as isDieType, Sr as exitAs, St as runtime, T as as, Ti as unsafeGet, Tn as map$6, Tr as exitSucceed, Tt as scopeWith, U as forEach$2, Ui as map$8, Un as set$1, Ur as uninterruptibleMask$1, Ut as withFiberRuntime$1, V as flatten$4, Vi as isNone, Vn as make$16, Vr as tap$1, Vt as unsafeMakeSemaphore$1, W as forkDaemon, Wi as match$4, Wn as update$1, Wr as void_$2, Wt as zip$1, X as interruptible, Xi as right, Xn as fail$4, Xr as combine, Xt as tagged, Y as interrupt$4, Yi as match$2, Yn as die, Yr as empty$6, Yt as TaggedError$1, Z as intoDeferred, Zi as pipeArguments, Zn as failCause$3, Zr as combineAll, Zt as fromEffect$5, _ as decodeSync, _i as of, _n as fail$3, _r as deferredIsDone, _t as raceWith, a as Literal, aa as constTrue, ai as size$2, an as updateContext$1, ar as zipRight$2, at as matchCause, b as acquireRelease, bi as reverse, bn as interrupt$3, br as deferredUnsafeDone, bt as runPromise, c as String$, ca as dual, ci as append$1, cn as Scope, cr as asyncInterrupt, ct as negate, d as Union, di as empty$4, dn as close, dr as deferredAwait, dt as orElse, ea as format, ei as none$1, en as provideMerge$1, er as mapBoth, et as makeSemaphore, f as between, fi as filter, fn as extend, fr as deferredComplete, ft as orElseSucceed, gi as map$7, gn as die$1, gr as deferredInterruptWith, gt as race, hi as isEmpty$2, hn as NoSuchElementException, hr as deferredInterrupt, ht as provideService, i as Defect, ia as constFalse, ii as has, in as unsafeRunPromiseExit, ir as zip$2, it as match$5, j as catchTag, ji as get$5, jn as scopeTag, jr as interrupt$2, jt as sync$2, k as catchAllCause, ki as Tag, kn as forEachConcurrentDiscard, kr as fiberRefLocally, kt as succeed$6, l as Struct, la as identity, li as appendAll, ln as addFinalizer, lr as catchAll, lt as onError, m as optional$1, mi as isChunk, mn as make$18, mr as deferredFailCause, mt as provide$2, n as Boolean$, na as equals, ni as make$17, nn as succeed$3, nr as succeed$5, nt as mapBoth$1, o as Never, oa as constUndefined, oi as decode, on as forkIn$1, or as as$1, ot as matchCauseEffect, p as decodeUnknown, pi as fromIterable$1, pn as fork, pr as deferredFail, pt as promise, q as gen, qi as isLeft, qn as spanTag, qr as zipRight$1, qt as zipWith, r as Cause, ra as hasProperty, ri as set$2, rn as unsafeFork, rr as void_$3, rt as mapError, s as Number$, sa as constVoid, si as isFinite, sn as unsafeMakeSemaphore, sr as asVoid, st as matchEffect, t as Array$, ta as toJSON, ti as get$4, tn as scoped$3, tr as match$3, tt as map$4, u as TaggedError, ua as pipe, ui as drop, un as addFinalizerExit, ur as currentContext$1, ut as orDie, v as encodeSync, vi as prepend, vn as failureOrCause, vr as deferredMake, vt as repeat, w as annotateLogs, wi as unsafeFromArray, wn as isInterruptedOnly, wr as exitFailCause, wt as scope, x as acquireUseRelease$2, xi as take$2, xn as interruptors, xr as deferredUnsafeMake, xt as runPromiseExit$1, y as _void, yi as reduce, yn as flipCauseOption, yr as deferredSucceed, yt as retry, z as fiberIdWith, zi as fromNullable, zn as sleep, zr as suspend$4, zt as uninterruptibleMask } from "./chunks/Schema-DO5ttJaI.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
package/dist/wire.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as beatKindOf, B as ACCESS_REFUSAL, C as renderLandPlain, D as renderBeatJson, E as beatDocument, F as EXIT_RUNTIME_ERROR, H as WIRE_SCHEMA, I as EXIT_SIGINT, L as EXIT_SIGTERM, M as stallDiagnosis, N as EXIT_CODES, O as statusOf, P as EXIT_OK, R as EXIT_STRAYS_FOUND, S as renderLandJson, T as renderBeatPlain, U as renderFormat, V as UNATTRIBUTED_MODEL, _ as selectPath, a as contextLimitFault, b as landProseText, c as hookOutput, d as transcriptTokens, f as usageTokens, g as resolveSession, h as globMatches, i as contextHook, j as demandOf, k as BEAT_KINDS, l as parseContextWindow, m as slicesDocument, n as CONTEXT_STOP_FILE_ENV, o as contextShapeFault, p as renderSlicesJson, r as DEFAULT_CONTEXT_LIMIT, s as contextWindowFor, t as CONTEXT_LIMIT_MARKER, u as subagentTranscriptPath, v as judgeJson, w as DEMAND_BRIEFING, x as noopText, y as landFields, z as EXIT_USAGE_ERROR } from "./chunks/wire-
|
|
1
|
+
import { A as beatKindOf, B as ACCESS_REFUSAL, C as renderLandPlain, D as renderBeatJson, E as beatDocument, F as EXIT_RUNTIME_ERROR, H as WIRE_SCHEMA, I as EXIT_SIGINT, L as EXIT_SIGTERM, M as stallDiagnosis, N as EXIT_CODES, O as statusOf, P as EXIT_OK, R as EXIT_STRAYS_FOUND, S as renderLandJson, T as renderBeatPlain, U as renderFormat, V as UNATTRIBUTED_MODEL, _ as selectPath, a as contextLimitFault, b as landProseText, c as hookOutput, d as transcriptTokens, f as usageTokens, g as resolveSession, h as globMatches, i as contextHook, j as demandOf, k as BEAT_KINDS, l as parseContextWindow, m as slicesDocument, n as CONTEXT_STOP_FILE_ENV, o as contextShapeFault, p as renderSlicesJson, r as DEFAULT_CONTEXT_LIMIT, s as contextWindowFor, t as CONTEXT_LIMIT_MARKER, u as subagentTranscriptPath, v as judgeJson, w as DEMAND_BRIEFING, x as noopText, y as landFields, z as EXIT_USAGE_ERROR } from "./chunks/wire-BJuZWR3C.mjs";
|
|
2
2
|
export { ACCESS_REFUSAL, BEAT_KINDS, CONTEXT_LIMIT_MARKER, CONTEXT_STOP_FILE_ENV, DEFAULT_CONTEXT_LIMIT, DEMAND_BRIEFING, EXIT_CODES, EXIT_OK, EXIT_RUNTIME_ERROR, EXIT_SIGINT, EXIT_SIGTERM, EXIT_STRAYS_FOUND, EXIT_USAGE_ERROR, UNATTRIBUTED_MODEL, WIRE_SCHEMA, beatDocument, beatKindOf, contextHook, contextLimitFault, contextShapeFault, contextWindowFor, demandOf, globMatches, hookOutput, judgeJson, landFields, landProseText, noopText, parseContextWindow, renderBeatJson, renderBeatPlain, renderFormat, renderLandJson, renderLandPlain, renderSlicesJson, resolveSession, selectPath, slicesDocument, stallDiagnosis, statusOf, subagentTranscriptPath, transcriptTokens, usageTokens };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { agent, changes, glob, read, refuse, scope, start, vars } from "../flows.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-
|
|
2
|
+
import { Dt as registryEntry, Ot as requireFlag, S as coder, St as envDefaults, Tt as flagReferences, i as skills, n as summary, o as flagShipped, r as access, t as steering, xt as defaults } from "../chunks/reserved-CfQ8eurM.mjs";
|
|
3
|
+
import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-C7yaWvaS.mjs";
|
|
4
4
|
//#region src/workflows/cleanup/cleanup.ts
|
|
5
5
|
const removingPrompt = (name, registry) => `Clean up the release flag "${name}", which is default-on: delete its entry in ${registry}, and remove every \`GTD_FLAG_${name.toUpperCase()}\` check from the shipped sources. Keep the flag-on path; delete code only the off path reached, including tests that pin the off path.`;
|
|
6
6
|
const cleanupFlow = async () => {
|