@pmelab/gtd 1.9.2 → 1.10.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 +78 -1
- package/dist/gtd.bundle.mjs +66 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -759,6 +759,7 @@ Commands:
|
|
|
759
759
|
(default) Run the gtd driver loop — detect state, emit next prompt
|
|
760
760
|
format <file> Format a markdown file in place
|
|
761
761
|
review <target> Ad-hoc human review against a git ref or branch
|
|
762
|
+
status Print current state, next state, and pending edge actions (no actions, no prompt)
|
|
762
763
|
|
|
763
764
|
Options:
|
|
764
765
|
--json Output structured JSON instead of plain text
|
|
@@ -773,7 +774,7 @@ repository-state work — they run outside a repo and in any repo state.
|
|
|
773
774
|
|
|
774
775
|
## Subcommands
|
|
775
776
|
|
|
776
|
-
gtd ships
|
|
777
|
+
gtd ships three subcommands: `format`, `review`, and `status`.
|
|
777
778
|
|
|
778
779
|
## Review subcommand
|
|
779
780
|
|
|
@@ -812,6 +813,82 @@ All errors exit with **code 1** and write a message to **stderr**:
|
|
|
812
813
|
(nothing to review):
|
|
813
814
|
`gtd review: nothing to review (<target> diff is empty after filtering)`
|
|
814
815
|
|
|
816
|
+
## Status subcommand
|
|
817
|
+
|
|
818
|
+
```bash
|
|
819
|
+
gtd status
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
Pure, read-only introspection. Prints the current machine state, the state the
|
|
823
|
+
next real `gtd` run would stop at, and a short summary of the edge actions the
|
|
824
|
+
next run would perform. Performs **nothing** (no commit, reset, or file write)
|
|
825
|
+
and prints **no prompt** — guaranteed side-effect free.
|
|
826
|
+
|
|
827
|
+
### Fields
|
|
828
|
+
|
|
829
|
+
| Field | Description |
|
|
830
|
+
| ----------------- | ----------------------------------------------------------------- |
|
|
831
|
+
| `state` | Current machine state |
|
|
832
|
+
| `nextState` | State the next `gtd` run would stop at, or `null` for edge-only |
|
|
833
|
+
| `willAutoAdvance` | `true` when the current state is edge-only (auto-advances on run) |
|
|
834
|
+
| `edgeActions` | List of edge actions the next run would perform before prompting |
|
|
835
|
+
|
|
836
|
+
### One-hop semantics
|
|
837
|
+
|
|
838
|
+
`status` runs the same read-only gather+resolve the driver's first iteration
|
|
839
|
+
does, then reports it without looping or performing.
|
|
840
|
+
|
|
841
|
+
- A **prompt-bearing / human / terminal** current state reports itself as
|
|
842
|
+
`nextState`. The next run performs any pending edge action, then prompts
|
|
843
|
+
there.
|
|
844
|
+
- An **edge-only** current state reports `nextState: null` and
|
|
845
|
+
`willAutoAdvance: true`, naming the immediate edge action. Because the landing
|
|
846
|
+
state after auto-advance depends on side effects (test pass/fail, commits)
|
|
847
|
+
that `status` refuses to run, it honestly reports the current state rather
|
|
848
|
+
than guessing a landing state. There is **no** multi-hop simulation.
|
|
849
|
+
|
|
850
|
+
### Output
|
|
851
|
+
|
|
852
|
+
Default (human-readable) — `building` example:
|
|
853
|
+
|
|
854
|
+
```
|
|
855
|
+
State: building
|
|
856
|
+
Next state: building (next run prompts here)
|
|
857
|
+
Edge actions:
|
|
858
|
+
- commit pending changes as "gtd: building"
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
With `--json` — same example:
|
|
862
|
+
|
|
863
|
+
```json
|
|
864
|
+
{
|
|
865
|
+
"state": "building",
|
|
866
|
+
"nextState": "building",
|
|
867
|
+
"willAutoAdvance": false,
|
|
868
|
+
"edgeActions": ["commit pending changes as \"gtd: building\""]
|
|
869
|
+
}
|
|
870
|
+
```
|
|
871
|
+
|
|
872
|
+
Edge-only example (`testing` state):
|
|
873
|
+
|
|
874
|
+
```json
|
|
875
|
+
{
|
|
876
|
+
"state": "testing",
|
|
877
|
+
"nextState": null,
|
|
878
|
+
"willAutoAdvance": true,
|
|
879
|
+
"edgeActions": ["run the test suite (attempt 1)"]
|
|
880
|
+
}
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
The JSON envelope contains no `prompt` field — this distinguishes it from the
|
|
884
|
+
default `gtd` run and `gtd review` JSON output.
|
|
885
|
+
|
|
886
|
+
### Requirements
|
|
887
|
+
|
|
888
|
+
- Must be run from the **repository root** (same cwd guard as other repo
|
|
889
|
+
commands).
|
|
890
|
+
- Takes **no arguments** — extra args are rejected with an error.
|
|
891
|
+
|
|
815
892
|
## Format subcommand
|
|
816
893
|
|
|
817
894
|
`gtd format` formats a markdown file in place:
|
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -389281,6 +389281,37 @@ var EDGE_ONLY_STATES2 = /* @__PURE__ */ new Set([
|
|
|
389281
389281
|
"health-check"
|
|
389282
389282
|
]);
|
|
389283
389283
|
var isEdgeOnly = (state) => EDGE_ONLY_STATES2.has(state);
|
|
389284
|
+
var edgeActionHandlers = {
|
|
389285
|
+
transportReset: () => "reset the working tree to the gtd: transport parent",
|
|
389286
|
+
seedNewFeature: () => "seed a new feature (write the initial TODO.md)",
|
|
389287
|
+
seedAcceptReview: () => "seed the accept-review step",
|
|
389288
|
+
captureGrillingEdits: () => "capture pending grilling edits into TODO.md",
|
|
389289
|
+
runTest: (a5) => `run the test suite (attempt ${a5.errorCount + 1}${a5.capReached ? ", cap reached" : ""})`,
|
|
389290
|
+
commitPending: (a5) => {
|
|
389291
|
+
let msg = `commit pending changes as "${a5.prefix}"`;
|
|
389292
|
+
if (a5.removeTodo) msg += " (removing TODO.md)";
|
|
389293
|
+
if (a5.removeFeedback) msg += " (removing FEEDBACK.md)";
|
|
389294
|
+
if (a5.removeHealth) msg += " (removing HEALTH.md)";
|
|
389295
|
+
return msg;
|
|
389296
|
+
},
|
|
389297
|
+
runHealthCheck: (a5) => `run the health check${a5.commitErrorsReset ? " (resetting the error budget)" : ""}`,
|
|
389298
|
+
closePackage: () => "close the active package (commit gtd: package done)",
|
|
389299
|
+
commitReview: () => "commit the review record (REVIEW.md)",
|
|
389300
|
+
done: () => "finalize the review cycle (commit gtd: done)",
|
|
389301
|
+
squashCommit: (a5) => `squash the cycle onto ${a5.squashBase}`,
|
|
389302
|
+
removeHealthSentinel: () => "remove the health-squash sentinel before prompting for a squash message",
|
|
389303
|
+
removeStraySquashMsg: () => "remove a stray SQUASH_MSG.md"
|
|
389304
|
+
};
|
|
389305
|
+
var describeEdgeAction = (a5) => edgeActionHandlers[a5.kind](a5);
|
|
389306
|
+
var describeStatus = (result) => {
|
|
389307
|
+
const willAutoAdvance = isEdgeOnly(result.state);
|
|
389308
|
+
return {
|
|
389309
|
+
state: result.state,
|
|
389310
|
+
nextState: willAutoAdvance ? null : result.state,
|
|
389311
|
+
willAutoAdvance,
|
|
389312
|
+
edgeActions: result.edgeAction ? [describeEdgeAction(result.edgeAction)] : []
|
|
389313
|
+
};
|
|
389314
|
+
};
|
|
389284
389315
|
var detect = () => Effect_exports.gen(function* () {
|
|
389285
389316
|
const events = yield* gatherEvents();
|
|
389286
389317
|
return yield* Effect_exports.try({
|
|
@@ -389298,6 +389329,7 @@ Commands:
|
|
|
389298
389329
|
(default) Run the gtd driver loop \u2014 detect state, emit next prompt
|
|
389299
389330
|
format <file> Format a markdown file in place
|
|
389300
389331
|
review <target> Ad-hoc human review against a git ref or branch
|
|
389332
|
+
status Print current state, next state, and pending edge actions (no actions, no prompt)
|
|
389301
389333
|
|
|
389302
389334
|
Options:
|
|
389303
389335
|
--json Output structured JSON instead of plain text
|
|
@@ -389320,6 +389352,24 @@ var IDLE_RESULT = {
|
|
|
389320
389352
|
}
|
|
389321
389353
|
};
|
|
389322
389354
|
var MAX_EDGE_HOPS = 100;
|
|
389355
|
+
var renderStatus = (s5) => {
|
|
389356
|
+
const lines3 = [];
|
|
389357
|
+
lines3.push(`State: ${s5.state}`);
|
|
389358
|
+
if (s5.willAutoAdvance) {
|
|
389359
|
+
lines3.push(`Next state: (edge-only \u2014 next run performs the action(s) below and auto-advances)`);
|
|
389360
|
+
} else {
|
|
389361
|
+
lines3.push(`Next state: ${s5.nextState} (next run prompts here)`);
|
|
389362
|
+
}
|
|
389363
|
+
if (s5.edgeActions.length === 0) {
|
|
389364
|
+
lines3.push(`Edge actions: none`);
|
|
389365
|
+
} else {
|
|
389366
|
+
lines3.push(`Edge actions:`);
|
|
389367
|
+
for (const action of s5.edgeActions) {
|
|
389368
|
+
lines3.push(` - ${action}`);
|
|
389369
|
+
}
|
|
389370
|
+
}
|
|
389371
|
+
return lines3.join("\n") + "\n";
|
|
389372
|
+
};
|
|
389323
389373
|
function makeProgram(opts = {}) {
|
|
389324
389374
|
const argv = opts.argv ?? process.argv;
|
|
389325
389375
|
const write4 = opts.write ?? ((chunk4) => process.stdout.write(chunk4));
|
|
@@ -389404,6 +389454,22 @@ function makeProgram(opts = {}) {
|
|
|
389404
389454
|
}
|
|
389405
389455
|
return;
|
|
389406
389456
|
}
|
|
389457
|
+
if (sub === "status") {
|
|
389458
|
+
const args2 = argv.slice(3).filter((a5) => a5.length > 0 && !a5.startsWith("--"));
|
|
389459
|
+
if (args2.length > 0) {
|
|
389460
|
+
return yield* Effect_exports.fail(
|
|
389461
|
+
new Error(`gtd status: too many arguments \u2014 expected none, got: ${args2.join(", ")}`)
|
|
389462
|
+
);
|
|
389463
|
+
}
|
|
389464
|
+
const result = yield* detect();
|
|
389465
|
+
const summary5 = describeStatus(result);
|
|
389466
|
+
if (json2) {
|
|
389467
|
+
write4(JSON.stringify(summary5) + "\n");
|
|
389468
|
+
} else {
|
|
389469
|
+
write4(renderStatus(summary5));
|
|
389470
|
+
}
|
|
389471
|
+
return;
|
|
389472
|
+
}
|
|
389407
389473
|
if (sub !== void 0) {
|
|
389408
389474
|
return yield* Effect_exports.fail(new Error(`unknown command '${sub}'`));
|
|
389409
389475
|
}
|