flanders 0.7.0 → 0.8.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.
Files changed (3) hide show
  1. package/README.md +72 -76
  2. package/lib/cli.js +2 -2
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Flanders
1
+ # Motivation
2
2
 
3
- Hi-diddly-ho, neighbor! Flanders is a Node.js toolkit that helps you author contracts, derive work plans from them, and implement those plans through a mix of plain code and AI orchestration. It reaches you through two surfaces a CLI invoked as `npx flanders <command>`, and three AI-tool skills invoked from inside an AI-coding-tool session.
3
+ Hi-diddly-ho, neighbor! I am a Node.js toolkit that helps avoid AI drifting. I was sick of the AI not reading the `CLAUDE.md`, avoiding rules and forgetting what I told it 3 prompts ago. You know that I, Ned Flanders, will never break a rule, so it was natural for me to spawn here at some point. I will help you define a specification, the public contracts and private rules, and then I will orchestrate the AI for you to implement and review anything without breaking the specification. I have no problem hitting the AI with a stick when it drifts.
4
4
 
5
5
  ## Contents
6
6
 
@@ -14,41 +14,49 @@ Hi-diddly-ho, neighbor! Flanders is a Node.js toolkit that helps you author cont
14
14
 
15
15
  ## How it works
16
16
 
17
- Flanders speaks to you through two surfaces. The **CLI** invoked as `npx flanders <command>` — carries three commands: `install`, which sets Flanders up in your project or your home directory; `update`, which refreshes the already-installed skills in place; and `implement [plan]`, which builds a plan from start to finish. The three **AI-tool skills** `/flanders-spec`, `/flanders-plan`, and `/flanders-work` — are invoked from right inside an AI-coding-tool session.
17
+ With Flanders you first define a specification that will be stored in a `.spec` folder alongside where the specification applies. Then Flanders will help you to create a plan divided into tasks, and via CLI you then implement the plan.
18
18
 
19
- Underneath, Flanders keeps a tidy little spec corpus alongside your code, and everything flows from it:
19
+ Flanders will implement one task at a time, and then will launch, in parallel, as many validators as you have configured. If something differs from the specification, they will notify the worker to review the problem and fix it.
20
20
 
21
- - **`.spec/contracts`** holds the public obligations a scope exposes the promises its surface makes to the outside world.
22
- - **`.spec/rules`** holds the internal conventions its code follows — the house rules it keeps for itself.
23
- - **`.spec/flanders`** holds behavior rules — the obligations that govern how Flanders' own commands and skills behave while they work in your project.
24
-
25
- Ordered work plans then live under **`plans/`**: each plan is a sequence of tasks derived from the contracts and rules, ready to be built one at a time.
21
+ I'm not gonna lie, it is token hungry, but that's what you get when you want to reduce specification drifting. The AI has to iterate and validate multiple times what it is doing to avoid the typical "Ah, you are right! You already told me that". Still, Flanders has rate limit detection and retries, so you can let an implementation run overnight while you sleep, without worrying about the limits.
26
22
 
27
23
  The whole neighborly cycle runs **spec → plan → implement**:
28
24
 
29
- 1. Capture obligations and conventions as contracts, rules, and behavior rules in the spec corpus (with `/flanders-spec`).
25
+ 1. Capture obligations and conventions as contracts and rules in the spec corpus (with `/flanders-spec`).
30
26
  2. Derive an ordered work plan from them under `plans/` (with `/flanders-plan`).
31
- 3. Implement the plan task by task, gating each result through build, test, and adversarial review (with `npx flanders implement`).
27
+ 3. Implement the plan task by task, gating each result through build, test, and adversarial review (with `flanders implement`).
32
28
 
33
29
  For a small, self-contained change that doesn't need a whole plan, there's a friendly shortcut: **`/flanders-work`** implements the request directly and gates it through the same build, test, and adversarial review, all in one invocation.
34
30
 
31
+ Underneath, Flanders keeps a tidy little spec corpus alongside your code, and everything flows from it:
32
+
33
+ - **`.spec/contracts`** holds the public obligations a scope exposes — the promises its surface makes to the outside world.
34
+ - **`.spec/rules`** holds the internal conventions its code follows — the house rules it keeps for itself.
35
+ - **`.spec/flanders`** holds behavior rules — the obligations that govern how Flanders' own commands and skills behave while they work in your project.
36
+
35
37
  ## Requirements
36
38
 
37
39
  A few neighborly things to have on hand before you start:
38
40
 
39
- - **Node.js** — the CLI is run with `npx`.
41
+ - **Node.js**.
40
42
  - **A git repository** — the `implement` command requires the project to be a git repository.
41
- - **A supported AI coding tool** — currently Claude Code or Codex CLI.
43
+ - **A supported CLI AI coding tool** — currently Claude Code or Codex.
42
44
 
43
45
  ## Installation
44
46
 
45
47
  Setting Flanders up is a breeze, neighbor — just run:
46
48
 
47
49
  ```sh
48
- npx flanders install
50
+ npm install flanders -g
51
+ ```
52
+
53
+ and then:
54
+
55
+ ```sh
56
+ flanders install
49
57
  ```
50
58
 
51
- This is how Flanders first sets up on disk: it is the only command that writes the persistent `.flanders/` configuration that `implement` reads, and the way you publish the skills to a fresh scope. Once the skills are in place, `npx flanders update` refreshes them where they already live (see [Updating](#updating)).
59
+ This is how Flanders first sets up on disk: it is the only command that writes the persistent `.flanders/` configuration that `implement` reads, and the way you publish the skills to a fresh scope.
52
60
 
53
61
  ### Scope
54
62
 
@@ -57,8 +65,6 @@ Flanders installs at one of two scopes, chosen with a pair of mutually exclusive
57
65
  - `--project` — the scope is the current working directory. Skills go into the project's AI-tool skill folders, and the `.flanders/` configuration is written at the project root.
58
66
  - `--global` — the scope is your home directory. Skills go into the user-level AI-tool skill folders, and the `.flanders/` configuration is written at your home directory.
59
67
 
60
- Passing both at once is a usage error. When you supply neither, the command kindly prompts you to pick one.
61
-
62
68
  ### What it writes
63
69
 
64
70
  For each AI tool you select for skills, `install` writes one skill artifact per Flanders skill (`/flanders-spec`, `/flanders-plan`, and `/flanders-work`) into that tool's skill folder for the chosen scope:
@@ -77,12 +83,10 @@ Run it without flags and Flanders walks you through the setup, asking in this or
77
83
  1. **Skills tool** — `claude`, `codex`, or `both`.
78
84
  2. **Scope** — `--project` or `--global`, each option labelled with the concrete destination path(s) for the skills tool you picked.
79
85
  3. **Worker tool, model, and effort** — the AI the `implement` command's worker uses.
80
- 4. **Reviewer configuration** — an ordered list of one or more adversarial reviewers, each with its own tool, model, and effort.
81
- 5. **Weighted-review configuration** — when two or more reviewers are configured, the minimum number of reviewers that must run to a verdict, and which reviewers are optional.
82
-
83
- Any question whose answer you supply by flag is not prompted again.
86
+ 4. **Reviewer configuration** — an ordered list of one or more adversarial reviewers, each with its own tool, model, and effort. You can have any number of reviewers, for example Claude Opus, Claude Sonnet and Codex. You can even duplicate them if you think that one pass is not enough to detect a problem.
87
+ 5. **Weighted-review configuration** — when two or more reviewers are configured, the minimum number of reviewers that must run to a verdict, and which reviewers are optional. Optional reviewers will not halt the implementation when they reach a rate limit.
84
88
 
85
- And if a `.flanders/` configuration already lives at the scope you choose, neighbor, `install` reads it the moment you pick that scope and pre-selects your stored answers as the question defaults the worker's tool, model, and effort; the reviewer list, including how many reviewers there are and, for each one, its tool, model, effort, and whether it's optional; and the minimum number of reviewers that must run. Press Enter straight through and, but for one edge case, you reproduce your saved configuration just as it was. That edge case is a stored Codex model the probe no longer offers: with it no longer on the menu, that one question is shown with no pre-selected default and you answer it afresh. The skills tool and the scope aren't kept in that file, so they're always asked fresh too, and any flag you pass still wins over a pre-selected default. When no configuration lives at that scope yet — or the file can't be read — Flanders gently falls back to its fresh-install defaults and pre-selects nothing.
89
+ And if a `.flanders/` configuration already lives at the scope you choose, neighbor, `install` reads it the moment you pick that scope and pre-selects your stored answers as the question defaults. Just press Enter straight through to reproduce your saved configuration just as it was.
86
90
 
87
91
  ### Flags
88
92
 
@@ -121,18 +125,14 @@ Existing files at the destination — both skill artifacts and `.flanders/` conf
121
125
 
122
126
  ## Updating
123
127
 
124
- Already set up and itching for the freshest skills, neighbor? Just run:
128
+ Updated the lib and itching for the freshest skills, neighbor? Just run:
125
129
 
126
130
  ```sh
127
- npx flanders update
131
+ flanders update
128
132
  ```
129
133
 
130
134
  `update` takes no flags. It scans the four skill destinations `install` writes to — Claude Code and Codex CLI, each at project and global scope — and wherever it finds at least one Flanders skill artifact already in place, it rewrites the full `/flanders-spec`, `/flanders-plan`, and `/flanders-work` trio there with the current version. A destination where no Flanders skill artifact is present is left untouched, so `update` refreshes the installations you already have and never creates one where you had none.
131
135
 
132
- It is entirely hands-off: `update` asks you nothing, and it never reads or writes your `.flanders/` configuration — the worker and reviewer answers a previous `install` saved carry over exactly as they were. Existing skill files are overwritten silently, the same way `install` overwrites them. On success it prints every file it wrote, one path per line.
133
-
134
- If no Flanders skills are installed at any scope or tool, `update` has nothing to refresh: it exits with an error that points you to `npx flanders install` to set one up first.
135
-
136
136
  ## Configuration
137
137
 
138
138
  The `install` command tucks your answers into a `.flanders/` folder so the command that consumes them — `implement` — knows just how you like things done. (`update` leaves this configuration untouched; it only refreshes the skills.) Where that folder lives depends on the scope you chose:
@@ -140,16 +140,6 @@ The `install` command tucks your answers into a `.flanders/` folder so the comma
140
140
  - **Project scope** — `.flanders/` at the project root.
141
141
  - **Global scope** — `~/.flanders/` in your home directory.
142
142
 
143
- It persists exactly the answers downstream commands need at run time:
144
-
145
- - The **worker** the `implement` command uses: its tool (`claude` or `codex`), its model, and its reasoning effort.
146
- - The **ordered list of adversarial reviewers**, in the order you configured them. Each reviewer carries its own tool (`claude` or `codex`), model, and effort, plus whether it is optional.
147
- - The **minimum number of reviewers** that must run to a verdict in each review round.
148
-
149
- For any model or effort you leave unset — the worker's or a reviewer's — Flanders doesn't record a concrete value; instead it persists the explicit marker `default configured model` or `default configured effort`, which tells the tool to fall back to its own default at run time.
150
-
151
- The skills-tool answer is used by `install` itself to decide which folders to write into, so it isn't persisted here.
152
-
153
143
  ### Which configuration wins
154
144
 
155
145
  When a command reads the configuration, a project-scope `.flanders/` always takes precedence over a global one — and it's all or nothing, with no field-by-field merge between the two. So a project `.flanders/` is used in full when it's present; otherwise the global `~/.flanders/` is used.
@@ -158,20 +148,10 @@ When a command reads the configuration, a project-scope `.flanders/` always take
158
148
 
159
149
  With Flanders installed, here's how to put it to work — running plans from the CLI and shaping them with the three skills.
160
150
 
161
- ### Implementing a plan
162
-
163
- ```sh
164
- npx flanders implement [plan]
165
- ```
166
-
167
- `implement` takes a plan from your `plans/` folder and carries it through from start to finish. Leave `[plan]` off and Flanders runs the single plan in `plans/` for you automatically; when there's more than one, it lists them and asks you to re-run naming the one to implement. From there it works through each open task with the worker AI, gating every result through build, test, and adversarial review before marking that task complete in the plan — and it commits once per accepted task, so each step lands as its own neat little commit. The whole run is non-interactive: once started, it never stops to ask you anything, and it caps each task at five attempts before halting. The project must be a git repository: `implement` needs git and has no flag to turn it off.
168
-
169
151
  ### The three skills
170
152
 
171
- The skills become available after a successful `npx flanders install` run, and each is invoked from inside your AI-coding-tool session. Each one shapes a different part of the spec → plan → implement cycle:
172
-
173
153
  - **`/flanders-spec`** — turns a free-form request into your contracts, rules, and behavior rules, written into the `.spec/contracts`, `.spec/rules`, and `.spec/flanders` folders.
174
- - **`/flanders-plan`** — derives a single, ordered, contract-aware work plan under `plans/` from your request.
154
+ - **`/flanders-plan`** — derives a single, ordered, specification-aware work plan from your request.
175
155
  - **`/flanders-work`** — implements a small, self-contained request directly and gates it through build, test, and a single adversarial review, all in one invocation — no plan file and no commit.
176
156
 
177
157
  Each skill takes the same optional `<data>` argument:
@@ -186,14 +166,24 @@ Each skill takes the same optional `<data>` argument:
186
166
  - Give it a path to an existing file, and the skill reads that file as the input.
187
167
  - Give it any other text, and the skill uses that text verbatim.
188
168
 
169
+ ### Implementing a plan
170
+
171
+ ```sh
172
+ flanders implement [plan]
173
+ ```
174
+
175
+ `implement` takes a plan from your `plans/` folder and carries it through from start to finish. Leave `[plan]` off and Flanders runs the single plan in `plans/` for you automatically. From there it works through each open task with the worker AI, gating every result through build, test, and adversarial review before marking that task complete in the plan — and it commits once per accepted task, so each step lands as its own neat little commit. The whole run is non-interactive: once started, it never stops to ask you anything, and it caps each task at five attempts before halting. The project must be a git repository: `implement` needs git and has no flag to turn it off.
176
+
177
+ When the plan implementation is finished, you can squash all the plan commits. They are ordered by task for easier identification.
178
+
189
179
  ### A typical workflow
190
180
 
191
181
  Here's the neighborly path from a blank slate to shipped code:
192
182
 
193
- 1. **`npx flanders install`** — set Flanders up and deliver the skills.
183
+ 1. **`flanders install`** — set Flanders up and deliver the skills.
194
184
  2. **`/flanders-spec`** — capture your obligations and conventions as contracts, rules, and behavior rules.
195
185
  3. **`/flanders-plan`** — derive an ordered work plan from them under `plans/`.
196
- 4. **`npx flanders implement`** — build the plan task by task, each result gated through build, test, and review.
186
+ 4. **`flanders implement`** — build the plan task by task, each result gated through build, test, and review.
197
187
 
198
188
  And when a change is small enough that a whole plan would be overkill, **`/flanders-work`** is your shortcut — it carries that one request from request to reviewed finish without a plan or a commit.
199
189
 
@@ -203,43 +193,49 @@ Let's build a tiny web calculator that only multiplies and subtracts, neighbor
203
193
 
204
194
  1. **Set Flanders up** in your project and deliver the skills:
205
195
 
206
- ```sh
207
- npx flanders install
208
- ```
196
+ ```sh
197
+ flanders install
198
+ ```
209
199
 
210
200
  2. **Capture the spec** with `/flanders-spec`. You describe what you want; the skill sorts each obligation into the right folder — public behavior into `.spec/contracts`, internal conventions into `.spec/rules`:
211
201
 
212
- ```
213
- /flanders-spec A web calculator with exactly two operations — multiply and
214
- subtract — over two number inputs, showing the result. The operation buttons
215
- are teal, the result panel is white, and the page background is slate. Build
216
- the UI with React bundled by Vite, and use no other UI framework.
217
- ```
202
+ ```
203
+ /flanders-spec A web calculator with exactly two operations — multiply and subtract — over two number inputs, showing the result. The operation buttons are teal, the result panel is white, and the page background is slate. Build the UI with React bundled by Vite, and use no other UI framework.
204
+ ```
218
205
 
219
- From that one request it writes, for example:
206
+ From that one request it writes, for example:
220
207
 
221
- - a **functionality contract** under `.spec/contracts/` — the calculator offers exactly two operations, multiply and subtract, over two numeric inputs, and shows the result;
222
- - a **colors contract** under `.spec/contracts/` — the operation buttons are teal, the result panel white, and the background slate;
223
- - a **frameworks rule** under `.spec/rules/` — the UI is built with React bundled by Vite, and no other UI framework is introduced.
208
+ - a **functionality contract** under `.spec/contracts/` — the calculator offers exactly two operations, multiply and subtract, over two numeric inputs, and shows the result;
209
+ - a **colors contract** under `.spec/contracts/` — the operation buttons are teal, the result panel white, and the background slate;
210
+ - a **frameworks rule** under `.spec/rules/` — the UI is built with React bundled by Vite, and no other UI framework is introduced.
224
211
 
225
- The skill shows you the planned layout first and writes the files once you approve.
212
+ The skill shows you the planned layout first and writes the files once you approve.
226
213
 
227
- 3. **Derive the plan** with `/flanders-plan` — one ordered, contract-aware plan under `plans/`, each task linked back to the contracts and rules it satisfies:
214
+ 3. **Derive the plan** with `/flanders-plan` — one ordered, specification-aware plan under `plans/`, each task linked back to the contracts and rules it satisfies:
228
215
 
229
- ```
230
- /flanders-plan
231
- ```
216
+ ```
217
+ /flanders-plan
218
+ ```
232
219
 
233
220
  4. **Build it** with `implement` — Flanders works each task with the worker AI, gates every result through build, test, and adversarial review, and lands one commit per accepted task:
234
221
 
235
- ```sh
236
- npx flanders implement
237
- ```
222
+ ```sh
223
+ flanders implement
224
+ ```
238
225
 
239
- When it finishes, the contracts are honored by code: a calculator that multiplies and subtracts and nothing else, in teal, white, and slate, built on the framework your rule pinned.
226
+ When it finishes, the contracts are honored by code: a calculator that multiplies and subtracts and nothing else, in teal, white, and slate, built on the framework your rule pinned.
240
227
 
241
228
  5. **Tweak it later** with the shortcut — a small change that doesn't need a whole plan:
242
229
 
243
- ```
244
- /flanders-work make the result panel use a larger font
245
- ```
230
+ ```
231
+ /flanders-work make the result panel use a larger font
232
+ ```
233
+
234
+ If you really want the font to be kept at that size, just save the spec, and no future work will ever break that specification:
235
+
236
+ ```
237
+ /flanders-spec make the result panel use a larger font
238
+ ```
239
+ ```
240
+ /flanders-work
241
+ ```
package/lib/cli.js CHANGED
@@ -235,7 +235,7 @@ const ask = (() => {
235
235
  const o = q.options[i];
236
236
  const marker = pickedLabels.has(o.label) ? "*" : " ";
237
237
  const isDefault = q.defaultIndex === i;
238
- out.write(` ${marker} ${i + 1}) ${o.label}${o.description ? ` — ${o.description}` : ""}${isDefault ? " (default — press Enter)" : ""}\n`);
238
+ out.write(` ${marker} ${i + 1}) ${o.label}${o.description ? ` — ${o.description}` : ""}${isDefault ? " (configured — press Enter)" : ""}\n`);
239
239
  }
240
240
  if (existing) {
241
241
  const labels = existing.picked.map(p => p.label).join(", ");
@@ -260,7 +260,7 @@ const ask = (() => {
260
260
  ? `[1-${q.options.length}, comma-separated; free-text OK]`
261
261
  : `[1-${q.options.length}; free-text OK]`);
262
262
  if (q.defaultIndex !== undefined) {
263
- hints.push("Enter for default");
263
+ hints.push("Enter for configured");
264
264
  }
265
265
  if (idx > 0) {
266
266
  hints.push("'-' back");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flanders",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "Flanders never breaks a rule",
5
5
  "main": "lib/",
6
6
  "types": "lib/types",