Skip to content

TypeScript rules

112 rules across 23 categories, enforced by chisel-js.

agent · 1 rule

An agent tool or protocol server constructed outside the declared tool adapters

Fix. Build tools through the adapter listed in agent.toolAdapters, which applies the shared approval and feedback policy.

architecture · 12 rules

Prohibited behaviour reached through an alias, barrel, namespace import, wrapper or injected function port; or an entry point calling a service, repository or store

Fix. Put the application operation in a controller and inject the narrow capability there. An entry point parses its input and calls controller operations.

An exported service function or callable, or a public service member outside its implemented contract

Fix. Expose one cohesive class capability through its interface; keep helpers private. A test does not justify a public helper.

A public service class without explicit interface contracts, including alias and default exports

Fix. Declare the capability callers need and implements it.

A concrete implementation used as a dependency type, including through aliases, utility types and inferred factory results

Fix. Depend on the declared contract. Pick<ConcreteService, …> is still the concrete class, and a factory’s public results need interface annotations; satisfies keeps the inferred concrete type.

A controller invoking another controller, through an interface, alias, getter or callback

Fix. Coordinate the underlying services in the owning controller. Shared data types belong in models.

A controller calling a repository, directly or through an injected port typed as one

Fix. Put a service between them. The service owns the reads and writes and the rules around them.

A controller result exposing a service, transport, repository or writable store

Fix. Return operation results or readonly state views, never the collaborators that produced them.

Mutable service fields, module state or captured state that survive an operation

Fix. Keep values local to the operation. State that must outlive it is a database record on the server and a store in the browser.

A store invoking a capability or network transport, directly or through a traced callback

Fix. A store applies controlled updates. Let a controller do the work and write the result.

A factory executing a capability, including inside a callback it returns

Fix. Construct and connect dependencies only. Execution belongs to a controller, called by an entry point.

An agent tool calling a service, repository or store instead of a controller operation

Fix. Wrap the one public controller operation the tool stands for. When none exists, give the controller an ordinary operation any entry point could call.

Source or a local module the analyzer cannot inspect

Fix. Repair the syntax or the module path. An incomplete scan is not a passing one.

bundle · 1 rule

A client chunk containing application code exceeds the size budget

Fix. Split the route or import the heavy part dynamically. Vendor-only chunks are tolerated as a known cost; a chunk mixing application code is a regression. Requires a production build — run chisel-js bundle after building.

checker · 1 rule

A file that does not parse, so rules reading its syntax skipped it

Fix. Fix the syntax error the message names. Until then the file is checked by import and path rules only, and a violation inside it cannot be reported.

coherence · 2 rules

A test-runner include pattern matches no files

Fix. Fix the pattern or delete it. A glob matching nothing means part of the suite stopped running and CI stayed green — the one failure mode the test suite cannot report itself.

Maintained documentation cites a path that does not exist

Fix. Update the reference or remove it. Checked in root and docs/ markdown; generated API references and build output are excluded. A path the repository gitignores is a file the project creates at run time, such as a cached login, so it is allowed to be absent.

colour-enforcement · 4 rules

Arbitrary Tailwind colour value syntax (bg-[…], text-[#…], border-[…], etc.)

Fix. Add the colour as a CSS custom property in app.css first, then reference it as a Tailwind token (e.g. bg-primary).

Hardcoded Tailwind palette colour (text-red-500, bg-slate-800, from-blue-500)

Fix. Use a semantic token from app.css (bg-background, text-muted-foreground, text-destructive). A palette class pins one appearance and cannot follow the theme, so it looks wrong in whichever mode it was not written for.

Dynamic class construction (class={bg-${variable}})

Fix. Use a lookup object of pre-approved token names instead: const colourMap = { primary: ‘bg-primary’ }.

Experimental modifier class on semantic HTML

Fix. Modifier classes (.glass, .neumorphic) restricted to Hero components and Overlay widgets.

component-enforcement · 24 rules

Raw