UNPKG

@aurelienbbn/agentlint

Version:

Stateless, deterministic CLI that bridges traditional linters and AI-assisted code review

265 lines 12.2 kB
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