@pmelab/gtd 28.2.0 → 29.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 +28 -14
- package/claude/hooks/handoff.ts +2 -3
- package/claude/hooks/ship.ts +762 -62
- package/dist/chunks/{reserved-DeBS4Ymh.mjs → reserved-DoHUII2D.mjs} +206 -121
- package/dist/chunks/{tail-B2SER2Ih.mjs → tail-C6YBG5zh.mjs} +19 -12
- package/dist/testkit.mjs +2 -1
- package/dist/workflow-kit.mjs +51 -21
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +247 -96
- 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 +528 -262
- package/package.json +1 -1
- package/src/testkit/TestRepo.ts +3 -0
- package/src/testkit/index.ts +1 -1
- package/src/testkit/steps.ts +44 -0
- package/src/workflow-kit/review.test.ts +366 -8
- package/src/workflow-kit/review.ts +109 -26
- package/src/workflows/feature/feature.test.ts +313 -1
- package/src/workflows/feature/feature.ts +48 -43
- package/src/workflows/feature/one-step-land.feature +4 -0
- package/src/workflows/feature/refactor-first.feature +54 -24
- package/src/workflows/feature/refactor-review.feature +1706 -0
- package/src/workflows/feature/refactor.test.ts +592 -2
- package/src/workflows/feature/refactor.ts +160 -42
- package/src/workflows/feature/review.test.ts +322 -5
- package/src/workflows/feature/review.ts +77 -10
- package/src/workflows/feature/seam-rejection.feature +4 -0
- package/src/workflows/feature/seam.feature +3 -4
- package/src/workflows/feature/seam.test.ts +196 -1
- package/src/workflows/feature/seam.ts +23 -9
- package/src/workflows/feature/steps.test.ts +54 -2
- package/src/workflows/feature/steps.ts +45 -9
- package/src/workflows/feature/tier.test.ts +4 -0
- package/src/workflows/feature/tier.ts +2 -20
- package/src/workflows/shared/__fixtures__/feature-collecting-prompt.txt +97 -0
- package/src/workflows/shared/access.test.ts +31 -1
- package/src/workflows/shared/access.ts +7 -1
- package/src/workflows/shared/fences.ts +19 -0
- package/src/workflows/shared/health.ts +32 -12
- package/src/workflows/shared/options.test.ts +18 -0
- package/src/workflows/shared/options.ts +1 -0
- package/src/workflows/shared/prose.ts +4 -2
- package/src/workflows/shared/skills.test.ts +20 -1
- package/src/workflows/shared/skills.ts +43 -32
- package/src/workflows/shared/steps.ts +33 -19
- package/src/workflows/shared/tail.test.ts +84 -1
- package/src/workflows/shared/tail.ts +30 -12
- package/src/workflows/shared/text.test.ts +266 -3
- package/src/workflows/shared/text.ts +183 -69
- package/src/workflows/shared/vars.ts +12 -2
package/README.md
CHANGED
|
@@ -338,16 +338,21 @@ the process on only when you say so; a review you leave untouched signs off.
|
|
|
338
338
|
While a step runs you can keep asking; requests for changes wait for the next
|
|
339
339
|
rest. When the process finishes, Claude offers to squash it and open its pull
|
|
340
340
|
request(s) (or run `/gtd ship`; `GTD_SHIP_MODE` picks one stacked pull request
|
|
341
|
-
per slice or one commit per slice, see the [driver doc](docs/driver.md))
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
341
|
+
per slice or one commit per slice, see the [driver doc](docs/driver.md));
|
|
342
|
+
re-running `/gtd ship` after a lower stacked pull request merged restacks the
|
|
343
|
+
rest (it refuses, with nothing changed, when that pull request merged anywhere
|
|
344
|
+
but the default branch (unless into a lower slice branch before that one merged
|
|
345
|
+
into it), a slice branch is checked out in another worktree, an unrelated local
|
|
346
|
+
branch sits inside the rebased commits, or a slice's change is already upstream;
|
|
347
|
+
a failed rebase is rolled back). A process can change hands at any gate: ask
|
|
348
|
+
Claude to hand it off (or run `/gtd throw @dev`) and it opens a draft pull
|
|
349
|
+
request assigned to them, and `/gtd catch <pr>` picks it up exactly where it
|
|
350
|
+
waits, so whoever wrote the requirements can hand the architecture to someone
|
|
351
|
+
else. Ship, hand-off and throw answer at once and run in the background, with
|
|
352
|
+
progress on the status line; they report by waking Claude, a toast, a transcript
|
|
353
|
+
line and a push notification, and a failed push or `gh` call reports as a
|
|
354
|
+
failure. While a ship or hand-off runs or is queued, `/gtd catch`, the doors,
|
|
355
|
+
`/gtd <requirements>` and bare `/gtd` wait for its report. See
|
|
351
356
|
[Inside Claude Code](https://github.com/pmelab/gtd/blob/main/docs/driver.md#inside-claude-code-the-gtd-mod).
|
|
352
357
|
|
|
353
358
|
### Then let an agent build your own
|
|
@@ -570,8 +575,16 @@ home directory — fails every command until you delete it. See
|
|
|
570
575
|
architecture and package files, the agent first implements the requirements
|
|
571
576
|
directly. A judge checks whether it changed anything outside the expected set
|
|
572
577
|
(tests, steering files; see `seamAllow`). Incidental changes land; a needed seam
|
|
573
|
-
change
|
|
574
|
-
|
|
578
|
+
change is refactored first, in its own slice with its own quality lap
|
|
579
|
+
(`refactorQualityReviews`) and review, before the feature is implemented and
|
|
580
|
+
reviewed; a wrong approach is retried twice, then rests for you to steer or
|
|
581
|
+
overrule it. `gtd slices` lists the `refactor` and `feature` slices. Feedback at
|
|
582
|
+
the feature review re-runs design and the implementation, never the naive pass;
|
|
583
|
+
feedback at the refactor review re-runs the refactor, never design; a
|
|
584
|
+
refactor-review change the refactor cannot build is refused, and the only way
|
|
585
|
+
out is `gtd abandon`. A process from 27.5.0 or later whose judge ruled
|
|
586
|
+
`refactor-first` must `gtd abandon` too. Each slice's quality lap reviews only
|
|
587
|
+
that slice. Details in
|
|
575
588
|
[the naive-pass path](docs/configuration.md#the-naive-pass-path).
|
|
576
589
|
|
|
577
590
|
**Risk tier (flag `GTD_FLAG_RISK_TIER=1`, off by default, needs
|
|
@@ -656,8 +669,9 @@ are not process history: `gtd history` does not list them, and the
|
|
|
656
669
|
`refs/gtd/history/*` refspecs above neither push nor fetch them.
|
|
657
670
|
|
|
658
671
|
A workflow can rest at an approval gate (`human(name, { approve: true })`; the
|
|
659
|
-
`seamGate` helper does this
|
|
660
|
-
a clean `gtd land` approves it, and the
|
|
672
|
+
`seamGate` helper does this for a `refactor-first` diff-shape judgment; the
|
|
673
|
+
shipped flow does not use it). Only a clean `gtd land` approves it, and the
|
|
674
|
+
commit records who in a
|
|
661
675
|
`Gtd-Approved: {"step":"<step>#<n>","name":"<name>","email":"<email>"}` trailer;
|
|
662
676
|
a landing with any edit is refused (as is a script run after the tree changed —
|
|
663
677
|
revert and land again), and `gtd abandon` is the only other way out. `approve`
|
package/claude/hooks/handoff.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// pushing the branch and telling them. `throw` opens (or refreshes) a draft
|
|
3
3
|
// pull request for the hand-off; `catch` checks it out wherever it was thrown.
|
|
4
4
|
|
|
5
|
-
import { pushBranch, THROWN } from "./ship"
|
|
5
|
+
import { defaultBranch, pushBranch, THROWN } from "./ship"
|
|
6
6
|
import type { ShipIo, Shipped } from "./ship"
|
|
7
7
|
|
|
8
8
|
export type Rest = { state?: string; label?: string; content?: string; isIdle: boolean }
|
|
@@ -73,8 +73,7 @@ async function throwBranch(io: ShipIo, now: string) {
|
|
|
73
73
|
const git = async (...args: string[]) => (await io.run(["git", ...args])).out.trim()
|
|
74
74
|
const branch = await git("rev-parse", "--abbrev-ref", "HEAD")
|
|
75
75
|
if (!branch || branch === "HEAD") return "Detached HEAD: there is no branch to throw."
|
|
76
|
-
const
|
|
77
|
-
const base = head.replace(/^origin\//, "") || "main"
|
|
76
|
+
const base = await defaultBranch(git)
|
|
78
77
|
if (branch !== base) return { branch, base }
|
|
79
78
|
const fresh = `gtd/${now.replace(/[-:]/g, "").replace("T", "-").slice(0, 13)}`
|
|
80
79
|
const switched = await io.run(["git", "switch", "-c", fresh])
|