@aurelienbbn/agentlint
Version:
Stateless, deterministic CLI that bridges traditional linters and AI-assisted code review
265 lines • 12.2 kB
text/typescript
import { Schema } from "effect";
//#region src/domain/node.d.ts
/**
* 0-indexed position in source text.
*
* Defined as a `Schema.Struct` so positions can be decoded and
* validated from external sources if needed.
*
* @since 0.1.0
* @category models
*/
declare const Position: Schema.Struct<{
readonly row: Schema.Number;
readonly column: Schema.Number;
}>;
/** @since 0.1.0 */
type Position = Schema.Schema.Type<typeof Position>;
/**
* Read-only view of a syntax tree node.
*
* One universal type — no per-kind subtypes. Rules narrow via
* `node.type` string checks and field accessors.
*
* @since 0.1.0
* @category models
*/
interface AgentReviewNode {
/** tree-sitter grammar node type (e.g. `"function_declaration"`, `"comment"`) */
readonly type: string;
/** Full source text covered by this node. */
readonly text: string;
/** 0-indexed start position. */
readonly startPosition: Position;
/** 0-indexed end position. */
readonly endPosition: Position;
/** Whether this is a named node in the grammar. */
readonly isNamed: boolean;
/** Direct child nodes (lazily wrapped). */
readonly children: ReadonlyArray<AgentReviewNode>;
/** Parent node, or null for the root. */
readonly parent: AgentReviewNode | null;
/** Number of direct children. */
readonly childCount: number;
/** Get a child by its grammar field name (e.g. `"name"`, `"body"`). */
childByFieldName(name: string): AgentReviewNode | null;
/** All direct children matching the given node type. */
childrenByType(type: string): ReadonlyArray<AgentReviewNode>;
/** Recursively collect all descendants matching the given node type. */
descendantsOfType(type: string): ReadonlyArray<AgentReviewNode>;
}
//#endregion
//#region src/domain/node-types.d.ts
/**
* Generated from tree-sitter-typescript's `node-types.json`.
* Provides autocomplete for visitor keys in {@link Visitors}.
*
* @module
* @since 0.1.0
*/
/**
* Named node types from the tree-sitter TypeScript/TSX grammar.
*
* @since 0.1.0
* @category models
*/
type TreeSitterNodeType = "abstract_class_declaration" | "abstract_method_signature" | "accessibility_modifier" | "ambient_declaration" | "arguments" | "array" | "array_pattern" | "array_type" | "arrow_function" | "as_expression" | "assignment_expression" | "assignment_pattern" | "augmented_assignment_expression" | "await_expression" | "binary_expression" | "break_statement" | "call_expression" | "call_signature" | "catch_clause" | "class" | "class_body" | "class_declaration" | "class_heritage" | "class_static_block" | "comment" | "computed_property_name" | "conditional_type" | "construct_signature" | "constructor_type" | "continue_statement" | "debugger_statement" | "decorator" | "default_type" | "do_statement" | "else_clause" | "empty_statement" | "enum_assignment" | "enum_body" | "enum_declaration" | "escape_sequence" | "export_clause" | "export_specifier" | "export_statement" | "expression_statement" | "extends_clause" | "extends_type_clause" | "false" | "finally_clause" | "for_in_statement" | "for_statement" | "formal_parameters" | "function_declaration" | "function_expression" | "function_signature" | "function_type" | "generator_function" | "generator_function_declaration" | "generic_type" | "hash_bang_line" | "identifier" | "if_statement" | "implements_clause" | "import" | "import_alias" | "import_attribute" | "import_clause" | "import_require_clause" | "import_specifier" | "import_statement" | "index_signature" | "index_type_query" | "infer_type" | "instantiation_expression" | "interface_body" | "interface_declaration" | "internal_module" | "intersection_type" | "labeled_statement" | "lexical_declaration" | "literal_type" | "lookup_type" | "mapped_type_clause" | "member_expression" | "meta_property" | "method_definition" | "method_signature" | "module" | "named_imports" | "namespace_export" | "namespace_import" | "nested_identifier" | "nested_type_identifier" | "new_expression" | "non_null_expression" | "null" | "number" | "object" | "object_assignment_pattern" | "object_pattern" | "object_type" | "optional_parameter" | "optional_type" | "override_modifier" | "pair" | "pair_pattern" | "parenthesized_expression" | "parenthesized_type" | "predefined_type" | "private_property_identifier" | "program" | "property_identifier" | "property_signature" | "public_field_definition" | "readonly_type" | "regex" | "regex_flags" | "regex_pattern" | "required_parameter" | "rest_pattern" | "rest_type" | "return_statement" | "satisfies_expression" | "sequence_expression" | "shorthand_property_identifier" | "shorthand_property_identifier_pattern" | "spread_element" | "statement_block" | "string" | "string_fragment" | "subscript_expression" | "super" | "switch_body" | "switch_case" | "switch_default" | "switch_statement" | "template_literal_type" | "template_string" | "template_substitution" | "template_type" | "ternary_expression" | "this" | "this_type" | "throw_statement" | "true" | "try_statement" | "tuple_type" | "type_alias_declaration" | "type_annotation" | "type_arguments" | "type_assertion" | "type_identifier" | "type_parameter" | "type_parameters" | "type_predicate" | "type_predicate_annotation" | "type_query" | "unary_expression" | "undefined" | "union_type" | "update_expression" | "variable_declaration" | "variable_declarator" | "while_statement" | "with_statement" | "yield_expression" | "jsx_attribute" | "jsx_closing_element" | "jsx_element" | "jsx_expression" | "jsx_fragment" | "jsx_namespace_name" | "jsx_opening_element" | "jsx_self_closing_element" | "jsx_text";
//#endregion
//#region src/domain/flag.d.ts
/**
* Options passed to `context.flag()` by rule visitors.
*
* @since 0.1.0
* @category models
*/
interface FlagOptions {
/** The AST node that triggered the match. */
readonly node: AgentReviewNode;
/** Short one-liner displayed next to file:line in output. */
readonly message: string;
/**
* Override `meta.instruction` for this specific match.
* Appears inline in per-match notes.
*/
readonly instruction?: string | undefined;
/** Hint toward the fix. Not a command - just a nudge. */
readonly suggest?: string | undefined;
}
declare const FlagRecord_base: Schema.Class<FlagRecord, Schema.Struct<{
readonly ruleName: Schema.String;
readonly filename: Schema.String; /** 1-based line number. */
readonly line: Schema.Number; /** 1-based column number. */
readonly col: Schema.Number;
readonly message: Schema.String;
readonly sourceSnippet: Schema.String; /** 7-char hex hash for stable match identification. */
readonly hash: Schema.String;
readonly instruction: Schema.UndefinedOr<Schema.String>;
readonly suggest: Schema.UndefinedOr<Schema.String>;
}>, {}>;
/**
* Enriched flag record after processing — ready for the reporter.
*
* Uses `Schema.Class` for structural equality AND runtime validation
* on construction — invalid fields throw a clear `ParseError`.
*
* @since 0.1.0
* @category models
*/
declare class FlagRecord extends FlagRecord_base {}
//#endregion
//#region src/domain/rule-context.d.ts
/**
* Context object passed to `createOnce`. Available throughout the rule's lifecycle.
*
* @since 0.1.0
* @category models
*/
interface RuleContext {
/** Absolute path of the current file being analyzed. */
getFilename(): string;
/** Full source content of the current file. */
getSourceCode(): string;
/**
* Lines around the given 1-based line number, formatted with line numbers.
* @param line 1-based line number
* @param radius number of lines above/below to include (default 10)
*/
getLinesAround(line: number, radius?: number): string;
/** Record a match for the output report. */
flag(options: FlagOptions): void;
}
//#endregion
//#region src/domain/rule.d.ts
/**
* Static metadata for a rule.
*
* Defined as a `Schema.Struct` so that rule metadata is validated at
* runtime when `defineRule` is called — catches typos, missing fields,
* and wrong types with clear error messages.
*
* @since 0.1.0
* @category models
*/
declare const RuleMeta: Schema.Struct<{
/** Unique identifier. kebab-case. Used in output and --rule filtering. */readonly name: Schema.String; /** One-liner explaining what the rule checks. */
readonly description: Schema.String; /** File extensions this rule applies to, without the dot. e.g. `["ts", "tsx"]` */
readonly languages: Schema.$Array<Schema.String>;
/**
* Natural language instruction for the calling AI agent.
* Defines pass/fail criteria and how to evaluate flagged matches.
*/
readonly instruction: Schema.String; /** If provided, rule only runs on files matching these globs (after global filtering). */
readonly include: Schema.optional<Schema.$Array<Schema.String>>; /** If provided, files matching these globs are excluded from this rule. */
readonly ignore: Schema.optional<Schema.$Array<Schema.String>>;
}>;
/** @since 0.1.0 */
type RuleMeta = Schema.Schema.Type<typeof RuleMeta>;
/**
* Callback invoked when a matching AST node type is visited.
*
* @since 0.1.0
* @category models
*/
type VisitorHandler = (node: AgentReviewNode) => void;
/**
* Visitor object returned by `createOnce`.
*
* Maps tree-sitter node type strings to handler functions.
* Known node types provide autocomplete; any string is accepted.
*
* @since 0.1.0
* @category models
*/
type Visitors = {
/**
* Called once before each file is traversed.
* Return `false` to skip this file entirely for this rule.
*/
before?: ((filename: string) => boolean | void) | undefined;
/**
* Called once after all files have been visited.
* Use for aggregate analysis.
*/
after?: (() => void) | undefined;
} & { [K in TreeSitterNodeType]?: VisitorHandler } & {
[nodeType: string]: VisitorHandler | ((filename: string) => boolean | void) | (() => void) | undefined;
};
/**
* A complete rule definition.
*
* @since 0.1.0
* @category models
*/
interface AgentReviewRule {
readonly meta: RuleMeta;
/**
* Called once per agentlint run (not per file).
* The returned visitor object is reused across files.
* Per-file state must be reset in `before()`.
*/
readonly createOnce: (context: RuleContext) => Visitors;
}
/**
* Identity function that provides type inference and IDE support for rule definitions.
*
* @example
* ```ts
* import { defineRule } from "agentlint"
*
* export const myRule = defineRule({
* meta: {
* name: "my-rule",
* description: "Checks for something",
* languages: ["ts", "tsx"],
* instruction: "Evaluate whether ..."
* },
* createOnce(context) {
* return {
* comment(node) {
* context.flag({ node, message: "Found comment" })
* }
* }
* }
* })
* ```
*
* @since 0.1.0
* @category constructors
*/
declare function defineRule(rule: AgentReviewRule): AgentReviewRule;
//#endregion
//#region src/domain/config.d.ts
/**
* Top-level configuration schema for `agentlint.config.ts`.
*
* @since 0.1.0
* @category models
*/
interface AgentReviewConfig {
/** Rule registry. Keys are kebab-case names used in output and `--rule` filtering. */
readonly rules: Record<string, AgentReviewRule>;
/** If provided, only files matching at least one pattern are scanned. */
readonly include?: ReadonlyArray<string> | undefined;
/** Files matching any pattern are excluded (merged with built-in defaults). */
readonly ignore?: ReadonlyArray<string> | undefined;
}
/**
* Identity function that provides type inference and IDE support for config files.
*
* @example
* ```ts
* import { defineConfig } from "agentlint"
*
* export default defineConfig({
* include: ["src/**\/*.ts"],
* rules: { "my-rule": myRule }
* })
* ```
*
* @since 0.1.0
* @category constructors
*/
declare function defineConfig(config: AgentReviewConfig): AgentReviewConfig;
//#endregion
export { type AgentReviewConfig, type AgentReviewNode, type AgentReviewRule, type FlagOptions, FlagRecord, Position, type RuleContext, RuleMeta, type TreeSitterNodeType, type VisitorHandler, type Visitors, defineConfig, defineRule };
//# sourceMappingURL=index.d.mts.map