Skip to content

Roadmap

This tracks the full backlog, grouped by theme and ordered by how directly each item serves the core goal: force AI-generated code to conform to your conventions. Shipped items move out of here into the reference pages.

Shipped

  • Pattern matching: declare a file's shape by example (pattern), one template or a list of acceptable shapes.
  • filename: filename conventions + placeholder binding.
  • sameType: fold equal type spellings (React.FCFC).
  • denyImports / allowImports: import path boundaries.
  • unmatched: every source file must be governed (escape-hatch closer).
  • severity, ignore, sourceFiles.
  • Usage rules: disallowElements, disallowCalls, within, except (ban raw <input> / fetch; require the design-system component).
  • belongsHere: inverse check: a file that looks governed must live in the governed folder.
  • Closed export surface: allowExtraExports; flag stray exports.
  • requires: mandatory sibling files.
  • Suppressions: // shapelint-disable-next-line <rule> -- reason.
  • Output formats: human, agent, json, github.
  • CLI: check, fix, new, explain, init.
  • shapelint fix: mechanical autofix: rename symbol; change export form + rewrite importers; rename a file to a filename convention; move a misplaced (belongsHere) file into its governed folder, all with move-aware verify-and- rollback, dry-run by default, refuses a dirty tree without --force.
  • shapelint new <rule> <Name>: scaffold a conforming file from a rule's pattern.
  • requires companions: {stem} token requires a per-file companion (e.g. Button.tsxButton.stories.tsx, orders.module.tsorders.service.ts).
  • --cache: content-hash cache for the pure per-file checks; invalidated by content or config change.
  • shapelint baseline: grandfather existing violations for incremental adoption.
  • Semantic (AI) tier: provider-agnostic judge, opt-in via check --semantic, non-blocking by default, content-hash cached.
  • Naming: repo-wide config naming (files + folders) plus per-rule filename / foldername, with rule-over-config precedence.

Near-term (not yet built)

FeatureWhat it adds
shapelint fix, alias-aware movesRewrite @/… path-alias importers on move (today the verify step refuses a move that would break one).
shapelint fix, stub generationGenerate requires companions / barrel index.ts stubs.
Worker-thread poolParallelize cold runs on very large repos (the --cache already covers warm runs).

Rule-expressiveness long tail (build on demand)

exact: ['members' | 'topLevel'] (closed-world negation) · maxLines · forbid (anti-pattern templates) · importedBy (inverse dependency) · resolveTypes (type-checker-backed comparison, opt-in and slow) · custom(ctx) predicate escape hatch.

Design principles (not future work)

  • Deterministic core. The default check is fully static, reproducible, fast, free, safe to block a build. The semantic tier is strictly opt-in (--semantic), non-blocking by default, and cached, so it advises without compromising the gate.
  • Complements ESLint / tsc, never re-reporting what they already catch.

Later (a separate product surface)

  • init full-repo inference (v2): walk the whole repo, group files by directory, detect the dominant declaration/export shape in each, and generate a config whose rules already match the code. Today init only writes a starter config with an example rule; this would make it genuinely infer one.
  • Agent-loop integration: a general adapter (Claude Code hooks, Cursor, Windsurf) so the gate is unavoidable in-session, not only at CI.
  • MCP server: let an agent query a rule's shape before writing a file.
  • Digest generator: emit a compact AGENTS.md block from the config, so prose and enforcement can't drift.

Preset rule libraries & scoped packages

Today every project authors its own rules from scratch. The next distribution step is a library of predefined, battle-tested rule sets for common stacks, so a project can adopt sensible conventions with one line instead of hand-writing them:

  • Framework/runtime presets: ready-made rules for React, Node, Next.js, NestJS, etc. (component-file shape, hook naming, no data fetching in UI primitives, service/controller layering, import boundaries…).
  • Composable: a config extends one or more presets and overrides or disables individual rules, the same way ESLint shareable configs work.

This is delivered as a flagship-plus-scoped split on npm, the unscoped shapelint engine stays dependency-free, and presets ship under the @shapelint/* scope, opt-in:

PackageContents
shapelintThe engine, defineConfig, the checkers, the CLI. No opinions.
@shapelint/reactPreset rule set for React codebases.
@shapelint/nodePreset rule set for Node services.
@shapelint/…Further stack presets (Next.js, NestJS, …) added on demand.
ts
// shapelint.config.ts (illustrative)
import { defineConfig } from 'shapelint';
import react from '@shapelint/react';

export default defineConfig({
  root: 'src',
  extends: [react.recommended],
  rules: [
    /* project-specific overrides */
  ],
});

The shapelint package stays the engine and CLI; presets publish under the @shapelint/* scope and layer on top, so existing configs keep working.

Released under the MIT License.