@webpieces/ai-hook-rules 0.3.185 → 0.3.187
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -4
- package/src/core/custom-rule-adapter.d.ts +21 -0
- package/src/core/custom-rule-adapter.js +48 -0
- package/src/core/custom-rule-adapter.js.map +1 -0
- package/src/core/load-rules.d.ts +3 -2
- package/src/core/load-rules.js +71 -50
- package/src/core/load-rules.js.map +1 -1
- package/src/core/rule-base.d.ts +38 -0
- package/src/core/rule-base.js +36 -0
- package/src/core/rule-base.js.map +1 -0
- package/src/core/rules/branch-creation-guard.d.ts +12 -3
- package/src/core/rules/branch-creation-guard.js +37 -37
- package/src/core/rules/branch-creation-guard.js.map +1 -1
- package/src/core/rules/catch-error-pattern.d.ts +10 -3
- package/src/core/rules/catch-error-pattern.js +26 -26
- package/src/core/rules/catch-error-pattern.js.map +1 -1
- package/src/core/rules/max-file-lines.d.ts +13 -3
- package/src/core/rules/max-file-lines.js +14 -15
- package/src/core/rules/max-file-lines.js.map +1 -1
- package/src/core/rules/merge-in-progress-guard.d.ts +9 -3
- package/src/core/rules/merge-in-progress-guard.js +12 -13
- package/src/core/rules/merge-in-progress-guard.js.map +1 -1
- package/src/core/rules/no-any-unknown.d.ts +10 -3
- package/src/core/rules/no-any-unknown.js +14 -13
- package/src/core/rules/no-any-unknown.js.map +1 -1
- package/src/core/rules/no-destructure.d.ts +13 -3
- package/src/core/rules/no-destructure.js +13 -12
- package/src/core/rules/no-destructure.js.map +1 -1
- package/src/core/rules/no-direct-main-update.d.ts +9 -3
- package/src/core/rules/no-direct-main-update.js +12 -13
- package/src/core/rules/no-direct-main-update.js.map +1 -1
- package/src/core/rules/no-edit-on-main.d.ts +13 -3
- package/src/core/rules/no-edit-on-main.js +14 -14
- package/src/core/rules/no-edit-on-main.js.map +1 -1
- package/src/core/rules/no-implicit-any.d.ts +10 -3
- package/src/core/rules/no-implicit-any.js +12 -12
- package/src/core/rules/no-implicit-any.js.map +1 -1
- package/src/core/rules/no-js-files.d.ts +13 -3
- package/src/core/rules/no-js-files.js +13 -16
- package/src/core/rules/no-js-files.js.map +1 -1
- package/src/core/rules/no-shell-substitution.d.ts +9 -3
- package/src/core/rules/no-shell-substitution.js +22 -23
- package/src/core/rules/no-shell-substitution.js.map +1 -1
- package/src/core/rules/no-symbol-di-tokens.d.ts +13 -3
- package/src/core/rules/no-symbol-di-tokens.js +14 -13
- package/src/core/rules/no-symbol-di-tokens.js.map +1 -1
- package/src/core/rules/no-unmanaged-exceptions.d.ts +10 -3
- package/src/core/rules/no-unmanaged-exceptions.js +17 -17
- package/src/core/rules/no-unmanaged-exceptions.js.map +1 -1
- package/src/core/rules/pr-creation-guard.d.ts +9 -3
- package/src/core/rules/pr-creation-guard.js +12 -13
- package/src/core/rules/pr-creation-guard.js.map +1 -1
- package/src/core/rules/pr-merge-cleanup.d.ts +9 -3
- package/src/core/rules/pr-merge-cleanup.js +13 -14
- package/src/core/rules/pr-merge-cleanup.js.map +1 -1
- package/src/core/rules/require-return-type.d.ts +10 -3
- package/src/core/rules/require-return-type.js +23 -23
- package/src/core/rules/require-return-type.js.map +1 -1
- package/src/core/rules/throw-cause-required.d.ts +10 -3
- package/src/core/rules/throw-cause-required.js +12 -12
- package/src/core/rules/throw-cause-required.js.map +1 -1
- package/src/core/rules/validate-ts-in-src.d.ts +14 -3
- package/src/core/rules/validate-ts-in-src.js +15 -18
- package/src/core/rules/validate-ts-in-src.js.map +1 -1
- package/src/core/runner.js +38 -67
- package/src/core/runner.js.map +1 -1
- package/src/core/types.d.ts +14 -13
- package/src/core/types.js.map +1 -1
- package/src/index.d.ts +21 -1
- package/src/index.js +47 -1
- package/src/index.js.map +1 -1
- package/src/core/configs/default.d.ts +0 -2
- package/src/core/configs/default.js +0 -22
- package/src/core/configs/default.js.map +0 -1
package/src/core/runner.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/runner.ts"],"names":[],"mappings":"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","sourcesContent":["import * as path from 'path';\n\nimport { shouldSkipRule } from '@webpieces/rules-config';\n\nimport { buildContexts, buildBashContext } from './build-context';\nimport { loadConfig } from './load-config';\nimport { loadRules, globMatches } from './load-rules';\nimport { toError } from './to-error';\nimport { formatReport } from './report';\nimport {\n ToolKind, NormalizedToolInput, BlockedResult,\n Rule, EditRule, FileRule, BashRule, Violation, RuleGroup,\n EditContext, FileContext, BashContext,\n ResolvedConfig, ResolvedRuleConfig, RuleOptions,\n} from './types';\n\nexport function run(\n toolKind: ToolKind,\n input: NormalizedToolInput,\n cwd: string,\n): BlockedResult | null {\n return runInternal(toolKind, input, cwd);\n}\n\nfunction runInternal(\n toolKind: ToolKind,\n input: NormalizedToolInput,\n cwd: string,\n): BlockedResult | null {\n const config = loadConfig(cwd);\n if (!config.configPath) {\n return new BlockedResult(\n 'webpieces.config.json not found.\\n' +\n 'Tell the human: run `./node_modules/.bin/wp-setup-ai-hooks` to initialize the project configuration.\\n' +\n 'Do not proceed until the human has done this.',\n );\n }\n\n const workspaceRoot = path.dirname(config.configPath);\n\n // Always allow edits to webpieces.config.json — it's the fix target when out of sync\n if (path.resolve(input.filePath) === path.resolve(config.configPath)) {\n return null;\n }\n\n const rules = loadRules(config, workspaceRoot);\n if (rules.length === 0) return null;\n\n const outOfSync = checkConfigSync(rules, config);\n if (outOfSync) return outOfSync;\n\n const contexts = buildContexts(toolKind, input, workspaceRoot);\n const relativePath = path.relative(workspaceRoot, input.filePath);\n\n const editGroups = runEditRules(rules, contexts.editContexts, config);\n const fileGroups = runFileRules(rules, contexts.fileContext, config);\n const allGroups = [...editGroups, ...fileGroups];\n\n if (allGroups.length === 0) return null;\n\n const report = formatReport(relativePath, allGroups);\n return new BlockedResult(report);\n}\n\nexport function runBash(command: string, cwd: string): BlockedResult | null {\n return runBashInternal(command, cwd);\n}\n\nfunction runBashInternal(command: string, cwd: string): BlockedResult | null {\n const config = loadConfig(cwd);\n if (!config.configPath) {\n return new BlockedResult(\n 'webpieces.config.json not found.\\n' +\n 'Tell the human: run `./node_modules/.bin/wp-setup-ai-hooks` to initialize the project configuration.\\n' +\n 'Do not proceed until the human has done this.',\n );\n }\n\n const workspaceRoot = path.dirname(config.configPath);\n const rules = loadRules(config, workspaceRoot);\n if (rules.length === 0) return null;\n\n const outOfSync = checkConfigSync(rules, config);\n if (outOfSync) return outOfSync;\n\n const ctx = buildBashContext(command, workspaceRoot);\n const groups = runBashRules(rules, ctx, config);\n if (groups.length === 0) return null;\n\n const report = formatReport('<bash>', groups);\n return new BlockedResult(report);\n}\n\nfunction checkConfigSync(rules: readonly Rule[], config: ResolvedConfig): BlockedResult | null {\n const unconfiguredRules = rules.filter((r: Rule) => !config.userConfiguredRuleNames.has(r.name));\n if (unconfiguredRules.length === 0) return null;\n\n const lines = [\n 'webpieces.config.json is out of sync — new built-in rules are present that have no entry in webpieces.config.json.',\n '',\n 'Tell the human: the following rules need to be configured. Ask for each one:',\n ' - Should this rule be ON, OFF, MODIFIED_CODE, or MODIFIED_FILES?',\n ' - What values do you want for the options listed below?',\n 'Then update webpieces.config.json and retry.',\n '',\n 'Do NOT proceed until webpieces.config.json has an entry for every rule below.',\n '',\n ];\n\n for (const rule of unconfiguredRules) {\n lines.push(`--- ${rule.name} ---`);\n lines.push(`Description: ${rule.description}`);\n const opts = rule.defaultOptions;\n const optKeys = Object.keys(opts);\n if (optKeys.length > 0) {\n lines.push(`Available options (suggested defaults shown):`);\n for (const key of optKeys) {\n lines.push(` ${key}: ${JSON.stringify(opts[key])}`);\n }\n } else {\n lines.push('Available options: none beyond mode');\n }\n lines.push(`Example entry for webpieces.config.json:`);\n lines.push(` \"${rule.name}\": { \"mode\": \"ON\" }`);\n lines.push('');\n }\n\n return new BlockedResult(lines.join('\\n'));\n}\n\n// N-legs pattern: each rule runs independently; crash → visible violation so AI sees it, not silent []\nfunction runRuleCheck(rule: Rule, ctx: EditContext | FileContext | BashContext): readonly Violation[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return (rule as EditRule | FileRule | BashRule).check(ctx as never);\n } catch (err: unknown) {\n const error = toError(err);\n return [new Violation(0, '', `Rule '${rule.name}' crashed: ${error.message}`)];\n }\n}\n\nfunction runBashRules(\n rules: readonly Rule[],\n bashContext: BashContext,\n config: ResolvedConfig,\n): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'bash') continue;\n const ruleConfig = config.rules.get(rule.name);\n if (!ruleConfig || ruleConfig.isOff) continue;\n if (isRuleSkipped(ruleConfig)) continue;\n bashContext.options = mergeOptions(rule.defaultOptions, ruleConfig);\n const vs = runRuleCheck(rule, bashContext);\n if (vs.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], [...vs],\n ));\n }\n }\n return groups;\n}\n\n// Every rule honors the universal escape hatches: skip while on a named branch\n// (ignoreRuleWhileOnBranch) or until an epoch passes (ignoreModifiedUntilEpoch).\nfunction isRuleSkipped(ruleConfig: ResolvedRuleConfig): boolean {\n return shouldSkipRule(\n ruleConfig.options['ignoreModifiedUntilEpoch'] as number | undefined,\n ruleConfig.options['ignoreRuleWhileOnBranch'] as string | undefined,\n ).skip;\n}\n\nfunction ruleMatchesFile(rule: Rule, relativePath: string): boolean {\n for (const pattern of rule.files) {\n if (globMatches(pattern, relativePath)) return true;\n }\n return false;\n}\n\nfunction mergeOptions(defaultOptions: RuleOptions, ruleConfig: ResolvedRuleConfig): RuleOptions {\n // webpieces-disable no-any-unknown -- building an options bag from opaque RuleOptions\n const out: Record<string, unknown> = {};\n for (const key of Object.keys(defaultOptions)) out[key] = defaultOptions[key];\n for (const key of Object.keys(ruleConfig.options)) {\n // 'mode' is the framework-level on/off switch, not a rule option.\n if (key === 'mode') continue;\n out[key] = ruleConfig.options[key];\n }\n return out;\n}\n\nfunction runEditRules(\n rules: readonly Rule[],\n editContexts: readonly EditContext[],\n config: ResolvedConfig,\n): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'edit') continue;\n const ruleConfig = config.rules.get(rule.name);\n if (!ruleConfig || ruleConfig.isOff) continue;\n if (isRuleSkipped(ruleConfig)) continue;\n const allViolations: Violation[] = [];\n for (const ctx of editContexts) {\n if (!ruleMatchesFile(rule, ctx.relativePath)) continue;\n ctx.options = mergeOptions(rule.defaultOptions, ruleConfig);\n const vs = runRuleCheck(rule, ctx);\n for (const v of vs) {\n const copy = new Violation(v.line, v.snippet, v.message);\n copy.editIndex = ctx.editIndex;\n copy.editCount = ctx.editCount;\n allViolations.push(copy);\n }\n }\n if (allViolations.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], allViolations,\n ));\n }\n }\n return groups;\n}\n\nfunction runFileRules(\n rules: readonly Rule[],\n fileContext: FileContext,\n config: ResolvedConfig,\n): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'file') continue;\n const ruleConfig = config.rules.get(rule.name);\n if (!ruleConfig || ruleConfig.isOff) continue;\n if (isRuleSkipped(ruleConfig)) continue;\n if (!ruleMatchesFile(rule, fileContext.relativePath)) continue;\n fileContext.options = mergeOptions(rule.defaultOptions, ruleConfig);\n const vs = runRuleCheck(rule, fileContext);\n if (vs.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], [...vs],\n ));\n }\n }\n return groups;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/runner.ts"],"names":[],"mappings":";;AAmBA,kBAMC;AAoCD,0BAEC;;AA/DD,mDAA6B;AAE7B,0DAAyF;AAEzF,mDAAkE;AAClE,6CAAsD;AACtD,yCAAqC;AACrC,qCAAwC;AACxC,mCAIiB;AAEjB,MAAM,qBAAqB,GACvB,oCAAoC;IACpC,wGAAwG;IACxG,+CAA+C,CAAC;AAEpD,SAAgB,GAAG,CACf,QAAkB,EAClB,KAA0B,EAC1B,GAAW;IAEX,OAAO,WAAW,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW,CAChB,QAAkB,EAClB,KAA0B,EAC1B,GAAW;IAEX,MAAM,MAAM,GAAG,IAAA,uCAAwB,EAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,qBAAa,CAAC,qBAAqB,CAAC,CAAC;IAE7D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAEtD,qFAAqF;IACrF,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;QACnE,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,KAAK,GAAG,IAAA,sBAAS,EAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,MAAM,QAAQ,GAAG,IAAA,6BAAa,EAAC,QAAQ,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAC/D,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;IAElE,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC9D,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC7D,MAAM,SAAS,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,UAAU,CAAC,CAAC;IAEjD,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IACrD,OAAO,IAAI,qBAAa,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,SAAgB,OAAO,CAAC,OAAe,EAAE,GAAW;IAChD,OAAO,eAAe,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,GAAW;IACjD,MAAM,MAAM,GAAG,IAAA,uCAAwB,EAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,qBAAa,CAAC,qBAAqB,CAAC,CAAC;IAE7D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,IAAA,sBAAS,EAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpC,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC;IACxD,IAAI,SAAS;QAAE,OAAO,SAAS,CAAC;IAEhC,MAAM,GAAG,GAAG,IAAA,gCAAgB,EAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC9C,OAAO,IAAI,qBAAa,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,iGAAiG;AACjG,SAAS,mBAAmB,CAAC,MAA4B;IACrD,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,eAAe,CAAC,KAAsB,EAAE,MAA4B;IACzE,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAC/C,MAAM,iBAAiB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAO,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7E,IAAI,iBAAiB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEhD,MAAM,KAAK,GAAG;QACV,oHAAoH;QACpH,EAAE;QACF,8EAA8E;QAC9E,oEAAoE;QACpE,2DAA2D;QAC3D,8CAA8C;QAC9C,EAAE;QACF,+EAA+E;QAC/E,EAAE;KACL,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,iBAAiB,EAAE,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC;QACjC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;YAC5D,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC;YACzD,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACtD,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,0CAA0C,CAAC,CAAC;QACvD,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,qBAAqB,CAAC,CAAC;QACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,qBAAa,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,uGAAuG;AACvG,SAAS,YAAY,CAAC,IAAU,EAAE,GAA4C;IAC1E,8DAA8D;IAC9D,IAAI,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACpB,MAAM,KAAK,GAAG,IAAA,kBAAO,EAAC,GAAG,CAAC,CAAC;QAC3B,OAAO,CAAC,IAAI,iBAAS,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,IAAI,CAAC,IAAI,cAAc,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IACnF,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,IAAU,EAAE,YAAoB;IACrD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,IAAA,wBAAW,EAAC,OAAO,EAAE,YAAY,CAAC;YAAE,OAAO,IAAI,CAAC;IACxD,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,YAAY,CAAC,KAAsB,EAAE,WAAwB;IAClE,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,SAAS;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,SAAS;QAChC,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3C,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAS,CACrB,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAC1D,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,KAAsB,EAAE,YAAoC;IAC9E,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,SAAS;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,SAAS;QAChC,MAAM,aAAa,GAAgB,EAAE,CAAC;QACtC,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;YAC7B,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,YAAY,CAAC;gBAAE,SAAS;YACvD,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACnC,KAAK,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,GAAG,IAAI,iBAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;gBACzD,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;gBAC/B,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC,SAAS,CAAC;gBAC/B,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;QACL,CAAC;QACD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAS,CACrB,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,aAAa,CAChE,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED,SAAS,YAAY,CAAC,KAAsB,EAAE,WAAwB;IAClE,MAAM,MAAM,GAAgB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM;YAAE,SAAS;QACpC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YAAE,SAAS;QAChC,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,WAAW,CAAC,YAAY,CAAC;YAAE,SAAS;QAC/D,MAAM,EAAE,GAAG,YAAY,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QAC3C,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC,IAAI,iBAAS,CACrB,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAC1D,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC","sourcesContent":["import * as path from 'path';\n\nimport { loadWebpiecesRulesConfig, WebpiecesRulesConfig } from '@webpieces/rules-config';\n\nimport { buildContexts, buildBashContext } from './build-context';\nimport { loadRules, globMatches } from './load-rules';\nimport { toError } from './to-error';\nimport { formatReport } from './report';\nimport {\n ToolKind, NormalizedToolInput, BlockedResult,\n Rule, Violation, RuleGroup,\n EditContext, FileContext, BashContext,\n} from './types';\n\nconst CONFIG_MISSING_REPORT =\n 'webpieces.config.json not found.\\n' +\n 'Tell the human: run `./node_modules/.bin/wp-setup-ai-hooks` to initialize the project configuration.\\n' +\n 'Do not proceed until the human has done this.';\n\nexport function run(\n toolKind: ToolKind,\n input: NormalizedToolInput,\n cwd: string,\n): BlockedResult | null {\n return runInternal(toolKind, input, cwd);\n}\n\nfunction runInternal(\n toolKind: ToolKind,\n input: NormalizedToolInput,\n cwd: string,\n): BlockedResult | null {\n const loaded = loadWebpiecesRulesConfig(cwd);\n if (!loaded) return new BlockedResult(CONFIG_MISSING_REPORT);\n\n const workspaceRoot = path.dirname(loaded.configPath);\n\n // Always allow edits to webpieces.config.json — it's the fix target when out of sync\n if (path.resolve(input.filePath) === path.resolve(loaded.configPath)) {\n return null;\n }\n\n const rules = loadRules(loaded.config, workspaceRoot);\n if (rules.length === 0) return null;\n\n const outOfSync = checkConfigSync(rules, loaded.config);\n if (outOfSync) return outOfSync;\n\n const contexts = buildContexts(toolKind, input, workspaceRoot);\n const relativePath = path.relative(workspaceRoot, input.filePath);\n\n const editGroups = runEditRules(rules, contexts.editContexts);\n const fileGroups = runFileRules(rules, contexts.fileContext);\n const allGroups = [...editGroups, ...fileGroups];\n\n if (allGroups.length === 0) return null;\n\n const report = formatReport(relativePath, allGroups);\n return new BlockedResult(report);\n}\n\nexport function runBash(command: string, cwd: string): BlockedResult | null {\n return runBashInternal(command, cwd);\n}\n\nfunction runBashInternal(command: string, cwd: string): BlockedResult | null {\n const loaded = loadWebpiecesRulesConfig(cwd);\n if (!loaded) return new BlockedResult(CONFIG_MISSING_REPORT);\n\n const workspaceRoot = path.dirname(loaded.configPath);\n const rules = loadRules(loaded.config, workspaceRoot);\n if (rules.length === 0) return null;\n\n const outOfSync = checkConfigSync(rules, loaded.config);\n if (outOfSync) return outOfSync;\n\n const ctx = buildBashContext(command, workspaceRoot);\n const groups = runBashRules(rules, ctx);\n if (groups.length === 0) return null;\n\n const report = formatReport('<bash>', groups);\n return new BlockedResult(report);\n}\n\n// The set of rule names explicitly present in webpieces.config.json (every key except rulesDir).\nfunction configuredRuleNames(config: WebpiecesRulesConfig): ReadonlySet<string> {\n return new Set(Object.keys(config).filter((k: string) => k !== 'rulesDir'));\n}\n\nfunction checkConfigSync(rules: readonly Rule[], config: WebpiecesRulesConfig): BlockedResult | null {\n const configured = configuredRuleNames(config);\n const unconfiguredRules = rules.filter((r: Rule) => !configured.has(r.name));\n if (unconfiguredRules.length === 0) return null;\n\n const lines = [\n 'webpieces.config.json is out of sync — new built-in rules are present that have no entry in webpieces.config.json.',\n '',\n 'Tell the human: the following rules need to be configured. Ask for each one:',\n ' - Should this rule be ON, OFF, MODIFIED_CODE, or MODIFIED_FILES?',\n ' - What values do you want for the options listed below?',\n 'Then update webpieces.config.json and retry.',\n '',\n 'Do NOT proceed until webpieces.config.json has an entry for every rule below.',\n '',\n ];\n\n for (const rule of unconfiguredRules) {\n lines.push(`--- ${rule.name} ---`);\n lines.push(`Description: ${rule.description}`);\n const opts = rule.defaultOptions;\n const optKeys = Object.keys(opts);\n if (optKeys.length > 0) {\n lines.push(`Available options (suggested defaults shown):`);\n for (const key of optKeys) {\n lines.push(` ${key}: ${JSON.stringify(opts[key])}`);\n }\n } else {\n lines.push('Available options: none beyond mode');\n }\n lines.push(`Example entry for webpieces.config.json:`);\n lines.push(` \"${rule.name}\": { \"mode\": \"ON\" }`);\n lines.push('');\n }\n\n return new BlockedResult(lines.join('\\n'));\n}\n\n// N-legs pattern: each rule runs independently; crash → visible violation so AI sees it, not silent []\nfunction runRuleCheck(rule: Rule, ctx: EditContext | FileContext | BashContext): readonly Violation[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n return rule.check(ctx);\n } catch (err: unknown) {\n const error = toError(err);\n return [new Violation(0, '', `Rule '${rule.name}' crashed: ${error.message}`)];\n }\n}\n\nfunction ruleMatchesFile(rule: Rule, relativePath: string): boolean {\n for (const pattern of rule.files) {\n if (globMatches(pattern, relativePath)) return true;\n }\n return false;\n}\n\nfunction runBashRules(rules: readonly Rule[], bashContext: BashContext): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'bash') continue;\n if (!rule.shouldRun()) continue;\n const vs = runRuleCheck(rule, bashContext);\n if (vs.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], [...vs],\n ));\n }\n }\n return groups;\n}\n\nfunction runEditRules(rules: readonly Rule[], editContexts: readonly EditContext[]): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'edit') continue;\n if (!rule.shouldRun()) continue;\n const allViolations: Violation[] = [];\n for (const ctx of editContexts) {\n if (!ruleMatchesFile(rule, ctx.relativePath)) continue;\n const vs = runRuleCheck(rule, ctx);\n for (const v of vs) {\n const copy = new Violation(v.line, v.snippet, v.message);\n copy.editIndex = ctx.editIndex;\n copy.editCount = ctx.editCount;\n allViolations.push(copy);\n }\n }\n if (allViolations.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], allViolations,\n ));\n }\n }\n return groups;\n}\n\nfunction runFileRules(rules: readonly Rule[], fileContext: FileContext): readonly RuleGroup[] {\n const groups: RuleGroup[] = [];\n for (const rule of rules) {\n if (rule.scope !== 'file') continue;\n if (!rule.shouldRun()) continue;\n if (!ruleMatchesFile(rule, fileContext.relativePath)) continue;\n const vs = runRuleCheck(rule, fileContext);\n if (vs.length > 0) {\n groups.push(new RuleGroup(\n rule.name, rule.description, [...rule.fixHint], [...vs],\n ));\n }\n }\n return groups;\n}\n"]}
|
package/src/core/types.d.ts
CHANGED
|
@@ -60,26 +60,27 @@ export declare class FileContext {
|
|
|
60
60
|
options: RuleOptions;
|
|
61
61
|
constructor(tool: ToolKind, filePath: string, relativePath: string, workspaceRoot: string, currentFileLines: number, linesAdded: number, linesRemoved: number, projectedFileLines: number);
|
|
62
62
|
}
|
|
63
|
-
|
|
63
|
+
/**
|
|
64
|
+
* The shape of a custom rule loaded from a `rulesDir` (a plain object returned by require()).
|
|
65
|
+
* It carries only metadata + a `check` method — no on/off logic of its own.
|
|
66
|
+
*/
|
|
67
|
+
export interface PlainRule {
|
|
64
68
|
readonly name: string;
|
|
65
69
|
readonly description: string;
|
|
70
|
+
readonly scope: RuleScope;
|
|
66
71
|
readonly files: readonly string[];
|
|
67
72
|
readonly defaultOptions: RuleOptions;
|
|
68
73
|
readonly fixHint: readonly string[];
|
|
74
|
+
check(ctx: EditContext | FileContext | BashContext): readonly Violation[];
|
|
69
75
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
76
|
+
/**
|
|
77
|
+
* The runtime contract the runner iterates. Both the built-in rule classes (which extend
|
|
78
|
+
* EditRuleBase/FileRuleBase/BashRuleBase) and the custom-rule adapter satisfy this: they add
|
|
79
|
+
* `shouldRun()` (mode + escape-hatch decision) on top of the PlainRule metadata.
|
|
80
|
+
*/
|
|
81
|
+
export interface Rule extends PlainRule {
|
|
82
|
+
shouldRun(): boolean;
|
|
73
83
|
}
|
|
74
|
-
export interface FileRule extends RuleBase {
|
|
75
|
-
readonly scope: 'file';
|
|
76
|
-
check(ctx: FileContext): readonly Violation[];
|
|
77
|
-
}
|
|
78
|
-
export interface BashRule extends RuleBase {
|
|
79
|
-
readonly scope: 'bash';
|
|
80
|
-
check(ctx: BashContext): readonly Violation[];
|
|
81
|
-
}
|
|
82
|
-
export type Rule = EditRule | FileRule | BashRule;
|
|
83
84
|
export declare class RuleGroup {
|
|
84
85
|
readonly ruleName: string;
|
|
85
86
|
readonly ruleDescription: string;
|
package/src/core/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../../../packages/tooling/ai-hook-rules/src/core/types.ts"],"names":[],"mappings":"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","sourcesContent":["// ResolvedConfig / ResolvedRuleConfig / RuleOptions now live in @webpieces/rules-config\n// so ai-hooks and the Nx validate-code executor share one loader and one config file.\nimport { RuleOptions } from '@webpieces/rules-config';\nexport { ResolvedConfig, ResolvedRuleConfig, RuleOptions, InformAiError } from '@webpieces/rules-config';\n\nexport type ToolKind = 'Write' | 'Edit' | 'MultiEdit';\nexport type RuleScope = 'edit' | 'file' | 'bash';\nexport type IsLineDisabled = (lineNum: number, ruleName: string) => boolean;\n\nexport class Violation {\n readonly line: number;\n readonly snippet: string;\n readonly message: string;\n editIndex: number | undefined;\n editCount: number | undefined;\n\n constructor(line: number, snippet: string, message: string) {\n this.line = line;\n this.snippet = snippet;\n this.message = message;\n this.editIndex = undefined;\n this.editCount = undefined;\n }\n}\n\nexport class NormalizedEdit {\n readonly oldString: string;\n readonly newString: string;\n\n constructor(oldString: string, newString: string) {\n this.oldString = oldString;\n this.newString = newString;\n }\n}\n\nexport class NormalizedToolInput {\n readonly filePath: string;\n readonly edits: readonly NormalizedEdit[];\n\n constructor(filePath: string, edits: readonly NormalizedEdit[]) {\n this.filePath = filePath;\n this.edits = edits;\n }\n}\n\nexport class NormalizedBashInput {\n readonly command: string;\n\n constructor(command: string) {\n this.command = command;\n }\n}\n\nexport class EditContext {\n readonly tool: ToolKind;\n readonly editIndex: number;\n readonly editCount: number;\n readonly filePath: string;\n readonly relativePath: string;\n readonly workspaceRoot: string;\n readonly addedContent: string;\n readonly strippedContent: string;\n readonly lines: readonly string[];\n readonly strippedLines: readonly string[];\n readonly removedContent: string;\n readonly isLineDisabled: IsLineDisabled;\n options: RuleOptions;\n\n constructor(\n tool: ToolKind,\n editIndex: number,\n editCount: number,\n filePath: string,\n relativePath: string,\n workspaceRoot: string,\n addedContent: string,\n strippedContent: string,\n lines: readonly string[],\n strippedLines: readonly string[],\n removedContent: string,\n isLineDisabled: IsLineDisabled,\n ) {\n this.tool = tool;\n this.editIndex = editIndex;\n this.editCount = editCount;\n this.filePath = filePath;\n this.relativePath = relativePath;\n this.workspaceRoot = workspaceRoot;\n this.addedContent = addedContent;\n this.strippedContent = strippedContent;\n this.lines = lines;\n this.strippedLines = strippedLines;\n this.removedContent = removedContent;\n this.isLineDisabled = isLineDisabled;\n this.options = {};\n }\n}\n\nexport class BashContext {\n readonly tool: 'Bash';\n readonly command: string;\n readonly workspaceRoot: string;\n options: RuleOptions;\n\n constructor(command: string, workspaceRoot: string) {\n this.tool = 'Bash';\n this.command = command;\n this.workspaceRoot = workspaceRoot;\n this.options = {};\n }\n}\n\nexport class FileContext {\n readonly tool: ToolKind;\n readonly filePath: string;\n readonly relativePath: string;\n readonly workspaceRoot: string;\n readonly currentFileLines: number;\n readonly linesAdded: number;\n readonly linesRemoved: number;\n readonly projectedFileLines: number;\n options: RuleOptions;\n\n constructor(\n tool: ToolKind,\n filePath: string,\n relativePath: string,\n workspaceRoot: string,\n currentFileLines: number,\n linesAdded: number,\n linesRemoved: number,\n projectedFileLines: number,\n ) {\n this.tool = tool;\n this.filePath = filePath;\n this.relativePath = relativePath;\n this.workspaceRoot = workspaceRoot;\n this.currentFileLines = currentFileLines;\n this.linesAdded = linesAdded;\n this.linesRemoved = linesRemoved;\n this.projectedFileLines = projectedFileLines;\n this.options = {};\n }\n}\n\n/**\n * The shape of a custom rule loaded from a `rulesDir` (a plain object returned by require()).\n * It carries only metadata + a `check` method — no on/off logic of its own.\n */\nexport interface PlainRule {\n readonly name: string;\n readonly description: string;\n readonly scope: RuleScope;\n readonly files: readonly string[];\n readonly defaultOptions: RuleOptions;\n readonly fixHint: readonly string[];\n check(ctx: EditContext | FileContext | BashContext): readonly Violation[];\n}\n\n/**\n * The runtime contract the runner iterates. Both the built-in rule classes (which extend\n * EditRuleBase/FileRuleBase/BashRuleBase) and the custom-rule adapter satisfy this: they add\n * `shouldRun()` (mode + escape-hatch decision) on top of the PlainRule metadata.\n */\nexport interface Rule extends PlainRule {\n shouldRun(): boolean;\n}\n\nexport class RuleGroup {\n readonly ruleName: string;\n readonly ruleDescription: string;\n readonly fixHint: readonly string[];\n readonly violations: readonly Violation[];\n\n constructor(\n ruleName: string,\n ruleDescription: string,\n fixHint: readonly string[],\n violations: readonly Violation[],\n ) {\n this.ruleName = ruleName;\n this.ruleDescription = ruleDescription;\n this.fixHint = fixHint;\n this.violations = violations;\n }\n}\n\nexport class BlockedResult {\n readonly report: string;\n\n constructor(report: string) {\n this.report = report;\n }\n}\n\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
|
-
export { ToolKind, RuleScope, RuleOptions, IsLineDisabled, Violation, NormalizedEdit, NormalizedToolInput, EditContext, FileContext,
|
|
1
|
+
export { ToolKind, RuleScope, RuleOptions, IsLineDisabled, Violation, NormalizedEdit, NormalizedToolInput, EditContext, FileContext, BashContext, Rule, PlainRule, RuleGroup, BlockedResult, ResolvedConfig, ResolvedRuleConfig, } from './core/types';
|
|
2
|
+
export { EditRuleBase, FileRuleBase, BashRuleBase, EmptyRuleConfig } from './core/rule-base';
|
|
3
|
+
export { CustomRuleAdapter } from './core/custom-rule-adapter';
|
|
4
|
+
export { NoAnyUnknownRule } from './core/rules/no-any-unknown';
|
|
5
|
+
export { NoImplicitAnyRule } from './core/rules/no-implicit-any';
|
|
6
|
+
export { MaxFileLinesRule } from './core/rules/max-file-lines';
|
|
7
|
+
export { ValidateTsInSrcRule } from './core/rules/validate-ts-in-src';
|
|
8
|
+
export { NoDestructureRule } from './core/rules/no-destructure';
|
|
9
|
+
export { RequireReturnTypeRule } from './core/rules/require-return-type';
|
|
10
|
+
export { NoUnmanagedExceptionsRule } from './core/rules/no-unmanaged-exceptions';
|
|
11
|
+
export { CatchErrorPatternRule } from './core/rules/catch-error-pattern';
|
|
12
|
+
export { ThrowCauseRequiredRule } from './core/rules/throw-cause-required';
|
|
13
|
+
export { NoShellSubstitutionRule } from './core/rules/no-shell-substitution';
|
|
14
|
+
export { NoSymbolDiTokensRule } from './core/rules/no-symbol-di-tokens';
|
|
15
|
+
export { BranchCreationGuardRule } from './core/rules/branch-creation-guard';
|
|
16
|
+
export { PrCreationGuardRule } from './core/rules/pr-creation-guard';
|
|
17
|
+
export { MergeInProgressGuardRule } from './core/rules/merge-in-progress-guard';
|
|
18
|
+
export { PrMergeCleanupRule } from './core/rules/pr-merge-cleanup';
|
|
19
|
+
export { NoDirectMainUpdateRule } from './core/rules/no-direct-main-update';
|
|
20
|
+
export { NoJsFilesRule } from './core/rules/no-js-files';
|
|
21
|
+
export { NoEditOnMainRule } from './core/rules/no-edit-on-main';
|
|
2
22
|
export { run } from './core/runner';
|
|
3
23
|
export { stripTsNoise } from './core/strip-ts-noise';
|
|
4
24
|
export { parseDirectives, DirectiveIndex, createIsLineDisabled } from './core/disable-directives';
|
package/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.formatReport = exports.createIsLineDisabled = exports.DirectiveIndex = exports.parseDirectives = exports.stripTsNoise = exports.run = exports.ResolvedRuleConfig = exports.ResolvedConfig = exports.BlockedResult = exports.RuleGroup = exports.FileContext = exports.EditContext = exports.NormalizedToolInput = exports.NormalizedEdit = exports.Violation = void 0;
|
|
3
|
+
exports.formatReport = exports.createIsLineDisabled = exports.DirectiveIndex = exports.parseDirectives = exports.stripTsNoise = exports.run = exports.NoEditOnMainRule = exports.NoJsFilesRule = exports.NoDirectMainUpdateRule = exports.PrMergeCleanupRule = exports.MergeInProgressGuardRule = exports.PrCreationGuardRule = exports.BranchCreationGuardRule = exports.NoSymbolDiTokensRule = exports.NoShellSubstitutionRule = exports.ThrowCauseRequiredRule = exports.CatchErrorPatternRule = exports.NoUnmanagedExceptionsRule = exports.RequireReturnTypeRule = exports.NoDestructureRule = exports.ValidateTsInSrcRule = exports.MaxFileLinesRule = exports.NoImplicitAnyRule = exports.NoAnyUnknownRule = exports.CustomRuleAdapter = exports.EmptyRuleConfig = exports.BashRuleBase = exports.FileRuleBase = exports.EditRuleBase = exports.ResolvedRuleConfig = exports.ResolvedConfig = exports.BlockedResult = exports.RuleGroup = exports.BashContext = exports.FileContext = exports.EditContext = exports.NormalizedToolInput = exports.NormalizedEdit = exports.Violation = void 0;
|
|
4
4
|
// Pluggable write-time validation framework for AI coding agents
|
|
5
5
|
var types_1 = require("./core/types");
|
|
6
6
|
Object.defineProperty(exports, "Violation", { enumerable: true, get: function () { return types_1.Violation; } });
|
|
@@ -8,10 +8,56 @@ Object.defineProperty(exports, "NormalizedEdit", { enumerable: true, get: functi
|
|
|
8
8
|
Object.defineProperty(exports, "NormalizedToolInput", { enumerable: true, get: function () { return types_1.NormalizedToolInput; } });
|
|
9
9
|
Object.defineProperty(exports, "EditContext", { enumerable: true, get: function () { return types_1.EditContext; } });
|
|
10
10
|
Object.defineProperty(exports, "FileContext", { enumerable: true, get: function () { return types_1.FileContext; } });
|
|
11
|
+
Object.defineProperty(exports, "BashContext", { enumerable: true, get: function () { return types_1.BashContext; } });
|
|
11
12
|
Object.defineProperty(exports, "RuleGroup", { enumerable: true, get: function () { return types_1.RuleGroup; } });
|
|
12
13
|
Object.defineProperty(exports, "BlockedResult", { enumerable: true, get: function () { return types_1.BlockedResult; } });
|
|
13
14
|
Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
|
|
14
15
|
Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
|
|
16
|
+
// Scope-specific rule bases (each extends the shared AbstractRule from @webpieces/rules-config)
|
|
17
|
+
var rule_base_1 = require("./core/rule-base");
|
|
18
|
+
Object.defineProperty(exports, "EditRuleBase", { enumerable: true, get: function () { return rule_base_1.EditRuleBase; } });
|
|
19
|
+
Object.defineProperty(exports, "FileRuleBase", { enumerable: true, get: function () { return rule_base_1.FileRuleBase; } });
|
|
20
|
+
Object.defineProperty(exports, "BashRuleBase", { enumerable: true, get: function () { return rule_base_1.BashRuleBase; } });
|
|
21
|
+
Object.defineProperty(exports, "EmptyRuleConfig", { enumerable: true, get: function () { return rule_base_1.EmptyRuleConfig; } });
|
|
22
|
+
var custom_rule_adapter_1 = require("./core/custom-rule-adapter");
|
|
23
|
+
Object.defineProperty(exports, "CustomRuleAdapter", { enumerable: true, get: function () { return custom_rule_adapter_1.CustomRuleAdapter; } });
|
|
24
|
+
// Built-in rule classes — each constructed with its typed *Config from @webpieces/rules-config
|
|
25
|
+
var no_any_unknown_1 = require("./core/rules/no-any-unknown");
|
|
26
|
+
Object.defineProperty(exports, "NoAnyUnknownRule", { enumerable: true, get: function () { return no_any_unknown_1.NoAnyUnknownRule; } });
|
|
27
|
+
var no_implicit_any_1 = require("./core/rules/no-implicit-any");
|
|
28
|
+
Object.defineProperty(exports, "NoImplicitAnyRule", { enumerable: true, get: function () { return no_implicit_any_1.NoImplicitAnyRule; } });
|
|
29
|
+
var max_file_lines_1 = require("./core/rules/max-file-lines");
|
|
30
|
+
Object.defineProperty(exports, "MaxFileLinesRule", { enumerable: true, get: function () { return max_file_lines_1.MaxFileLinesRule; } });
|
|
31
|
+
var validate_ts_in_src_1 = require("./core/rules/validate-ts-in-src");
|
|
32
|
+
Object.defineProperty(exports, "ValidateTsInSrcRule", { enumerable: true, get: function () { return validate_ts_in_src_1.ValidateTsInSrcRule; } });
|
|
33
|
+
var no_destructure_1 = require("./core/rules/no-destructure");
|
|
34
|
+
Object.defineProperty(exports, "NoDestructureRule", { enumerable: true, get: function () { return no_destructure_1.NoDestructureRule; } });
|
|
35
|
+
var require_return_type_1 = require("./core/rules/require-return-type");
|
|
36
|
+
Object.defineProperty(exports, "RequireReturnTypeRule", { enumerable: true, get: function () { return require_return_type_1.RequireReturnTypeRule; } });
|
|
37
|
+
var no_unmanaged_exceptions_1 = require("./core/rules/no-unmanaged-exceptions");
|
|
38
|
+
Object.defineProperty(exports, "NoUnmanagedExceptionsRule", { enumerable: true, get: function () { return no_unmanaged_exceptions_1.NoUnmanagedExceptionsRule; } });
|
|
39
|
+
var catch_error_pattern_1 = require("./core/rules/catch-error-pattern");
|
|
40
|
+
Object.defineProperty(exports, "CatchErrorPatternRule", { enumerable: true, get: function () { return catch_error_pattern_1.CatchErrorPatternRule; } });
|
|
41
|
+
var throw_cause_required_1 = require("./core/rules/throw-cause-required");
|
|
42
|
+
Object.defineProperty(exports, "ThrowCauseRequiredRule", { enumerable: true, get: function () { return throw_cause_required_1.ThrowCauseRequiredRule; } });
|
|
43
|
+
var no_shell_substitution_1 = require("./core/rules/no-shell-substitution");
|
|
44
|
+
Object.defineProperty(exports, "NoShellSubstitutionRule", { enumerable: true, get: function () { return no_shell_substitution_1.NoShellSubstitutionRule; } });
|
|
45
|
+
var no_symbol_di_tokens_1 = require("./core/rules/no-symbol-di-tokens");
|
|
46
|
+
Object.defineProperty(exports, "NoSymbolDiTokensRule", { enumerable: true, get: function () { return no_symbol_di_tokens_1.NoSymbolDiTokensRule; } });
|
|
47
|
+
var branch_creation_guard_1 = require("./core/rules/branch-creation-guard");
|
|
48
|
+
Object.defineProperty(exports, "BranchCreationGuardRule", { enumerable: true, get: function () { return branch_creation_guard_1.BranchCreationGuardRule; } });
|
|
49
|
+
var pr_creation_guard_1 = require("./core/rules/pr-creation-guard");
|
|
50
|
+
Object.defineProperty(exports, "PrCreationGuardRule", { enumerable: true, get: function () { return pr_creation_guard_1.PrCreationGuardRule; } });
|
|
51
|
+
var merge_in_progress_guard_1 = require("./core/rules/merge-in-progress-guard");
|
|
52
|
+
Object.defineProperty(exports, "MergeInProgressGuardRule", { enumerable: true, get: function () { return merge_in_progress_guard_1.MergeInProgressGuardRule; } });
|
|
53
|
+
var pr_merge_cleanup_1 = require("./core/rules/pr-merge-cleanup");
|
|
54
|
+
Object.defineProperty(exports, "PrMergeCleanupRule", { enumerable: true, get: function () { return pr_merge_cleanup_1.PrMergeCleanupRule; } });
|
|
55
|
+
var no_direct_main_update_1 = require("./core/rules/no-direct-main-update");
|
|
56
|
+
Object.defineProperty(exports, "NoDirectMainUpdateRule", { enumerable: true, get: function () { return no_direct_main_update_1.NoDirectMainUpdateRule; } });
|
|
57
|
+
var no_js_files_1 = require("./core/rules/no-js-files");
|
|
58
|
+
Object.defineProperty(exports, "NoJsFilesRule", { enumerable: true, get: function () { return no_js_files_1.NoJsFilesRule; } });
|
|
59
|
+
var no_edit_on_main_1 = require("./core/rules/no-edit-on-main");
|
|
60
|
+
Object.defineProperty(exports, "NoEditOnMainRule", { enumerable: true, get: function () { return no_edit_on_main_1.NoEditOnMainRule; } });
|
|
15
61
|
var runner_1 = require("./core/runner");
|
|
16
62
|
Object.defineProperty(exports, "run", { enumerable: true, get: function () { return runner_1.run; } });
|
|
17
63
|
var strip_ts_noise_1 = require("./core/strip-ts-noise");
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/ai-hook-rules/src/index.ts"],"names":[],"mappings":";;;AAAA,iEAAiE;AACjE,sCAOsB;AALlB,kGAAA,SAAS,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAC9C,oGAAA,WAAW,OAAA;AAAE,oGAAA,WAAW,OAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/ai-hook-rules/src/index.ts"],"names":[],"mappings":";;;AAAA,iEAAiE;AACjE,sCAOsB;AALlB,kGAAA,SAAS,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,4GAAA,mBAAmB,OAAA;AAC9C,oGAAA,WAAW,OAAA;AAAE,oGAAA,WAAW,OAAA;AAAE,oGAAA,WAAW,OAAA;AAErC,kGAAA,SAAS,OAAA;AAAE,sGAAA,aAAa,OAAA;AACxB,uGAAA,cAAc,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AAGtC,gGAAgG;AAChG,8CAA6F;AAApF,yGAAA,YAAY,OAAA;AAAE,yGAAA,YAAY,OAAA;AAAE,yGAAA,YAAY,OAAA;AAAE,4GAAA,eAAe,OAAA;AAClE,kEAA+D;AAAtD,wHAAA,iBAAiB,OAAA;AAE1B,+FAA+F;AAC/F,8DAA+D;AAAtD,kHAAA,gBAAgB,OAAA;AACzB,gEAAiE;AAAxD,oHAAA,iBAAiB,OAAA;AAC1B,8DAA+D;AAAtD,kHAAA,gBAAgB,OAAA;AACzB,sEAAsE;AAA7D,yHAAA,mBAAmB,OAAA;AAC5B,8DAAgE;AAAvD,mHAAA,iBAAiB,OAAA;AAC1B,wEAAyE;AAAhE,4HAAA,qBAAqB,OAAA;AAC9B,gFAAiF;AAAxE,oIAAA,yBAAyB,OAAA;AAClC,wEAAyE;AAAhE,4HAAA,qBAAqB,OAAA;AAC9B,0EAA2E;AAAlE,8HAAA,sBAAsB,OAAA;AAC/B,4EAA6E;AAApE,gIAAA,uBAAuB,OAAA;AAChC,wEAAwE;AAA/D,2HAAA,oBAAoB,OAAA;AAC7B,4EAA6E;AAApE,gIAAA,uBAAuB,OAAA;AAChC,oEAAqE;AAA5D,wHAAA,mBAAmB,OAAA;AAC5B,gFAAgF;AAAvE,mIAAA,wBAAwB,OAAA;AACjC,kEAAmE;AAA1D,sHAAA,kBAAkB,OAAA;AAC3B,4EAA4E;AAAnE,+HAAA,sBAAsB,OAAA;AAC/B,wDAAyD;AAAhD,4GAAA,aAAa,OAAA;AACtB,gEAAgE;AAAvD,mHAAA,gBAAgB,OAAA;AAEzB,wCAAoC;AAA3B,6FAAA,GAAG,OAAA;AACZ,wDAAqD;AAA5C,8GAAA,YAAY,OAAA;AACrB,gEAAkG;AAAzF,qHAAA,eAAe,OAAA;AAAE,oHAAA,cAAc,OAAA;AAAE,0HAAA,oBAAoB,OAAA;AAC9D,wCAA6C;AAApC,sGAAA,YAAY,OAAA","sourcesContent":["// Pluggable write-time validation framework for AI coding agents\nexport {\n ToolKind, RuleScope, RuleOptions, IsLineDisabled,\n Violation, NormalizedEdit, NormalizedToolInput,\n EditContext, FileContext, BashContext,\n Rule, PlainRule,\n RuleGroup, BlockedResult,\n ResolvedConfig, ResolvedRuleConfig,\n} from './core/types';\n\n// Scope-specific rule bases (each extends the shared AbstractRule from @webpieces/rules-config)\nexport { EditRuleBase, FileRuleBase, BashRuleBase, EmptyRuleConfig } from './core/rule-base';\nexport { CustomRuleAdapter } from './core/custom-rule-adapter';\n\n// Built-in rule classes — each constructed with its typed *Config from @webpieces/rules-config\nexport { NoAnyUnknownRule } from './core/rules/no-any-unknown';\nexport { NoImplicitAnyRule } from './core/rules/no-implicit-any';\nexport { MaxFileLinesRule } from './core/rules/max-file-lines';\nexport { ValidateTsInSrcRule } from './core/rules/validate-ts-in-src';\nexport { NoDestructureRule } from './core/rules/no-destructure';\nexport { RequireReturnTypeRule } from './core/rules/require-return-type';\nexport { NoUnmanagedExceptionsRule } from './core/rules/no-unmanaged-exceptions';\nexport { CatchErrorPatternRule } from './core/rules/catch-error-pattern';\nexport { ThrowCauseRequiredRule } from './core/rules/throw-cause-required';\nexport { NoShellSubstitutionRule } from './core/rules/no-shell-substitution';\nexport { NoSymbolDiTokensRule } from './core/rules/no-symbol-di-tokens';\nexport { BranchCreationGuardRule } from './core/rules/branch-creation-guard';\nexport { PrCreationGuardRule } from './core/rules/pr-creation-guard';\nexport { MergeInProgressGuardRule } from './core/rules/merge-in-progress-guard';\nexport { PrMergeCleanupRule } from './core/rules/pr-merge-cleanup';\nexport { NoDirectMainUpdateRule } from './core/rules/no-direct-main-update';\nexport { NoJsFilesRule } from './core/rules/no-js-files';\nexport { NoEditOnMainRule } from './core/rules/no-edit-on-main';\n\nexport { run } from './core/runner';\nexport { stripTsNoise } from './core/strip-ts-noise';\nexport { parseDirectives, DirectiveIndex, createIsLineDisabled } from './core/disable-directives';\nexport { formatReport } from './core/report';\n"]}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.defaultRulesDir = exports.defaultRules = void 0;
|
|
4
|
-
// webpieces-disable no-any-unknown -- rule options are opaque at framework level
|
|
5
|
-
exports.defaultRules = {
|
|
6
|
-
'no-any-unknown': { mode: 'ON' },
|
|
7
|
-
'max-file-lines': { mode: 'ON', limit: 900 },
|
|
8
|
-
'validate-ts-in-src': {
|
|
9
|
-
mode: 'ON',
|
|
10
|
-
allowedRootFiles: ['jest.setup.ts'],
|
|
11
|
-
excludePaths: [
|
|
12
|
-
'node_modules', 'dist', '.nx', '.git',
|
|
13
|
-
'architecture', 'tmp', 'scripts',
|
|
14
|
-
],
|
|
15
|
-
},
|
|
16
|
-
'no-destructure': { mode: 'ON', allowTopLevel: true },
|
|
17
|
-
'require-return-type': { mode: 'ON' },
|
|
18
|
-
'no-unmanaged-exceptions': { mode: 'ON' },
|
|
19
|
-
'catch-error-pattern': { mode: 'ON' },
|
|
20
|
-
};
|
|
21
|
-
exports.defaultRulesDir = [];
|
|
22
|
-
//# sourceMappingURL=default.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"default.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/ai-hook-rules/src/core/configs/default.ts"],"names":[],"mappings":";;;AAAA,iFAAiF;AACpE,QAAA,YAAY,GAA4C;IACjE,gBAAgB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IAChC,gBAAgB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE;IAC5C,oBAAoB,EAAE;QAClB,IAAI,EAAE,IAAI;QACV,gBAAgB,EAAE,CAAC,eAAe,CAAC;QACnC,YAAY,EAAE;YACV,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM;YACrC,cAAc,EAAE,KAAK,EAAE,SAAS;SACnC;KACJ;IACD,gBAAgB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE;IACrD,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACrC,yBAAyB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;IACzC,qBAAqB,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE;CACxC,CAAC;AAEW,QAAA,eAAe,GAAsB,EAAE,CAAC","sourcesContent":["// webpieces-disable no-any-unknown -- rule options are opaque at framework level\nexport const defaultRules: Record<string, Record<string, unknown>> = {\n 'no-any-unknown': { mode: 'ON' },\n 'max-file-lines': { mode: 'ON', limit: 900 },\n 'validate-ts-in-src': {\n mode: 'ON',\n allowedRootFiles: ['jest.setup.ts'],\n excludePaths: [\n 'node_modules', 'dist', '.nx', '.git',\n 'architecture', 'tmp', 'scripts',\n ],\n },\n 'no-destructure': { mode: 'ON', allowTopLevel: true },\n 'require-return-type': { mode: 'ON' },\n 'no-unmanaged-exceptions': { mode: 'ON' },\n 'catch-error-pattern': { mode: 'ON' },\n};\n\nexport const defaultRulesDir: readonly string[] = [];\n"]}
|