@webpieces/rules-config 0.4.452 → 0.4.454

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webpieces/rules-config",
3
- "version": "0.4.452",
3
+ "version": "0.4.454",
4
4
  "description": "Shared webpieces.config.json loader. Single source of truth for validation rule configuration consumed by @webpieces/ai-hook-rules, @webpieces/code-rules, and @webpieces/nx-webpieces-rules.",
5
5
  "type": "commonjs",
6
6
  "main": "./src/index.js",
package/src/index.d.ts CHANGED
@@ -30,7 +30,7 @@ export { SyncFlowGuidance, WP_START_UPDATE, WP_FINISH_UPDATE, WP_START_UPSERT_PR
30
30
  export { MaxMethodLinesConfig, MaxFileLinesConfig, RequireReturnTypeConfig, NoInlineTypeLiteralsConfig, NoAnyUnknownConfig, NoImplicitAnyConfig, PrismaValidateDtosConfig, PrismaConverterConfig, NoDestructureConfig, NoUnmanagedExceptionsConfig, CatchErrorPatternConfig, ThrowCauseRequiredConfig, AngularNoDirectApiInResolverConfig, NoSymbolDiTokensConfig, NoCustomCssConfig, NoProcessExitOutsideMainConfig, NoFunctionOutsideClassConfig, InjectAnnotationNotNeededForConcreteClassConfig, FrameworkTagConfig, RoleTagConfig, BranchCreationGuardConfig, PrCreationOrPushGuardConfig, MergeInProgressGuardConfig, PrMergeGuardConfig, RedirectHowToMergeMainConfig, FeatureBranchGuardConfig, ReadStaleGuardConfig, MergedBranchBashGuardConfig, NoFileImportCyclesConfig, RuntimeArchitectureConfig, NxWiringConfig, DiGraphConfig, NoJsFilesConfig, ValidateTsInSrcConfig, BaseRuleConfig, } from './rule-configs';
31
31
  export { METHOD_LIMIT_MODES, FILE_LIMIT_MODES, RETURN_TYPE_MODES, INLINE_TYPE_MODES, MODIFIED_CODE_MODES, PROJECT_MODES, PRISMA_DTOS_MODES, PRISMA_CONVERTER_MODES, DIRECT_API_RESOLVER_MODES, THROW_CAUSE_MODES, ON_OFF_MODES, STRUCTURAL_MODES, VALIDATE_TS_MODES, } from './rule-configs';
32
32
  export type { MethodLimitMode, FileLimitMode, ReturnTypeMode, InlineTypeMode, ModifiedCodeMode, ProjectMode, PrismaValidateDtosMode, PrismaConverterMode, DirectApiResolverMode, ThrowCauseMode, OnOffMode, StructuralMode, ValidateTsMode, } from './rule-configs';
33
- export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, buildPrGateConfig, } from './pr-gate-config';
33
+ export { GateDefinition, PrGateConfig, defaultGates, defaultPrGateConfig, buildPrGateConfig, MERGE_MODE_AUTO, MERGE_MODE_NONE, MERGE_MODES, } from './pr-gate-config';
34
34
  export { ReviewJson, ReviewJsonService, loadReviewJson, prDirFor, reviewJsonPath, reviewJsonSchemaHint, } from './review-json';
35
35
  export { MainSyncStatus, MainSyncLock, MainSyncStatusService, DEFAULT_HANG_TIMEOUT_MINUTES, mainSyncStatusPath, mainSyncLockPath, readMainSyncStatus, writeMainSyncStatus, readMainSyncLock, writeMainSyncLock, isLockStale, isRefreshInProgress, inProcessLock, finishedLock, computeMainSyncStatus, stampCleanMainSyncStatus, squashRecoverySteps, } from './main-sync-status';
36
36
  export { MergedBranch, DeletableBranch, DeletableWorktree, MergedBranchesCache, MergedBranchesService, } from './merged-branches';
package/src/index.js CHANGED
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getCurrentBranch = exports.shouldSkipRule = exports.FieldDef = exports.sectionForRule = exports.isHookGuard = exports.HOOK_GUARD_NAMES = exports.DEFAULT_MATCH_RULES = exports.renderMatchRuleMessage = exports.compileMatchRulePatterns = exports.isMatchRuleAllowedPath = exports.findMatchRuleViolations = exports.MatchRuleViolation = exports.MatchRuleConfig = exports.allRuleNames = exports.validateMatchRulesSection = exports.validateExcludePaths = exports.validateCommandsSection = exports.validateSectionPlacement = exports.validatePrGateSection = exports.validateWebpiecesConfig = exports.TemplateWriter = exports.writeTemplate = exports.writeTemplateIfMissing = exports.loadTemplate = exports.defaultRulesDir = exports.defaultRules = exports.isPathExcluded = exports.ExcludePaths = exports.DESIGN_METADATA_KEYS = exports.isDocumentDesign = exports.DocumentDesign = exports.RulesConfigDesign = exports.INSTRUCT_AI_DIR = exports.RepoRootFinder = exports.ConfigFile = exports.CONFIG_FILENAME = exports.findConfigFile = exports.ConfigLoader = exports.LoadedConfig = exports.loadAndValidate = exports.toError = exports.runMain = exports.CliArgs = exports.CliArgsCheck = exports.CliUsage = exports.CliExitError = exports.RuleFailError = exports.InformAiError = exports.ResolvedRuleConfig = exports.ResolvedConfig = void 0;
4
4
  exports.PrMergeGuardConfig = exports.MergeInProgressGuardConfig = exports.PrCreationOrPushGuardConfig = exports.BranchCreationGuardConfig = exports.RoleTagConfig = exports.FrameworkTagConfig = exports.InjectAnnotationNotNeededForConcreteClassConfig = exports.NoFunctionOutsideClassConfig = exports.NoProcessExitOutsideMainConfig = exports.NoCustomCssConfig = exports.NoSymbolDiTokensConfig = exports.AngularNoDirectApiInResolverConfig = exports.ThrowCauseRequiredConfig = exports.CatchErrorPatternConfig = exports.NoUnmanagedExceptionsConfig = exports.NoDestructureConfig = exports.PrismaConverterConfig = exports.PrismaValidateDtosConfig = exports.NoImplicitAnyConfig = exports.NoAnyUnknownConfig = exports.NoInlineTypeLiteralsConfig = exports.RequireReturnTypeConfig = exports.MaxFileLinesConfig = exports.MaxMethodLinesConfig = exports.WP_FINISH_UPSERT_PR = exports.WP_START_UPSERT_PR = exports.WP_FINISH_UPDATE = exports.WP_START_UPDATE = exports.SyncFlowGuidance = exports.WebpiecesRulesConfig = exports.MERGE_EXPLANATION_FILE = exports.MERGE_IN_PROGRESS_FILE = exports.PR_REVIEW_DIR = exports.MERGE_INFO_DIR = exports.WEBPIECES_TMP_DIR = exports.hasDisable = exports.RULE_NAMES = exports.WEBPIECES_DISABLE = exports.AbstractRule = exports.ChangedFilesOptions = exports.DiffRange = exports.DiffScope = exports.isNewOrModified = exports.hasChangesInRange = exports.findNewMethodSignaturesInDiff = exports.getChangedLineNumbers = exports.getFileDiff = exports.getChangedFiles = exports.resolveBase = exports.detectBase = void 0;
5
- exports.computeMainSyncStatus = exports.finishedLock = exports.inProcessLock = exports.isRefreshInProgress = exports.isLockStale = exports.writeMainSyncLock = exports.readMainSyncLock = exports.writeMainSyncStatus = exports.readMainSyncStatus = exports.mainSyncLockPath = exports.mainSyncStatusPath = exports.DEFAULT_HANG_TIMEOUT_MINUTES = exports.MainSyncStatusService = exports.MainSyncLock = exports.MainSyncStatus = exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.prDirFor = exports.loadReviewJson = exports.ReviewJsonService = exports.ReviewJson = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.VALIDATE_TS_MODES = exports.STRUCTURAL_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.PROJECT_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.MergedBranchBashGuardConfig = exports.ReadStaleGuardConfig = exports.FeatureBranchGuardConfig = exports.RedirectHowToMergeMainConfig = void 0;
6
- exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.logBranchMutation = exports.branchMutationLogPath = exports.BranchMutationLog = exports.BranchMutationEvent = exports.BranchReaper = exports.ReapResult = exports.ReapedBranch = exports.WorktreeService = exports.Worktree = exports.MergedBranchesService = exports.MergedBranchesCache = exports.DeletableWorktree = exports.DeletableBranch = exports.MergedBranch = exports.squashRecoverySteps = exports.stampCleanMainSyncStatus = void 0;
5
+ exports.isRefreshInProgress = exports.isLockStale = exports.writeMainSyncLock = exports.readMainSyncLock = exports.writeMainSyncStatus = exports.readMainSyncStatus = exports.mainSyncLockPath = exports.mainSyncStatusPath = exports.DEFAULT_HANG_TIMEOUT_MINUTES = exports.MainSyncStatusService = exports.MainSyncLock = exports.MainSyncStatus = exports.reviewJsonSchemaHint = exports.reviewJsonPath = exports.prDirFor = exports.loadReviewJson = exports.ReviewJsonService = exports.ReviewJson = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.buildPrGateConfig = exports.defaultPrGateConfig = exports.defaultGates = exports.PrGateConfig = exports.GateDefinition = exports.VALIDATE_TS_MODES = exports.STRUCTURAL_MODES = exports.ON_OFF_MODES = exports.THROW_CAUSE_MODES = exports.DIRECT_API_RESOLVER_MODES = exports.PRISMA_CONVERTER_MODES = exports.PRISMA_DTOS_MODES = exports.PROJECT_MODES = exports.MODIFIED_CODE_MODES = exports.INLINE_TYPE_MODES = exports.RETURN_TYPE_MODES = exports.FILE_LIMIT_MODES = exports.METHOD_LIMIT_MODES = exports.BaseRuleConfig = exports.ValidateTsInSrcConfig = exports.NoJsFilesConfig = exports.DiGraphConfig = exports.NxWiringConfig = exports.RuntimeArchitectureConfig = exports.NoFileImportCyclesConfig = exports.MergedBranchBashGuardConfig = exports.ReadStaleGuardConfig = exports.FeatureBranchGuardConfig = exports.RedirectHowToMergeMainConfig = void 0;
6
+ exports.DEFAULT_MERGE_COMPLETE_COMMAND = exports.DEFAULT_UPSERT_PR_COMMAND = exports.buildCommandsConfig = exports.CommandsConfig = exports.logBranchMutation = exports.branchMutationLogPath = exports.BranchMutationLog = exports.BranchMutationEvent = exports.BranchReaper = exports.ReapResult = exports.ReapedBranch = exports.WorktreeService = exports.Worktree = exports.MergedBranchesService = exports.MergedBranchesCache = exports.DeletableWorktree = exports.DeletableBranch = exports.MergedBranch = exports.squashRecoverySteps = exports.stampCleanMainSyncStatus = exports.computeMainSyncStatus = exports.finishedLock = exports.inProcessLock = void 0;
7
7
  var types_1 = require("./types");
8
8
  Object.defineProperty(exports, "ResolvedConfig", { enumerable: true, get: function () { return types_1.ResolvedConfig; } });
9
9
  Object.defineProperty(exports, "ResolvedRuleConfig", { enumerable: true, get: function () { return types_1.ResolvedRuleConfig; } });
@@ -163,6 +163,9 @@ Object.defineProperty(exports, "PrGateConfig", { enumerable: true, get: function
163
163
  Object.defineProperty(exports, "defaultGates", { enumerable: true, get: function () { return pr_gate_config_1.defaultGates; } });
164
164
  Object.defineProperty(exports, "defaultPrGateConfig", { enumerable: true, get: function () { return pr_gate_config_1.defaultPrGateConfig; } });
165
165
  Object.defineProperty(exports, "buildPrGateConfig", { enumerable: true, get: function () { return pr_gate_config_1.buildPrGateConfig; } });
166
+ Object.defineProperty(exports, "MERGE_MODE_AUTO", { enumerable: true, get: function () { return pr_gate_config_1.MERGE_MODE_AUTO; } });
167
+ Object.defineProperty(exports, "MERGE_MODE_NONE", { enumerable: true, get: function () { return pr_gate_config_1.MERGE_MODE_NONE; } });
168
+ Object.defineProperty(exports, "MERGE_MODES", { enumerable: true, get: function () { return pr_gate_config_1.MERGE_MODES; } });
166
169
  var review_json_1 = require("./review-json");
167
170
  Object.defineProperty(exports, "ReviewJson", { enumerable: true, get: function () { return review_json_1.ReviewJson; } });
168
171
  Object.defineProperty(exports, "ReviewJsonService", { enumerable: true, get: function () { return review_json_1.ReviewJsonService; } });
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { RuleFailError } from './rule-fail-error';\nexport { CliExitError } from './cli-exit-error';\nexport { CliUsage, CliArgsCheck, CliArgs } from './cli-args';\nexport { runMain } from './run-main';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig, ConfigLoader } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME, ConfigFile } from './config-file';\nexport { RepoRootFinder, INSTRUCT_AI_DIR } from './repo-root';\nexport { RulesConfigDesign } from './rules-config-design';\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './di';\nexport { ExcludePaths } from './exclude-hook-paths';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate, TemplateWriter } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';\nexport {\n MatchRuleConfig,\n MatchRuleViolation,\n findMatchRuleViolations,\n isMatchRuleAllowedPath,\n compileMatchRulePatterns,\n renderMatchRuleMessage,\n DEFAULT_MATCH_RULES,\n} from './match-rules-config';\nexport type { ConfigSection } from './sections';\nexport { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n DiffScope,\n DiffRange,\n ChangedFilesOptions,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_INFO_DIR,\n PR_REVIEW_DIR,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n SyncFlowGuidance,\n WP_START_UPDATE,\n WP_FINISH_UPDATE,\n WP_START_UPSERT_PR,\n WP_FINISH_UPSERT_PR,\n} from './sync-flow-guidance';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n BranchCreationGuardConfig,\n PrCreationOrPushGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeGuardConfig,\n RedirectHowToMergeMainConfig,\n FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PROJECT_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n ProjectMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n} from './pr-gate-config';\nexport {\n ReviewJson,\n ReviewJsonService,\n loadReviewJson,\n prDirFor,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncLock,\n MainSyncStatusService,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n writeMainSyncStatus,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n MergedBranch,\n DeletableBranch,\n DeletableWorktree,\n MergedBranchesCache,\n MergedBranchesService,\n} from './merged-branches';\nexport {\n Worktree,\n WorktreeService,\n} from './worktrees';\nexport {\n ReapedBranch,\n ReapResult,\n BranchReaper,\n} from './branch-reaper';\nexport type { MutationVerb, MutationPhase } from './branch-mutation-log';\nexport {\n BranchMutationEvent,\n BranchMutationLog,\n branchMutationLogPath,\n logBranchMutation,\n} from './branch-mutation-log';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export { ResolvedConfig, ResolvedRuleConfig, RuleOptions } from './types';\nexport { InformAiError } from './inform-ai-error';\nexport { RuleFailError } from './rule-fail-error';\nexport { CliExitError } from './cli-exit-error';\nexport { CliUsage, CliArgsCheck, CliArgs } from './cli-args';\nexport { runMain } from './run-main';\nexport { toError } from './to-error';\nexport { loadAndValidate, LoadedConfig, ConfigLoader } from './load-config';\nexport { findConfigFile, CONFIG_FILENAME, ConfigFile } from './config-file';\nexport { RepoRootFinder, INSTRUCT_AI_DIR } from './repo-root';\nexport { RulesConfigDesign } from './rules-config-design';\nexport { DocumentDesign, isDocumentDesign, DESIGN_METADATA_KEYS } from './di';\nexport { ExcludePaths } from './exclude-hook-paths';\nexport { isPathExcluded } from './exclude-paths';\nexport { defaultRules, defaultRulesDir } from './default-rules';\nexport { loadTemplate, writeTemplateIfMissing, writeTemplate, TemplateWriter } from './load-template';\nexport { validateWebpiecesConfig, validatePrGateSection, validateSectionPlacement, validateCommandsSection, validateExcludePaths, validateMatchRulesSection, allRuleNames } from './validate-config';\nexport {\n MatchRuleConfig,\n MatchRuleViolation,\n findMatchRuleViolations,\n isMatchRuleAllowedPath,\n compileMatchRulePatterns,\n renderMatchRuleMessage,\n DEFAULT_MATCH_RULES,\n} from './match-rules-config';\nexport type { ConfigSection } from './sections';\nexport { HOOK_GUARD_NAMES, isHookGuard, sectionForRule } from './sections';\nexport { FieldDef } from './field-def';\nexport type { SchemaShape } from './field-def';\nexport { shouldSkipRule, getCurrentBranch } from './skip-rule';\nexport type { SkipRuleResult } from './skip-rule';\nexport {\n detectBase,\n resolveBase,\n getChangedFiles,\n getFileDiff,\n getChangedLineNumbers,\n findNewMethodSignaturesInDiff,\n hasChangesInRange,\n isNewOrModified,\n DiffScope,\n DiffRange,\n ChangedFilesOptions,\n} from './diff-scope';\nexport { AbstractRule } from './abstract-rule';\nexport {\n WEBPIECES_DISABLE,\n RULE_NAMES,\n hasDisable,\n WEBPIECES_TMP_DIR,\n MERGE_INFO_DIR,\n PR_REVIEW_DIR,\n MERGE_IN_PROGRESS_FILE,\n MERGE_EXPLANATION_FILE,\n} from './constants';\nexport { WebpiecesRulesConfig } from './WebpiecesRulesConfig';\nexport {\n SyncFlowGuidance,\n WP_START_UPDATE,\n WP_FINISH_UPDATE,\n WP_START_UPSERT_PR,\n WP_FINISH_UPSERT_PR,\n} from './sync-flow-guidance';\nexport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n BranchCreationGuardConfig,\n PrCreationOrPushGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeGuardConfig,\n RedirectHowToMergeMainConfig,\n FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n BaseRuleConfig,\n} from './rule-configs';\n// Mode unions + their value arrays — the single source of truth shared with code-rules.\nexport {\n METHOD_LIMIT_MODES,\n FILE_LIMIT_MODES,\n RETURN_TYPE_MODES,\n INLINE_TYPE_MODES,\n MODIFIED_CODE_MODES,\n PROJECT_MODES,\n PRISMA_DTOS_MODES,\n PRISMA_CONVERTER_MODES,\n DIRECT_API_RESOLVER_MODES,\n THROW_CAUSE_MODES,\n ON_OFF_MODES,\n STRUCTURAL_MODES,\n VALIDATE_TS_MODES,\n} from './rule-configs';\nexport type {\n MethodLimitMode,\n FileLimitMode,\n ReturnTypeMode,\n InlineTypeMode,\n ModifiedCodeMode,\n ProjectMode,\n PrismaValidateDtosMode,\n PrismaConverterMode,\n DirectApiResolverMode,\n ThrowCauseMode,\n OnOffMode,\n StructuralMode,\n ValidateTsMode,\n} from './rule-configs';\nexport {\n GateDefinition,\n PrGateConfig,\n defaultGates,\n defaultPrGateConfig,\n buildPrGateConfig,\n MERGE_MODE_AUTO,\n MERGE_MODE_NONE,\n MERGE_MODES,\n} from './pr-gate-config';\nexport {\n ReviewJson,\n ReviewJsonService,\n loadReviewJson,\n prDirFor,\n reviewJsonPath,\n reviewJsonSchemaHint,\n} from './review-json';\nexport {\n MainSyncStatus,\n MainSyncLock,\n MainSyncStatusService,\n DEFAULT_HANG_TIMEOUT_MINUTES,\n mainSyncStatusPath,\n mainSyncLockPath,\n readMainSyncStatus,\n writeMainSyncStatus,\n readMainSyncLock,\n writeMainSyncLock,\n isLockStale,\n isRefreshInProgress,\n inProcessLock,\n finishedLock,\n computeMainSyncStatus,\n stampCleanMainSyncStatus,\n squashRecoverySteps,\n} from './main-sync-status';\nexport {\n MergedBranch,\n DeletableBranch,\n DeletableWorktree,\n MergedBranchesCache,\n MergedBranchesService,\n} from './merged-branches';\nexport {\n Worktree,\n WorktreeService,\n} from './worktrees';\nexport {\n ReapedBranch,\n ReapResult,\n BranchReaper,\n} from './branch-reaper';\nexport type { MutationVerb, MutationPhase } from './branch-mutation-log';\nexport {\n BranchMutationEvent,\n BranchMutationLog,\n branchMutationLogPath,\n logBranchMutation,\n} from './branch-mutation-log';\nexport {\n CommandsConfig,\n buildCommandsConfig,\n DEFAULT_UPSERT_PR_COMMAND,\n DEFAULT_MERGE_COMPLETE_COMMAND,\n} from './commands-config';\n"]}
@@ -5,11 +5,29 @@ export declare class GateDefinition {
5
5
  disabled: boolean;
6
6
  constructor(name: string, patterns: string[], warningColor: string, disabled?: boolean);
7
7
  }
8
+ export declare const MERGE_MODE_AUTO = "AUTO";
9
+ export declare const MERGE_MODE_NONE = "NONE";
10
+ export declare const MERGE_MODES: string[];
8
11
  export declare class PrGateConfig {
9
12
  mode: string;
10
13
  buildCommand: string;
11
14
  gates: GateDefinition[];
12
- constructor(mode: string, buildCommand: string, gates: GateDefinition[]);
15
+ /**
16
+ * REQUIRED — every repo must state its policy; there is deliberately no default, because the two
17
+ * answers are a real policy decision and guessing it either merges when a team did not want that,
18
+ * or silently stops landing PRs on a team that relied on it.
19
+ *
20
+ * AUTO — wp-finish-upsert-pr LANDS the PR: squash-merge it right away when it is mergeable, else
21
+ * enable GitHub auto-merge so it lands when the checks pass. Both carry an explicit --subject /
22
+ * --body-file, which is the ONLY way main's history gets the PR title plus the compact
23
+ * risk/flags body — no repo setting can produce that. Requires allow_auto_merge on the repo.
24
+ * NONE — wp-finish-upsert-pr only opens/updates the PR and stops; a human merges. NOTE the cost:
25
+ * a UI merge cannot use the compact body, so main's commit falls back to the repo's
26
+ * squash_merge_commit_title/message settings. Set squash_merge_commit_title=PR_TITLE there, or
27
+ * commits land as the internal "Squash merge of <branch>" subject.
28
+ */
29
+ mergeMode: string;
30
+ constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string);
13
31
  }
14
32
  export declare function defaultGates(): GateDefinition[];
15
33
  export declare function defaultPrGateConfig(): PrGateConfig;
@@ -4,7 +4,7 @@
4
4
  // top-level `pr-gate` key in webpieces.config.json. It is built and validated by
5
5
  // loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.PrGateConfig = exports.GateDefinition = void 0;
7
+ exports.PrGateConfig = exports.MERGE_MODES = exports.MERGE_MODE_NONE = exports.MERGE_MODE_AUTO = exports.GateDefinition = void 0;
8
8
  exports.defaultGates = defaultGates;
9
9
  exports.defaultPrGateConfig = defaultPrGateConfig;
10
10
  exports.buildPrGateConfig = buildPrGateConfig;
@@ -27,14 +27,38 @@ class GateDefinition {
27
27
  }
28
28
  }
29
29
  exports.GateDefinition = GateDefinition;
30
+ // How wp-finish-upsert-pr should try to LAND the PR once it has posted it. GitHub's auto-merge queue
31
+ // is a REPO-level setting (`allow_auto_merge`) that many orgs turn OFF as a policy control, and it
32
+ // CANNOT be forced from the client: `gh pr merge --auto` calls the enablePullRequestAutoMerge GraphQL
33
+ // mutation, which hard-errors with "Auto merge is not allowed for this repository" when the repo says
34
+ // no. So the only lever a config knob has is WHICH PATHS WE ATTEMPT — never whether the queue exists.
35
+ exports.MERGE_MODE_AUTO = 'AUTO';
36
+ exports.MERGE_MODE_NONE = 'NONE';
37
+ exports.MERGE_MODES = [exports.MERGE_MODE_AUTO, exports.MERGE_MODE_NONE];
30
38
  class PrGateConfig {
31
39
  mode;
32
40
  buildCommand;
33
41
  gates;
34
- constructor(mode, buildCommand, gates) {
42
+ /**
43
+ * REQUIRED — every repo must state its policy; there is deliberately no default, because the two
44
+ * answers are a real policy decision and guessing it either merges when a team did not want that,
45
+ * or silently stops landing PRs on a team that relied on it.
46
+ *
47
+ * AUTO — wp-finish-upsert-pr LANDS the PR: squash-merge it right away when it is mergeable, else
48
+ * enable GitHub auto-merge so it lands when the checks pass. Both carry an explicit --subject /
49
+ * --body-file, which is the ONLY way main's history gets the PR title plus the compact
50
+ * risk/flags body — no repo setting can produce that. Requires allow_auto_merge on the repo.
51
+ * NONE — wp-finish-upsert-pr only opens/updates the PR and stops; a human merges. NOTE the cost:
52
+ * a UI merge cannot use the compact body, so main's commit falls back to the repo's
53
+ * squash_merge_commit_title/message settings. Set squash_merge_commit_title=PR_TITLE there, or
54
+ * commits land as the internal "Squash merge of <branch>" subject.
55
+ */
56
+ mergeMode;
57
+ constructor(mode, buildCommand, gates, mergeMode) {
35
58
  this.mode = mode;
36
59
  this.buildCommand = buildCommand;
37
60
  this.gates = gates;
61
+ this.mergeMode = mergeMode;
38
62
  }
39
63
  }
40
64
  exports.PrGateConfig = PrGateConfig;
@@ -49,7 +73,7 @@ function defaultGates() {
49
73
  ];
50
74
  }
51
75
  function defaultPrGateConfig() {
52
- return new PrGateConfig('ON', '', defaultGates());
76
+ return new PrGateConfig('ON', '', defaultGates(), exports.MERGE_MODE_AUTO);
53
77
  }
54
78
  function toGate(raw) {
55
79
  return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.warningColor ?? 'yellow', raw.disabled ?? false);
@@ -69,6 +93,9 @@ function buildPrGateConfig(section) {
69
93
  const mode = raw.mode ?? defaults.mode;
70
94
  const buildCommand = raw.buildCommand ?? defaults.buildCommand;
71
95
  const gates = raw.gates !== undefined ? raw.gates.map(toGate) : defaults.gates;
72
- return new PrGateConfig(mode, buildCommand, gates);
96
+ // REQUIRED validatePrGateSection rejects an omitted/unknown value, so this fallback only ever
97
+ // applies to the no-config-file path that defaultPrGateConfig() serves.
98
+ const mergeMode = raw.mergeMode ?? defaults.mergeMode;
99
+ return new PrGateConfig(mode, buildCommand, gates, mergeMode);
73
100
  }
74
101
  //# sourceMappingURL=pr-gate-config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pr-gate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/pr-gate-config.ts"],"names":[],"mappings":";AAAA,2FAA2F;AAC3F,2FAA2F;AAC3F,iFAAiF;AACjF,iGAAiG;;;AAoCjG,oCAOC;AAED,kDAEC;AA0BD,8CASC;AAhFD,MAAa,cAAc;IACvB,IAAI,CAAS;IACb,QAAQ,CAAW;IACnB,iGAAiG;IACjG,8FAA8F;IAC9F,+FAA+F;IAC/F,gGAAgG;IAChG,YAAY,CAAS,CAAC,mBAAmB;IACzC,2FAA2F;IAC3F,yFAAyF;IACzF,QAAQ,CAAU;IAElB,YAAY,IAAY,EAAE,QAAkB,EAAE,YAAoB,EAAE,QAAQ,GAAG,KAAK;QAChF,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;CACJ;AAlBD,wCAkBC;AAED,MAAa,YAAY;IACrB,IAAI,CAAS;IACb,YAAY,CAAS;IACrB,KAAK,CAAmB;IAExB,YAAY,IAAY,EAAE,YAAoB,EAAE,KAAuB;QACnE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;CACJ;AAVD,oCAUC;AAED,0FAA0F;AAC1F,qEAAqE;AACrE,SAAgB,YAAY;IACxB,OAAO;QACH,IAAI,cAAc,CAAC,aAAa,EAAE,CAAC,mBAAmB,EAAE,YAAY,CAAC,EAAE,QAAQ,CAAC;QAChF,IAAI,cAAc,CAAC,sBAAsB,EAAE,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,QAAQ,CAAC;QAC1H,IAAI,cAAc,CAAC,0BAA0B,EAAE,CAAC,gCAAgC,CAAC,EAAE,QAAQ,CAAC;QAC5F,IAAI,cAAc,CAAC,wBAAwB,EAAE,CAAC,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,uBAAuB,CAAC,EAAE,QAAQ,CAAC;KACpI,CAAC;AACN,CAAC;AAED,SAAgB,mBAAmB;IAC/B,OAAO,IAAI,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;AACtD,CAAC;AAeD,SAAS,MAAM,CAAC,GAAY;IACxB,OAAO,IAAI,cAAc,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC,QAAQ,IAAI,EAAE,EAAE,GAAG,CAAC,YAAY,IAAI,QAAQ,EAAE,GAAG,CAAC,QAAQ,IAAI,KAAK,CAAC,CAAC;AACvH,CAAC;AAED;;;;;GAKG;AACH,4FAA4F;AAC5F,SAAgB,iBAAiB,CAAC,OAAgB;IAC9C,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE9F,MAAM,GAAG,GAAG,OAA2B,CAAC;IACxC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC;IACvC,MAAM,YAAY,GAAG,GAAG,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,CAAC;IAC/D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IAC/E,OAAO,IAAI,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;AACvD,CAAC","sourcesContent":["// PrGateConfig is the \"special section\" for the pr-gate dashboard. It does NOT live in the\n// validated `rules` map (the FieldDef schema can't express nested object arrays), but as a\n// top-level `pr-gate` key in webpieces.config.json. It is built and validated by\n// loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.\n\nexport class GateDefinition {\n name: string;\n patterns: string[];\n // The warning color shown on the dashboard WHEN this gate's patterns match a changed file. Green\n // is implicit (shown when nothing matched), so it is never configured. warningColor is purely\n // visual — even 'red' never fails/blocks the PR (only the build gate can). 'yellow' = caution,\n // 'red' = louder \"look here\" flag (e.g. DB schema / migration changes). REQUIRED on every gate.\n warningColor: string; // 'yellow' | 'red'\n // Example/inactive gate: parsed and kept in the file (JSON has no comments) but skipped at\n // compute/render time. Other projects flip this to false and tune patterns/warningColor.\n disabled: boolean;\n\n constructor(name: string, patterns: string[], warningColor: string, disabled = false) {\n this.name = name;\n this.patterns = patterns;\n this.warningColor = warningColor;\n this.disabled = disabled;\n }\n}\n\nexport class PrGateConfig {\n mode: string;\n buildCommand: string;\n gates: GateDefinition[];\n\n constructor(mode: string, buildCommand: string, gates: GateDefinition[]) {\n this.mode = mode;\n this.buildCommand = buildCommand;\n this.gates = gates;\n }\n}\n\n// Default infra gates — path-pattern based, tuned for this monorepo. Clients override the\n// whole list via the `pr-gate.gates` array in webpieces.config.json.\nexport function defaultGates(): GateDefinition[] {\n return [\n new GateDefinition('API Changed', ['libraries/apis/**', '**/*Api.ts'], 'yellow'),\n new GateDefinition('Config Files Changed', ['**/package.json', '**/tsconfig*.json', 'nx.json', '**/*.config.*'], 'yellow'),\n new GateDefinition('Dependency Graph Changed', ['architecture/dependencies.json'], 'yellow'),\n new GateDefinition('Claude / Rules Changed', ['**/CLAUDE.md', '**/claude.*.md', '.claude/**', 'webpieces.config.json'], 'yellow'),\n ];\n}\n\nexport function defaultPrGateConfig(): PrGateConfig {\n return new PrGateConfig('ON', '', defaultGates());\n}\n\ninterface RawGate {\n name?: string;\n patterns?: string[];\n warningColor?: string;\n disabled?: boolean;\n}\n\ninterface RawPrGateSection {\n mode?: string;\n buildCommand?: string;\n gates?: RawGate[];\n}\n\nfunction toGate(raw: RawGate): GateDefinition {\n return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.warningColor ?? 'yellow', raw.disabled ?? false);\n}\n\n/**\n * Build a PrGateConfig from the already-parsed top-level `pr-gate` section, falling back to defaults\n * for any field the consumer omits. Pure transform — the file read + structural validation happen in\n * loadAndValidate (load-config.ts) so every consumer goes through one validated path. Pass undefined\n * (no `pr-gate` key / no config file) to get full defaults.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here\nexport function buildPrGateConfig(section: unknown): PrGateConfig {\n const defaults = defaultPrGateConfig();\n if (section === undefined || section === null || typeof section !== 'object') return defaults;\n\n const raw = section as RawPrGateSection;\n const mode = raw.mode ?? defaults.mode;\n const buildCommand = raw.buildCommand ?? defaults.buildCommand;\n const gates = raw.gates !== undefined ? raw.gates.map(toGate) : defaults.gates;\n return new PrGateConfig(mode, buildCommand, gates);\n}\n"]}
1
+ {"version":3,"file":"pr-gate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/pr-gate-config.ts"],"names":[],"mappings":"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","sourcesContent":["// PrGateConfig is the \"special section\" for the pr-gate dashboard. It does NOT live in the\n// validated `rules` map (the FieldDef schema can't express nested object arrays), but as a\n// top-level `pr-gate` key in webpieces.config.json. It is built and validated by\n// loadAndValidate (load-config.ts); this module holds only the data classes + defaults + toGate.\n\nexport class GateDefinition {\n name: string;\n patterns: string[];\n // The warning color shown on the dashboard WHEN this gate's patterns match a changed file. Green\n // is implicit (shown when nothing matched), so it is never configured. warningColor is purely\n // visual — even 'red' never fails/blocks the PR (only the build gate can). 'yellow' = caution,\n // 'red' = louder \"look here\" flag (e.g. DB schema / migration changes). REQUIRED on every gate.\n warningColor: string; // 'yellow' | 'red'\n // Example/inactive gate: parsed and kept in the file (JSON has no comments) but skipped at\n // compute/render time. Other projects flip this to false and tune patterns/warningColor.\n disabled: boolean;\n\n constructor(name: string, patterns: string[], warningColor: string, disabled = false) {\n this.name = name;\n this.patterns = patterns;\n this.warningColor = warningColor;\n this.disabled = disabled;\n }\n}\n\n// How wp-finish-upsert-pr should try to LAND the PR once it has posted it. GitHub's auto-merge queue\n// is a REPO-level setting (`allow_auto_merge`) that many orgs turn OFF as a policy control, and it\n// CANNOT be forced from the client: `gh pr merge --auto` calls the enablePullRequestAutoMerge GraphQL\n// mutation, which hard-errors with \"Auto merge is not allowed for this repository\" when the repo says\n// no. So the only lever a config knob has is WHICH PATHS WE ATTEMPT — never whether the queue exists.\nexport const MERGE_MODE_AUTO = 'AUTO';\nexport const MERGE_MODE_NONE = 'NONE';\nexport const MERGE_MODES = [MERGE_MODE_AUTO, MERGE_MODE_NONE];\n\nexport class PrGateConfig {\n mode: string;\n buildCommand: string;\n gates: GateDefinition[];\n /**\n * REQUIRED — every repo must state its policy; there is deliberately no default, because the two\n * answers are a real policy decision and guessing it either merges when a team did not want that,\n * or silently stops landing PRs on a team that relied on it.\n *\n * AUTO — wp-finish-upsert-pr LANDS the PR: squash-merge it right away when it is mergeable, else\n * enable GitHub auto-merge so it lands when the checks pass. Both carry an explicit --subject /\n * --body-file, which is the ONLY way main's history gets the PR title plus the compact\n * risk/flags body — no repo setting can produce that. Requires allow_auto_merge on the repo.\n * NONE — wp-finish-upsert-pr only opens/updates the PR and stops; a human merges. NOTE the cost:\n * a UI merge cannot use the compact body, so main's commit falls back to the repo's\n * squash_merge_commit_title/message settings. Set squash_merge_commit_title=PR_TITLE there, or\n * commits land as the internal \"Squash merge of <branch>\" subject.\n */\n mergeMode: string;\n\n constructor(mode: string, buildCommand: string, gates: GateDefinition[], mergeMode: string) {\n this.mode = mode;\n this.buildCommand = buildCommand;\n this.gates = gates;\n this.mergeMode = mergeMode;\n }\n}\n\n// Default infra gates — path-pattern based, tuned for this monorepo. Clients override the\n// whole list via the `pr-gate.gates` array in webpieces.config.json.\nexport function defaultGates(): GateDefinition[] {\n return [\n new GateDefinition('API Changed', ['libraries/apis/**', '**/*Api.ts'], 'yellow'),\n new GateDefinition('Config Files Changed', ['**/package.json', '**/tsconfig*.json', 'nx.json', '**/*.config.*'], 'yellow'),\n new GateDefinition('Dependency Graph Changed', ['architecture/dependencies.json'], 'yellow'),\n new GateDefinition('Claude / Rules Changed', ['**/CLAUDE.md', '**/claude.*.md', '.claude/**', 'webpieces.config.json'], 'yellow'),\n ];\n}\n\nexport function defaultPrGateConfig(): PrGateConfig {\n return new PrGateConfig('ON', '', defaultGates(), MERGE_MODE_AUTO);\n}\n\ninterface RawGate {\n name?: string;\n patterns?: string[];\n warningColor?: string;\n disabled?: boolean;\n}\n\ninterface RawPrGateSection {\n mode?: string;\n buildCommand?: string;\n gates?: RawGate[];\n mergeMode?: string;\n}\n\nfunction toGate(raw: RawGate): GateDefinition {\n return new GateDefinition(raw.name ?? '', raw.patterns ?? [], raw.warningColor ?? 'yellow', raw.disabled ?? false);\n}\n\n/**\n * Build a PrGateConfig from the already-parsed top-level `pr-gate` section, falling back to defaults\n * for any field the consumer omits. Pure transform — the file read + structural validation happen in\n * loadAndValidate (load-config.ts) so every consumer goes through one validated path. Pass undefined\n * (no `pr-gate` key / no config file) to get full defaults.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed here\nexport function buildPrGateConfig(section: unknown): PrGateConfig {\n const defaults = defaultPrGateConfig();\n if (section === undefined || section === null || typeof section !== 'object') return defaults;\n\n const raw = section as RawPrGateSection;\n const mode = raw.mode ?? defaults.mode;\n const buildCommand = raw.buildCommand ?? defaults.buildCommand;\n const gates = raw.gates !== undefined ? raw.gates.map(toGate) : defaults.gates;\n // REQUIRED — validatePrGateSection rejects an omitted/unknown value, so this fallback only ever\n // applies to the no-config-file path that defaultPrGateConfig() serves.\n const mergeMode = raw.mergeMode ?? defaults.mergeMode;\n return new PrGateConfig(mode, buildCommand, gates, mergeMode);\n}\n"]}
@@ -190,6 +190,20 @@ function validateWebpiecesConfig(rawRules, hasCustomRulesDir = false) {
190
190
  return errors;
191
191
  }
192
192
  const PR_GATE_MODES = ['ON', 'OFF'];
193
+ // Optional — omitted means DETECT. Kept inline (like prGateExample) to avoid a load-config ↔
194
+ // pr-gate-config import cycle; the canonical list + semantics live in pr-gate-config.ts.
195
+ const PR_GATE_MERGE_MODES = ['AUTO', 'NONE'];
196
+ // Spelled out because the choice is a POLICY decision with a consequence the chooser cannot see:
197
+ // only the AUTO path can put the compact risk/flags body in main's history, because a UI merge is
198
+ // limited to the repo's squash_merge_commit_title/message settings and no setting produces it.
199
+ const MERGE_MODE_HELP = (`Must be one of: ${PR_GATE_MERGE_MODES.join(', ')}.\n` +
200
+ ` "AUTO" — wp-finish-upsert-pr lands the PR: it squash-merges when mergeable, else enables\n` +
201
+ ` GitHub auto-merge, both with an explicit --subject/--body-file so main's history\n` +
202
+ ` gets the PR title + the compact risk/flags body. Needs allow_auto_merge on the repo\n` +
203
+ ` (gh api repos/{owner}/{repo} --jq .allow_auto_merge).\n` +
204
+ ` "NONE" — wp-finish-upsert-pr only opens/updates the PR; a human merges it. The compact body\n` +
205
+ ` is then impossible, so set the repo's squash_merge_commit_title to PR_TITLE or\n` +
206
+ ` commits land as the internal "Squash merge of <branch>" subject.`);
193
207
  // Copy-paste example for the top-level `pr-gate` block (sibling of `rules`). Kept inline rather
194
208
  // than imported from pr-gate-config.ts to avoid a load-config ↔ pr-gate-config import cycle.
195
209
  function prGateExample() {
@@ -247,13 +261,22 @@ function validatePrGateSection(section) {
247
261
  else if (typeof s['mode'] !== 'string' || !PR_GATE_MODES.includes(s['mode'])) {
248
262
  errors.push(`[pr-gate] "mode" = "${String(s['mode'])}" is not valid. Must be one of: ${PR_GATE_MODES.join(', ')}.`);
249
263
  }
250
- // buildCommand is required whenever the gate is active (mode !== OFF).
264
+ // buildCommand and mergeMode are both required whenever the gate is active (mode !== OFF). There
265
+ // is deliberately NO default for mergeMode: whether the tooling may land your PRs is a policy
266
+ // decision, and either guess is wrong for somebody.
251
267
  if (s['mode'] !== 'OFF') {
252
268
  const cmd = s['buildCommand'];
253
269
  if (typeof cmd !== 'string' || cmd.trim() === '') {
254
270
  errors.push(`[pr-gate] Missing required field "buildCommand" — the command CI runs to validate a PR. ` +
255
271
  `Add e.g. "buildCommand": "pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)".`);
256
272
  }
273
+ const mm = s['mergeMode'];
274
+ if (!('mergeMode' in s)) {
275
+ errors.push(`[pr-gate] Missing required field "mergeMode". ${MERGE_MODE_HELP}`);
276
+ }
277
+ else if (typeof mm !== 'string' || !PR_GATE_MERGE_MODES.includes(mm)) {
278
+ errors.push(`[pr-gate] "mergeMode" = "${String(mm)}" is not valid. ${MERGE_MODE_HELP}`);
279
+ }
257
280
  }
258
281
  if ('gates' in s) {
259
282
  const gates = s['gates'];
@@ -1 +1 @@
1
- {"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/validate-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { FieldDef } from './field-def';\nimport { sectionForRule, isHookGuard } from './sections';\nimport { MODIFIED_CODE_MODES } from './rule-configs';\nimport { DEFAULT_MATCH_RULES } from './match-rules-config';\nimport { toError } from './to-error';\nimport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n BranchCreationGuardConfig,\n PrCreationOrPushGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeGuardConfig,\n RedirectHowToMergeMainConfig,\n FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n MissingDesignAnnotationConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n} from './rule-configs';\n\n// Thin lookup table — each entry delegates to the class's own SCHEMA.\n// No field lists here; all schemas live with their config class.\nconst RULE_SCHEMAS: Record<string, Record<string, FieldDef>> = {\n 'max-method-lines': MaxMethodLinesConfig.SCHEMA,\n 'max-file-lines': MaxFileLinesConfig.SCHEMA,\n 'require-return-type': RequireReturnTypeConfig.SCHEMA,\n 'no-inline-type-literals': NoInlineTypeLiteralsConfig.SCHEMA,\n 'no-any-unknown': NoAnyUnknownConfig.SCHEMA,\n 'no-implicit-any': NoImplicitAnyConfig.SCHEMA,\n 'prisma-validate-dtos': PrismaValidateDtosConfig.SCHEMA,\n 'prisma-converter': PrismaConverterConfig.SCHEMA,\n 'no-destructure': NoDestructureConfig.SCHEMA,\n 'no-unmanaged-exceptions': NoUnmanagedExceptionsConfig.SCHEMA,\n 'catch-error-pattern': CatchErrorPatternConfig.SCHEMA,\n 'throw-cause-required': ThrowCauseRequiredConfig.SCHEMA,\n 'angular-no-direct-api-in-resolver': AngularNoDirectApiInResolverConfig.SCHEMA,\n 'no-symbol-di-tokens': NoSymbolDiTokensConfig.SCHEMA,\n 'no-custom-css': NoCustomCssConfig.SCHEMA,\n 'no-process-exit-outside-main': NoProcessExitOutsideMainConfig.SCHEMA,\n 'no-function-outside-class': NoFunctionOutsideClassConfig.SCHEMA,\n 'inject-annotation-not-needed-for-concrete-class': InjectAnnotationNotNeededForConcreteClassConfig.SCHEMA,\n 'framework-tag': FrameworkTagConfig.SCHEMA,\n 'role-tag': RoleTagConfig.SCHEMA,\n 'branch-creation-guard': BranchCreationGuardConfig.SCHEMA,\n 'pr-creation-or-push-guard': PrCreationOrPushGuardConfig.SCHEMA,\n 'merge-in-progress-guard': MergeInProgressGuardConfig.SCHEMA,\n 'pr-merge-guard': PrMergeGuardConfig.SCHEMA,\n 'redirect-how-to-merge-main': RedirectHowToMergeMainConfig.SCHEMA,\n 'feature-branch-guard': FeatureBranchGuardConfig.SCHEMA,\n 'read-stale-guard': ReadStaleGuardConfig.SCHEMA,\n 'merged-branch-bash-guard': MergedBranchBashGuardConfig.SCHEMA,\n 'no-file-import-cycles': NoFileImportCyclesConfig.SCHEMA,\n 'runtime-architecture': RuntimeArchitectureConfig.SCHEMA,\n 'nx-wiring': NxWiringConfig.SCHEMA,\n 'di-graph': DiGraphConfig.SCHEMA,\n 'missing-design-annotation': MissingDesignAnnotationConfig.SCHEMA,\n 'no-js-files': NoJsFilesConfig.SCHEMA,\n 'validate-ts-in-src': ValidateTsInSrcConfig.SCHEMA,\n};\n\n// Every built-in rule name that has a typed schema (code rules + bash guards). The installer uses\n// this (with sectionForRule) to seed a fresh webpieces.config.json with every rule in its section.\nexport function allRuleNames(): readonly string[] {\n return Object.keys(RULE_SCHEMAS);\n}\n\nfunction valueHint(def: FieldDef, key?: string): string {\n // ignoreModifiedUntilEpoch is required on every rule; 0 keeps the rule active (epoch in the\n // past), a future unix epoch (seconds) temporarily disables it. Spell that out for the AI.\n if (key === 'ignoreModifiedUntilEpoch') return '0 (0 = active; future unix-epoch seconds = temporarily off)';\n return def.enumValues\n ? `\"${def.enumValues.join(' | ')}\"`\n : def.type === 'string[]' ? '[\"<string>\", ...]'\n : def.type === 'number' ? '<number>'\n : def.type === 'boolean' ? '<boolean>'\n : '\"<string>\"';\n}\n\n// Scoped modes (narrowest → broadest) that enforce ONLY on what changed, so a rule can be\n// adopted gradually instead of all-at-once. When a rule offers one, recommend the first it\n// supports so a fresh config opts into a low-friction rollout rather than reflexively OFF.\nconst GRADUAL_MODE_PREFERENCE = [\n 'MODIFIED_PROJECTS',\n 'NEW_AND_MODIFIED_CODE',\n 'NEW_AND_MODIFIED_METHODS',\n 'MODIFIED_CLASS',\n 'NEW_METHODS',\n 'NEW_AND_MODIFIED_FILES',\n];\n\n/** A rollout hint for the copy-paste snippet: recommend the narrowest gradual mode the rule supports. */\nfunction rolloutTip(schema: Record<string, FieldDef>): string {\n const modes = schema['mode']?.enumValues ?? [];\n const recommended = GRADUAL_MODE_PREFERENCE.find((m: string) => modes.includes(m));\n if (!recommended) return '';\n const optOut = modes.includes('OFF') ? ' Set \"mode\": \"OFF\" to opt out entirely.' : '';\n return (\n `\\n\\n💡 Recommended: start with \"mode\": \"${recommended}\" — it enforces only on what you ` +\n `actually change, so the rule rolls out gradually (existing code stays grandfathered until ` +\n `you next touch that project/file/method).${optOut}`\n );\n}\n\nfunction missingRuleSnippet(ruleName: string, schema: Record<string, FieldDef>): string {\n // Only required fields go in the copy-paste entry. Optional fields (e.g. the\n // universal escape hatches ignoreRuleWhileOnBranch / ignoreModifiedUntilEpoch)\n // are listed separately so the snippet doesn't over-state what's mandatory.\n const fields = Object.keys(schema);\n const required = fields.filter(f => !schema[f].optional);\n const optional = fields.filter(f => schema[f].optional);\n\n const requiredLines = required.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n const section = sectionForRule(ruleName);\n let out =\n `[${ruleName}] Not configured in webpieces.config.json. Add this entry to the \"${section}\" section\\n` +\n `(choose values appropriate for your project):\\n\\n` +\n ` \"${ruleName}\": {\\n${requiredLines.join(',\\n')}\\n }`;\n\n if (optional.length > 0) {\n const optionalLines = optional.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n out +=\n `\\n\\nOptional fields you may add to this rule (omit if not needed):\\n` +\n `${optionalLines.join(',\\n')}`;\n }\n out += rolloutTip(schema);\n return out;\n}\n\n// A config key under rules/hookGuards that the RUNNING validator has no schema for (and no rulesDir is\n// set to supply custom rules). Two very different causes, so the message leads with the common one:\n// 1. Version skew (most common — happens right after a dep bump): webpieces.config.json references a\n// rule a NEWER @webpieces release added, but the installed guard is OLDER and doesn't know it yet.\n// Fix = `pnpm install` (NOT deleting the key — the key is valid, the validator is just stale).\n// 2. A genuinely removed/renamed rule left behind, or a typo. Fix = remove the key.\n// Do NOT tell the AI to delete first — that destroys valid config in case 1 (the trap that made the AI\n// gut a working config instead of running `pnpm install`). The banner in load-config.ts spells out the\n// ordered \"run pnpm install, THEN edit only if it persists\" fix.\nfunction unknownRuleError(ruleName: string): string {\n return (\n `[${ruleName}] Unknown rule — the running @webpieces validator has no schema for it, and no ` +\n `\"rulesDir\" is configured to supply custom rules. Most often this means your installed guard is a ` +\n `release BEHIND this webpieces.config.json: run \\`pnpm install\\` first (see the fix steps below) so ` +\n `the validator learns \"${ruleName}\". Only if it is STILL unknown after a fresh install is it a ` +\n `removed/renamed rule or a typo — then remove the \"${ruleName}\" key from webpieces.config.json.`\n );\n}\n\n// Fields we DELETED from a rule's schema, keyed by \"<rule>.<field>\". The generic unknown-field error\n// (\"Unknown field ... Valid fields: [...]\") is correct but doesn't say WHY the field vanished, so an AI\n// might re-add it. These hints explain the removal so the only action left is to delete the key.\nconst RETIRED_FIELD_HINTS: Record<string, string> = {\n 'runtime-architecture.servicePaths':\n 'This field was removed — it was never read. The runtime graph is derived automatically from ' +\n 'architecture/dependencies.json (apiRelations + project roles). Delete it.',\n 'runtime-architecture.apiProjectPaths':\n 'This field was removed — it was never read. The runtime graph is derived automatically from ' +\n 'architecture/dependencies.json, so there is NO list of api libs to maintain. Delete it (do not ' +\n 'enumerate api libs and do not replace it with a glob).',\n};\n\n// webpieces-disable no-any-unknown -- rawRules values are opaque JSON; each field is validated individually\nexport function validateWebpiecesConfig(\n rawRules: Record<string, Record<string, unknown>>,\n hasCustomRulesDir: boolean = false,\n): string[] {\n const errors: string[] = [];\n\n // Check field-level correctness for rules that are present\n for (const [ruleName, entry] of Object.entries(rawRules)) {\n const schema = RULE_SCHEMAS[ruleName];\n if (!schema) {\n // No built-in schema. With no rulesDir there are no custom rules, so this key is a\n // dead/typo'd entry — tell the AI to remove it (a removed rule like no-shell-substitution\n // lingers here otherwise). With a rulesDir it may be a legitimate custom rule → skip.\n if (!hasCustomRulesDir) errors.push(unknownRuleError(ruleName));\n continue;\n }\n for (const [key, value] of Object.entries(entry)) {\n const fieldDef = schema[key];\n if (!fieldDef) {\n const retiredHint = RETIRED_FIELD_HINTS[`${ruleName}.${key}`];\n const suffix = retiredHint ? ` ${retiredHint}` : '';\n errors.push(`[${ruleName}] Unknown field \"${key}\". Valid fields: [${Object.keys(schema).join(', ')}].${suffix}`);\n continue;\n }\n if (fieldDef.type === 'string[]') {\n if (!Array.isArray(value) || !value.every(v => typeof v === 'string'))\n errors.push(`[${ruleName}] \"${key}\" must be string[], got ${typeof value}.`);\n } else if (typeof value !== fieldDef.type) {\n errors.push(`[${ruleName}] \"${key}\" must be ${fieldDef.type}, got ${typeof value}.`);\n } else if (fieldDef.enumValues && !fieldDef.enumValues.includes(value as string)) {\n errors.push(`[${ruleName}] \"${key}\" = \"${value}\" is not valid. Must be one of: ${fieldDef.enumValues.join(', ')}.`);\n }\n }\n // Required fields must actually be present. Until now the loop above only checked\n // fields that WERE present, so an entry like `{}` (or one missing `mode` /\n // `ignoreModifiedUntilEpoch`) slipped through. Every non-optional schema field is mandatory.\n for (const [key, fieldDef] of Object.entries(schema)) {\n if (!fieldDef.optional && !(key in entry)) {\n errors.push(`[${ruleName}] Missing required field \"${key}\". Add ${key}: ${valueHint(fieldDef, key)}.`);\n }\n }\n }\n\n // Every built-in rule must be explicitly configured — no silent defaults.\n // When a new rule is added to the framework, this check surfaces it immediately\n // with a ready-to-copy snippet so AI can configure it in one pass.\n for (const [ruleName, schema] of Object.entries(RULE_SCHEMAS)) {\n if (!(ruleName in rawRules)) {\n errors.push(missingRuleSnippet(ruleName, schema));\n }\n }\n\n return errors;\n}\n\nconst PR_GATE_MODES = ['ON', 'OFF'] as const;\n\n// Copy-paste example for the top-level `pr-gate` block (sibling of `rules`). Kept inline rather\n// than imported from pr-gate-config.ts to avoid a load-config ↔ pr-gate-config import cycle.\nfunction prGateExample(): string {\n return (\n ` \"pr-gate\": {\\n` +\n ` \"mode\": \"ON\",\\n` +\n ` \"buildCommand\": \"<command CI runs to validate a PR, e.g. pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)>\",\\n` +\n ` \"gates\": [\\n` +\n ` { \"name\": \"API Changed\", \"patterns\": [\"libraries/apis/**\", \"**/*Api.ts\"], \"warningColor\": \"yellow\" }\\n` +\n ` ]\\n` +\n ` }`\n );\n}\n\n// webpieces-disable no-any-unknown -- one gate entry from opaque consumer JSON, validated field-by-field\nfunction validateGate(gate: unknown, index: number): string[] {\n if (typeof gate !== 'object' || gate === null) {\n return [`[pr-gate] gates[${index}] must be an object { name, patterns, warningColor, disabled? }.`];\n }\n // webpieces-disable no-any-unknown -- narrowing one opaque gate object from consumer JSON\n const g = gate as Record<string, unknown>;\n const errors: string[] = [];\n if (typeof g['name'] !== 'string') errors.push(`[pr-gate] gates[${index}].name must be a string.`);\n if (!Array.isArray(g['patterns']) || !g['patterns'].every(p => typeof p === 'string'))\n errors.push(`[pr-gate] gates[${index}].patterns must be string[].`);\n if (g['warningColor'] === undefined)\n errors.push(`[pr-gate] gates[${index}].warningColor is required — set it to \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n else if (g['warningColor'] !== 'yellow' && g['warningColor'] !== 'red')\n errors.push(`[pr-gate] gates[${index}].warningColor must be \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n if (g['disabled'] !== undefined && typeof g['disabled'] !== 'boolean')\n errors.push(`[pr-gate] gates[${index}].disabled must be a boolean (example/inactive gate kept in the file).`);\n return errors;\n}\n\n/**\n * Validate the top-level `pr-gate` section. It is REQUIRED (a client that opts out sets mode \"OFF\").\n * `buildCommand` is required unless mode is \"OFF\". Returns human-readable, copy-paste-friendly errors\n * — never throws. The pr-gate block lives outside the FieldDef-driven `rules` schema because its\n * nested `gates` array can't be expressed there, so it gets its own structural validation here.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validatePrGateSection(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[pr-gate] Not configured in webpieces.config.json. Add this block under the \"commands\" ` +\n `section (set \"mode\": \"OFF\" to opt out):\\n\\n${prGateExample()}`,\n ];\n }\n if (typeof section !== 'object' || Array.isArray(section)) {\n return [`[pr-gate] Must be an object. Example:\\n\\n${prGateExample()}`];\n }\n // webpieces-disable no-any-unknown -- narrowing the opaque pr-gate section from consumer JSON\n const s = section as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!('mode' in s)) {\n errors.push(`[pr-gate] Missing required field \"mode\". Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n } else if (typeof s['mode'] !== 'string' || !PR_GATE_MODES.includes(s['mode'] as typeof PR_GATE_MODES[number])) {\n errors.push(`[pr-gate] \"mode\" = \"${String(s['mode'])}\" is not valid. Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n }\n\n // buildCommand is required whenever the gate is active (mode !== OFF).\n if (s['mode'] !== 'OFF') {\n const cmd = s['buildCommand'];\n if (typeof cmd !== 'string' || cmd.trim() === '') {\n errors.push(\n `[pr-gate] Missing required field \"buildCommand\" — the command CI runs to validate a PR. ` +\n `Add e.g. \"buildCommand\": \"pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)\".`,\n );\n }\n }\n\n if ('gates' in s) {\n const gates = s['gates'];\n if (!Array.isArray(gates)) {\n errors.push(`[pr-gate] \"gates\" must be an array of { name, patterns, warningColor, disabled? }.`);\n } else {\n for (let i = 0; i < gates.length; i += 1) {\n errors.push(...validateGate(gates[i], i));\n }\n }\n }\n\n return errors;\n}\n\nfunction excludePathsExample(): string {\n return '\"excludePaths\": {\\n' +\n ' \"rules\": [\"repositories/**\"],\\n' +\n ' \"guards\": []\\n' +\n ' }';\n}\n\n// One of the two excludePaths lists: required, must be a string[] (may be empty).\n// webpieces-disable no-any-unknown -- `value` is opaque consumer JSON until narrowed here\nfunction validateExcludeList(value: unknown, key: string): string[] {\n if (!(Array.isArray(value) && value.every(p => typeof p === 'string'))) {\n return [`[excludePaths] \"${key}\" must be a string[] of glob paths (use [] for none).`];\n }\n return [];\n}\n\n/**\n * Validate the REQUIRED top-level `excludePaths` block: two independent glob lists (`rules`,\n * `guards`) that suppress hook enforcement per file path. Required so every client upgrading is\n * forced to declare it (as [] to keep today's behavior, or with real paths). Returns copy-paste\n * friendly errors and never throws — same contract as validatePrGateSection.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validateExcludePaths(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[excludePaths] Not configured in webpieces.config.json. Add this REQUIRED block ` +\n `(use empty arrays to keep enforcing everywhere):\\n\\n ${excludePathsExample()}`,\n ];\n }\n if (typeof section !== 'object' || Array.isArray(section)) {\n return [`[excludePaths] Must be an object with \"rules\" and \"guards\" string arrays. Example:\\n\\n ${excludePathsExample()}`];\n }\n // webpieces-disable no-any-unknown -- narrowing the opaque excludePaths section from consumer JSON\n const s = section as Record<string, unknown>;\n return [\n ...validateExcludeList(s['rules'], 'rules'),\n ...validateExcludeList(s['guards'], 'guards'),\n ];\n}\n\n// ---------------------------------------------------------------------------\n// match-rules — a new top-level ARRAY section (parallel to pr-gate/excludePaths). Each entry is a\n// client-authored content guard (raw-regex patterns + message + scoping). Validated structurally here\n// the same way pr-gate's `gates` are, because an array of objects can't be expressed in FieldDef schema.\n// ---------------------------------------------------------------------------\n\nfunction matchRulesExample(): string {\n return `\"match-rules\": ${JSON.stringify(DEFAULT_MATCH_RULES, null, 4)}`;\n}\n\n// webpieces-disable no-any-unknown -- generic type guard over an opaque JSON value\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(v => typeof v === 'string');\n}\n\n// Compile a pattern to validate it; returns the error message, or undefined when it compiles.\nfunction regexError(pattern: string): string | undefined {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n // Constructed only to validate the syntax; the object is intentionally discarded.\n void new RegExp(pattern);\n return undefined;\n } catch (err: unknown) {\n const error = toError(err);\n return error.message;\n }\n}\n\n// One entry of the match-rules array, validated field-by-field (see validateGate for the pattern).\n// webpieces-disable no-any-unknown -- one match-rule entry from opaque consumer JSON, validated field-by-field\nfunction validateMatchRule(entry: unknown, index: number): string[] {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n return [`[match-rules] entry[${index}] must be an object { name, patterns, mainMessage, mode, ignoreModifiedUntilEpoch, ... }.`];\n }\n // webpieces-disable no-any-unknown -- narrowing one opaque match-rule entry from consumer JSON\n const e = entry as Record<string, unknown>;\n const label = typeof e['name'] === 'string' ? `\"${e['name']}\"` : `entry[${index}]`;\n const errors: string[] = [];\n\n if (typeof e['name'] !== 'string' || e['name'].trim() === '')\n errors.push(`[match-rules] entry[${index}].name must be a non-empty string (it is the disable token and report label).`);\n\n if (!isStringArray(e['patterns']) || e['patterns'].length === 0) {\n errors.push(`[match-rules] ${label}.patterns must be a non-empty string[] of regexes.`);\n } else {\n e['patterns'].forEach((p: string, pi: number) => {\n const rxErr = regexError(p);\n if (rxErr) errors.push(`[match-rules] ${label}.patterns[${pi}] is not a valid regex: ${rxErr}`);\n });\n }\n\n if (typeof e['mainMessage'] !== 'string' || e['mainMessage'].trim() === '')\n errors.push(`[match-rules] ${label}.mainMessage must be a non-empty string.`);\n\n if (typeof e['mode'] !== 'string' || !MODIFIED_CODE_MODES.includes(e['mode'] as typeof MODIFIED_CODE_MODES[number]))\n errors.push(`[match-rules] ${label}.mode must be one of: ${MODIFIED_CODE_MODES.join(', ')}.`);\n\n if (typeof e['ignoreModifiedUntilEpoch'] !== 'number')\n errors.push(`[match-rules] ${label}.ignoreModifiedUntilEpoch must be a number (0 = active; future unix-epoch seconds = temporarily off).`);\n\n if (e['options'] !== undefined && !isStringArray(e['options']))\n errors.push(`[match-rules] ${label}.options must be a string[] (omit if not needed).`);\n if (e['allowedPaths'] !== undefined && !isStringArray(e['allowedPaths']))\n errors.push(`[match-rules] ${label}.allowedPaths must be a string[] of globs (omit if not needed).`);\n if (e['disableAllowed'] !== undefined && typeof e['disableAllowed'] !== 'boolean')\n errors.push(`[match-rules] ${label}.disableAllowed must be a boolean.`);\n if (e['ignoreRuleWhileOnBranch'] !== undefined && typeof e['ignoreRuleWhileOnBranch'] !== 'string')\n errors.push(`[match-rules] ${label}.ignoreRuleWhileOnBranch must be a string.`);\n\n return errors;\n}\n\n/**\n * Validate the REQUIRED top-level `match-rules` array (client-authored content guards). MISSING →\n * one error printing the ready-to-paste `no-fetch` example (add at least this; more can follow).\n * Present-but-`[]` → allowed (a conscious opt-out, matching pr-gate mode:OFF / excludePaths []).\n * Otherwise every entry is validated field-by-field (each regex compile-checked) plus name\n * uniqueness. Copy-paste-friendly errors; never throws — same contract as validatePrGateSection.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validateMatchRulesSection(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[match-rules] Not configured in webpieces.config.json. Add this REQUIRED top-level array — ` +\n `seed it with the no-fetch guard below (you can add more entries: no-moment, no-lodash-chain, …):\\n\\n${matchRulesExample()}`,\n ];\n }\n if (!Array.isArray(section)) {\n return [`[match-rules] Must be an array of content-guard objects. Example:\\n\\n${matchRulesExample()}`];\n }\n\n const errors: string[] = [];\n const seen = new Set<string>();\n for (let i = 0; i < section.length; i += 1) {\n errors.push(...validateMatchRule(section[i], i));\n // webpieces-disable no-any-unknown -- reading the name off an opaque entry only to dedupe\n const name = (section[i] as Record<string, unknown> | null)?.['name'];\n if (typeof name === 'string') {\n if (seen.has(name)) errors.push(`[match-rules] duplicate entry name \"${name}\" — each match-rule name must be unique.`);\n seen.add(name);\n }\n }\n return errors;\n}\n\n/**\n * Enforce that each built-in lives in its correct section: code rules under `rules`, bash guards\n * under `hookGuards`. A guard left in `rules` (or a rule placed in `hookGuards`) is reported with a\n * \"move it\" message so the split stays clean. Unknown/custom names are ignored (they may be custom\n * rules from rulesDir). Presence (\"every built-in must be configured\") is checked separately by\n * validateWebpiecesConfig against the merged map.\n */\n// webpieces-disable no-any-unknown -- section maps are opaque consumer JSON\nexport function validateSectionPlacement(\n rulesSection: Record<string, Record<string, unknown>>,\n hookGuardsSection: Record<string, Record<string, unknown>>,\n): string[] {\n const errors: string[] = [];\n for (const name of Object.keys(rulesSection)) {\n if (isHookGuard(name)) {\n errors.push(\n `[${name}] is a hook guard and belongs in the \"hookGuards\" section, not \"rules\". ` +\n `Move it (or run \\`wp-install-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n for (const name of Object.keys(hookGuardsSection)) {\n // Only flag KNOWN code rules misplaced into hookGuards; unknown names may be custom rules.\n if (!isHookGuard(name) && RULE_SCHEMAS[name]) {\n errors.push(\n `[${name}] is a code rule and belongs in the \"rules\" section, not \"hookGuards\". ` +\n `Move it (or run \\`wp-install-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n return errors;\n}\n\n/**\n * Validate the `commands` section: its `pr-gate` block (delegated to validatePrGateSection) plus the\n * optional command-string fields. Also surfaces a migration error if a DEPRECATED top-level `pr-gate`\n * block is still present, telling the consumer to move it under `commands`.\n */\n// webpieces-disable no-any-unknown -- `commands`/`legacyPrGate` are opaque consumer JSON\nexport function validateCommandsSection(commands: unknown, legacyPrGate: unknown): string[] {\n const errors: string[] = [];\n\n if (legacyPrGate !== undefined) {\n errors.push(\n `[pr-gate] The top-level \"pr-gate\" block is deprecated. Move it under the \"commands\" ` +\n `section as commands[\"pr-gate\"] (run \\`wp-install-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n\n if (commands !== undefined && (typeof commands !== 'object' || commands === null || Array.isArray(commands))) {\n errors.push(`[commands] Must be an object { \"pr-gate\": {...}, \"upsertPr\": \"...\", \"mergeComplete\": \"...\" }.`);\n return errors;\n }\n\n // webpieces-disable no-any-unknown -- narrowing the opaque commands section from consumer JSON\n const c = (commands ?? {}) as Record<string, unknown>;\n\n // pr-gate is required (set mode OFF to opt out). Prefer commands[\"pr-gate\"]; fall back to the\n // legacy top-level block so an un-migrated file still validates its gate config.\n errors.push(...validatePrGateSection(c['pr-gate'] ?? legacyPrGate));\n\n for (const field of ['upsertPr', 'mergeComplete']) {\n if (field in c && typeof c[field] !== 'string') {\n errors.push(`[commands] \"${field}\" must be a string (the gated command to run).`);\n }\n }\n\n return errors;\n}\n"]}
1
+ {"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../../../../packages/tooling/rules-config/src/validate-config.ts"],"names":[],"mappings":"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","sourcesContent":["import { FieldDef } from './field-def';\nimport { sectionForRule, isHookGuard } from './sections';\nimport { MODIFIED_CODE_MODES } from './rule-configs';\nimport { DEFAULT_MATCH_RULES } from './match-rules-config';\nimport { toError } from './to-error';\nimport {\n MaxMethodLinesConfig,\n MaxFileLinesConfig,\n RequireReturnTypeConfig,\n NoInlineTypeLiteralsConfig,\n NoAnyUnknownConfig,\n NoImplicitAnyConfig,\n PrismaValidateDtosConfig,\n PrismaConverterConfig,\n NoDestructureConfig,\n NoUnmanagedExceptionsConfig,\n CatchErrorPatternConfig,\n ThrowCauseRequiredConfig,\n AngularNoDirectApiInResolverConfig,\n NoSymbolDiTokensConfig,\n NoCustomCssConfig,\n NoProcessExitOutsideMainConfig,\n NoFunctionOutsideClassConfig,\n InjectAnnotationNotNeededForConcreteClassConfig,\n FrameworkTagConfig,\n RoleTagConfig,\n BranchCreationGuardConfig,\n PrCreationOrPushGuardConfig,\n MergeInProgressGuardConfig,\n PrMergeGuardConfig,\n RedirectHowToMergeMainConfig,\n FeatureBranchGuardConfig,\n ReadStaleGuardConfig,\n MergedBranchBashGuardConfig,\n NoFileImportCyclesConfig,\n RuntimeArchitectureConfig,\n NxWiringConfig,\n DiGraphConfig,\n MissingDesignAnnotationConfig,\n NoJsFilesConfig,\n ValidateTsInSrcConfig,\n} from './rule-configs';\n\n// Thin lookup table — each entry delegates to the class's own SCHEMA.\n// No field lists here; all schemas live with their config class.\nconst RULE_SCHEMAS: Record<string, Record<string, FieldDef>> = {\n 'max-method-lines': MaxMethodLinesConfig.SCHEMA,\n 'max-file-lines': MaxFileLinesConfig.SCHEMA,\n 'require-return-type': RequireReturnTypeConfig.SCHEMA,\n 'no-inline-type-literals': NoInlineTypeLiteralsConfig.SCHEMA,\n 'no-any-unknown': NoAnyUnknownConfig.SCHEMA,\n 'no-implicit-any': NoImplicitAnyConfig.SCHEMA,\n 'prisma-validate-dtos': PrismaValidateDtosConfig.SCHEMA,\n 'prisma-converter': PrismaConverterConfig.SCHEMA,\n 'no-destructure': NoDestructureConfig.SCHEMA,\n 'no-unmanaged-exceptions': NoUnmanagedExceptionsConfig.SCHEMA,\n 'catch-error-pattern': CatchErrorPatternConfig.SCHEMA,\n 'throw-cause-required': ThrowCauseRequiredConfig.SCHEMA,\n 'angular-no-direct-api-in-resolver': AngularNoDirectApiInResolverConfig.SCHEMA,\n 'no-symbol-di-tokens': NoSymbolDiTokensConfig.SCHEMA,\n 'no-custom-css': NoCustomCssConfig.SCHEMA,\n 'no-process-exit-outside-main': NoProcessExitOutsideMainConfig.SCHEMA,\n 'no-function-outside-class': NoFunctionOutsideClassConfig.SCHEMA,\n 'inject-annotation-not-needed-for-concrete-class': InjectAnnotationNotNeededForConcreteClassConfig.SCHEMA,\n 'framework-tag': FrameworkTagConfig.SCHEMA,\n 'role-tag': RoleTagConfig.SCHEMA,\n 'branch-creation-guard': BranchCreationGuardConfig.SCHEMA,\n 'pr-creation-or-push-guard': PrCreationOrPushGuardConfig.SCHEMA,\n 'merge-in-progress-guard': MergeInProgressGuardConfig.SCHEMA,\n 'pr-merge-guard': PrMergeGuardConfig.SCHEMA,\n 'redirect-how-to-merge-main': RedirectHowToMergeMainConfig.SCHEMA,\n 'feature-branch-guard': FeatureBranchGuardConfig.SCHEMA,\n 'read-stale-guard': ReadStaleGuardConfig.SCHEMA,\n 'merged-branch-bash-guard': MergedBranchBashGuardConfig.SCHEMA,\n 'no-file-import-cycles': NoFileImportCyclesConfig.SCHEMA,\n 'runtime-architecture': RuntimeArchitectureConfig.SCHEMA,\n 'nx-wiring': NxWiringConfig.SCHEMA,\n 'di-graph': DiGraphConfig.SCHEMA,\n 'missing-design-annotation': MissingDesignAnnotationConfig.SCHEMA,\n 'no-js-files': NoJsFilesConfig.SCHEMA,\n 'validate-ts-in-src': ValidateTsInSrcConfig.SCHEMA,\n};\n\n// Every built-in rule name that has a typed schema (code rules + bash guards). The installer uses\n// this (with sectionForRule) to seed a fresh webpieces.config.json with every rule in its section.\nexport function allRuleNames(): readonly string[] {\n return Object.keys(RULE_SCHEMAS);\n}\n\nfunction valueHint(def: FieldDef, key?: string): string {\n // ignoreModifiedUntilEpoch is required on every rule; 0 keeps the rule active (epoch in the\n // past), a future unix epoch (seconds) temporarily disables it. Spell that out for the AI.\n if (key === 'ignoreModifiedUntilEpoch') return '0 (0 = active; future unix-epoch seconds = temporarily off)';\n return def.enumValues\n ? `\"${def.enumValues.join(' | ')}\"`\n : def.type === 'string[]' ? '[\"<string>\", ...]'\n : def.type === 'number' ? '<number>'\n : def.type === 'boolean' ? '<boolean>'\n : '\"<string>\"';\n}\n\n// Scoped modes (narrowest → broadest) that enforce ONLY on what changed, so a rule can be\n// adopted gradually instead of all-at-once. When a rule offers one, recommend the first it\n// supports so a fresh config opts into a low-friction rollout rather than reflexively OFF.\nconst GRADUAL_MODE_PREFERENCE = [\n 'MODIFIED_PROJECTS',\n 'NEW_AND_MODIFIED_CODE',\n 'NEW_AND_MODIFIED_METHODS',\n 'MODIFIED_CLASS',\n 'NEW_METHODS',\n 'NEW_AND_MODIFIED_FILES',\n];\n\n/** A rollout hint for the copy-paste snippet: recommend the narrowest gradual mode the rule supports. */\nfunction rolloutTip(schema: Record<string, FieldDef>): string {\n const modes = schema['mode']?.enumValues ?? [];\n const recommended = GRADUAL_MODE_PREFERENCE.find((m: string) => modes.includes(m));\n if (!recommended) return '';\n const optOut = modes.includes('OFF') ? ' Set \"mode\": \"OFF\" to opt out entirely.' : '';\n return (\n `\\n\\n💡 Recommended: start with \"mode\": \"${recommended}\" — it enforces only on what you ` +\n `actually change, so the rule rolls out gradually (existing code stays grandfathered until ` +\n `you next touch that project/file/method).${optOut}`\n );\n}\n\nfunction missingRuleSnippet(ruleName: string, schema: Record<string, FieldDef>): string {\n // Only required fields go in the copy-paste entry. Optional fields (e.g. the\n // universal escape hatches ignoreRuleWhileOnBranch / ignoreModifiedUntilEpoch)\n // are listed separately so the snippet doesn't over-state what's mandatory.\n const fields = Object.keys(schema);\n const required = fields.filter(f => !schema[f].optional);\n const optional = fields.filter(f => schema[f].optional);\n\n const requiredLines = required.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n const section = sectionForRule(ruleName);\n let out =\n `[${ruleName}] Not configured in webpieces.config.json. Add this entry to the \"${section}\" section\\n` +\n `(choose values appropriate for your project):\\n\\n` +\n ` \"${ruleName}\": {\\n${requiredLines.join(',\\n')}\\n }`;\n\n if (optional.length > 0) {\n const optionalLines = optional.map(f => ` \"${f}\": ${valueHint(schema[f], f)}`);\n out +=\n `\\n\\nOptional fields you may add to this rule (omit if not needed):\\n` +\n `${optionalLines.join(',\\n')}`;\n }\n out += rolloutTip(schema);\n return out;\n}\n\n// A config key under rules/hookGuards that the RUNNING validator has no schema for (and no rulesDir is\n// set to supply custom rules). Two very different causes, so the message leads with the common one:\n// 1. Version skew (most common — happens right after a dep bump): webpieces.config.json references a\n// rule a NEWER @webpieces release added, but the installed guard is OLDER and doesn't know it yet.\n// Fix = `pnpm install` (NOT deleting the key — the key is valid, the validator is just stale).\n// 2. A genuinely removed/renamed rule left behind, or a typo. Fix = remove the key.\n// Do NOT tell the AI to delete first — that destroys valid config in case 1 (the trap that made the AI\n// gut a working config instead of running `pnpm install`). The banner in load-config.ts spells out the\n// ordered \"run pnpm install, THEN edit only if it persists\" fix.\nfunction unknownRuleError(ruleName: string): string {\n return (\n `[${ruleName}] Unknown rule — the running @webpieces validator has no schema for it, and no ` +\n `\"rulesDir\" is configured to supply custom rules. Most often this means your installed guard is a ` +\n `release BEHIND this webpieces.config.json: run \\`pnpm install\\` first (see the fix steps below) so ` +\n `the validator learns \"${ruleName}\". Only if it is STILL unknown after a fresh install is it a ` +\n `removed/renamed rule or a typo — then remove the \"${ruleName}\" key from webpieces.config.json.`\n );\n}\n\n// Fields we DELETED from a rule's schema, keyed by \"<rule>.<field>\". The generic unknown-field error\n// (\"Unknown field ... Valid fields: [...]\") is correct but doesn't say WHY the field vanished, so an AI\n// might re-add it. These hints explain the removal so the only action left is to delete the key.\nconst RETIRED_FIELD_HINTS: Record<string, string> = {\n 'runtime-architecture.servicePaths':\n 'This field was removed — it was never read. The runtime graph is derived automatically from ' +\n 'architecture/dependencies.json (apiRelations + project roles). Delete it.',\n 'runtime-architecture.apiProjectPaths':\n 'This field was removed — it was never read. The runtime graph is derived automatically from ' +\n 'architecture/dependencies.json, so there is NO list of api libs to maintain. Delete it (do not ' +\n 'enumerate api libs and do not replace it with a glob).',\n};\n\n// webpieces-disable no-any-unknown -- rawRules values are opaque JSON; each field is validated individually\nexport function validateWebpiecesConfig(\n rawRules: Record<string, Record<string, unknown>>,\n hasCustomRulesDir: boolean = false,\n): string[] {\n const errors: string[] = [];\n\n // Check field-level correctness for rules that are present\n for (const [ruleName, entry] of Object.entries(rawRules)) {\n const schema = RULE_SCHEMAS[ruleName];\n if (!schema) {\n // No built-in schema. With no rulesDir there are no custom rules, so this key is a\n // dead/typo'd entry — tell the AI to remove it (a removed rule like no-shell-substitution\n // lingers here otherwise). With a rulesDir it may be a legitimate custom rule → skip.\n if (!hasCustomRulesDir) errors.push(unknownRuleError(ruleName));\n continue;\n }\n for (const [key, value] of Object.entries(entry)) {\n const fieldDef = schema[key];\n if (!fieldDef) {\n const retiredHint = RETIRED_FIELD_HINTS[`${ruleName}.${key}`];\n const suffix = retiredHint ? ` ${retiredHint}` : '';\n errors.push(`[${ruleName}] Unknown field \"${key}\". Valid fields: [${Object.keys(schema).join(', ')}].${suffix}`);\n continue;\n }\n if (fieldDef.type === 'string[]') {\n if (!Array.isArray(value) || !value.every(v => typeof v === 'string'))\n errors.push(`[${ruleName}] \"${key}\" must be string[], got ${typeof value}.`);\n } else if (typeof value !== fieldDef.type) {\n errors.push(`[${ruleName}] \"${key}\" must be ${fieldDef.type}, got ${typeof value}.`);\n } else if (fieldDef.enumValues && !fieldDef.enumValues.includes(value as string)) {\n errors.push(`[${ruleName}] \"${key}\" = \"${value}\" is not valid. Must be one of: ${fieldDef.enumValues.join(', ')}.`);\n }\n }\n // Required fields must actually be present. Until now the loop above only checked\n // fields that WERE present, so an entry like `{}` (or one missing `mode` /\n // `ignoreModifiedUntilEpoch`) slipped through. Every non-optional schema field is mandatory.\n for (const [key, fieldDef] of Object.entries(schema)) {\n if (!fieldDef.optional && !(key in entry)) {\n errors.push(`[${ruleName}] Missing required field \"${key}\". Add ${key}: ${valueHint(fieldDef, key)}.`);\n }\n }\n }\n\n // Every built-in rule must be explicitly configured — no silent defaults.\n // When a new rule is added to the framework, this check surfaces it immediately\n // with a ready-to-copy snippet so AI can configure it in one pass.\n for (const [ruleName, schema] of Object.entries(RULE_SCHEMAS)) {\n if (!(ruleName in rawRules)) {\n errors.push(missingRuleSnippet(ruleName, schema));\n }\n }\n\n return errors;\n}\n\nconst PR_GATE_MODES = ['ON', 'OFF'] as const;\n// Optional — omitted means DETECT. Kept inline (like prGateExample) to avoid a load-config ↔\n// pr-gate-config import cycle; the canonical list + semantics live in pr-gate-config.ts.\nconst PR_GATE_MERGE_MODES = ['AUTO', 'NONE'] as const;\n\n// Spelled out because the choice is a POLICY decision with a consequence the chooser cannot see:\n// only the AUTO path can put the compact risk/flags body in main's history, because a UI merge is\n// limited to the repo's squash_merge_commit_title/message settings and no setting produces it.\nconst MERGE_MODE_HELP = (\n `Must be one of: ${PR_GATE_MERGE_MODES.join(', ')}.\\n` +\n ` \"AUTO\" — wp-finish-upsert-pr lands the PR: it squash-merges when mergeable, else enables\\n` +\n ` GitHub auto-merge, both with an explicit --subject/--body-file so main's history\\n` +\n ` gets the PR title + the compact risk/flags body. Needs allow_auto_merge on the repo\\n` +\n ` (gh api repos/{owner}/{repo} --jq .allow_auto_merge).\\n` +\n ` \"NONE\" — wp-finish-upsert-pr only opens/updates the PR; a human merges it. The compact body\\n` +\n ` is then impossible, so set the repo's squash_merge_commit_title to PR_TITLE or\\n` +\n ` commits land as the internal \"Squash merge of <branch>\" subject.`\n);\n\n// Copy-paste example for the top-level `pr-gate` block (sibling of `rules`). Kept inline rather\n// than imported from pr-gate-config.ts to avoid a load-config ↔ pr-gate-config import cycle.\nfunction prGateExample(): string {\n return (\n ` \"pr-gate\": {\\n` +\n ` \"mode\": \"ON\",\\n` +\n ` \"buildCommand\": \"<command CI runs to validate a PR, e.g. pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)>\",\\n` +\n ` \"gates\": [\\n` +\n ` { \"name\": \"API Changed\", \"patterns\": [\"libraries/apis/**\", \"**/*Api.ts\"], \"warningColor\": \"yellow\" }\\n` +\n ` ]\\n` +\n ` }`\n );\n}\n\n// webpieces-disable no-any-unknown -- one gate entry from opaque consumer JSON, validated field-by-field\nfunction validateGate(gate: unknown, index: number): string[] {\n if (typeof gate !== 'object' || gate === null) {\n return [`[pr-gate] gates[${index}] must be an object { name, patterns, warningColor, disabled? }.`];\n }\n // webpieces-disable no-any-unknown -- narrowing one opaque gate object from consumer JSON\n const g = gate as Record<string, unknown>;\n const errors: string[] = [];\n if (typeof g['name'] !== 'string') errors.push(`[pr-gate] gates[${index}].name must be a string.`);\n if (!Array.isArray(g['patterns']) || !g['patterns'].every(p => typeof p === 'string'))\n errors.push(`[pr-gate] gates[${index}].patterns must be string[].`);\n if (g['warningColor'] === undefined)\n errors.push(`[pr-gate] gates[${index}].warningColor is required — set it to \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n else if (g['warningColor'] !== 'yellow' && g['warningColor'] !== 'red')\n errors.push(`[pr-gate] gates[${index}].warningColor must be \"yellow\" or \"red\" (green is implicit when nothing matches).`);\n if (g['disabled'] !== undefined && typeof g['disabled'] !== 'boolean')\n errors.push(`[pr-gate] gates[${index}].disabled must be a boolean (example/inactive gate kept in the file).`);\n return errors;\n}\n\n/**\n * Validate the top-level `pr-gate` section. It is REQUIRED (a client that opts out sets mode \"OFF\").\n * `buildCommand` is required unless mode is \"OFF\". Returns human-readable, copy-paste-friendly errors\n * — never throws. The pr-gate block lives outside the FieldDef-driven `rules` schema because its\n * nested `gates` array can't be expressed there, so it gets its own structural validation here.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validatePrGateSection(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[pr-gate] Not configured in webpieces.config.json. Add this block under the \"commands\" ` +\n `section (set \"mode\": \"OFF\" to opt out):\\n\\n${prGateExample()}`,\n ];\n }\n if (typeof section !== 'object' || Array.isArray(section)) {\n return [`[pr-gate] Must be an object. Example:\\n\\n${prGateExample()}`];\n }\n // webpieces-disable no-any-unknown -- narrowing the opaque pr-gate section from consumer JSON\n const s = section as Record<string, unknown>;\n const errors: string[] = [];\n\n if (!('mode' in s)) {\n errors.push(`[pr-gate] Missing required field \"mode\". Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n } else if (typeof s['mode'] !== 'string' || !PR_GATE_MODES.includes(s['mode'] as typeof PR_GATE_MODES[number])) {\n errors.push(`[pr-gate] \"mode\" = \"${String(s['mode'])}\" is not valid. Must be one of: ${PR_GATE_MODES.join(', ')}.`);\n }\n\n // buildCommand and mergeMode are both required whenever the gate is active (mode !== OFF). There\n // is deliberately NO default for mergeMode: whether the tooling may land your PRs is a policy\n // decision, and either guess is wrong for somebody.\n if (s['mode'] !== 'OFF') {\n const cmd = s['buildCommand'];\n if (typeof cmd !== 'string' || cmd.trim() === '') {\n errors.push(\n `[pr-gate] Missing required field \"buildCommand\" — the command CI runs to validate a PR. ` +\n `Add e.g. \"buildCommand\": \"pnpm nx affected --target=ci --base=$(git merge-base origin/main HEAD)\".`,\n );\n }\n const mm = s['mergeMode'];\n if (!('mergeMode' in s)) {\n errors.push(`[pr-gate] Missing required field \"mergeMode\". ${MERGE_MODE_HELP}`);\n } else if (typeof mm !== 'string' || !PR_GATE_MERGE_MODES.includes(mm as typeof PR_GATE_MERGE_MODES[number])) {\n errors.push(`[pr-gate] \"mergeMode\" = \"${String(mm)}\" is not valid. ${MERGE_MODE_HELP}`);\n }\n }\n\n if ('gates' in s) {\n const gates = s['gates'];\n if (!Array.isArray(gates)) {\n errors.push(`[pr-gate] \"gates\" must be an array of { name, patterns, warningColor, disabled? }.`);\n } else {\n for (let i = 0; i < gates.length; i += 1) {\n errors.push(...validateGate(gates[i], i));\n }\n }\n }\n\n return errors;\n}\n\nfunction excludePathsExample(): string {\n return '\"excludePaths\": {\\n' +\n ' \"rules\": [\"repositories/**\"],\\n' +\n ' \"guards\": []\\n' +\n ' }';\n}\n\n// One of the two excludePaths lists: required, must be a string[] (may be empty).\n// webpieces-disable no-any-unknown -- `value` is opaque consumer JSON until narrowed here\nfunction validateExcludeList(value: unknown, key: string): string[] {\n if (!(Array.isArray(value) && value.every(p => typeof p === 'string'))) {\n return [`[excludePaths] \"${key}\" must be a string[] of glob paths (use [] for none).`];\n }\n return [];\n}\n\n/**\n * Validate the REQUIRED top-level `excludePaths` block: two independent glob lists (`rules`,\n * `guards`) that suppress hook enforcement per file path. Required so every client upgrading is\n * forced to declare it (as [] to keep today's behavior, or with real paths). Returns copy-paste\n * friendly errors and never throws — same contract as validatePrGateSection.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validateExcludePaths(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[excludePaths] Not configured in webpieces.config.json. Add this REQUIRED block ` +\n `(use empty arrays to keep enforcing everywhere):\\n\\n ${excludePathsExample()}`,\n ];\n }\n if (typeof section !== 'object' || Array.isArray(section)) {\n return [`[excludePaths] Must be an object with \"rules\" and \"guards\" string arrays. Example:\\n\\n ${excludePathsExample()}`];\n }\n // webpieces-disable no-any-unknown -- narrowing the opaque excludePaths section from consumer JSON\n const s = section as Record<string, unknown>;\n return [\n ...validateExcludeList(s['rules'], 'rules'),\n ...validateExcludeList(s['guards'], 'guards'),\n ];\n}\n\n// ---------------------------------------------------------------------------\n// match-rules — a new top-level ARRAY section (parallel to pr-gate/excludePaths). Each entry is a\n// client-authored content guard (raw-regex patterns + message + scoping). Validated structurally here\n// the same way pr-gate's `gates` are, because an array of objects can't be expressed in FieldDef schema.\n// ---------------------------------------------------------------------------\n\nfunction matchRulesExample(): string {\n return `\"match-rules\": ${JSON.stringify(DEFAULT_MATCH_RULES, null, 4)}`;\n}\n\n// webpieces-disable no-any-unknown -- generic type guard over an opaque JSON value\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every(v => typeof v === 'string');\n}\n\n// Compile a pattern to validate it; returns the error message, or undefined when it compiles.\nfunction regexError(pattern: string): string | undefined {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n // Constructed only to validate the syntax; the object is intentionally discarded.\n void new RegExp(pattern);\n return undefined;\n } catch (err: unknown) {\n const error = toError(err);\n return error.message;\n }\n}\n\n// One entry of the match-rules array, validated field-by-field (see validateGate for the pattern).\n// webpieces-disable no-any-unknown -- one match-rule entry from opaque consumer JSON, validated field-by-field\nfunction validateMatchRule(entry: unknown, index: number): string[] {\n if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) {\n return [`[match-rules] entry[${index}] must be an object { name, patterns, mainMessage, mode, ignoreModifiedUntilEpoch, ... }.`];\n }\n // webpieces-disable no-any-unknown -- narrowing one opaque match-rule entry from consumer JSON\n const e = entry as Record<string, unknown>;\n const label = typeof e['name'] === 'string' ? `\"${e['name']}\"` : `entry[${index}]`;\n const errors: string[] = [];\n\n if (typeof e['name'] !== 'string' || e['name'].trim() === '')\n errors.push(`[match-rules] entry[${index}].name must be a non-empty string (it is the disable token and report label).`);\n\n if (!isStringArray(e['patterns']) || e['patterns'].length === 0) {\n errors.push(`[match-rules] ${label}.patterns must be a non-empty string[] of regexes.`);\n } else {\n e['patterns'].forEach((p: string, pi: number) => {\n const rxErr = regexError(p);\n if (rxErr) errors.push(`[match-rules] ${label}.patterns[${pi}] is not a valid regex: ${rxErr}`);\n });\n }\n\n if (typeof e['mainMessage'] !== 'string' || e['mainMessage'].trim() === '')\n errors.push(`[match-rules] ${label}.mainMessage must be a non-empty string.`);\n\n if (typeof e['mode'] !== 'string' || !MODIFIED_CODE_MODES.includes(e['mode'] as typeof MODIFIED_CODE_MODES[number]))\n errors.push(`[match-rules] ${label}.mode must be one of: ${MODIFIED_CODE_MODES.join(', ')}.`);\n\n if (typeof e['ignoreModifiedUntilEpoch'] !== 'number')\n errors.push(`[match-rules] ${label}.ignoreModifiedUntilEpoch must be a number (0 = active; future unix-epoch seconds = temporarily off).`);\n\n if (e['options'] !== undefined && !isStringArray(e['options']))\n errors.push(`[match-rules] ${label}.options must be a string[] (omit if not needed).`);\n if (e['allowedPaths'] !== undefined && !isStringArray(e['allowedPaths']))\n errors.push(`[match-rules] ${label}.allowedPaths must be a string[] of globs (omit if not needed).`);\n if (e['disableAllowed'] !== undefined && typeof e['disableAllowed'] !== 'boolean')\n errors.push(`[match-rules] ${label}.disableAllowed must be a boolean.`);\n if (e['ignoreRuleWhileOnBranch'] !== undefined && typeof e['ignoreRuleWhileOnBranch'] !== 'string')\n errors.push(`[match-rules] ${label}.ignoreRuleWhileOnBranch must be a string.`);\n\n return errors;\n}\n\n/**\n * Validate the REQUIRED top-level `match-rules` array (client-authored content guards). MISSING →\n * one error printing the ready-to-paste `no-fetch` example (add at least this; more can follow).\n * Present-but-`[]` → allowed (a conscious opt-out, matching pr-gate mode:OFF / excludePaths []).\n * Otherwise every entry is validated field-by-field (each regex compile-checked) plus name\n * uniqueness. Copy-paste-friendly errors; never throws — same contract as validatePrGateSection.\n */\n// webpieces-disable no-any-unknown -- `section` is opaque consumer JSON until narrowed below\nexport function validateMatchRulesSection(section: unknown): string[] {\n if (section === undefined || section === null) {\n return [\n `[match-rules] Not configured in webpieces.config.json. Add this REQUIRED top-level array — ` +\n `seed it with the no-fetch guard below (you can add more entries: no-moment, no-lodash-chain, …):\\n\\n${matchRulesExample()}`,\n ];\n }\n if (!Array.isArray(section)) {\n return [`[match-rules] Must be an array of content-guard objects. Example:\\n\\n${matchRulesExample()}`];\n }\n\n const errors: string[] = [];\n const seen = new Set<string>();\n for (let i = 0; i < section.length; i += 1) {\n errors.push(...validateMatchRule(section[i], i));\n // webpieces-disable no-any-unknown -- reading the name off an opaque entry only to dedupe\n const name = (section[i] as Record<string, unknown> | null)?.['name'];\n if (typeof name === 'string') {\n if (seen.has(name)) errors.push(`[match-rules] duplicate entry name \"${name}\" — each match-rule name must be unique.`);\n seen.add(name);\n }\n }\n return errors;\n}\n\n/**\n * Enforce that each built-in lives in its correct section: code rules under `rules`, bash guards\n * under `hookGuards`. A guard left in `rules` (or a rule placed in `hookGuards`) is reported with a\n * \"move it\" message so the split stays clean. Unknown/custom names are ignored (they may be custom\n * rules from rulesDir). Presence (\"every built-in must be configured\") is checked separately by\n * validateWebpiecesConfig against the merged map.\n */\n// webpieces-disable no-any-unknown -- section maps are opaque consumer JSON\nexport function validateSectionPlacement(\n rulesSection: Record<string, Record<string, unknown>>,\n hookGuardsSection: Record<string, Record<string, unknown>>,\n): string[] {\n const errors: string[] = [];\n for (const name of Object.keys(rulesSection)) {\n if (isHookGuard(name)) {\n errors.push(\n `[${name}] is a hook guard and belongs in the \"hookGuards\" section, not \"rules\". ` +\n `Move it (or run \\`wp-install-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n for (const name of Object.keys(hookGuardsSection)) {\n // Only flag KNOWN code rules misplaced into hookGuards; unknown names may be custom rules.\n if (!isHookGuard(name) && RULE_SCHEMAS[name]) {\n errors.push(\n `[${name}] is a code rule and belongs in the \"rules\" section, not \"hookGuards\". ` +\n `Move it (or run \\`wp-install-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n }\n return errors;\n}\n\n/**\n * Validate the `commands` section: its `pr-gate` block (delegated to validatePrGateSection) plus the\n * optional command-string fields. Also surfaces a migration error if a DEPRECATED top-level `pr-gate`\n * block is still present, telling the consumer to move it under `commands`.\n */\n// webpieces-disable no-any-unknown -- `commands`/`legacyPrGate` are opaque consumer JSON\nexport function validateCommandsSection(commands: unknown, legacyPrGate: unknown): string[] {\n const errors: string[] = [];\n\n if (legacyPrGate !== undefined) {\n errors.push(\n `[pr-gate] The top-level \"pr-gate\" block is deprecated. Move it under the \"commands\" ` +\n `section as commands[\"pr-gate\"] (run \\`wp-install-ai-hooks --sync\\` to migrate automatically).`,\n );\n }\n\n if (commands !== undefined && (typeof commands !== 'object' || commands === null || Array.isArray(commands))) {\n errors.push(`[commands] Must be an object { \"pr-gate\": {...}, \"upsertPr\": \"...\", \"mergeComplete\": \"...\" }.`);\n return errors;\n }\n\n // webpieces-disable no-any-unknown -- narrowing the opaque commands section from consumer JSON\n const c = (commands ?? {}) as Record<string, unknown>;\n\n // pr-gate is required (set mode OFF to opt out). Prefer commands[\"pr-gate\"]; fall back to the\n // legacy top-level block so an un-migrated file still validates its gate config.\n errors.push(...validatePrGateSection(c['pr-gate'] ?? legacyPrGate));\n\n for (const field of ['upsertPr', 'mergeComplete']) {\n if (field in c && typeof c[field] !== 'string') {\n errors.push(`[commands] \"${field}\" must be a string (the gated command to run).`);\n }\n }\n\n return errors;\n}\n"]}