Diagnostics
The diagnostic is the product. While shapelint fix mechanically handles symbol renames, export conversions, and file moves, architectural shape corrections are actioned by the agent (or you). Each message is designed to be actioned in a single pass, without opening the config.
Anatomy of a finding
src/components/ui/Card.tsx:5:1 error shapelint/ui-component ARCH_NAME_MISMATCH
Interface is named "Props" but this rule requires the literal name "IProps".
$Name = Card
expected interface IProps {}
actual interface Props {}
pattern
interface IProps {}
const $Name: React.FC<IProps> = () => {}
export default $Name
hint Primitives are presentational, lift data access into a block.Every finding carries:
- Location:
file:line:col, plus the rule name and a stable code. - Message: one sentence stating the exact defect.
- Bindings: resolved placeholders (
$Name = Card), so there's no ambiguity about what the hole matched. - expected / actual: the required shape versus what's there.
- pattern: the rule's template, echoed inline. The fixer never has to open
shapelint.config.ts. - hint: the rule's optional fix guidance.
Design choices that matter
- Pairing over precision. When a props interface is named
Propsinstead ofIProps, Shapelint pairs the two and reports a rename, rather than emitting "IProps missing" and "Props unexpected". One actionable message beats two technically-correct ones. - Capped at 3 per file. A wall of a dozen findings makes a fixer thrash. Extra findings are summarized as
(N more, hidden, rerun after fixing the above); they surface on the next run once the first batch is resolved. - Summary line. A run ends with a count:
5 errors in 2 files.
Diagnostic codes
| Code | Meaning |
|---|---|
ARCH_MISSING_DECL | A declaration the pattern requires is absent from the file. |
ARCH_NAME_MISMATCH | A declaration has the wrong name, or violates placeholder casing. |
ARCH_KIND_MISMATCH | Right name, wrong kind (e.g. a function where a const is required). |
ARCH_EXPORT_FORM | The declaration is exported in the wrong form. |
ARCH_TYPE_MISMATCH | A type annotation the pattern states doesn't match. |
ARCH_NAME_AFFIX_MISMATCH | A name is missing the literal prefix/suffix an affix hole requires (${Name}Controller). |
ARCH_NAME_CORRELATION_MISMATCH | Two case spellings of one hole (filename / symbols) are different words. |
ARCH_MISSING_DECORATOR | A class is missing a decorator the pattern names (or none carries the anchored decorator). |
ARCH_MEMBER_PATTERN | A member matched a methods selector but lacks a required decorator. |
ARCH_MEMBER_DECORATOR_GROUP | A member violates a methods oneOf (exactly one) / anyOf (at least one) group. |
ARCH_CONSTRUCTOR_CONTRACT | A class violates the inject constructor contract (required params or injected types). |
ARCH_MEMBER_CORRELATION | An optionalNames member is misnamed, or a pairWith counterpart is missing. |
ARCH_DECORATOR_ARG | A decorator argument violates its decoratorArgs convention or filename correlation. |
ARCH_NAME_PLURALITY | A ${Name:singular}/${Name:plural} hole has the wrong grammatical number (plural-aware correlation). |
ARCH_BARREL_INCOMPLETE | A barrel index doesn't re-export a sibling matching mustReexport. |
ARCH_CARDINALITY | A folder violates a contains cardinality (exactly-one / at-most-one / at-least-one). |
ARCH_LAYER_VIOLATION | An import crosses a boundary the config-level layers graph forbids. |
ARCH_FILENAME_MISMATCH | The basename violates the rule's filename or config naming.files. |
ARCH_FOLDERNAME_MISMATCH | A folder name violates foldername or config naming.folders. |
ARCH_DENIED_IMPORT | An import violates denyImports / allowImports. |
ARCH_DISALLOWED_ELEMENT | A banned JSX element/component was used. |
ARCH_DISALLOWED_CALL | A banned function call was used. |
ARCH_BODY_ORDER | A statement inside a body violates the rule's bodyOrder. |
ARCH_BODY_INTRA_SPACING | Statements within the same bodyOrder group have unwanted blank lines between them. |
ARCH_BODY_INTER_SPACING | Statements between distinct bodyOrder groups lack required blank line separation. |
ARCH_MEMBER_ORDER | A class member is out of the rule's memberOrder group order. |
ARCH_EXTRA_EXPORT | An export the pattern didn't declare (closed export surface). |
ARCH_MISSING_SIBLING | A requires sibling file is absent. |
ARCH_MISPLACED_FILE | A file matching a rule's belongsHere lives in the wrong place. |
ARCH_UNMATCHED_FILE | No rule claims this file and unmatched is not 'ignore'. |
ARCH_SUPPRESS_NO_REASON | A suppression comment is missing its mandatory -- reason. |
ARCH_SEMANTIC | A semantic (AI) criterion failed. warn unless the rule sets blocking. |
Codes are stable and greppable, safe to key CI logic or suppressions on.
Suppressions
Suppress a finding inline, with a mandatory reason (a reasonless suppression is itself an error, ARCH_SUPPRESS_NO_REASON):
// shapelint-disable-next-line ui-component -- legacy modal, tracked in TICKET-123
export const LegacyModal = () => null;Forms: shapelint-disable-next-line, shapelint-disable-line, shapelint-disable-file. Name one or more rules after the directive, or omit to cover all rules.
Output for agents
--format agent emits the text form with color stripped, for piping into a model. --format json emits the same content structured. Today the CLI emits the human/agent text form (with color when the terminal supports it).