npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

flanders

v0.24.0

Published

Flanders never breaks a rule

Readme

Flanders

Hi-diddly-ho, neighbor! Flanders is a Node.js toolkit for keeping AI-assisted work aligned with the specifications you choose. It helps you author a spec corpus, derive an ordered plan, and implement each task through build, test, adversarial review, and commit gates.

Contents

How it works

The usual cycle is spec → plan → implement:

  1. From inside an AI coding session, invoke /flanders-spec to capture the project's obligations and conventions.
  2. From inside an AI coding session, invoke /flanders-plan to turn the request and spec corpus into an ordered plan under plans/.
  3. From the Flanders CLI, run npx flanders implement to execute the plan one task at a time.

For one self-contained request, invoke /flanders-implement from inside an AI coding session. It carries that request through the same task cycle. To implement a plan, run npx flanders implement from the Flanders CLI instead.

At the start of a run, Flanders detects the project's build and test commands; a command it cannot determine confidently is skipped. For each task, it launches the configured worker, runs build then test, runs the configured adversarial reviewers concurrently, hands any findings they recorded to the error-log reviewer when your configuration holds one — the same pass described in Running a review round — and commits the accepted result. Failed gates brief the next iteration, and reviewers judge the worker's changes against the task and every applicable obligation.

I'm not gonna lie, it is token hungry: the AI may iterate and re-check its work several times to prevent specification drift. When an AI session reaches a rate limit, Flanders retries it periodically and resumes as soon as it recovers. During a CLI implement run, you can also press F5 to retry rate-limited jobs manually.

The spec corpus can contain .spec folders at the project root or deeper in the tree; ignored .spec folders are not part of the corpus. Each folder scopes its containing directory and everything below it:

  • .spec/contracts holds behavior visible across that scope's boundary.
  • .spec/rules holds implementation conventions internal to that scope.
  • .spec/flanders holds behavior rules for Flanders commands and skills working in that scope.
  • The project-root plans/ folder holds project-wide work plans.

/flanders-spec is the entry point for authoring contracts, rules, and behavior rules, while /flanders-plan authors plans. Workers and reviewers may read those files but do not edit them; the CLI's bounded plan-file changes are described in Implementing a plan.

Flanders enforces the practices you put in the corpus. Whether SOLID, a duplication policy, a style guide, or another design, architecture, or code-quality practice governs the project is your decision; Flanders supplies none of its own. Its one built-in discipline is for source comments: workers first make the code express its meaning and reserve comments for constraints, invariants, or consequences the code cannot express.

Requirements

  • Node.js.
  • Claude Code or OpenAI Codex CLI.
  • Git on PATH and a git working tree when running implement, review, task, or /flanders-implement.
  • A logged-in session for every configured AI tool.

The CLI implement command also requires every spec file to be committed and every unstaged change outside the selected plan to be staged or committed before it starts. Staged non-spec changes are allowed and join the first accepted task's commit.

Installation

Install the package from a shell with npm:

npm install --global flanders

Then run setup from the Flanders CLI:

npx flanders install

With no flags, install asks for the skills tool or tools, installation scope, worker, and one or more reviewers. Each worker and reviewer has its own tool, model, effort, and optional Claude fast-mode setting, which is off by default. With multiple reviewers, setup also collects the minimum number that must reach a verdict and which reviewers may be abandoned if they are still rate-limited after the round can complete. By default every reviewer is required.

Setup then asks whether to configure an error-log reviewer, the finding-pruning pass described in Running a review round. It is off by default, and saying yes adds that role's own tool, model, effort, and fast-mode setting. The role takes no part in the weighted-review configuration: the minimum verdict count does not count it, and it cannot be marked optional.

The two mutually exclusive scopes are:

| Flag | Skills | Configuration | | --- | --- | --- | | --project | .claude/skills/ and/or .agents/skills/ in the current project | .flanders/ at the project root | | --global | ~/.claude/skills/ and/or ~/.agents/skills/ | ~/.flanders/ |

For every selected AI tool, install writes the /flanders-spec, /flanders-plan, /flanders-implement, and /flanders-hard-stop-review skill artifacts. Selecting both tools installs the full set for each.

Flags

Every setup answer has a flag equivalent. Omit any flag and install asks for that answer interactively.

| Flag | Meaning | | --- | --- | | --project, --global | Choose one installation scope. | | --skills-tool=<claude\|codex\|claude,codex> | Install skills for one or both supported tools. Values must be distinct. | | --worker-tool=<claude\|codex> | Select the worker tool. | | --worker-model=<value> | Select the worker model; an empty value uses the tool's configured default. | | --worker-effort=<value> | Select the worker effort; an empty value uses the tool's configured default. | | --worker-fast | Enable higher-speed, higher-cost fast mode for a Claude worker whose model supports it. | | --reviewer-tool=<claude\|codex> | Select reviewer 1's tool. | | --reviewer-model=<value> | Select reviewer 1's model; an empty value uses the tool's configured default. | | --reviewer-effort=<value> | Select reviewer 1's effort; an empty value uses the tool's configured default. | | --reviewer-fast | Enable fast mode for reviewer 1 when it uses a supported Claude model. | | --reviewer-N-tool=<claude\|codex> | Select reviewer N's tool, for N starting at 2. | | --reviewer-N-model=<value> | Select reviewer N's model; an empty value uses the tool's configured default. | | --reviewer-N-effort=<value> | Select reviewer N's effort; an empty value uses the tool's configured default. | | --reviewer-N-fast | Enable fast mode for reviewer N when it uses a supported Claude model. | | --reviewer-optional, --reviewer-N-optional | Mark a configured reviewer optional. | | --reviewer-minimum=<value> | Require an integer from 1 through the configured reviewer count to reach a verdict. | | --error-log-reviewer-tool=<claude\|codex> | Select the error-log reviewer's tool. | | --error-log-reviewer-model=<value> | Select the error-log reviewer's model; an empty value uses the tool's configured default. | | --error-log-reviewer-effort=<value> | Select the error-log reviewer's effort; an empty value uses the tool's configured default. | | --error-log-reviewer-fast | Enable fast mode for the error-log reviewer when it uses a supported Claude model. | | --no-error-log-reviewer | Configure the run without an error-log reviewer. |

Reviewer tool, model, and effort flags establish an ordered, contiguous reviewer list starting with reviewer 1. Supplying any of them fixes the list to the indices supplied; fast and optional flags only annotate reviewers already in that list. Weighted-review flags require at least two reviewers, and no reviewer may be optional when the minimum equals the reviewer count. Tool values are restricted to the supported names; model and effort values are accepted verbatim. Fast flags are valid only for Claude roles whose selected model supports fast mode.

Any of the error-log reviewer's tool, model, and effort flags configures that role and answers its yes/no question for you, leaving every field you left unflagged to be asked. --error-log-reviewer-fast only annotates a role those three flags configured, and --no-error-log-reviewer configures the run without the role, so it cannot be combined with the other four.

If the chosen scope already has readable configuration, install uses its stored worker, reviewer, and error-log-reviewer choices as the interactive defaults. Missing, malformed, or unreadable existing configuration falls back to fresh defaults and is replaced by a completed run.

Existing skills and configuration at the destination are overwritten without a prompt or backup. On success, install prints every file it wrote.

Updating

After upgrading the package, refresh installed skills from the Flanders CLI with:

npx flanders update

update takes no flags. It checks every project and global Claude Code and Codex CLI skill destination; wherever it finds at least one Flanders skill, it overwrites the full four-skill set with the current version without a prompt or backup. It does not create a new installation, and it neither reads nor changes .flanders/ configuration. On success it prints every skill file written; if it finds no installation, it exits with a diagnostic directing you to install.

Inspecting applicable specs

To see which spec files govern one or more paths, neighbor, run this from the Flanders CLI:

npx flanders specs [--keywords] <path>...

At least one <path> is required. An existing directory is inspected from that directory; every other path is inspected from its containing directory. Flanders follows each path's ancestors to the filesystem root, excludes git-ignored .spec folders, and prints every governing spec file once. Paths in the output are relative to the current working directory, use / separators, and are ordered by deepest .spec folder first, then by ascending folder and file path. When --keywords is present, each path is followed by a comma-separated list of the file's keywords in declaration order. With no governing specs, the command prints nothing and succeeds. specs reads only the project tree: it does not invoke AI, read Flanders configuration, or write files.

Inspecting a plan

To inspect the task counts in a plan file, neighbor, run this from the Flanders CLI:

npx flanders plan <plan-file>

<plan-file> is required and names the markdown plan to read. The command prints exactly these four lines:

tasks: <n>
open: <n>
done: <n>
malformed: <n>

tasks counts the detected leaf task lines, while open and done count their checkbox states and add up to tasks. malformed counts lines that attempt the task-line shape without conforming to it. A plan with malformed lines or no task lines is reported through these counts and still succeeds. A missing argument or an unreadable file instead produces a diagnostic and a non-zero exit. plan reads only the named file: it does not invoke AI, read Flanders configuration, or create or modify a plan.

Running a review round

To give newly authored specs or a plan an independent once-over, or to put one task's pending work in front of the adversarial reviewers, run one of these from the Flanders CLI:

npx flanders review spec <criteria-file>
npx flanders review plan <plan-file>
npx flanders review implement <task-file>

Each kind takes exactly one file and accepts no options. spec takes the acceptance criteria written for the run under audit, and reads the files it audits from the project's pending change — every addition, modification, deletion, or rename the index or the working tree holds that traverses a .spec folder, minus any path your git ignore rules exclude — so the audit covers what the run actually altered rather than what it claims to have altered. A pending change touching no such spec file leaves nothing under audit and produces a diagnostic. plan takes the plan file to audit. implement takes the file holding a task, and puts the whole pending change of your working tree under review as the work that task had to produce, judged against the task by the same adversarial reviewers the implement command runs over a plan task.

An implement round works in the run folder described in Running one task — the directory that holds the task file — and names it on standard error on every run. Each round leaves its verdict there in a file of its own; a round whose verdict is not empty also writes it into that folder's briefing, so the next pass of the cycle picks it up without you relaying anything, while a clean round leaves no briefing behind.

Every kind requires git, per Requirements. The command runs the configured reviewers concurrently, using each reviewer's tool, model, effort, fast-mode setting, and optionality together with the configured minimum verdict count, and it changes nothing in the project or in git. It prints no progress while they work. A clean verdict produces no standard output and exits successfully; a verdict carrying findings is printed to standard output and produces a non-zero exit. Missing arguments, unreadable files, a missing git working tree, absent configuration, AI invocation errors, and login failures instead produce a diagnostic and a non-zero exit.

With an error-log reviewer in your Flanders configuration, a round whose findings are not empty hands them to that reviewer before anything is reported — on spec, plan, and implement alike. That neighborly second pair of eyes may only take entries out, and only the ones that do not hold up against the work under review or that duplicate another; every entry it keeps stays exactly as it found it. What it leaves is what the round reports: the standard output, the exit code, and — on an implement run — the round's own file and the run folder's briefing all carry it.

Running one task

To run the implementation stages of the task cycle over a single task, neighbor, run this from the Flanders CLI:

npx flanders task implement <task-file>

implement is the action and <task-file> names the file holding the task to implement. Both are required and the command accepts no options. One invocation is one pass over that task: it launches the configured worker, stages what the worker changed, and runs the build and test gates described in How it works. It makes no commit of its own. Counting iterations, running the adversarial reviewers, and committing an accepted result are not part of an invocation; they belong to whatever surface drives the cycle.

The run's state lives in the directory that holds the task file. Point a later invocation at the same task file and it continues that run, briefed by whatever failed last time; a task file in a fresh directory starts a new run instead.

task requires git, per Requirements. A clean pass exits successfully and leaves the work in your tree to review and commit. A failing gate prints its captured output to standard output and exits non-zero, and a worker that declares the task structurally impossible reports the declaration and exits non-zero as well. Every non-zero exit names the run folder on standard error. A missing or unknown action, a missing, doubled, or unreadable task file, a missing git working tree, absent configuration, and a login failure each produce a diagnostic on standard error with nothing on standard output and no briefing left behind, so you can tell them apart from a gate that actually ran.

Configuration

install persists the configured worker and ordered reviewer list, including each role's tool, model, effort, fast-mode setting, reviewer optionality, and the minimum reviewer count. When you configured an error-log reviewer, its tool, model, effort, and fast-mode setting are persisted too; a run configured without one stores nothing for it. The skills-tool choice is used only during installation and is not stored.

When Flanders runs, project configuration takes precedence over global configuration as a complete unit: if the project has .flanders/, Flanders uses it alone; otherwise it uses ~/.flanders/. The two scopes are never merged. Malformed selected configuration is an error; if neither scope has configuration, implement, review, task, and /flanders-implement stop and direct you to npx flanders install.

Usage

Flanders has seven CLI commands—install, update, specs, plan, review, task, and implement—and four skills invoked from inside an AI coding session.

The four skills

The slash forms below name the skills. Invoke each through the skill mechanism provided by Claude Code or Codex CLI; the exact token the tool expects may differ.

/flanders-spec [<data>]
/flanders-plan [<data>]
/flanders-implement [<data>]
/flanders-hard-stop-review [<data>]

For /flanders-spec, /flanders-plan, and /flanders-implement, <data> is the request. Omit it to use the conversation, supply an existing file path to use that file's contents, or supply other text to use it verbatim. For /flanders-implement, file-path <data> does not make a plan file a valid request; see the request-versus-plan boundary. For /flanders-hard-stop-review, <data> is the preserved hard-stop folder path; omit it when the path is already in the conversation.

Skills address you in the language of your latest message when it is determinable, adding the light Flanders touch only in English. For a path-only hard-stop review, the skill falls back to the plan and then the spec corpus for that language. When skills have independent clarification questions, they ask them together; bounded choices use the AI tool's question facility when available. Any report owed before a question is delivered first.

The two content skills gate completion by running the review command under your Flanders configuration.

/flanders-plan and /flanders-implement first confront your request with the specs governing the work it asks for. When the outcome you asked for cannot be delivered while an obligation the corpus already pins stays satisfied, the skill produces nothing: it reports the clash, links the contract or rule your request collides with, and asks whether to launch /flanders-spec to change the spec first or to end the run. A request the corpus does not cover, or one that only tightens an obligation in a way that obligation already allows, passes the check without a word.

  • /flanders-spec classifies a request into contracts, rules, and behavior rules across the appropriate .spec scopes. It asks about unresolved obligations, shows the planned file layout and the effect of changed obligations for approval, and writes only after approval. It updates existing coverage instead of duplicating it, then offers /flanders-plan, /flanders-implement, or neither. When it changes project-root public contracts, it warns that the README may need reconciliation. Written specs use an explicitly requested language, otherwise the existing corpus language, otherwise the request language.
  • /flanders-plan creates exactly one ordered, specification-aware markdown plan in plans/, with complete leaf tasks, acceptance criteria, and markdown links to applicable contracts and rules. Its clarifying questions cover only observable outcomes, scope ambiguities, or unverified runtime premises that the plan cannot reasonably resolve. It writes without a pre-write approval step, reports the plan path, and tells you to implement it from the Flanders CLI. The plan uses the request's language unless you ask otherwise.
  • /flanders-implement follows the shortcut path introduced in How it works. It designs one task from your request, sized by the obligations implementing it triggers rather than by how long the request reads; a request that needs more than one task is not implemented, and it recommends /flanders-plan instead. It commits pending spec changes, then requires the rest of the working tree to be clean: any other pending change stops it so you can commit or discard it. On success it reports what was implemented and that it is committed; its hard-stop behavior is covered in Hard stop.
  • /flanders-hard-stop-review is the read-only recovery skill described in Hard stop.

Implementing a plan

Run from the Flanders CLI:

npx flanders implement [plan]

[plan], when supplied, is a markdown file under plans/. Leave it off and Flanders runs the single plan in plans/, or asks which one to run when plans/ holds more than one. An empty plans/ folder, or a selected plan that is missing, empty, or malformed, produces a startup diagnostic; a plan whose tasks are already complete exits successfully without running a task.

Before work begins, implement checks the plan's shape and the git requirements under Requirements. Once the plan is selected, the run asks no further questions. It streams the worker, build, test, and reviewer output while showing live task and plan progress.

Each open task runs through the cycle described in How it works, with up to five iterations. An accepted task has its checkbox and metrics updated and is committed with its plan number and title. Completing the last task prefixes the plan filename with V-. A hard stop follows the recovery path in Hard stop.

A typical workflow

  1. From the Flanders CLI, run npx flanders install to configure Flanders and install its skills.
  2. From inside an AI coding session, invoke /flanders-spec with the project's obligations and conventions.
  3. From inside an AI coding session, invoke /flanders-plan with the work to plan.
  4. From the Flanders CLI, run npx flanders implement against that plan.

For small work, replace steps 3 and 4 by invoking /flanders-implement from inside the AI coding session.

A worked example

Here is the same path for a calculator that only multiplies and subtracts, neighbor:

  1. From the Flanders CLI, install project-scoped skills and configuration:

    npx flanders install --project
  2. From inside an AI coding session, invoke the spec skill with the requirement:

    /flanders-spec A web calculator with exactly two operations—multiply and subtract—over two number inputs, showing the result. Use teal operation buttons, a white result panel, a slate background, and React bundled by Vite with no other UI framework.
  3. In the same AI coding session, invoke the planning skill after the spec is approved and reviewed:

    /flanders-plan
  4. From the Flanders CLI, implement the resulting plan:

    npx flanders implement
  5. For a later small change, invoke /flanders-spec from inside an AI coding session to add make the result panel use a larger font, then accept its offer to launch /flanders-implement in that session.

Hard stop

When a hard stop happens, hand the preserved folder path that implement prints to the /flanders-hard-stop-review skill from inside an AI coding session. A hard stop ends the run with a non-zero status and occurs for one of three causes:

  • A task exceeds the fixed limit of five iterations.
  • The worker declares that the task is structurally impossible within the work and obligations it was given.
  • A configured AI tool reports that it is not logged in.

For a task stop, implement identifies the plan line and task title; for a worker-declared stop, it also reports the worker's cause, evidence, and proposed unblocking change. A login stop instead tells you which configured tool needs a login and asks you to re-run. The temporary folder is preserved so it can be inspected.

When a stop leaves review findings behind, the next implement run on that project that picks the very same task starts its first iteration from them; picking a different task drops them instead. Either way the new run gets the full five iterations.

/flanders-hard-stop-review reads the folder, the affected plan task, and its specs, then reports the root cause and recommends re-running unchanged, revising the plan through /flanders-plan, fixing the spec through /flanders-spec, or combining those actions. It can offer to launch the appropriate skill, but it does not re-run the Flanders CLI itself.

/flanders-implement uses the same hard-stop causes for its one-request cycle. It diagnoses iteration-cap and worker-declared stops in the same invocation and offers the appropriate next skill; a login failure is reported without diagnosis. Its temporary folder is preserved on every hard stop.