@pmelab/gtd 9.1.1 → 9.2.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 +169 -107
- package/dist/gtd.bundle.mjs +166 -85
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -21,9 +21,10 @@ No chat scrollback. No lost sessions. No infinite fix loops. Just git.
|
|
|
21
21
|
- **Shareable.** Push the branch, and the workflow travels with it — the state
|
|
22
22
|
lives in the commits, so another machine (or another person) picks up exactly
|
|
23
23
|
where you left off.
|
|
24
|
-
- **Files, not chat.** Plans live in `.gtd
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
- **Files, not chat.** Plans live in `.gtd/` steering files (`REQUIREMENTS.md`,
|
|
25
|
+
`ARCHITECTURE.md`, the package files under `.gtd/packages/`). Request changes
|
|
26
|
+
by editing them, approve by leaving the tree clean — all in your own editor.
|
|
27
|
+
There is no chat UI to lose.
|
|
27
28
|
- **Harness agnostic.** gtd emits prompts to stdout (or JSON). Claude Code, a
|
|
28
29
|
bash loop, a CI job, or you reading it out loud — the workflow doesn't care
|
|
29
30
|
who executes it.
|
|
@@ -61,17 +62,23 @@ gtd init
|
|
|
61
62
|
This writes a minimal `.gtdrc.json` seeding the one variable most projects
|
|
62
63
|
change — the test command (`vars.testCommand`, defaulting to `npm test`) — plus
|
|
63
64
|
a top-level `modes:` block suggesting **Prettier** as the steering-file
|
|
64
|
-
formatter (`npx prettier --write` for the built-in `qa`/`review
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
up. To customize the machine itself, add a `workflow:` key (there is no default
|
|
65
|
+
formatter (`npx prettier --write` for the built-in `qa`/`review` modes — format
|
|
66
|
+
only, so gtd still validates them); edit or drop either freely (point
|
|
67
|
+
`testCommand` at your suite, swap Prettier for dprint or a script, delete a
|
|
68
|
+
key). It writes **no** `workflow:` key — the machine is built in — so review and
|
|
69
|
+
commit the file before your first `gtd land`. `gtd init` takes no argument and
|
|
70
|
+
refuses to clobber an existing config; it may also run in a plain parent
|
|
71
|
+
directory (not a git repo) to seed a shared config a nested repo picks up. To
|
|
72
|
+
customize the machine itself, add a `workflow:` key (there is no default
|
|
73
73
|
fallback to merge over — a `workflow:` is the whole definition).
|
|
74
74
|
|
|
75
|
+
gtd requires a repository with **at least one commit** before any state command
|
|
76
|
+
(`land`, `--entry`, `next`, `status`, `abandon`, `restore`, `validate`) will run
|
|
77
|
+
— there is no workflow state to derive from an empty history. Committing the
|
|
78
|
+
`.gtdrc.json` above (or anything else) satisfies this by construction;
|
|
79
|
+
`gtd init`, `gtd install`, `gtd lsp`, `gtd visualize`, and `gtd check` are
|
|
80
|
+
unaffected since none of them derive workflow state.
|
|
81
|
+
|
|
75
82
|
## How it works
|
|
76
83
|
|
|
77
84
|
gtd is a small **pattern machine**: named states, each awaiting one actor and
|
|
@@ -110,70 +117,96 @@ together: the `action` leads when the edge declares one, with the raw pattern
|
|
|
110
117
|
(and `describe`) still shown alongside it, so a human choosing between routes
|
|
111
118
|
reads intent first, glob second.
|
|
112
119
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
120
|
+
**Your input is a spec, not the work.** The unified workflow treats ANY change
|
|
121
|
+
to the tree — a hand-edit to real code, a scratch note in some file, anything at
|
|
122
|
+
all — as a sketch to be finished, never as work to be preserved: there is no
|
|
123
|
+
fork on which steering file you happen to create, and `idle` has exactly one
|
|
124
|
+
outgoing edge, into `unwind`. `unwind` reverts that whole diff back out of your
|
|
125
|
+
working tree (`git revert --no-commit` against the commit it just landed in)
|
|
126
|
+
before planning ever starts — your tree is back to exactly what it was, and your
|
|
127
|
+
intent doesn't disappear, it survives in history for `design.triage` to read.
|
|
128
|
+
|
|
129
|
+
From there, `start-gate.check` runs your test suite on the tree as it now stands
|
|
130
|
+
— which, thanks to the unwind, is simply your repo's own baseline. The rule is
|
|
131
|
+
the plain one: the baseline must be green. A red run halts the process and tells
|
|
132
|
+
you to repair it first (that's what `gtd --entry fix-precheck` is for);
|
|
133
|
+
`review-gate` follows the same rule.
|
|
134
|
+
|
|
135
|
+
Once past the gate, `design.triage` reads the diff that started the process
|
|
136
|
+
itself — the prompt never inlines it; it finds the entry commit (the one
|
|
137
|
+
`unwind` reverted) and runs `git show` against it — and groups that diff into an
|
|
138
|
+
ORDERED list of **concerns**, each one able to leave the test suite green on its
|
|
139
|
+
own, classifying each as **product** (a user-facing/requirements decision) or
|
|
140
|
+
**technical** (an implementation decision). It raises open questions for the
|
|
141
|
+
product concerns only, in `.gtd/REQUIREMENTS.md`, folding EVERYTHING the entry
|
|
142
|
+
commit added into those concerns — a scratch sketch and a hand-edited code
|
|
143
|
+
change alike, since the unwind already reverted both; nothing is left to delete.
|
|
144
|
+
A shared check+answer gate then probes `.gtd/REQUIREMENTS.md` for unanswered
|
|
145
|
+
questions: each open question offers a couple of candidate answers plus a
|
|
146
|
+
`- [ ] _your answer_` slot, and you tick exactly one per question (the gate
|
|
147
|
+
won't let the phase advance while any question is unanswered) — but a phase
|
|
148
|
+
whose document has no open questions skips that human stop entirely and falls
|
|
149
|
+
straight through.
|
|
150
|
+
|
|
151
|
+
Once the product questions are settled, `architecture.author` picks up as a
|
|
152
|
+
**cold reader** — a separate machine with its own memory scope, so it does not
|
|
153
|
+
resume the triage conversation but reads `.gtd/REQUIREMENTS.md` in full — and
|
|
154
|
+
develops the _how_ for each settled concern, raising only technical open
|
|
155
|
+
questions in `.gtd/ARCHITECTURE.md` (routed through that same shared
|
|
156
|
+
check+answer gate shape, again skipping the human stop when nothing is open),
|
|
157
|
+
deleting `.gtd/REQUIREMENTS.md` once its content is folded in. Once those are
|
|
158
|
+
settled, `architecture.decompose` is a purely mechanical write-out — **one
|
|
159
|
+
package file per concern**, in the settled order, with no merge/split judgement
|
|
160
|
+
of its own (that already happened in triage's grouping) — handing off to the
|
|
161
|
+
per-package build queue: each package (a set of independent tasks a single build
|
|
162
|
+
turn fans out to parallel subagents) runs its own test loop and a per-package
|
|
163
|
+
**agentic review** that verifies it against its own spec. A package whose work
|
|
164
|
+
already landed (an earlier package's fix turn pulled it in) is not a dead end:
|
|
165
|
+
the build turn records per-criterion evidence in `.gtd/SATISFIED.md` instead of
|
|
166
|
+
implementing anything, and the package still goes through the checks and the
|
|
167
|
+
spec review before closing out. If a queue item ever _does_ dead-end (a build
|
|
168
|
+
turn that authors nothing stalls), the supported recovery is to write that same
|
|
169
|
+
file yourself and `gtd land` — no hand-authored state commit.
|
|
170
|
+
|
|
171
|
+
The process converges on that same shared tail: an agent hands you a
|
|
172
|
+
`.gtd/REVIEW.md` checkbox review of the diff — the prompt never inlines the diff
|
|
173
|
+
itself; it names the commit the changes are based at and the agent runs
|
|
174
|
+
`git diff` to read the range before writing the review. While the process rests
|
|
175
|
+
at that gate, the landing script opens a **review checkout window**: HEAD is
|
|
176
|
+
rewound to the review base with the working tree untouched, so the whole
|
|
177
|
+
reviewable change shows up as ordinary uncommitted changes in your editor's
|
|
178
|
+
normal git integration (and files added during the process show up as ordinary
|
|
179
|
+
untracked files, so discarding one deletes it — an untracked file you leave
|
|
180
|
+
alone is not a pending change, and only actually removing it from disk counts as
|
|
181
|
+
a deletion). The next landing's own script closes the window before it commits.
|
|
182
|
+
Tick a box as you review each hunk (ticking just records "I read this"), and
|
|
183
|
+
leave a **comment** to request changes: a note on a line, an inline
|
|
184
|
+
`// TODO`-style comment in the code, or a direct code edit. Any comment sends a
|
|
185
|
+
build + re-review round — an agent first turns your comments into an explicit
|
|
186
|
+
instruction list, then a build turn implements it (a re-review then covers only
|
|
187
|
+
the follow-through, and a hand-edit is treated as your own fix the agent
|
|
188
|
+
completes without reverting your lines; a comment can't be silently dropped — a
|
|
189
|
+
build turn that addresses nothing is refused). The build turn that follows
|
|
190
|
+
through on feedback and the turn that drafts the final squash message both
|
|
191
|
+
resume the same session that built the feature in the first place, since the
|
|
192
|
+
review tail is nested inside that build identity rather than sitting beside it.
|
|
193
|
+
Ticking every box with no comment is the sign-off, which collapses the whole
|
|
194
|
+
process into one commit (a **squash finale** whose message an agent drafts).
|
|
195
|
+
Landing with a box still unticked and no comment is refused (finish reviewing
|
|
196
|
+
first), as is deleting `.gtd/REVIEW.md`. Both refusals hold wherever the review
|
|
197
|
+
doc lives: repointing `reviewFile` out of `.gtd/` (say to `REVIEW.md` at the
|
|
198
|
+
repo root) changes nothing about them — your own edit to the review doc is never
|
|
199
|
+
mistaken for a code comment, and the doc's pre-turn copy is read at the review
|
|
200
|
+
window's saved head rather than at the rewound `HEAD`.
|
|
201
|
+
|
|
202
|
+
A second entry, the same review tail's own direct entry point —
|
|
170
203
|
`gtd --entry review-gate.check --var reviewBase=<commitish>` starts a brand new
|
|
171
204
|
process reviewing `<commitish>..HEAD` with no build of its own, e.g. a
|
|
172
205
|
colleague's PR branch (`review-gate.check`'s `reviewBase:` is a template bound
|
|
173
206
|
to the `reviewBase` var, so supplying it via `--var` fixes the whole process's
|
|
174
207
|
diff base to that commitish). Its squash keeps and describes only the fixes made
|
|
175
208
|
_during_ the review (not the reviewed changeset); a clean sign-off with no fixes
|
|
176
|
-
becomes an empty `chore: human review` commit. A
|
|
209
|
+
becomes an empty `chore: human review` commit. A third entry,
|
|
177
210
|
`gtd --entry fix-precheck`, starts from a clean `idle` and goes straight into
|
|
178
211
|
repairing a red baseline — repair, review, and squash into one commit. If the
|
|
179
212
|
suite is already green there is nothing to fix, and the log is left untouched —
|
|
@@ -185,10 +218,11 @@ no commit is left behind.
|
|
|
185
218
|
_extra_ reachability root (and drives a badge in `gtd visualize`) for a state
|
|
186
219
|
that would otherwise be unreachable from the ordinary `idle` rest —
|
|
187
220
|
`review-gate.check` and `fix-precheck` need it for exactly that reason, while
|
|
188
|
-
`
|
|
189
|
-
|
|
190
|
-
state flags
|
|
191
|
-
`entry: true` is not a precondition for `--entry`
|
|
221
|
+
`start-gate.check` carries it too (the bundled template dedups its two
|
|
222
|
+
`entryGate` instances — `start-gate` and `review-gate` — into one shared
|
|
223
|
+
machine, so flagging the shared state flags both) even though `idle` already
|
|
224
|
+
reaches it the ordinary way. `entry: true` is not a precondition for `--entry`
|
|
225
|
+
to target a state.
|
|
192
226
|
|
|
193
227
|
Every agent state routes its model through two `vars` tiers — `plannerModel`
|
|
194
228
|
(heavier planning and review) and `coderModel` (the coding turns) — so you can
|
|
@@ -274,7 +308,9 @@ Commands:
|
|
|
274
308
|
non-zero when there are any. Resolves no workflow state and
|
|
275
309
|
reads no config — standalone, runnable from any directory
|
|
276
310
|
with <mode>/<file> given explicitly. This is what a
|
|
277
|
-
workflow's emitted validation script invokes as a leaf step
|
|
311
|
+
workflow's emitted validation script invokes as a leaf step.
|
|
312
|
+
--open-questions runs the qa unanswered-questions predicate
|
|
313
|
+
instead (see --help)
|
|
278
314
|
install Print a complete, self-contained briefing that teaches an
|
|
279
315
|
agent (or a human) to build a gtd driver in any shell or
|
|
280
316
|
runtime — the self-serve version of README's 'Writing
|
|
@@ -297,6 +333,10 @@ Options:
|
|
|
297
333
|
(with --entry; repeatable) supply a fixed it.vars
|
|
298
334
|
override for the new process; the name must already be
|
|
299
335
|
declared by the workflow's own vars: or the .gtdrc vars:
|
|
336
|
+
--open-questions (gtd check only) ignore <mode>'s structural findings and
|
|
337
|
+
instead run the qa open-questions predicate over <file>,
|
|
338
|
+
printing each unanswered question one per line and exiting
|
|
339
|
+
non-zero when any remain
|
|
300
340
|
--version, -v Print version and exit
|
|
301
341
|
--help, -h Print this help and exit
|
|
302
342
|
```
|
|
@@ -377,17 +417,17 @@ exits. You act by editing files (answer a plan question, tick a review box, fix
|
|
|
377
417
|
code) and re-running it — your pending edit arrives as the loop's first beat
|
|
378
418
|
(`kind: "capture"`, landed immediately), so you never run `gtd land` by hand.
|
|
379
419
|
|
|
380
|
-
Some gates accept by INACTION instead:
|
|
381
|
-
|
|
382
|
-
"accept
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
no-op (see `gtd land`'s exit
|
|
389
|
-
|
|
390
|
-
actually next.
|
|
420
|
+
Some gates could accept by INACTION instead: a workflow may declare a `"C"`
|
|
421
|
+
(clean-tree) pattern on a human-actor state that routes onward, so changing
|
|
422
|
+
nothing there means "accept as-is" rather than nothing happening. That reaches
|
|
423
|
+
the driver as `kind: "message"` either way, which no inspection can tell apart
|
|
424
|
+
from a gate you have not read yet — so the driver treats its OPENING beat as
|
|
425
|
+
yours regardless and lands it: you re-ran it while resting there, and that
|
|
426
|
+
invocation IS the decision. Every later beat halts as usual, because a gate the
|
|
427
|
+
driver produced mid-run is one you have not seen. Landing an opening beat at a
|
|
428
|
+
gate with no `"C"` pattern is harmless — a benign no-op (see `gtd land`'s exit
|
|
429
|
+
codes below) — and the gate then prints on the next beat. A mid-process restart
|
|
430
|
+
simply resumes driving from whatever beat is actually next.
|
|
391
431
|
|
|
392
432
|
Anything richer at that boundary — opening your editor, desktop notifications,
|
|
393
433
|
terminal-multiplexer status — is the job of an outer wrapper around the driver,
|
|
@@ -752,17 +792,14 @@ emitted script opens by asserting its own precondition
|
|
|
752
792
|
and the same shape for a review window's saved ref — see `src/Emit.ts`'s
|
|
753
793
|
`headAssertion`/`reviewWindowAssertion`), so a script generated against a
|
|
754
794
|
repository state that has since moved refuses loudly instead of corrupting
|
|
755
|
-
anything.
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
yet — safe to retry verbatim) or gtd's next invocation reads the new real state
|
|
764
|
-
and emits a fresh script for what remains. A driver never needs its own
|
|
765
|
-
retry/resume logic beyond "if the script failed, ask gtd again."
|
|
795
|
+
anything. **Emitted scripts are re-runnable**: this is the single most important
|
|
796
|
+
property for a driver's recovery logic. Re-running a script that already fully
|
|
797
|
+
applied is a no-op (its git writes are `--allow-empty` commits, idempotent ref
|
|
798
|
+
updates, and tolerant staged-restore calls), and re-running one that only
|
|
799
|
+
partially applied resumes correctly, because the precondition either still holds
|
|
800
|
+
(nothing landed yet — safe to retry verbatim) or gtd's next invocation reads the
|
|
801
|
+
new real state and emits a fresh script for what remains. A driver never needs
|
|
802
|
+
its own retry/resume logic beyond "if the script failed, ask gtd again."
|
|
766
803
|
|
|
767
804
|
### Prerequisites
|
|
768
805
|
|
|
@@ -1031,6 +1068,24 @@ model, pattern grammar, load-time rules, and how to verify a change compiles.
|
|
|
1031
1068
|
> discard it and start over (or finish the process on the pre-upgrade workflow
|
|
1032
1069
|
> version first).
|
|
1033
1070
|
|
|
1071
|
+
> **Upgrading a `workflow:` from the old two-flow (`.gtd/TODO.md` vs.
|
|
1072
|
+
> `.gtd/REQUIREMENTS.md`) shape?** The bundled template collapsed that fork into
|
|
1073
|
+
> one flow: `idle` now has a single outgoing edge — any change at all starts the
|
|
1074
|
+
> process, never a fork on which steering file you create — and
|
|
1075
|
+
> `plan-gate.check`/`spec-gate.check` merged into one shared `start-gate.check`.
|
|
1076
|
+
> The old plan-iteration machine's `plan.planning`/`plan.await-plan` states and
|
|
1077
|
+
> its monolithic `build.building` state are gone outright; every concern now
|
|
1078
|
+
> goes through the same per-package build queue instead. Renamed:
|
|
1079
|
+
> `design.product-author` → `design.triage`, `design.product-answer` →
|
|
1080
|
+
> `design.gate.answer`, `design.technical-author` → `architecture.author`,
|
|
1081
|
+
> `design.technical-answer` → `architecture.gate.answer`, `design.decompose` →
|
|
1082
|
+
> `architecture.decompose` (architecture is now its own sibling machine with its
|
|
1083
|
+
> own memory scope, not nested under `design`). The `todoFile` var and the
|
|
1084
|
+
> `prose` mode are both gone — there is no more free-form plan file. As with
|
|
1085
|
+
> every rename above, an in-flight process resting at one of the old names can
|
|
1086
|
+
> no longer be resumed; `gtd abandon` it (or finish it on the pre-upgrade
|
|
1087
|
+
> workflow version) before upgrading.
|
|
1088
|
+
|
|
1034
1089
|
### Variables
|
|
1035
1090
|
|
|
1036
1091
|
Every template — `script`/`prompt`/`message`/`commit`, a machine's own `model:`,
|
|
@@ -1136,7 +1191,9 @@ the compiler's job at load time.
|
|
|
1136
1191
|
per `review`-mode chunk that still has an unchecked hunk (an outline of the
|
|
1137
1192
|
packages left to review) plus check/uncheck actions over those chunks,
|
|
1138
1193
|
go-to-definition from a `review`-mode hunk line into the file it points at (at
|
|
1139
|
-
its `#line`
|
|
1194
|
+
its `#line` — a hunk's path is a single whitespace-delimited `./`-relative
|
|
1195
|
+
token, so a hyphen in a filename stays part of the path, never a note
|
|
1196
|
+
separator), symbols over a `qa`-mode file's open questions plus "pick this
|
|
1140
1197
|
option"/"uncheck this option" code actions on each option — offered anywhere on
|
|
1141
1198
|
the option's list item, including any wrapped continuation lines, not just its
|
|
1142
1199
|
own `- [ ]` line — diagnostics for both (live as you edit), and a
|
|
@@ -1152,10 +1209,10 @@ itself, so you bring your own formatter and your own checkers. Overriding one of
|
|
|
1152
1209
|
actions — those come from the FORMAT (the name), independent of who validates —
|
|
1153
1210
|
but `gtd lsp` never runs a shell command per keystroke, so live diagnostics
|
|
1154
1211
|
become one `Information` notice pointing at `gtd validate` instead of the
|
|
1155
|
-
built-in findings. Any OTHER mode name —
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1212
|
+
built-in findings. Any OTHER mode name — a project's own declared name (e.g.
|
|
1213
|
+
`prose`, for a free-form note) — has no built-in format, so it gets no live
|
|
1214
|
+
editor support at all: `gtd validate`'s emitted script and the `gtd land` gate
|
|
1215
|
+
still format and validate it like any other mode.
|
|
1159
1216
|
|
|
1160
1217
|
## Development
|
|
1161
1218
|
|
|
@@ -1163,16 +1220,21 @@ gate still format and validate it like any other mode.
|
|
|
1163
1220
|
npm install
|
|
1164
1221
|
npm run dev # run from source, no build (node dev/run.mjs)
|
|
1165
1222
|
npm run build # tsdown → dist/gtd.bundle.mjs
|
|
1166
|
-
npm test #
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
npm run test:
|
|
1170
|
-
npm run test:e2e:live # @live scenarios against the built bundle — --project e2e-live
|
|
1223
|
+
npm test # the whole gate, via turbo — cached and parallel
|
|
1224
|
+
npx turbo run test:unit # one task, cached (add --force to bypass)
|
|
1225
|
+
npx turbo run test:e2e:live # builds first (turbo dependsOn), then @live
|
|
1226
|
+
npm run test:changed # local pre-flight: only unit/@inmem tests git says changed
|
|
1171
1227
|
npm run test:mutation # StrykerJS mutation testing (manual only, ~10 min)
|
|
1172
1228
|
npm run typecheck
|
|
1173
1229
|
npm run lint
|
|
1174
1230
|
```
|
|
1175
1231
|
|
|
1232
|
+
`npm test` is a turbo task graph (`turbo.json`): each check declares its own
|
|
1233
|
+
`inputs`, so an unchanged check is skipped, and a check that does run is run in
|
|
1234
|
+
parallel with the others. Caveat from the `test:e2e:live` task's `build`
|
|
1235
|
+
dependency: a bare `npm run test:e2e:live` skips the build, so use
|
|
1236
|
+
`npx turbo run test:e2e:live` to test against a fresh bundle.
|
|
1237
|
+
|
|
1176
1238
|
A pre-commit hook is installed automatically via the `prepare` script when you
|
|
1177
1239
|
run `npm install` on a fresh clone — it runs
|
|
1178
1240
|
[lint-staged](https://github.com/lint-staged/lint-staged) with
|