@pmelab/gtd 29.0.0 → 29.1.1
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 +29 -19
- package/claude/hooks/handoff.ts +2 -3
- package/claude/hooks/ship.ts +762 -62
- package/dist/chunks/{reserved-DoHUII2D.mjs → reserved-fqf-c9dc.mjs} +34 -9
- package/dist/chunks/{tail-C6YBG5zh.mjs → tail-Do11DVcw.mjs} +1 -1
- package/dist/workflows/cleanup.mjs +2 -2
- package/dist/workflows/feature.mjs +127 -41
- 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 +159 -48
- package/package.json +1 -1
- package/src/workflows/feature/feature.ts +6 -5
- package/src/workflows/feature/packages.test.ts +299 -5
- package/src/workflows/feature/packages.ts +109 -26
- package/src/workflows/feature/refactor.ts +9 -2
- package/src/workflows/feature/review.ts +25 -7
- package/src/workflows/feature/seam.ts +28 -8
- package/src/workflows/shared/text.test.ts +44 -0
- package/src/workflows/shared/text.ts +57 -10
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
|
|
@@ -415,15 +420,20 @@ noted in steps 3 and 4 below.
|
|
|
415
420
|
|
|
416
421
|
3. **You wait.** The work is split into vertical slices and built one at a time,
|
|
417
422
|
each one starting from the unit and e2e tests it declares (a build turn
|
|
418
|
-
missing one is refused
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
423
|
+
missing one is refused; a test the package only relies on is marked
|
|
424
|
+
`(unchanged)`; it must exist before the turn, and the build turn must not
|
|
425
|
+
create, edit or delete it — a wrong marker is fixed upstream, in the plan,
|
|
426
|
+
and a process stuck on one is ended with `gtd abandon`; and a package whose
|
|
427
|
+
work lies outside the repository, such as filing issues, closes on recorded
|
|
428
|
+
evidence), checked against the full suite (`testCommand`) and fixed until it
|
|
429
|
+
passes before moving on — so keep that suite fast; gtd has no lighter one.
|
|
430
|
+
Scenario wording is not frozen: you sign the scenarios off once, in the
|
|
431
|
+
review's `## Scenarios` chunk, where any assertion an existing scenario lost
|
|
432
|
+
is marked `Weakened:`. After the last package the quality lap runs. Two
|
|
433
|
+
points along the process are judged rather than always asking you outright —
|
|
434
|
+
each stops and hands you a verdict to make (`gtd judge answer`, or land with
|
|
435
|
+
a clean tree to accept the conservative default, which never skips work;
|
|
436
|
+
`gtd judge run --provider fixed --answers <path>` — or the
|
|
427
437
|
`GTD_JUDGE_ANSWERS` env var, inline JSON — answers one from a file, piped
|
|
428
438
|
between `gtd judge --json` and `gtd judge answer`;
|
|
429
439
|
`gtd judge run --provider jev` asks TypeSafe's Jev instead, with the key in
|
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])
|