@pmelab/gtd 2.6.0 → 2.7.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/README.md +24 -13
- package/dist/gtd.bundle.mjs +37 -6
- package/package.json +1 -1
- package/schema.json +3 -0
package/README.md
CHANGED
|
@@ -39,6 +39,11 @@ or `REVIEW.md` at the repository root is the project's own file — gtd never
|
|
|
39
39
|
reads, consumes, or deletes it. (Corollary: don't gitignore `.gtd/` — the
|
|
40
40
|
workflow commits its state through it.)
|
|
41
41
|
|
|
42
|
+
A squash commit's message can carry a `## Decisions` section — one entry per
|
|
43
|
+
architecture/product question resolved that cycle. Grilling/architecting read
|
|
44
|
+
every past squash commit's `## Decisions` section back as "Prior decisions"
|
|
45
|
+
context, oldest to newest. See `decisionLog` under Configuration.
|
|
46
|
+
|
|
42
47
|
## Quick start: the two-beat loop
|
|
43
48
|
|
|
44
49
|
gtd splits what used to be one mutating command into three:
|
|
@@ -750,19 +755,20 @@ With `squash: true` (the default), `gtd: done` (or, once learning has run,
|
|
|
750
755
|
to `gtd: squash template`, writing and committing a `.gtd/SQUASH_MSG.md`
|
|
751
756
|
template. `gtd next` then emits the squashing prompt: the agent overwrites
|
|
752
757
|
`.gtd/SQUASH_MSG.md` with a real conventional-commits message (drawing on
|
|
753
|
-
grilling- and architecting-round decisions from history
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
758
|
+
grilling- and architecting-round decisions from history, and, when this cycle
|
|
759
|
+
resolved any open questions, a `## Decisions` section recording them) and
|
|
760
|
+
finishes its turn. `gtd step-agent` then performs the squash itself:
|
|
761
|
+
`git reset --soft <base>` + `git commit`, collapsing every intermediate `gtd: *`
|
|
762
|
+
commit of the cycle into one — including any review-feedback detours, and the
|
|
763
|
+
learning phase's own commits if learning ran: the squash base is the cycle's
|
|
764
|
+
ORIGINAL start (the first grilling or, via the escape hatch, architecting turn
|
|
765
|
+
since the previous `gtd: done` boundary, or the `gtd: reviewing <hash>` anchor
|
|
766
|
+
for an ad-hoc review cycle), not the most recent re-grilling round — the
|
|
767
|
+
collapse folds the whole cycle into one, using the overwritten message's content
|
|
768
|
+
verbatim (turn position, not message content, triggers the squash). Doc edits
|
|
769
|
+
made during `learning-apply` survive in the squashed tree, not as their own
|
|
770
|
+
commit. With `squash: false`, `gtd: done` (or `gtd: learning applied`) is the
|
|
771
|
+
resting boundary and no template is ever written.
|
|
766
772
|
|
|
767
773
|
### Health check
|
|
768
774
|
|
|
@@ -849,6 +855,10 @@ built-in defaults apply. Supported filenames (searched in this order):
|
|
|
849
855
|
`.gtd/LEARNINGS.md`, have a human review them, then integrate them into the
|
|
850
856
|
project's own docs before the squash decision runs. Set `false` to skip the
|
|
851
857
|
phase entirely — independent of `squash`.
|
|
858
|
+
- **`decisionLog`** (boolean, default `true`) — squashing records this cycle's
|
|
859
|
+
resolved open questions as a `## Decisions` section in the squash commit
|
|
860
|
+
message; grilling/architecting inline every past squash commit's section,
|
|
861
|
+
oldest to newest, as prior-decision context. Set `false` to skip both.
|
|
852
862
|
- **`models`** — model selection for the subagent-spawning states:
|
|
853
863
|
- `planning` — high-reasoning tier (default `claude-opus-4-8`), used by
|
|
854
864
|
`decompose` (the `grilled`/`planning` states), `grilling`, `architecting`,
|
|
@@ -913,6 +923,7 @@ reviewThreshold: 3
|
|
|
913
923
|
agenticReview: true
|
|
914
924
|
squash: true
|
|
915
925
|
learning: true
|
|
926
|
+
decisionLog: true
|
|
916
927
|
models:
|
|
917
928
|
planning: claude-opus-4-8
|
|
918
929
|
execution: claude-sonnet-4-8
|
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -189138,6 +189138,7 @@ const DEFAULT_TEST_COMMAND = "npm run test";
|
|
|
189138
189138
|
const DEFAULT_AGENTIC_REVIEW = true;
|
|
189139
189139
|
const DEFAULT_SQUASH = true;
|
|
189140
189140
|
const DEFAULT_LEARNING = true;
|
|
189141
|
+
const DEFAULT_DECISION_LOG = true;
|
|
189141
189142
|
const DEFAULT_FIX_ATTEMPT_CAP = 3;
|
|
189142
189143
|
const DEFAULT_REVIEW_THRESHOLD = 3;
|
|
189143
189144
|
const ModelStatesSchema = Struct({
|
|
@@ -189160,6 +189161,7 @@ const ConfigSchema = Struct({
|
|
|
189160
189161
|
agenticReview: optional(Boolean$),
|
|
189161
189162
|
squash: optional(Boolean$),
|
|
189162
189163
|
learning: optional(Boolean$),
|
|
189164
|
+
decisionLog: optional(Boolean$),
|
|
189163
189165
|
fixAttemptCap: optional(Int.pipe(greaterThanOrEqualTo(0))),
|
|
189164
189166
|
reviewThreshold: optional(Int.pipe(greaterThanOrEqualTo(1)))
|
|
189165
189167
|
});
|
|
@@ -189300,6 +189302,7 @@ const toOperations = (decoded) => {
|
|
|
189300
189302
|
agenticReview: decoded.agenticReview ?? DEFAULT_AGENTIC_REVIEW,
|
|
189301
189303
|
squash: decoded.squash ?? DEFAULT_SQUASH,
|
|
189302
189304
|
learning: decoded.learning ?? DEFAULT_LEARNING,
|
|
189305
|
+
decisionLog: decoded.decisionLog ?? DEFAULT_DECISION_LOG,
|
|
189303
189306
|
fixAttemptCap: decoded.fixAttemptCap ?? DEFAULT_FIX_ATTEMPT_CAP,
|
|
189304
189307
|
reviewThreshold: decoded.reviewThreshold ?? DEFAULT_REVIEW_THRESHOLD
|
|
189305
189308
|
};
|
|
@@ -351972,6 +351975,25 @@ const subjectOf$1 = (message) => (message.split("\n")[0] ?? "").trim();
|
|
|
351972
351975
|
* keeps pre-namespaced history classifying identically.
|
|
351973
351976
|
*/
|
|
351974
351977
|
const touchedFeedback = (touched) => touched.includes(FEEDBACK_FILE) || touched.includes(LEGACY_FEEDBACK_FILE);
|
|
351978
|
+
const DECISIONS_TRAILER_RE = /^Gtd-Decisions:\s*true\s*$/m;
|
|
351979
|
+
const DECISIONS_HEADING = "## Decisions";
|
|
351980
|
+
/**
|
|
351981
|
+
* Extracts one commit message's `## Decisions` section verbatim (heading
|
|
351982
|
+
* through the next `#`/`##` heading or end of message, trailer line
|
|
351983
|
+
* excluded), or `undefined` when the trailer is absent or the heading can't
|
|
351984
|
+
* be found despite it (a malformed historical commit — skipped, not an
|
|
351985
|
+
* error, since this reads commits the current turn doesn't own and can't be
|
|
351986
|
+
* asked to fix). Total, never throws.
|
|
351987
|
+
*/
|
|
351988
|
+
const extractDecisionsSection = (message) => {
|
|
351989
|
+
if (!DECISIONS_TRAILER_RE.test(message)) return void 0;
|
|
351990
|
+
const lines = message.split(/\r?\n/);
|
|
351991
|
+
const headingIdx = lines.findIndex((line) => line.trim() === DECISIONS_HEADING);
|
|
351992
|
+
if (headingIdx === -1) return void 0;
|
|
351993
|
+
const endIdx = lines.findIndex((line, i) => i > headingIdx && /^#{1,2}\s+\S/.test(line.trim()));
|
|
351994
|
+
const section = lines.slice(headingIdx, endIdx === -1 ? lines.length : endIdx).filter((line) => !DECISIONS_TRAILER_RE.test(line)).join("\n").trim();
|
|
351995
|
+
return section.length > 0 ? section : void 0;
|
|
351996
|
+
};
|
|
351975
351997
|
/**
|
|
351976
351998
|
* Gather ALL git/filesystem facts and produce the typed event stream the pure
|
|
351977
351999
|
* machine folds: one `COMMIT` per first-parent commit (oldest→newest) followed
|
|
@@ -352062,8 +352084,10 @@ const gatherEvents = (invoker) => gen(function* () {
|
|
|
352062
352084
|
let refDiff;
|
|
352063
352085
|
let reviewAnchor;
|
|
352064
352086
|
let hasCommitsAfterLastDone = true;
|
|
352087
|
+
let decisionLog = "";
|
|
352065
352088
|
if (hasCommits) {
|
|
352066
352089
|
const allHistory = isNone(base) ? history : yield* git.commitHistory();
|
|
352090
|
+
if (config.decisionLog) decisionLog = allHistory.map((c) => extractDecisionsSection(c.message)).filter((section) => section !== void 0).join("\n\n");
|
|
352067
352091
|
const lastDoneIdx = (() => {
|
|
352068
352092
|
let idx = -1;
|
|
352069
352093
|
for (let i = 0; i < allHistory.length; i++) if (subjectOf$1(allHistory[i].message) === DONE_SUBJECT) idx = i;
|
|
@@ -352230,7 +352254,8 @@ const gatherEvents = (invoker) => gen(function* () {
|
|
|
352230
352254
|
...healthFixBase !== void 0 ? { healthFixBase } : {},
|
|
352231
352255
|
learningEnabled: config.learning,
|
|
352232
352256
|
learningMsgPresent,
|
|
352233
|
-
learningMsgIsTemplate
|
|
352257
|
+
learningMsgIsTemplate,
|
|
352258
|
+
decisionLog
|
|
352234
352259
|
}
|
|
352235
352260
|
};
|
|
352236
352261
|
return [...commitEvents, resolveEvent];
|
|
@@ -352537,7 +352562,8 @@ const DEFAULT_PAYLOAD = {
|
|
|
352537
352562
|
healthCommitted: false,
|
|
352538
352563
|
learningEnabled: false,
|
|
352539
352564
|
learningMsgPresent: false,
|
|
352540
|
-
learningMsgIsTemplate: false
|
|
352565
|
+
learningMsgIsTemplate: false,
|
|
352566
|
+
decisionLog: ""
|
|
352541
352567
|
};
|
|
352542
352568
|
/** Build the prompt context from the payload passthrough + the folded counters. */
|
|
352543
352569
|
const buildContext = (p, counters) => ({
|
|
@@ -352549,7 +352575,8 @@ const buildContext = (p, counters) => ({
|
|
|
352549
352575
|
...p.squashBase !== void 0 ? { squashBase: p.squashBase } : {},
|
|
352550
352576
|
...p.squashDiff !== void 0 ? { squashDiff: p.squashDiff } : {},
|
|
352551
352577
|
feedbackContent: p.feedbackContent !== "" ? p.feedbackContent : p.healthContent,
|
|
352552
|
-
...p.headTurnDiff !== "" ? { turnDiff: p.headTurnDiff } : {}
|
|
352578
|
+
...p.headTurnDiff !== "" ? { turnDiff: p.headTurnDiff } : {},
|
|
352579
|
+
decisionLog: p.decisionLog
|
|
352553
352580
|
});
|
|
352554
352581
|
const healthFileConflictRules = [
|
|
352555
352582
|
{
|
|
@@ -353910,17 +353937,20 @@ var feedback_default = "<%\n const body = it.content.replace(/\\n$/, \"\")\n c
|
|
|
353910
353937
|
//#region src/prompts/partials/package.md
|
|
353911
353938
|
var package_default = "<%\n const lines = [\"\", \"### Package: `\" + it.pkg.name + \"/`\", \"\"]\n for (const task of it.pkg.taskContents) {\n const fence = it.fenceFor(task.content)\n lines.push(\"#### `\" + task.name + \"`\", \"\", fence, task.content.replace(/\\n$/, \"\"), fence, \"\")\n }\n%><%~ lines.join(\"\\n\") %>\n";
|
|
353912
353939
|
//#endregion
|
|
353940
|
+
//#region src/prompts/partials/decision-log.md
|
|
353941
|
+
var decision_log_default = "<%\n const body = it.decisionLog.replace(/\\n$/, \"\")\n const fence = it.fenceFor(body)\n const out = [\n \"\",\n \"### Prior decisions\",\n \"\",\n \"Recorded in past squash commits, oldest to newest, with no deduplication\" +\n \" — if two entries answer the same question differently, the LATER one\" +\n \" (further down) is the current, authoritative answer. Don't re-ask a\" +\n \" settled question unless the codebase now genuinely contradicts it.\",\n \"\",\n fence,\n body,\n fence,\n \"\",\n ].join(\"\\n\")\n%><%~ out %>\n";
|
|
353942
|
+
//#endregion
|
|
353913
353943
|
//#region src/prompts/partials/agent-turn.md
|
|
353914
353944
|
var agent_turn_default = "Finish your turn by running `gtd step-agent`. Then run `gtd next` and follow\nits output — repeat this cycle as long as the output is addressed to you (the\nagent); when it awaits the human, stop and hand off.\n";
|
|
353915
353945
|
//#endregion
|
|
353916
353946
|
//#region src/prompts/grilling-agent.md
|
|
353917
|
-
var grilling_agent_default = "<%~ include(\"@header\") %>\n\n`.gtd/TODO.md` holds the plan under development. Develop it into a concrete,\nproduct-level plan **in this one turn** — use subagents / internal iteration\nto go as deep as needed; there is no further agent-only round after this one.\n\n**Scope: product and user-facing decisions only.** Do not decide\nimplementation details in this file — file/module structure, data models,\nlibrary or tech-stack choices, and other architecture questions belong to the\nnext phase (`.gtd/ARCHITECTURE.md`) and must not be treated as open questions\nhere.\n\n### Develop the plan\n\nSpawn a **planning-model subagent** using model `<%= it.model %>` to develop the plan.\nThe subagent works entirely by editing `.gtd/TODO.md`:\n\n1. **Explore the codebase before asking anything** — read the relevant files,\n tests, and docs so every question below is one the codebase genuinely\n cannot answer.\n2. **Replace the captured input / seed template with a real product plan** —\n what to build and why, and the user-facing behavior it should have,\n grounded in the codebase. Leave *how* to build it for the next phase.\n3. **Iterate internally** (spawn further subagents, reconsider, cross-check)\n until the plan is as complete as it can get without human input. Do not\n leave this to a future round — there isn't one before the human is asked.\n4. For every remaining open question, add it under a `## Open Questions`\n section near the top of the file, one `### <question>` sub-heading per\n question, whose first body line is `Suggested default: <answer>` — your\n best-guess answer, stated plainly, that the human can accept as-is. This\n structure is enforced: a `###` question with no `Suggested default:` line\n blocks your turn — `gtd step-agent` refuses until it's fixed. Omit the\n `## Open Questions` section entirely once there are none.\n5. Leave `.gtd/TODO.md` **uncommitted** — the human's turn (`gtd step`) reads it\n next.\n<% if (it.context.turnDiff && it.context.turnDiff.trim()) { %>\n<%~ include(\"@diff\", { heading: \"Latest human input (answers / sketch / review feedback)\", diff: it.context.turnDiff, fenceFor: it.fenceFor }) %>\n\nRead the diff above as **feedback, not finished work**:\n\n- Code changes are suggestions — fold them into the plan and re-implement them\n properly, including test coverage, rather than restoring them verbatim.\n- Code comments are positional feedback about the code at that location.\n- Plan-text changes are global feedback on the plan (or the reviewed work) as\n a whole.\n<% } %>\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353947
|
+
var grilling_agent_default = "<%~ include(\"@header\") %>\n\n`.gtd/TODO.md` holds the plan under development. Develop it into a concrete,\nproduct-level plan **in this one turn** — use subagents / internal iteration\nto go as deep as needed; there is no further agent-only round after this one.\n\n**Scope: product and user-facing decisions only.** Do not decide\nimplementation details in this file — file/module structure, data models,\nlibrary or tech-stack choices, and other architecture questions belong to the\nnext phase (`.gtd/ARCHITECTURE.md`) and must not be treated as open questions\nhere.\n<% if (it.context.decisionLog && it.context.decisionLog.trim()) { %>\n<%~ include(\"@decision-log\", { decisionLog: it.context.decisionLog, fenceFor: it.fenceFor }) %>\n<% } %>\n\n### Develop the plan\n\nSpawn a **planning-model subagent** using model `<%= it.model %>` to develop the plan.\nThe subagent works entirely by editing `.gtd/TODO.md`:\n\n1. **Explore the codebase before asking anything** — read the relevant files,\n tests, and docs so every question below is one the codebase genuinely\n cannot answer.\n2. **Replace the captured input / seed template with a real product plan** —\n what to build and why, and the user-facing behavior it should have,\n grounded in the codebase. Leave *how* to build it for the next phase.\n3. **Iterate internally** (spawn further subagents, reconsider, cross-check)\n until the plan is as complete as it can get without human input. Do not\n leave this to a future round — there isn't one before the human is asked.\n4. For every remaining open question, add it under a `## Open Questions`\n section near the top of the file, one `### <question>` sub-heading per\n question, whose first body line is `Suggested default: <answer>` — your\n best-guess answer, stated plainly, that the human can accept as-is. This\n structure is enforced: a `###` question with no `Suggested default:` line\n blocks your turn — `gtd step-agent` refuses until it's fixed. Omit the\n `## Open Questions` section entirely once there are none.\n5. Leave `.gtd/TODO.md` **uncommitted** — the human's turn (`gtd step`) reads it\n next.\n<% if (it.context.turnDiff && it.context.turnDiff.trim()) { %>\n<%~ include(\"@diff\", { heading: \"Latest human input (answers / sketch / review feedback)\", diff: it.context.turnDiff, fenceFor: it.fenceFor }) %>\n\nRead the diff above as **feedback, not finished work**:\n\n- Code changes are suggestions — fold them into the plan and re-implement them\n properly, including test coverage, rather than restoring them verbatim.\n- Code comments are positional feedback about the code at that location.\n- Plan-text changes are global feedback on the plan (or the reviewed work) as\n a whole.\n<% } %>\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353918
353948
|
//#endregion
|
|
353919
353949
|
//#region src/prompts/grilling-answers.md
|
|
353920
353950
|
var grilling_answers_default = "<%~ include(\"@header\") %>\n\n`.gtd/TODO.md` holds the plan under development, with open questions under a\n`## Open Questions` section — each `### <question>` carrying a suggested\ndefault.\n\nThis is a human gate; there is nothing for the agent to do.\n\nTell the user:\n\n- To answer a question, edit its `### <question>` entry under `## Open\n Questions` in place — replace the `Suggested default: ...` line with\n `Answer: ...` (or annotate it further), then run `gtd step`.\n- To accept **all** suggested defaults as-is, run `gtd step` with **no\n edits** — this converges the plan and moves on to technical architecting.\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353921
353951
|
//#endregion
|
|
353922
353952
|
//#region src/prompts/architecting-agent.md
|
|
353923
|
-
var architecting_agent_default = "<%~ include(\"@header\") %>\n\n`.gtd/ARCHITECTURE.md` holds the technical plan under development — seeded\nfrom the converged product plan, or, if this is the very first turn on\nalready-technical input, written directly by the human. Develop it into a concrete,\nimplementation-ready technical plan **in this one turn** — use subagents /\ninternal iteration to go as deep as needed; there is no further agent-only\nround after this one.\n\n**Scope: technical/architectural decisions only.** Decide file/module\nstructure, data models, module boundaries, library or tech-stack choices, and\nerror-handling/concurrency strategy — the *how*, building on the *what*\nalready settled in this file's product content. Do not re-open or re-litigate\nproduct/user-facing decisions from the prior phase; treat them as settled\ncontext.\n\n### Develop the architecture\n\nSpawn a **planning-model subagent** using model `<%= it.model %>` to develop the\narchitecture. The subagent works entirely by editing `.gtd/ARCHITECTURE.md`:\n\n1. **Explore the codebase before asking anything** — read the relevant files,\n tests, and docs so every question below is one the codebase genuinely\n cannot answer.\n2. **Replace the seeded/captured content with a real architecture** — the\n files to change, module/data-model structure, and why, grounded in the\n codebase.\n3. **Iterate internally** (spawn further subagents, reconsider, cross-check)\n until the architecture is as complete as it can get without human input.\n Do not leave this to a future round — there isn't one before the human is\n asked.\n4. For every remaining open question, add it under a `## Open Questions`\n section near the top of the file, one `### <question>` sub-heading per\n question, whose first body line is `Suggested default: <answer>` — your\n best-guess answer, stated plainly, that the human can accept as-is. This\n structure is enforced: a `###` question with no `Suggested default:` line\n blocks your turn — `gtd step-agent` refuses until it's fixed. Omit the\n `## Open Questions` section entirely once there are none.\n5. Leave `.gtd/ARCHITECTURE.md` **uncommitted** — the human's turn (`gtd step`)\n reads it next.\n<% if (it.context.turnDiff && it.context.turnDiff.trim()) { %>\n<%~ include(\"@diff\", { heading: \"Latest human input (answers / sketch / review feedback)\", diff: it.context.turnDiff, fenceFor: it.fenceFor }) %>\n\nRead the diff above as **feedback, not finished work**:\n\n- Code changes are suggestions — fold them into the architecture and\n re-implement them properly, including test coverage, rather than restoring\n them verbatim.\n- Code comments are positional feedback about the code at that location.\n- Plan-text changes are global feedback on the architecture (or the reviewed\n work) as a whole.\n<% } %>\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353953
|
+
var architecting_agent_default = "<%~ include(\"@header\") %>\n\n`.gtd/ARCHITECTURE.md` holds the technical plan under development — seeded\nfrom the converged product plan, or, if this is the very first turn on\nalready-technical input, written directly by the human. Develop it into a concrete,\nimplementation-ready technical plan **in this one turn** — use subagents /\ninternal iteration to go as deep as needed; there is no further agent-only\nround after this one.\n\n**Scope: technical/architectural decisions only.** Decide file/module\nstructure, data models, module boundaries, library or tech-stack choices, and\nerror-handling/concurrency strategy — the *how*, building on the *what*\nalready settled in this file's product content. Do not re-open or re-litigate\nproduct/user-facing decisions from the prior phase; treat them as settled\ncontext.\n<% if (it.context.decisionLog && it.context.decisionLog.trim()) { %>\n<%~ include(\"@decision-log\", { decisionLog: it.context.decisionLog, fenceFor: it.fenceFor }) %>\n<% } %>\n\n### Develop the architecture\n\nSpawn a **planning-model subagent** using model `<%= it.model %>` to develop the\narchitecture. The subagent works entirely by editing `.gtd/ARCHITECTURE.md`:\n\n1. **Explore the codebase before asking anything** — read the relevant files,\n tests, and docs so every question below is one the codebase genuinely\n cannot answer.\n2. **Replace the seeded/captured content with a real architecture** — the\n files to change, module/data-model structure, and why, grounded in the\n codebase.\n3. **Iterate internally** (spawn further subagents, reconsider, cross-check)\n until the architecture is as complete as it can get without human input.\n Do not leave this to a future round — there isn't one before the human is\n asked.\n4. For every remaining open question, add it under a `## Open Questions`\n section near the top of the file, one `### <question>` sub-heading per\n question, whose first body line is `Suggested default: <answer>` — your\n best-guess answer, stated plainly, that the human can accept as-is. This\n structure is enforced: a `###` question with no `Suggested default:` line\n blocks your turn — `gtd step-agent` refuses until it's fixed. Omit the\n `## Open Questions` section entirely once there are none.\n5. Leave `.gtd/ARCHITECTURE.md` **uncommitted** — the human's turn (`gtd step`)\n reads it next.\n<% if (it.context.turnDiff && it.context.turnDiff.trim()) { %>\n<%~ include(\"@diff\", { heading: \"Latest human input (answers / sketch / review feedback)\", diff: it.context.turnDiff, fenceFor: it.fenceFor }) %>\n\nRead the diff above as **feedback, not finished work**:\n\n- Code changes are suggestions — fold them into the architecture and\n re-implement them properly, including test coverage, rather than restoring\n them verbatim.\n- Code comments are positional feedback about the code at that location.\n- Plan-text changes are global feedback on the architecture (or the reviewed\n work) as a whole.\n<% } %>\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353924
353954
|
//#endregion
|
|
353925
353955
|
//#region src/prompts/architecting-answers.md
|
|
353926
353956
|
var architecting_answers_default = "<%~ include(\"@header\") %>\n\n`.gtd/ARCHITECTURE.md` holds the technical plan under development, with open\nquestions under a `## Open Questions` section — each `### <question>`\ncarrying a suggested default.\n\nThis is a human gate; there is nothing for the agent to do.\n\nTell the user:\n\n- To answer a question, edit its `### <question>` entry under `## Open\n Questions` in place — replace the `Suggested default: ...` line with\n `Answer: ...` (or annotate it further), then run `gtd step`.\n- To accept **all** suggested defaults as-is, run `gtd step` with **no\n edits** — this converges the architecture and moves on to decomposition.\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
@@ -353947,7 +353977,7 @@ var review_default = "<%~ include(\"@header\") %>\n\nSpawn a **planning-model su
|
|
|
353947
353977
|
var await_review_default = "<%~ include(\"@header\") %>\n\n`.gtd/REVIEW.md` holds the review record for the completed work. This is a human\ngate; there is nothing for the agent to do.\n\nTell the user:\n\n- Read `.gtd/REVIEW.md` (and the underlying work it points at).\n- To **approve**: run `gtd step` with no edits, or only tick checkboxes in\n `.gtd/REVIEW.md` — either way ends the review with an approval.\n- To **request changes**: write substantive edits or annotations into\n `.gtd/REVIEW.md` (or the code) describing what's wrong, then run `gtd step` —\n this sends the feedback back for another round.\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353948
353978
|
//#endregion
|
|
353949
353979
|
//#region src/prompts/squashing.md
|
|
353950
|
-
var squashing_default = "<%~ include(\"@header\") %>\n\nThe process is **approved and done**. `.gtd/SQUASH_MSG.md` has already been\ncommitted with a template — your job is to overwrite it with the real\nconventional-commits squash message and finish your turn.\n\n### Step 1 — Extract decisions from grilling rounds\n\nScan the git history of recent `gtd: ...` / `gtd(agent): ...` /\n`gtd(human): ...` commits. Look for changes to `.gtd/TODO.md` and\n`.gtd/ARCHITECTURE.md` — specifically the `## Captured input` sections and any\nedits to plan/architecture text. Extract **key decisions, trade-offs, and\ndesign choices** made during grilling and architecting rounds
|
|
353980
|
+
var squashing_default = "<%~ include(\"@header\") %>\n\nThe process is **approved and done**. `.gtd/SQUASH_MSG.md` has already been\ncommitted with a template — your job is to overwrite it with the real\nconventional-commits squash message and finish your turn.\n\n### Step 1 — Extract decisions from grilling rounds\n\nScan the git history of recent `gtd: ...` / `gtd(agent): ...` /\n`gtd(human): ...` commits. Look for changes to `.gtd/TODO.md` and\n`.gtd/ARCHITECTURE.md` — specifically the `## Captured input` sections and any\nedits to plan/architecture text. Extract **key decisions, trade-offs, and\ndesign choices** made during grilling and architecting rounds — specifically\nthe `### <question>` entries under `## Open Questions` that got resolved\n(`Answer:`, or an accepted `Suggested default:`) this cycle.\n\n### Step 2 — Draft the commit message\n\nDraft ONE conventional-commits message:\n\n```\ntype(scope): subject\n\nbody (explain the why — motivation, trade-offs, key decisions from grilling)\n\n## Decisions\n\n### <question, verbatim from Step 1>\nAnswer: <the resolved answer> (default accepted | human override: <reason>)\n\nGtd-Decisions: true\n```\n\n- **type**: `feat` / `fix` / `refactor` / `chore` / `docs` / `test`\n- **subject**: imperative mood, ≤ 72 characters, lowercase after the colon\n- **body**: a brief motivation/trade-off summary.\n- **`## Decisions`**: one block per question resolved THIS cycle (from Step\n 1) — omit the whole section (and the `Gtd-Decisions: true` line) entirely\n when this cycle recorded no decisions. Don't restate decisions from earlier\n cycles — this commit only records what changed now; a later grilling round\n reads the full history of these sections back as context, so repeating old\n entries here would just duplicate them forever. If this cycle's answer\n contradicts an earlier cycle's, don't try to edit or annotate the old one —\n just state the new answer plainly; the newer commit naturally reads as the\n current truth.\n\n### Step 3 — Overwrite .gtd/SQUASH_MSG.md\n\nReplace the **entire content** of `.gtd/SQUASH_MSG.md` (plain text, no markdown\nwrapper, no leftover template scaffolding) with the message from Step 2, then\nleave it uncommitted and finish your turn — `gtd step-agent` performs the\nsquash using this file's content.\n<% if (it.context.squashDiff && it.context.squashDiff.trim()) { %>\n<%= it.context.squashBase !== undefined ? \"\\nSquash base: \" + it.context.squashBase + \"\\n\" : \"\" %>\n<%~ include(\"@diff\", { heading: \"Full-process diff (`git diff \" + (it.context.squashBase !== undefined ? it.context.squashBase : \"<squashBase>\") + \" HEAD`)\", diff: it.context.squashDiff, fenceFor: it.fenceFor }) %>\n<% } %>\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
353951
353981
|
//#endregion
|
|
353952
353982
|
//#region src/prompts/learning.md
|
|
353953
353983
|
var learning_default = "<%~ include(\"@header\") %>\n\nThe process is **approved and done**, and headed for a squash. Before that\nhappens, `.gtd/LEARNINGS.md` has been committed with a template — your job is\nto overwrite it with the real, distilled learnings from this cycle so they\nsurvive the squash even though the granular history won't.\n\n### Step 1 — Walk the cycle's history\n\nScan the git history back to the cycle's start (the full-process diff is\ninlined below, and `git log` over the same range shows every `gtd: ...` /\n`gtd(agent): ...` / `gtd(human): ...` commit). Look specifically for:\n\n- **Test failures and fixes** — each `gtd: errors` round and the fix that\n followed it. What broke, and what actually made it pass?\n- **Review feedback** — human `.gtd/REVIEW.md` notes and `gtd: review\n feedback` detours. What did the human have to correct that the agent got\n wrong on its own?\n- **Health-check rounds** — any `gtd: health-check` / `gtd: health-fix`\n cycles. Environmental or systemic issues surfaced outside normal building?\n- **Grilling decisions** — `.gtd/TODO.md`'s \"## Captured input\" sections and\n plan edits. Trade-offs or conventions the human specified that a future\n agent should already know.\n\n### Step 2 — Distill, don't transcribe\n\nFor each thing you found, ask: is this a **durable, generalizable lesson**\n(a convention, a gotcha, a pattern this project wants followed next time), or\na **one-off detail** specific to this change? Keep only the former. A future\nagent reading this should learn something that changes how it works on this\nproject, not a recap of what happened.\n\n### Step 3 — Overwrite .gtd/LEARNINGS.md\n\nReplace the **entire content** of `.gtd/LEARNINGS.md` with your distilled\nlearnings (plain markdown, no leftover template scaffolding). If nothing\ndurable surfaced this cycle, write a short explicit note saying so — don't\nleave the placeholder text in place. Leave the file uncommitted and finish\nyour turn; a human reviews it next before it's integrated into the project's\nown memory (CLAUDE.md/AGENTS.md/docs).\n<% if (it.context.squashDiff && it.context.squashDiff.trim()) { %>\n<%= it.context.squashBase !== undefined ? \"\\nCycle base: \" + it.context.squashBase + \"\\n\" : \"\" %>\n<%~ include(\"@diff\", { heading: \"Full-process diff (`git diff \" + (it.context.squashBase !== undefined ? it.context.squashBase : \"<squashBase>\") + \" HEAD`)\", diff: it.context.squashDiff, fenceFor: it.fenceFor }) %>\n<% } %>\n\n<% if (it.tail) { %>\n<%~ include(it.tail) %>\n<% } %>\n";
|
|
@@ -354034,6 +354064,7 @@ eta.loadTemplate("@header", header_default);
|
|
|
354034
354064
|
eta.loadTemplate("@diff", diff_default);
|
|
354035
354065
|
eta.loadTemplate("@feedback", feedback_default);
|
|
354036
354066
|
eta.loadTemplate("@package", package_default);
|
|
354067
|
+
eta.loadTemplate("@decision-log", decision_log_default);
|
|
354037
354068
|
eta.loadTemplate("@agent-turn", agent_turn_default);
|
|
354038
354069
|
eta.loadTemplate("@grilling-agent", grilling_agent_default);
|
|
354039
354070
|
eta.loadTemplate("@grilling-answers", grilling_answers_default);
|
package/package.json
CHANGED