{"version":3,"file":"index.mjs","names":[],"sources":["../src/domain/rule.ts","../src/domain/config.ts"],"sourcesContent":["/**\n * Rule definition types and the `defineRule` helper.\n *\n * A rule is a reusable lint check defined by {@link RuleMeta} (what to check)\n * and a `createOnce` factory (how to check it). The factory returns a\n * {@link Visitors} object whose keys are tree-sitter node types.\n *\n * @module\n * @since 0.1.0\n */\n\nimport { Schema } from \"effect\";\nimport type { AgentReviewNode } from \"./node.js\";\nimport type { TreeSitterNodeType } from \"./node-types.js\";\nimport type { RuleContext } from \"./rule-context.js\";\n\n/**\n * Static metadata for a rule.\n *\n * Defined as a `Schema.Struct` so that rule metadata is validated at\n * runtime when `defineRule` is called — catches typos, missing fields,\n * and wrong types with clear error messages.\n *\n * @since 0.1.0\n * @category models\n */\nexport const RuleMeta = Schema.Struct({\n  /** Unique identifier. kebab-case. Used in output and --rule filtering. */\n  name: Schema.String,\n  /** One-liner explaining what the rule checks. */\n  description: Schema.String,\n  /** File extensions this rule applies to, without the dot. e.g. `[\"ts\", \"tsx\"]` */\n  languages: Schema.Array(Schema.String),\n  /**\n   * Natural language instruction for the calling AI agent.\n   * Defines pass/fail criteria and how to evaluate flagged matches.\n   */\n  instruction: Schema.String,\n  /** If provided, rule only runs on files matching these globs (after global filtering). */\n  include: Schema.optional(Schema.Array(Schema.String)),\n  /** If provided, files matching these globs are excluded from this rule. */\n  ignore: Schema.optional(Schema.Array(Schema.String)),\n});\n\n/** @since 0.1.0 */\nexport type RuleMeta = Schema.Schema.Type<typeof RuleMeta>;\n\n/**\n * Callback invoked when a matching AST node type is visited.\n *\n * @since 0.1.0\n * @category models\n */\nexport type VisitorHandler = (node: AgentReviewNode) => void;\n\n/**\n * Visitor object returned by `createOnce`.\n *\n * Maps tree-sitter node type strings to handler functions.\n * Known node types provide autocomplete; any string is accepted.\n *\n * @since 0.1.0\n * @category models\n */\nexport type Visitors = {\n  /**\n   * Called once before each file is traversed.\n   * Return `false` to skip this file entirely for this rule.\n   */\n  before?: ((filename: string) => boolean | void) | undefined;\n  /**\n   * Called once after all files have been visited.\n   * Use for aggregate analysis.\n   */\n  after?: (() => void) | undefined;\n} & { [K in TreeSitterNodeType]?: VisitorHandler } & {\n  [nodeType: string]: VisitorHandler | ((filename: string) => boolean | void) | (() => void) | undefined;\n};\n\n/**\n * A complete rule definition.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface AgentReviewRule {\n  readonly meta: RuleMeta;\n  /**\n   * Called once per agentlint run (not per file).\n   * The returned visitor object is reused across files.\n   * Per-file state must be reset in `before()`.\n   */\n  readonly createOnce: (context: RuleContext) => Visitors;\n}\n\n/**\n * Identity function that provides type inference and IDE support for rule definitions.\n *\n * @example\n * ```ts\n * import { defineRule } from \"agentlint\"\n *\n * export const myRule = defineRule({\n *   meta: {\n *     name: \"my-rule\",\n *     description: \"Checks for something\",\n *     languages: [\"ts\", \"tsx\"],\n *     instruction: \"Evaluate whether ...\"\n *   },\n *   createOnce(context) {\n *     return {\n *       comment(node) {\n *         context.flag({ node, message: \"Found comment\" })\n *       }\n *     }\n *   }\n * })\n * ```\n *\n * @since 0.1.0\n * @category constructors\n */\nexport function defineRule(rule: AgentReviewRule): AgentReviewRule {\n  Schema.decodeUnknownSync(RuleMeta)(rule.meta);\n  return rule;\n}\n","/**\n * Configuration types and the `defineConfig` helper.\n *\n * A config file (`agentlint.config.ts`) default-exports an {@link AgentReviewConfig}\n * object that maps rule names to rule definitions and optionally scopes which\n * files are scanned.\n *\n * @module\n * @since 0.1.0\n */\n\nimport { Schema } from \"effect\";\nimport type { AgentReviewRule } from \"./rule.js\";\nimport { RuleMeta } from \"./rule.js\";\n\n/**\n * Top-level configuration schema for `agentlint.config.ts`.\n *\n * @since 0.1.0\n * @category models\n */\nexport interface AgentReviewConfig {\n  /** Rule registry. Keys are kebab-case names used in output and `--rule` filtering. */\n  readonly rules: Record<string, AgentReviewRule>;\n  /** If provided, only files matching at least one pattern are scanned. */\n  readonly include?: ReadonlyArray<string> | undefined;\n  /** Files matching any pattern are excluded (merged with built-in defaults). */\n  readonly ignore?: ReadonlyArray<string> | undefined;\n}\n\n/**\n * Identity function that provides type inference and IDE support for config files.\n *\n * @example\n * ```ts\n * import { defineConfig } from \"agentlint\"\n *\n * export default defineConfig({\n *   include: [\"src/**\\/*.ts\"],\n *   rules: { \"my-rule\": myRule }\n * })\n * ```\n *\n * @since 0.1.0\n * @category constructors\n */\nexport function defineConfig(config: AgentReviewConfig): AgentReviewConfig {\n  for (const rule of Object.values(config.rules)) {\n    Schema.decodeUnknownSync(RuleMeta)(rule.meta);\n  }\n  return config;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,WAAW,OAAO,OAAO;CAEpC,MAAM,OAAO;CAEb,aAAa,OAAO;CAEpB,WAAW,OAAO,MAAM,OAAO,OAAO;CAKtC,aAAa,OAAO;CAEpB,SAAS,OAAO,SAAS,OAAO,MAAM,OAAO,OAAO,CAAC;CAErD,QAAQ,OAAO,SAAS,OAAO,MAAM,OAAO,OAAO,CAAC;CACrD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgFF,SAAgB,WAAW,MAAwC;AACjE,QAAO,kBAAkB,SAAS,CAAC,KAAK,KAAK;AAC7C,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9ET,SAAgB,aAAa,QAA8C;AACzE,MAAK,MAAM,QAAQ,OAAO,OAAO,OAAO,MAAM,CAC5C,QAAO,kBAAkB,SAAS,CAAC,KAAK,KAAK;AAE/C,QAAO"}