@pmelab/gtd 32.1.0 → 34.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 +66 -53
- package/dist/chunks/{reserved-2fV0mj14.mjs → reserved-BcJgt5_R.mjs} +79 -12
- package/dist/chunks/{tail-BynhCfuv.mjs → tail-CM_fa93v.mjs} +1 -1
- package/dist/testkit.mjs +2 -2
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +174 -40
- 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 +249 -48
- package/package.json +1 -1
- package/skills/authoring/SKILL.md +2 -2
- package/src/testkit/steps.ts +4 -0
- package/src/workflows/feature/acceptance-criteria.feature +8 -0
- package/src/workflows/feature/fast-path.feature +11 -35
- package/src/workflows/feature/feature.test.ts +9 -100
- package/src/workflows/feature/feature.ts +29 -16
- package/src/workflows/feature/flag-mode.feature +2 -91
- package/src/workflows/feature/naive-acceptance.feature +140 -0
- package/src/workflows/feature/one-step-land.feature +11 -34
- package/src/workflows/feature/quality-unresolved.feature +96 -0
- package/src/workflows/feature/refactor-absorbs.feature +17 -25
- package/src/workflows/feature/refactor-first.feature +11 -35
- package/src/workflows/feature/refactor-lens-models.feature +6 -1
- package/src/workflows/feature/refactor-review.feature +67 -360
- package/src/workflows/feature/refactor.ts +4 -3
- package/src/workflows/feature/risk-tier.feature +10 -0
- package/src/workflows/feature/seam-rejection.feature +20 -37
- package/src/workflows/feature/seam.feature +66 -113
- package/src/workflows/feature/seam.test.ts +173 -3
- package/src/workflows/feature/seam.ts +196 -31
- package/src/workflows/review/review-door.feature +108 -0
- package/src/workflows/shared/tail.ts +2 -2
- package/src/workflows/shared/text.test.ts +40 -0
- package/src/workflows/shared/text.ts +110 -16
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { answered, changes, changesSince, hasThreadFor, head, human, judge, judgeDiffShape, kept, mark, matches, numeric, quote, read, refuse, removeScript, requireAnswers, requireProgress, requireReplies, requireRevert, requireThreadsClosed, restoreScript, revertScript, run, scope, slice, start, vars } from "../flows.mjs";
|
|
1
|
+
import { answered, changes, changesSince, check, env, hasThreadFor, head, human, judge, judgeDiffShape, kept, mark, matches, numeric, quote, read, refuse, removeScript, requireAnswers, requireProgress, requireReplies, requireRevert, requireThreadsClosed, restoreScript, revertScript, run, scope, slice, start, vars } from "../flows.mjs";
|
|
2
2
|
import { lensEntriesOf, review as review$1 } from "../workflow-kit.mjs";
|
|
3
|
-
import { $ as
|
|
4
|
-
import { a as refusePendingHandOff, i as isOptionalObject, n as closeReview, o as tail } from "../chunks/tail-
|
|
3
|
+
import { $ as refactorRules, A as buildReviewCollectingPrompt, B as designTriagePrompt, C as planner, D as agentWithSkills, E as reviewing, F as clearCriteriaQuestion, G as implementBuildingPrompt, I as criterionLine, J as normaliseCriteriaScript, K as implementFixPrompt, L as deferNotesScript, M as buildReviewTriageMessage, N as builderSystem, O as buildReviewAnswerQuestionsPrompt, P as clearCriteriaMessage, Q as refactorFixPrompt, R as designGateAnswerMessage, S as fixRisks, W as idleMessage, X as refactorBuildingPrompt, Y as qualityUnresolvedMessage, Z as refactorDroppedRefusal, _ as REVIEW, a as flagModeOn, at as seamByHandMessage, b as fixCheck, ct as unwindFailedMessage, d as guarded, dt as envDefaults, et as reviewEditNotesCapture, f as healthy, ft as testFileGlobs, g as REQUIREMENTS, h as REFACTOR, i as skills, it as reviewerSystem, j as buildReviewFixNitsPrompt, k as buildReviewAwaitAfterDeferMessage, lt as unwindFailure, m as QUALITY, n as summary, ot as seamSteerMessage, p as FEEDBACK, q as naivePassPrompt, r as access, rt as reviewNotesCapture, s as shipped, st as startGateBlockedMessage, t as steering, tt as reviewEditsCapture, u as gate, ut as defaults, v as awaitReview, w as reviewMissing, y as coder, z as designSystem } from "../chunks/reserved-BcJgt5_R.mjs";
|
|
4
|
+
import { a as refusePendingHandOff, i as isOptionalObject, n as closeReview, o as tail } from "../chunks/tail-CM_fa93v.mjs";
|
|
5
|
+
import { posix } from "node:path";
|
|
5
6
|
//#region src/workflows/shared/fences.ts
|
|
6
7
|
const markFenced = (text) => {
|
|
7
8
|
let fence;
|
|
@@ -727,7 +728,7 @@ const reviewedRefactor = async (shape, options = {}) => {
|
|
|
727
728
|
};
|
|
728
729
|
//#endregion
|
|
729
730
|
//#region src/workflows/feature/seam.ts
|
|
730
|
-
/** Naive-pass retries after a `reject
|
|
731
|
+
/** Naive-pass retries after a `reject` or a red suite; the next one rests at `seam.steer`. */
|
|
731
732
|
const NAIVE_RETRIES = 2;
|
|
732
733
|
/** A change to an existing file outside the allowlist is a stray even when the task needs it: the judge decides. */
|
|
733
734
|
const judgeSeam = (tip) => judgeDiffShape("judge", {
|
|
@@ -735,12 +736,95 @@ const judgeSeam = (tip) => judgeDiffShape("judge", {
|
|
|
735
736
|
allow: (vars.seamAllow ?? defaults.seamAllow).split(",").map((glob) => glob.trim()).filter((glob) => glob !== ""),
|
|
736
737
|
exempt: tip.changes.filter((c) => c.status === "added").map((c) => c.path)
|
|
737
738
|
});
|
|
738
|
-
const naivePass = (
|
|
739
|
-
label:
|
|
739
|
+
const naivePass = (retry) => agentWithSkills("naive", naivePassPrompt(retry), {
|
|
740
|
+
label: retry === void 0 ? "Writing the naive pass" : "Rewriting the naive pass",
|
|
740
741
|
keep: true,
|
|
741
742
|
model: coder(),
|
|
742
743
|
system: builderSystem()
|
|
743
744
|
});
|
|
745
|
+
const IMPORTED = /(?:\bfrom|\bimport|\brequire\s*\(|\bmock\s*\()\s*\(?\s*(["'`])([^"'`\n]+)\1/g;
|
|
746
|
+
const EXTENSION = /\.[\w-]+$/;
|
|
747
|
+
const ALIAS = /^(?:[@~]\/|#)/;
|
|
748
|
+
/** The specifiers an added `path` answers to: itself, without its extension, and its directory for an `index`. */
|
|
749
|
+
const namesOf = (path) => {
|
|
750
|
+
const bare = path.replace(EXTENSION, "");
|
|
751
|
+
return posix.basename(bare) === "index" ? [
|
|
752
|
+
path,
|
|
753
|
+
bare,
|
|
754
|
+
posix.dirname(bare)
|
|
755
|
+
] : [path, bare];
|
|
756
|
+
};
|
|
757
|
+
/**
|
|
758
|
+
* The repository paths `test` imports, each with and without an extension: a
|
|
759
|
+
* relative specifier resolved from its directory, an aliased one (`@/`, `~/`,
|
|
760
|
+
* `#`) as a path tail, anything else as written. Comments are skipped; a
|
|
761
|
+
* computed import goes unseen.
|
|
762
|
+
*/
|
|
763
|
+
const importsOf = (test) => [...(test.after ?? "").replace(COMMENT, "").matchAll(IMPORTED)].flatMap(([, , spec]) => {
|
|
764
|
+
const relative = /^\.\.?(\/|$)/.test(spec);
|
|
765
|
+
const tail = ALIAS.test(spec);
|
|
766
|
+
const path = relative ? posix.join(posix.dirname(test.path), spec) : spec.replace(ALIAS, "");
|
|
767
|
+
return [path, path.replace(EXTENSION, "")].map((p) => ({
|
|
768
|
+
path: p,
|
|
769
|
+
tail
|
|
770
|
+
}));
|
|
771
|
+
});
|
|
772
|
+
const reaches = (imports, added) => namesOf(added).some((name) => imports.some(({ path, tail }) => name === path || tail && name.endsWith(`/${path}`)));
|
|
773
|
+
const named = (id, text) => new RegExp(`(?<![\\w-])${id}(?!\\d)`).test(text);
|
|
774
|
+
/** The lines `change` added: an ID an earlier change left in the file does not count. */
|
|
775
|
+
const addedLines = (change) => {
|
|
776
|
+
const before = new Set((change.before ?? "").split("\n"));
|
|
777
|
+
return change.after.split("\n").filter((line) => !before.has(line)).join("\n");
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Why `tip`'s tests fall short, or `undefined`: a criterion ID of `file` no
|
|
781
|
+
* test line of the pass names, or a test importing a file the pass added —
|
|
782
|
+
* naive structure a reset and refactor replaces, which the tests must survive.
|
|
783
|
+
*/
|
|
784
|
+
const acceptanceFault = (file, tip) => {
|
|
785
|
+
const ids = (criteriaOf(read(file) ?? "") ?? []).map((c) => c.id).filter((id) => id !== "");
|
|
786
|
+
const tests = tip.changes.filter((c) => c.after !== void 0 && isCode$1(c.path) && isTestFile(c.path));
|
|
787
|
+
const lines = tests.map(addedLines);
|
|
788
|
+
const untested = ids.filter((id) => !lines.some((text) => named(id, text)));
|
|
789
|
+
if (untested.length > 0) return `acceptance-tests: no test of the naive pass names ${untested.join(", ")} — write a behaviour-level test for each criterion with its ID in the test or scenario name, e.g. "[${untested[0]}] …"`;
|
|
790
|
+
const added = tip.changes.filter((c) => c.status === "added" && isCode$1(c.path) && !isTestFile(c.path)).map((c) => c.path);
|
|
791
|
+
const reaching = tests.filter((test) => holdsCallSites(test.path)).flatMap((test) => {
|
|
792
|
+
const imports = importsOf(test);
|
|
793
|
+
return added.filter((path) => reaches(imports, path)).map((path) => ` - ${test.path} → ${path}`);
|
|
794
|
+
});
|
|
795
|
+
if (reaching.length > 0) return `acceptance-internals: these tests import files the naive pass added — test through code that existed before it (a public entry point, an existing module's exports):\n${reaching.join("\n")}`;
|
|
796
|
+
};
|
|
797
|
+
const restore = (path) => `if git cat-file -e ${quote(`HEAD:${path}`)} 2>/dev/null; then git checkout -q HEAD -- ${quote(path)}; else rm -f -- ${quote(path)}; fi`;
|
|
798
|
+
/**
|
|
799
|
+
* Run the suite with `tip`'s diff applied, then take it out again; resolves
|
|
800
|
+
* `true` when green. The pass's paths go back to HEAD before (an interrupted
|
|
801
|
+
* run left them applied) and after; afterwards so does anything else the run
|
|
802
|
+
* changed, judged against what was already dirty, which is left alone.
|
|
803
|
+
*/
|
|
804
|
+
const naiveGreen = (tip) => {
|
|
805
|
+
const paths = tip.changes.map((c) => restore(c.path));
|
|
806
|
+
return check("check", [
|
|
807
|
+
...paths,
|
|
808
|
+
"dirty=$(git -c core.quotePath=false ls-files -m -d -o --exclude-standard)",
|
|
809
|
+
`if ! git diff --binary ${quote(`${tip.hash}^`)} ${quote(tip.hash)} -- | git apply; then`,
|
|
810
|
+
" echo 'gtd: the kept naive pass no longer applies to HEAD; no test ran'",
|
|
811
|
+
" exit 1",
|
|
812
|
+
"fi",
|
|
813
|
+
"(",
|
|
814
|
+
env.testCommand ?? "",
|
|
815
|
+
")",
|
|
816
|
+
"code=$?",
|
|
817
|
+
...paths,
|
|
818
|
+
"git -c core.quotePath=false ls-files -m -d -o --exclude-standard | while IFS= read -r path; do",
|
|
819
|
+
" printf '%s\\n' \"$dirty\" | grep -qxF -- \"$path\" && continue",
|
|
820
|
+
" if git cat-file -e \"HEAD:$path\" 2>/dev/null; then git checkout -q HEAD -- \"$path\"; else rm -f -- \"$path\"; fi",
|
|
821
|
+
"done",
|
|
822
|
+
"exit \"$code\""
|
|
823
|
+
].join("\n"), {
|
|
824
|
+
report: FEEDBACK,
|
|
825
|
+
label: "Running the naive pass's tests"
|
|
826
|
+
});
|
|
827
|
+
};
|
|
744
828
|
function implement(first, tier, amend) {
|
|
745
829
|
const options = typeof first === "object" && first !== null ? first : {
|
|
746
830
|
reference: first,
|
|
@@ -767,36 +851,76 @@ function implement(first, tier, amend) {
|
|
|
767
851
|
await run("closing", removeScript([REQUIREMENTS]), { label: "Closing out the implementation" });
|
|
768
852
|
});
|
|
769
853
|
}
|
|
770
|
-
|
|
771
|
-
|
|
854
|
+
/** Resolves `true` when the human steered (edited), `false` on a clean overrule. */
|
|
855
|
+
const steer = async (retry) => {
|
|
856
|
+
await human("steer", {
|
|
857
|
+
message: seamSteerMessage(retry),
|
|
858
|
+
label: "Steer or overrule the naive pass",
|
|
859
|
+
file: REQUIREMENTS,
|
|
860
|
+
acceptClean: true
|
|
861
|
+
});
|
|
862
|
+
if (changes().length === 0) return false;
|
|
863
|
+
requireCriteria(REQUIREMENTS);
|
|
864
|
+
return true;
|
|
865
|
+
};
|
|
866
|
+
/** Rejects, test faults and red checks share one budget; a steer or an overrule refills it. */
|
|
867
|
+
const budget = () => {
|
|
772
868
|
let retries = 0;
|
|
773
|
-
|
|
774
|
-
await naivePass(rejection);
|
|
775
|
-
const tip = kept("naive");
|
|
776
|
-
const shape = await judgeSeam(tip);
|
|
777
|
-
if (shape.choice === "land") return { reference: tip.hash };
|
|
778
|
-
if (shape.choice === "refactor-first") return {
|
|
779
|
-
reference: tip.hash,
|
|
780
|
-
shape
|
|
781
|
-
};
|
|
782
|
-
rejection = {
|
|
783
|
-
strays: shape.strays,
|
|
784
|
-
p: shape.judgment?.answers.shape?.p ?? 0
|
|
785
|
-
};
|
|
869
|
+
return async (next) => {
|
|
786
870
|
if (retries < NAIVE_RETRIES) {
|
|
787
871
|
retries++;
|
|
788
|
-
|
|
872
|
+
return {
|
|
873
|
+
kind: "retry",
|
|
874
|
+
retry: next
|
|
875
|
+
};
|
|
789
876
|
}
|
|
790
|
-
await
|
|
791
|
-
message: seamSteerMessage(rejection),
|
|
792
|
-
label: "Steer or overrule the rejected naive pass",
|
|
793
|
-
file: REQUIREMENTS,
|
|
794
|
-
acceptClean: true
|
|
795
|
-
});
|
|
796
|
-
if (changes().length === 0) return { reference: tip.hash };
|
|
797
|
-
requireCriteria(REQUIREMENTS);
|
|
798
|
-
rejection = void 0;
|
|
877
|
+
const steered = await steer(next);
|
|
799
878
|
retries = 0;
|
|
879
|
+
if (read(".gtd/FEEDBACK.md") !== void 0) await run("clear", removeScript([FEEDBACK]), { label: "Clearing the red check" });
|
|
880
|
+
return { kind: steered ? "steered" : "overruled" };
|
|
881
|
+
};
|
|
882
|
+
};
|
|
883
|
+
/** Sends a pass whose tests fall short or run red back (`undefined`: it goes on, an overruled one as it is). */
|
|
884
|
+
const vetted = async (tip, vetting) => {
|
|
885
|
+
const fault = vetting.waived ? void 0 : acceptanceFault(REQUIREMENTS, tip);
|
|
886
|
+
if (fault !== void 0) {
|
|
887
|
+
const verdict = await vetting.again({
|
|
888
|
+
fault,
|
|
889
|
+
hash: tip.hash
|
|
890
|
+
});
|
|
891
|
+
if (verdict.kind !== "overruled") return verdict;
|
|
892
|
+
vetting.waived = true;
|
|
893
|
+
}
|
|
894
|
+
if (await naiveGreen(tip)) return void 0;
|
|
895
|
+
const verdict = await vetting.again({ red: tip.hash });
|
|
896
|
+
return verdict.kind === "overruled" ? void 0 : verdict;
|
|
897
|
+
};
|
|
898
|
+
/** The judge's ruling on a vetted pass: the decision, or the next attempt's verdict. */
|
|
899
|
+
const ruled = async (tip, again) => {
|
|
900
|
+
const shape = await judgeSeam(tip);
|
|
901
|
+
if (shape.choice === "land") return { reference: tip.hash };
|
|
902
|
+
if (shape.choice === "refactor-first") return {
|
|
903
|
+
reference: tip.hash,
|
|
904
|
+
shape
|
|
905
|
+
};
|
|
906
|
+
const next = await again({
|
|
907
|
+
strays: shape.strays,
|
|
908
|
+
p: shape.judgment?.answers.shape?.p ?? 0
|
|
909
|
+
});
|
|
910
|
+
return next.kind === "overruled" ? { reference: tip.hash } : next;
|
|
911
|
+
};
|
|
912
|
+
const decide = () => scope("seam", async () => {
|
|
913
|
+
const vetting = {
|
|
914
|
+
again: budget(),
|
|
915
|
+
waived: false
|
|
916
|
+
};
|
|
917
|
+
let retry;
|
|
918
|
+
for (;;) {
|
|
919
|
+
await naivePass(retry);
|
|
920
|
+
const tip = kept("naive");
|
|
921
|
+
const outcome = await vetted(tip, vetting) ?? await ruled(tip, vetting.again);
|
|
922
|
+
if (!("kind" in outcome)) return outcome;
|
|
923
|
+
retry = outcome.kind === "retry" ? outcome.retry : void 0;
|
|
800
924
|
}
|
|
801
925
|
});
|
|
802
926
|
const seamBuild = async (base) => {
|
|
@@ -834,7 +958,7 @@ const unwind = () => {
|
|
|
834
958
|
const commit = head();
|
|
835
959
|
return run("unwind", revertScript(commit, FEEDBACK, unwindFailure(commit)), { label: "Unwinding your input" });
|
|
836
960
|
};
|
|
837
|
-
/** A judged naive pass (none with `flagMode` off), then implement and
|
|
961
|
+
/** A judged naive pass (none with `flagMode` off), then implement and the quality lap; design must have run since `firstBase`. */
|
|
838
962
|
const buildFeature = async (firstBase) => {
|
|
839
963
|
const tier = riskTierOn() ? recordRisk() : void 0;
|
|
840
964
|
const seam = flagModeOn() ? await seamBuild(firstBase) : { base: firstBase };
|
|
@@ -845,18 +969,31 @@ const buildFeature = async (firstBase) => {
|
|
|
845
969
|
afterRefactor: seam.refactored
|
|
846
970
|
});
|
|
847
971
|
const base = seam.refactored === true && !changesSince(seam.base).some((c) => isCode$1(c.path)) ? firstBase : seam.base;
|
|
848
|
-
await
|
|
972
|
+
await tail(settleQuality, {
|
|
849
973
|
green: true,
|
|
850
974
|
lensBase: base
|
|
851
|
-
})
|
|
975
|
+
});
|
|
852
976
|
});
|
|
853
977
|
};
|
|
978
|
+
const settleQuality = async () => {
|
|
979
|
+
let rested = false;
|
|
980
|
+
while ((read(".gtd/QUALITY.md") ?? "").length > 0) {
|
|
981
|
+
rested = true;
|
|
982
|
+
await human("quality-unresolved", {
|
|
983
|
+
message: qualityUnresolvedMessage(),
|
|
984
|
+
label: "Quality findings left unresolved",
|
|
985
|
+
file: QUALITY
|
|
986
|
+
});
|
|
987
|
+
}
|
|
988
|
+
if (rested) await healthy(() => fixCheck());
|
|
989
|
+
};
|
|
854
990
|
/** Design — skipped when the sketch's own criteria are judged clear — then `buildFeature`. */
|
|
855
991
|
const planAndBuild = async (firstBase, stated) => {
|
|
856
992
|
if (!await skipDesign(riskTierOn() ? void 0 : stated)) await design(firstBase);
|
|
857
993
|
await buildFeature(firstBase);
|
|
858
994
|
};
|
|
859
|
-
|
|
995
|
+
/** After a tail that skipped planning: stop on sign-off, re-plan on feedback. Opens no slice: slices cannot nest. */
|
|
996
|
+
const afterTail = async (first) => {
|
|
860
997
|
let outcome = first;
|
|
861
998
|
while (outcome.verdict === "feedback") {
|
|
862
999
|
await reUnwind(outcome);
|
|
@@ -867,13 +1004,10 @@ const featureFeedback = async (first, lensBase) => {
|
|
|
867
1004
|
});
|
|
868
1005
|
outcome = await buildTail(outcome.base, {
|
|
869
1006
|
green: true,
|
|
870
|
-
lap: "feedback"
|
|
871
|
-
lensBase
|
|
1007
|
+
lap: "feedback"
|
|
872
1008
|
});
|
|
873
1009
|
}
|
|
874
1010
|
};
|
|
875
|
-
/** After a tail that skipped planning: stop on sign-off, re-plan on feedback. Opens no slice: slices cannot nest. */
|
|
876
|
-
const afterTail = (outcome) => featureFeedback(outcome);
|
|
877
1011
|
/** An ordinary start: wait at `idle`, unwind the sketch, check the baseline, then plan and build. */
|
|
878
1012
|
const ordinaryStart = async () => {
|
|
879
1013
|
await human("idle", {
|
|
@@ -898,4 +1032,4 @@ const feature = shipped(ordinaryStart);
|
|
|
898
1032
|
//#region src/workflows/feature/index.ts
|
|
899
1033
|
var feature_default = feature;
|
|
900
1034
|
//#endregion
|
|
901
|
-
export { REFACTOR_PACKAGE, access, afterTail, answerProductQuestions, answerReviewQuestions, buildFeature, buildTail, collecting, criteriaOf, feature_default as default, defaults, deferNotes, design, envDefaults, feature, fixNits, implement, judgeSeam, naivePass, ordinaryStart, planAndBuild, reUnwind, refactorCollecting, refactorFirst, refactorStrays, requireCriteria, requireCriteriaFrozen, requireNoNewFlags, requireNoTestFiles, requireTestCallSitesOnly, requireWithin, reviewedRefactor, seamBuild, skills, skipDesign, statedCriteria, steering, summary, triage, unwind };
|
|
1035
|
+
export { COMMENT, REFACTOR_PACKAGE, acceptanceFault, access, afterTail, answerProductQuestions, answerReviewQuestions, buildFeature, buildTail, collecting, criteriaOf, feature_default as default, defaults, deferNotes, design, envDefaults, feature, fixNits, holdsCallSites, implement, isTestFile, judgeSeam, naivePass, ordinaryStart, planAndBuild, reUnwind, refactorCollecting, refactorFirst, refactorStrays, requireCriteria, requireCriteriaFrozen, requireNoNewFlags, requireNoTestFiles, requireTestCallSitesOnly, requireWithin, reviewedRefactor, seamBuild, skills, skipDesign, statedCriteria, steering, summary, triage, unwind };
|
package/dist/workflows/fix.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { read, refuse, removeScript, run, scope, start } from "../flows.mjs";
|
|
2
2
|
import { d as reviewNotes, f as reviewRisks } from "../chunks/steering-DVILanVf.mjs";
|
|
3
|
-
import { D as agentWithSkills, H as fixReviewNotesPrompt, V as finisherSystem, _ as REVIEW, c as baseline,
|
|
4
|
-
import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-
|
|
3
|
+
import { D as agentWithSkills, H as fixReviewNotesPrompt, V as finisherSystem, _ as REVIEW, c as baseline, dt as envDefaults, i as skills, n as summary, r as access, s as shipped, t as steering, ut as defaults, y as coder } from "../chunks/reserved-BcJgt5_R.mjs";
|
|
4
|
+
import { r as handOffTail, t as REVIEW_ORIG } from "../chunks/tail-CM_fa93v.mjs";
|
|
5
5
|
//#region src/workflows/fix/fix.ts
|
|
6
6
|
/**
|
|
7
7
|
* Fix every note a human left in a handed-off `.gtd/REVIEW.md` and every
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { start } from "../flows.mjs";
|
|
2
|
-
import {
|
|
3
|
-
import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-
|
|
2
|
+
import { dt as envDefaults, i as skills, n as summary, nt as reviewGateBlockedMessage, r as access, s as shipped, t as steering, u as gate, ut as defaults } from "../chunks/reserved-BcJgt5_R.mjs";
|
|
3
|
+
import { a as refusePendingHandOff, r as handOffTail } from "../chunks/tail-CM_fa93v.mjs";
|
|
4
4
|
//#region src/workflows/review/review.ts
|
|
5
5
|
/**
|
|
6
6
|
* Pure review of everything since `reviewBase`: a green gate, the quality
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { agent, changesSince, glob, head, mark, read, refuse, removeScript, run, scope, vars } from "../flows.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { _t as requireFlag, dt as envDefaults, ht as flipProblems, i as skills, n as summary, o as flagShipped, p as FEEDBACK, pt as flagMentions, r as access, t as steering, u as gate, ut as defaults, y as coder } from "../chunks/reserved-BcJgt5_R.mjs";
|
|
3
3
|
//#region src/workflows/rollout/rollout.ts
|
|
4
4
|
const flippingPrompt = (name, registry) => `Roll out the release flag "${name}": in ${registry}, set \`defaultOn: true\` on its entry. Change nothing else — no other entry, no other field, no other file, no comments.`;
|
|
5
5
|
const suiteBlockedMessage = () => "The suite is red after the rollout. Fix it by hand — a rollout may only touch the flag's registry entry — then land.";
|